# FIFO
A first-in-first-out queue data structure for Elixir. It wraps Erlang's
[:queue](https://erlang.org/doc/man/queue.html) in a more Elixir-friendly API.
It implements the `Inspect` protocol for pretty printing. It also implements the
`Enumerable` and `Collectable` protocols for working with collections. Functions
take a `FIFO` as the first argument to allow for piping.
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `fifo` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:fifo, "~> 0.1.0"}
]
end
```
## Basic Usage
```
iex(1)> queue = FIFO.new
#FIFO<[]>
iex(2)> queue = queue |> FIFO.push(1) |> FIFO.push(2)
#FIFO<[1, 2]>
iex(3)> {_, queue} = FIFO.pop(queue)
{{:value, 1}, #FIFO<[2]>}
iex(4)> {_, queue} = FIFO.pop(queue)
{{:value, 2}, #FIFO<[]>}
iex(5)> {_, queue} = FIFO.pop(queue)
{:empty, #FIFO<[]>}
```
## Enumerable and Collectable
```
iex(37)> queue = FIFO.new([1, 2])
#FIFO<[1, 2]>
iex(38)> queue = Enum.into([3, 4], queue)
#FIFO<[1, 2, 3, 4]>
iex(39)> squared = fn n -> n * n end
#Function<7.126501267/1 in :erl_eval.expr/5>
iex(40)> queue = Enum.map(queue, squared) |> FIFO.new
#FIFO<[1, 4, 9, 16]>
```
## Documentation
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc).
Run `mix docs` to generate documentation locally.
## Benchmarks
Where there is more than one way to perform the same operation, I have included
benchmarks. These are located in the `bench` folder. You run them like this:
`mix run bench/<filename>.exs`
Often an alternative exists because there is a `FIFO` implementation and an
`Enum` implementation. The `FIFO` implementations may be faster because
they utilize the Erlang `:queue` library, which is optimized. For example,
`FIFO.reverse/1` runs in constant time, `O(1)`, whereas `Enum.reverse/1` runs
in linear time, `O(n)`. See the benchmarks for more information.