defmodule A.Vector.Tail do @moduledoc false import A.Vector.CodeGen alias A.Vector.Node @type t(value) :: Node.t(value | nil) def pop_last(tail, i) do {elem(tail, i), put_elem(tail, i, nil)} end @compile {:inline, partial_map: 3} for i <- args_range() do # def partial_map({arg1, arg2, arg3, arg4}, fun, 2) do # {fun.(arg1), fun.(arg2), arg3, arg4} # end def partial_map(array(), fun, unquote(i)) do map_arguments(apply_mapper(var(fun))) |> take_drop_arguments(arguments(), unquote(i)) |> array() end end @compile {:inline, partial_to_list: 2} for i <- args_range() do # def partial_to_list({arg1, arg2, _arg3, _arg4}, 2) do # [arg1, arg2] # end def partial_to_list(array(arguments_with_wildcards(unquote(i))), unquote(i)) do take_arguments(unquote(i)) end end @compile {:inline, partial_reverse: 2} for i <- args_range() do # def partial_reverse({arg1, arg2, _arg3, _arg4}, 2) do # [arg2, arg1] # end def partial_reverse(array(arguments_with_wildcards(unquote(i))), unquote(i)) do reverse_arguments(take_arguments(unquote(i))) end end for i <- args_range() do # def partial_duplicate(value, 2) do # {value, value, nil, nil} # end def partial_duplicate(value, unquote(i)) do array(arguments_with_nils(duplicate_argument(value), unquote(i))) end end for i <- args_range() do # def partial_member?({arg1, arg2, _arg3, _arg4}, 2, value) do # (arg1 === value) or (arg2 === value) # end def partial_member?(array(arguments_with_wildcards(unquote(i))), unquote(i), value) do unquote(i) |> take_arguments() |> map_arguments(strict_equal_mapper(var(value))) |> reduce_arguments(&strict_or_reducer/2) end end for i <- args_range() do # def partial_any?({arg1, arg2, arg3, _arg4}, 3) do # arg1 || arg2 || arg3 # end def partial_any?(array(arguments_with_wildcards(unquote(i))), unquote(i)) do unquote(i) |> take_arguments() |> reduce_arguments(&or_reducer/2) end end for i <- args_range() do # def partial_any?({arg1, arg2, arg3, _arg4}, 3, fun) do # fun.(arg1) || fun.(arg2) || fun.(arg3) # end def partial_any?(array(arguments_with_wildcards(unquote(i))), unquote(i), fun) do unquote(i) |> take_arguments() |> map_arguments(apply_mapper(var(fun))) |> reduce_arguments(&or_reducer/2) end end for i <- args_range() do # def partial_all?({arg1, arg2, arg3, _arg4}, 3) do # arg1 && arg2 && arg3 # end def partial_all?(array(arguments_with_wildcards(unquote(i))), unquote(i)) do unquote(i) |> take_arguments() |> reduce_arguments(&and_reducer/2) end end for i <- args_range() do # def partial_all?({arg1, arg2, arg3, _arg4}, 3, fun) do # fun.(arg1) && fun.(arg2) && fun.(arg3) # end def partial_all?(array(arguments_with_wildcards(unquote(i))), unquote(i), fun) do unquote(i) |> take_arguments() |> map_arguments(apply_mapper(var(fun))) |> reduce_arguments(&and_reducer/2) end end def partial_sum(array(arguments_with_wildcards(1)), 1) do # sum with 0 to have an ArithmeticError for vectors of length 1 argument_at(0) + 0 end # case i == 1 needs to check this is an int for i <- args_range(), i > 1 do # def partial_sum({arg1, arg2, arg3, _arg4}, 3) do # arg1 + arg2 + arg3 # end def partial_sum(array(arguments_with_wildcards(unquote(i))), unquote(i)) do unquote(i) |> take_arguments() |> reduce_arguments(&sum_reducer/2) end end def partial_join_as_iodata( array(arguments_with_wildcards(1)), 1, _joiner ) do [to_string(argument_at(0))] end # case i = 1 needs to declare `_joiner`, not `joiner` for i <- args_range(), i > 1 do # def partial_join_as_iodata({arg1, arg2, arg3, _arg4}, 3, joiner) do # [to_string(arg1), joiner, to_string(arg2), joiner, to_string(arg3)] # end def partial_join_as_iodata( array(arguments_with_wildcards(unquote(i))), unquote(i), joiner ) do unquote(i) |> take_arguments() |> reverse_arguments() |> map_arguments(apply_mapper(var(&to_string/1))) |> reduce_arguments(intersperse_reducer(var(joiner))) end end def complete_tail(tail, tail_size, values) def complete_tail(tail, _tail_size, []) do {tail, 0, []} end for i <- args_range() do # def complete_tail({arg1, arg2, _arg3, _arg4}, 2, [arg3, arg4 | rest]) do # {{arg1, arg2, arg3, arg4}, 2, rest} # end def complete_tail( array(arguments_with_wildcards(unquote(i))), unquote(i), list_with_rest(drop_arguments(unquote(i)), rest) ) do {array(), unquote(branch_factor() - i), rest} end end for i <- args_range() do # def complete_tail(tail, tail_size, [arg1, arg2]) do # new_tail = put_elem(put_elem(tail, tail_size, arg1), tail_size + 1, arg2) # {new_tail, 2, []} # end def complete_tail(tail, tail_size, take_arguments(unquote(i))) do new_tail = unquote(i) |> take_arguments() |> reduce_arguments_with_index(tail, fn arg, index, acc -> quote do put_elem(unquote(acc), var!(tail_size) + unquote(index), unquote(arg)) end end) {new_tail, unquote(i), []} end end end