A first-in-first-out queue data structure for Elixir. It wraps Erlang's
[:queue]( 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](, the package can be installed
by adding `fifo` to your list of dependencies in `mix.exs`:

def deps do
    {:fifo, "~> 0.1.0"}

## Basic Usage

iex(1)> queue =
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 =[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 =, squared) |>
#FIFO<[1, 4, 9, 16]>

## Documentation

Documentation can be generated with [ExDoc](
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.