# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # Version 2, December 2004 # # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION # # 0. You just DO WHAT THE FUCK YOU WANT TO. defmodule Data do alias Data.Protocol, as: P alias Data.Error, as: E defmacro __using__(_opts) do quote location: :keep do alias Data.Dict alias Data.Set alias Data.Queue alias Data.Seq alias Data.Set alias Data.Stack end end alias Data.Seq @spec contains?(P.Contains.t | P.Sequence.t, any) :: any def contains?(self, what) do cond do mod = P.Contains.impl_for(self) -> mod.contains?(self, what) Enumerable.impl_for(self) -> Enum.member?(self, what) true -> Data.Seq.contains?(self, what) end end @spec seq(P.Sequence.t | P.ToSequence.t | P.ToList.t) :: P.Sequence.t def seq([]) do nil end def seq(value) when value |> is_atom or value |> is_list or value |> is_binary do value end def seq(self) do cond do empty?(self) -> nil P.Sequence.impl_for(self) -> self mod = P.ToSequence.impl_for(self) -> mod.to_sequence(self) true -> list(self) end end @spec list(list | P.ToList.t | P.Sequence.t | Enumerable.t) :: list def list(value) when value |> is_list do value end def list(nil) do [] end def list(value) do cond do mod = P.ToList.impl_for(value) -> mod.to_list(value) P.Sequence.impl_for(value) -> Seq.to_list(value) P.ToSequence.impl_for(value) -> Seq.to_list(value) P.Reduce.impl_for(value) -> P.Reduce.reduce(value, [], &[&1 | &2]) |> reverse Enumerable.impl_for(value) -> Enum.to_list(value) true -> [value] end end @spec peek(P.Peek.t) :: any @spec peek(P.Peek.t, any) :: any def peek(self, default \\ nil) do case P.Peek.peek(self) do { :value, value } -> value :empty -> default end end @spec peek!(P.Peek.t) :: any | no_return def peek!(self) do case P.Peek.peek(self) do { :value, value } -> value :empty -> raise E.Empty end end @spec reduce(P.Reduce.t, any, ((any, any) -> any)) :: any def reduce(self, acc, fun) do P.Reduce.reduce(self, acc, fun) end @spec empty?(P.Empty.t | P.Sequence.t) :: P.t def empty?(nil) do true end def empty?([]) do true end def empty?(list) when list |> is_list do false end def empty?(self) do cond do mod = P.Empty.impl_for(self) -> mod.empty?(self) mod = P.ToSequence.impl_for(self) -> mod.to_sequence(self) == nil mod = P.ToList.impl_for(self) -> mod.to_list(self) == [] true -> false end end @spec clear(P.Empty.t) :: P.Empty.t def clear(self) do P.Empty.clear(self) end @spec count(P.Count.t | P.Sequence.t | Enumerable.t) :: P.Count.t | Enumerable.t def count(self) do cond do mod = P.Count.impl_for(self) -> mod.count(self) Enumerable.impl_for(self) -> Enum.count(self) P.Sequence.impl_for(self) -> Seq.count(self) P.ToSequence.impl_for(self) -> Seq.count(self) P.Reduce.impl_for(self) -> P.Reduce.reduce(self, 0, &(&1 + 1)) end end @spec count(P.Sequence.t | Enumerable.t, (any -> boolean)) :: P.Count.t | Enumerable.t def count(self, pred) do cond do Enumerable.impl_for(self) -> Enum.count(self, pred) P.Sequence.impl_for(self) -> Seq.count(self, pred) P.ToSequence.impl_for(self) -> Seq.count(self, pred) P.Reduce.impl_for(self) -> P.Reduce.reduce(self, 0, fn value, acc -> if pred.(value) do acc + 1 else acc end end) end end @spec reverse(P.Reverse.t) :: P.Reverse.t def reverse(self) do P.Reverse.reverse(self) end @spec into(P.Into.t, any) :: P.Into.t def into(self, value) do P.Into.into(self, value) end end