1
%% ``The contents of this file are subject to the Erlang Public License,
4
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
2
7
%% Version 1.1, (the "License"); you may not use this file except in
3
8
%% compliance with the License. You should have received a copy of the
4
9
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
10
%% retrieved online at http://www.erlang.org/.
7
12
%% Software distributed under the License is distributed on an "AS IS"
8
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
14
%% the License for the specific language governing rights and limitations
10
15
%% under the License.
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
20
21
%% Creation, inspection and conversion
21
-export([new/0,is_queue/1,is_empty/1,len/1,to_list/1,from_list/1]).
22
-export([new/0,is_queue/1,is_empty/1,len/1,to_list/1,from_list/1,member/2]).
22
23
%% Original style API
23
24
-export([in/2,in_r/2,out/1,out_r/1]).
24
25
%% Less garbage style API
43
44
%% that is; the RearList is reversed.
47
%% A declaration equivalent to the following is currently hard-coded
50
%% -opaque queue() :: {list(), list()}.
46
52
%% Creation, inspection and conversion
55
-spec new() -> queue().
49
56
new() -> {[],[]}. %{RearList,FrontList}
59
-spec is_queue(term()) -> bool().
52
60
is_queue({R,F}) when is_list(R), is_list(F) ->
66
-spec is_empty(queue()) -> bool().
58
67
is_empty({[],[]}) ->
60
69
is_empty({In,Out}) when is_list(In), is_list(Out) ->
63
72
erlang:error(badarg, [Q]).
75
-spec len(queue()) -> non_neg_integer().
66
76
len({R,F}) when is_list(R), is_list(F) ->
67
77
length(R)+length(F);
69
79
erlang:error(badarg, [Q]).
82
-spec to_list(queue()) -> list().
72
83
to_list({In,Out}) when is_list(In), is_list(Out) ->
73
84
Out++lists:reverse(In, []);
77
88
%% Create queue from list
91
-spec from_list(list()) -> queue().
80
92
from_list(L) when is_list(L) ->
83
95
erlang:error(badarg, [L]).
97
%% Return true or false depending on if element is in queue
99
%% O(length(Q)) worst case
100
-spec member(term(), queue()) -> bool().
101
member(X, {R,F}) when is_list(R), is_list(F) ->
102
lists:member(X, R) orelse lists:member(X, F);
104
erlang:error(badarg, [X,Q]).
85
106
%%--------------------------------------------------------------------------
86
107
%% Original style API
89
110
%% Put at least one element in each list, if it is cheap
113
-spec in(term(), queue()) -> queue().
92
114
in(X, {[_]=In,[]}) ->
94
116
in(X, {In,Out}) when is_list(In), is_list(Out) ->
100
122
%% Put at least one element in each list, if it is cheap
125
-spec in_r(term(), queue()) -> queue().
103
126
in_r(X, {[],[_]=F}) ->
105
128
in_r(X, {R,F}) when is_list(R), is_list(F) ->
147
172
%% Return the first element in the queue
149
174
%% O(1) since the queue is supposed to be well formed
175
-spec get(queue()) -> term().
150
176
get({[],[]}=Q) ->
151
177
erlang:error(empty, [Q]);
152
178
get({R,F}) when is_list(R), is_list(F) ->
161
188
get([_|R], []) -> % malformed queue -> O(len(Q))
166
191
%% Return the last element in the queue
168
193
%% O(1) since the queue is supposed to be well formed
194
-spec get_r(queue()) -> term().
169
195
get_r({[],[]}=Q) ->
170
196
erlang:error(empty, [Q]);
171
197
get_r({[H|_],F}) when is_list(F) ->
180
206
%% Return the first element in the queue
182
208
%% O(1) since the queue is supposed to be well formed
209
-spec peek(queue()) -> 'empty' | {'value',term()}.
185
212
peek({R,[H|_]}) when is_list(R) ->
194
221
%% Return the last element in the queue
196
223
%% O(1) since the queue is supposed to be well formed
224
-spec peek_r(queue()) -> 'empty' | {'value',term()}.
197
225
peek_r({[],[]}) ->
199
227
peek_r({[H|_],F}) when is_list(F) ->
255
286
%% Q2 empty: O(1)
256
287
%% else: O(len(Q1))
288
-spec join(queue(), queue()) -> queue().
257
289
join({R,F}=Q, {[],[]}) when is_list(R), is_list(F) ->
259
291
join({[],[]}, {R,F}=Q) when is_list(R), is_list(F) ->
269
301
%% O(max(N, len(Q)))
302
-spec split(non_neg_integer(), queue()) -> {queue(),queue()}.
270
303
split(0, {R,F}=Q) when is_list(R), is_list(F) ->
272
305
split(N, {R,F}=Q) when is_integer(N), N >= 1, is_list(R), is_list(F) ->
273
306
Lf = erlang:length(F),
274
307
if N < Lf -> % Lf >= 2
309
split_f1_to_r2(N-1, R, F1, [], [X]);
283
314
erlang:error(badarg, [N,Q]);
317
split_r1_to_f2(M-1, R1, F, [X], []);
312
341
%% Fun(_) -> List: O(length(List) * len(Q))
313
342
%% else: O(len(Q)
343
-spec filter(fun((term()) -> bool() | list()), queue()) -> queue().
314
344
filter(Fun, {R0,F0}) when is_function(Fun, 1), is_list(R0), is_list(F0) ->
315
345
F = filter_f(Fun, F0),
316
346
R = filter_r(Fun, R0),
394
425
%% Return the first element in the queue
396
427
%% O(1) since the queue is supposed to be well formed
428
-spec head(queue()) -> term().
397
429
head({[],[]}=Q) ->
398
430
erlang:error(empty, [Q]);
399
431
head({R,F}) when is_list(R), is_list(F) ->
446
-spec snoc(queue(), term()) -> queue().
416
450
%% Return last element
451
-spec daeh(queue()) -> term().
417
452
daeh(Q) -> get_r(Q).
453
-spec last(queue()) -> term().
418
454
last(Q) -> get_r(Q).
420
456
%% Remove last element and return resulting queue
457
-spec liat(queue()) -> queue().
421
458
liat(Q) -> drop_r(Q).
422
lait(Q) -> drop_r(Q). %% Oops, miss-spelled 'tail' reversed. Forget this one.
459
-spec lait(queue()) -> queue().
460
lait(Q) -> drop_r(Q). %% Oops, mis-spelled 'tail' reversed. Forget this one.
461
-spec init(queue()) -> queue().
423
462
init(Q) -> drop_r(Q).
425
464
%%--------------------------------------------------------------------------