1番下にある追記参照。
【ソース】
-module(stack).
-ifdef(debug).
-include_lib("eunit/include/eunit.hrl").
-endif.
-export([new/0,
is_stack/1,
is_empty/1,
len/1,
push/2,
pop/1,
from_list/1,
to_list/1,
reverse/1
]).
% -----
% stack of queue module
% -----
% stack()
-record( stack, { stk=undefined } ).
-define( __q, queue ).
-define( __is_q( X ), ?__q:is_queue( X ) ).
-define( __proc_q( X ), ( begin
case ?__is_q( Stack ) of
true ->
?__q:X( Stack );
_ ->
error
end
end )
).
% @spec new() -> stack()
new() ->
#stack{ stk=queue:new() }.
% @spec is_stack(Term::term()) -> boolean
is_stack( #stack{ stk=Stack } ) ->
?__is_q( Stack );
is_stack( _ ) ->
error.
% @spec is_empty(S :: stack()) -> boolean | error
%is_empty(Stack) ->
is_empty( #stack{ stk=Stack } ) ->
?__proc_q( is_empty );
is_empty( _ ) ->
error.
% @spec len( stack() ) -> integer() >= 0 | error
len( #stack{ stk=Stack } ) ->
?__proc_q( len );
len( _ ) ->
error.
% @spec push( term(), stack() ) -> stack() | error
push( Item, #stack{ stk=Stack } ) ->
case ?__is_q( Stack ) of
true ->
Stack1 = queue:in( Item, Stack ),
#stack{ stk=Stack1 };
_ ->
error
end;
push( _, _ ) ->
error.
% @spec pop( stack() ) -> {{value, term()}, stack()} | {empty, stack()} | error
pop( #stack{ stk=Stack } ) ->
Stack1 = ?__proc_q( out_r ),
case Stack1 of
{ { value, Value }, Queue } ->
{ {value, Value}, #stack{ stk=Queue } };
{ empty, Queue } ->
{ empty, #stack{ stk=Queue } };
_ ->
error
end;
pop( _ ) ->
error.
% @spec from_list( list() ) -> stack()
from_list( List ) when is_list( List ) ->
Stack = queue:from_list( List ),
#stack{ stk=Stack };
from_list( _ ) ->
error.
% @spec to_list( stack() ) -> list()
to_list( #stack{ stk=Stack } ) ->
case ?__is_q( Stack ) of
true ->
queue:to_list( Stack );
_ ->
error
end;
to_list( _ ) ->
error.
%@spec reverse( stack() ) -> stack() | error
reverse( #stack{ stk=Stack } ) ->
Stack1 = ?__proc_q( reverse ),
case Stack1 of
error ->
error;
_ ->
{ stack, Stack1 }
end;
reverse( _ ) ->
error.