@@ -6,12 +6,38 @@ defmodule Qex do
66 ## Protocols
77
88 `Inspect`, `Collectable` and `Enumerable` are implemented
9+
10+ iex> inspect Qex.new
11+ "<#Qex[]>"
12+
13+ iex> Enum.count Qex.new(1..5)
14+ 5
15+
16+ iex> Enum.empty? Qex.new
17+ true
18+
19+ iex> Enum.map Qex.new([1, 2, 3]), &(&1 + 1)
20+ [2, 3, 4]
21+
22+ iex> inspect Enum.into(1..5, %Qex{})
23+ "<#Qex[1, 2, 3, 4, 5]>"
924 """
1025
1126 @ opaque t :: % __MODULE__ { }
1227
1328 defstruct data: :queue . new
1429
30+ @ doc """
31+ Create a new queue from a range
32+
33+ iex> inspect Qex.new(1..3)
34+ "<#Qex[1, 2, 3]>"
35+
36+ Create a new queue from a list
37+
38+ iex> inspect Qex.new([1, 2, 3])
39+ "<#Qex[1, 2, 3]>"
40+ """
1541 @ spec new ( [ term ] | Range . t ) :: t
1642 def new ( init_data \\ [ ] )
1743
@@ -23,16 +49,43 @@ defmodule Qex do
2349 % __MODULE__ { data: :queue . from_list ( list ) }
2450 end
2551
52+ @ doc """
53+ Add an element to the back of the queue
54+
55+ iex> q = Qex.new([:mid])
56+ iex> Enum.to_list Qex.push(q, :back)
57+ [:mid, :back]
58+ """
2659 @ spec push ( t , term ) :: t
2760 def push ( % __MODULE__ { data: q } , item ) do
2861 % __MODULE__ { data: :queue . in ( item , q ) }
2962 end
3063
64+ @ doc """
65+ Add an element to the front of the queue
66+
67+ iex> q = Qex.new([:mid])
68+ iex> Enum.to_list Qex.push_front(q, :front)
69+ [:front, :mid]
70+ """
3171 @ spec push_front ( t , term ) :: t
3272 def push_front ( % __MODULE__ { data: q } , item ) do
3373 % __MODULE__ { data: :queue . in_r ( item , q ) }
3474 end
3575
76+ @ doc """
77+ Get and remove an element from the front of the queue
78+
79+ iex> q = Qex.new([:front, :mid])
80+ iex> {{:value, item}, _q} = Qex.pop(q)
81+ iex> item
82+ :front
83+
84+ iex> q = Qex.new
85+ iex> {empty, _q} = Qex.pop(q)
86+ iex> empty
87+ :empty
88+ """
3689 @ spec pop ( t ) :: { { :value , term } , t } | { :empty , t }
3790 def pop ( % __MODULE__ { data: q } ) do
3891 case :queue . out ( q ) do
@@ -49,6 +102,19 @@ defmodule Qex do
49102 end
50103 end
51104
105+ @ doc """
106+ Get and remove an element from the back of the queue
107+
108+ iex> q = Qex.new([:mid, :back])
109+ iex> {{:value, item}, _q} = Qex.pop_back(q)
110+ iex> item
111+ :back
112+
113+ iex> q = Qex.new
114+ iex> {empty, _q} = Qex.pop_back(q)
115+ iex> empty
116+ :empty
117+ """
52118 @ spec pop_back ( t ) :: { { :value , term } , t } | { :empty , t }
53119 def pop_back ( % __MODULE__ { data: q } ) do
54120 case :queue . out_r ( q ) do
@@ -65,18 +131,45 @@ defmodule Qex do
65131 end
66132 end
67133
134+ @ doc """
135+ Reverse a queue
136+
137+ iex> q = Qex.new(1..3)
138+ iex> Enum.to_list q
139+ [1, 2, 3]
140+ iex> Enum.to_list Qex.reverse(q)
141+ [3, 2, 1]
142+ """
68143 @ spec reverse ( t ) :: t
69144 def reverse ( % __MODULE__ { data: q } ) do
70145 % __MODULE__ { data: :queue . reverse ( q ) }
71146 end
72147
148+ @ doc """
149+ Split a queue into two, the front n items are put in the first queue
150+
151+ iex> q = Qex.new 1..5
152+ iex> {qex1, qex2} = Qex.split(q, 3)
153+ iex> Enum.to_list qex1
154+ [1, 2, 3]
155+ iex> Enum.to_list qex2
156+ [4, 5]
157+ """
73158 @ spec split ( t , pos_integer ) :: { t , t }
74159 def split ( % __MODULE__ { data: q } , n ) do
75160 with { q1 , q2 } <- :queue . split ( n , q ) do
76161 { % __MODULE__ { data: q1 } , % __MODULE__ { data: q2 } }
77162 end
78163 end
79164
165+ @ doc """
166+ Join two queues together
167+
168+ iex> q1 = Qex.new 1..3
169+ iex> q2 = Qex.new 4..5
170+ iex> Enum.to_list Qex.join(q1, q2)
171+ [1, 2, 3, 4, 5]
172+ """
80173 @ spec join ( t , t ) :: t
81174 def join ( % __MODULE__ { data: q1 } , % __MODULE__ { data: q2 } ) do
82175 % __MODULE__ { data: :queue . join ( q1 , q2 ) }
0 commit comments