Packages

A `:queue` wrapper with improvements in API and addition of Protocol implementations

Current section

Files

Jump to
qex lib queue.ex
Raw

lib/queue.ex

defmodule Qex do
@moduledoc ~S"""
A `:queue` wrapper with improvements in API and addition of Protocol implementations
## Protocols
`Inspect` and `Enumerable` are implemented
"""
@opaque t :: %__MODULE__{}
defstruct data: nil
@spec new([term] | Range.t) :: t
def new(init_data \\ [])
def new(x..y) do
%__MODULE__{data: :queue.from_list(Enum.to_list(x..y))}
end
def new(list) do
%__MODULE__{data: :queue.from_list(list)}
end
@spec push(t, term) :: t
def push(%__MODULE__{data: q}, item) do
%__MODULE__{data: :queue.in(item, q)}
end
@spec push_front(t, term) :: t
def push_front(%__MODULE__{data: q}, item) do
%__MODULE__{data: :queue.in_r(item, q)}
end
@spec pop(t) :: {{:value, term}, t} | {:empty, t}
def pop(%__MODULE__{data: q}) do
case :queue.out(q) do
{{:value, v}, q} -> {{:value, v}, %__MODULE__{data: q}}
{:empty, q} -> {:empty, %__MODULE__{data: q}}
end
end
@spec pop!(t) :: {term, t} | no_return
def pop!(%__MODULE__{data: q}) do
case :queue.out(q) do
{{:value, v}, q} -> {v, %__MODULE__{data: q}}
{:empty, _q} -> raise "Queue is empty"
end
end
@spec pop_back(t) :: {{:value, term}, t} | {:empty, t}
def pop_back(%__MODULE__{data: q}) do
case :queue.out_r(q) do
{{:value, v}, q} -> {{:value, v}, %__MODULE__{data: q}}
{:empty, q} -> {:empty, %__MODULE__{data: q}}
end
end
@spec pop_back!(t) :: {term, t} | no_return
def pop_back!(%__MODULE__{data: q}) do
case :queue.out_r(q) do
{{:value, v}, q} -> {v, %__MODULE__{data: q}}
{:empty, _q} -> raise "Queue is empty"
end
end
@spec reverse(t) :: t
def reverse(%__MODULE__{data: q}) do
%__MODULE__{data: :queue.reverse(q)}
end
@spec split(t, pos_integer) :: {t, t}
def split(%__MODULE__{data: q}, n) do
with {q1, q2} <- :queue.split(n, q) do
{%__MODULE__{data: q1}, %__MODULE__{data: q2}}
end
end
end