2009-02-09 15:29:09 -05:00
|
|
|
! Copyright (C) 2008 Daniel Ehrenberg
|
2008-08-09 12:40:17 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-02-09 15:29:09 -05:00
|
|
|
USING: kernel accessors math lists sequences combinators.short-circuit ;
|
2008-08-09 12:40:17 -04:00
|
|
|
IN: persistent.deques
|
|
|
|
|
|
|
|
! Amortized O(1) push/pop on both ends for single-threaded access
|
|
|
|
! In a pathological case, if there are m modified versions from the
|
|
|
|
! same source, it could take O(m) amortized time per update.
|
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
: split-reverse ( list -- back-reversed front )
|
2009-02-09 15:29:09 -05:00
|
|
|
dup llength 2/ lcut lreverse swap ;
|
2008-08-09 12:40:17 -04:00
|
|
|
PRIVATE>
|
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
TUPLE: deque { front read-only } { back read-only } ;
|
2009-02-09 15:29:09 -05:00
|
|
|
: <deque> ( -- deque )
|
|
|
|
T{ deque f +nil+ +nil+ } ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
<PRIVATE
|
|
|
|
: flip ( deque -- newdeque )
|
|
|
|
[ back>> ] [ front>> ] bi deque boa ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
: flipped ( deque quot -- newdeque )
|
2009-04-15 20:03:44 -04:00
|
|
|
[ flip ] dip call flip ; inline
|
2008-08-14 23:10:18 -04:00
|
|
|
PRIVATE>
|
2008-08-09 12:40:17 -04:00
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
: deque-empty? ( deque -- ? )
|
2009-02-09 15:29:09 -05:00
|
|
|
{ [ front>> nil? ] [ back>> nil? ] } 1&& ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
|
|
|
<PRIVATE
|
2008-08-14 23:10:18 -04:00
|
|
|
: push ( item deque -- newdeque )
|
2009-02-09 00:06:03 -05:00
|
|
|
[ front>> cons ] [ back>> ] bi deque boa ; inline
|
2008-08-09 12:40:17 -04:00
|
|
|
PRIVATE>
|
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
: push-front ( deque item -- newdeque )
|
|
|
|
swap push ;
|
|
|
|
|
|
|
|
: push-back ( deque item -- newdeque )
|
|
|
|
swap [ push ] flipped ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
|
|
|
<PRIVATE
|
2008-08-14 23:10:18 -04:00
|
|
|
: remove ( deque -- item newdeque )
|
2009-02-09 00:06:03 -05:00
|
|
|
[ front>> car ] [ [ front>> cdr ] [ back>> ] bi deque boa ] bi ; inline
|
2008-08-14 23:10:18 -04:00
|
|
|
|
|
|
|
: transfer ( deque -- item newdeque )
|
2009-02-09 15:29:09 -05:00
|
|
|
back>> dup nil?
|
|
|
|
[ "Popping from an empty deque" throw ]
|
|
|
|
[ split-reverse deque boa remove ] if ; inline
|
2008-08-09 12:40:17 -04:00
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
: pop ( deque -- item newdeque )
|
2009-02-09 15:29:09 -05:00
|
|
|
dup front>> nil? [ transfer ] [ remove ] if ; inline
|
2008-08-09 12:40:17 -04:00
|
|
|
PRIVATE>
|
|
|
|
|
2008-08-14 23:10:18 -04:00
|
|
|
: pop-front ( deque -- item newdeque )
|
|
|
|
pop ;
|
|
|
|
|
|
|
|
: pop-back ( deque -- item newdeque )
|
|
|
|
[ pop ] flipped ;
|
|
|
|
|
2009-02-09 15:29:09 -05:00
|
|
|
: peek-front ( deque -- item )
|
|
|
|
pop-front drop ;
|
2008-08-14 23:10:18 -04:00
|
|
|
|
2009-02-09 15:29:09 -05:00
|
|
|
: peek-back ( deque -- item )
|
|
|
|
pop-back drop ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
|
|
|
: sequence>deque ( sequence -- deque )
|
2009-02-09 15:29:09 -05:00
|
|
|
<deque> [ push-back ] reduce ;
|
2008-08-09 12:40:17 -04:00
|
|
|
|
|
|
|
: deque>sequence ( deque -- sequence )
|
2009-02-28 16:31:34 -05:00
|
|
|
[ dup deque-empty? not ] [ pop-front swap ] produce nip ;
|