factor/basis/persistent/deques/deques.factor

88 lines
2.2 KiB
Factor
Raw Normal View History

! Copyback (C) 2008 Daniel Ehrenberg
2008-08-09 12:40:17 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors math ;
2008-08-09 12:40:17 -04:00
QUALIFIED: sequences
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
TUPLE: cons { car read-only } { cdr read-only } ;
C: <cons> cons
2008-08-24 04:59:37 -04:00
: each ( list quot: ( elt -- ) -- )
2008-08-09 12:40:17 -04:00
over
2008-12-17 20:17:37 -05:00
[ [ [ car>> ] dip call ] [ [ cdr>> ] dip ] 2bi each ]
2008-08-24 04:59:37 -04:00
[ 2drop ] if ; inline recursive
2008-08-09 12:40:17 -04:00
: reduce ( list start quot -- end )
swapd each ; inline
: reverse ( list -- reversed )
f [ swap <cons> ] reduce ;
: length ( list -- length )
0 [ drop 1+ ] reduce ;
: cut ( list index -- back front-reversed )
2008-12-17 20:17:37 -05:00
f swap [ [ [ cdr>> ] [ car>> ] bi ] dip <cons> ] times ;
2008-08-09 12:40:17 -04:00
: split-reverse ( list -- back-reversed front )
dup length 2/ cut [ reverse ] bi@ ;
PRIVATE>
TUPLE: deque { front read-only } { back read-only } ;
2008-08-09 12:40:17 -04:00
: <deque> ( -- deque ) T{ deque } ;
<PRIVATE
: flip ( deque -- newdeque )
[ back>> ] [ front>> ] bi deque boa ;
2008-08-09 12:40:17 -04:00
: flipped ( deque quot -- newdeque )
2008-12-17 20:17:37 -05:00
[ flip ] dip call flip ;
PRIVATE>
2008-08-09 12:40:17 -04:00
: deque-empty? ( deque -- ? )
[ front>> ] [ back>> ] bi or not ;
2008-08-09 12:40:17 -04:00
<PRIVATE
: push ( item deque -- newdeque )
[ front>> <cons> ] [ back>> ] bi deque boa ; inline
2008-08-09 12:40:17 -04:00
PRIVATE>
: push-front ( deque item -- newdeque )
swap push ;
: push-back ( deque item -- newdeque )
swap [ push ] flipped ;
2008-08-09 12:40:17 -04:00
<PRIVATE
: remove ( deque -- item newdeque )
[ front>> car>> ] [ [ front>> cdr>> ] [ back>> ] bi deque boa ] bi ; inline
: transfer ( deque -- item newdeque )
back>> [ split-reverse deque boa remove ]
[ "Popping from an empty deque" throw ] if* ; inline
2008-08-09 12:40:17 -04:00
: pop ( deque -- item newdeque )
dup front>> [ remove ] [ transfer ] if ; inline
2008-08-09 12:40:17 -04:00
PRIVATE>
: pop-front ( deque -- item newdeque )
pop ;
: pop-back ( deque -- item newdeque )
[ pop ] flipped ;
: peek-front ( deque -- item ) pop-front drop ;
: peek-back ( deque -- item ) pop-back drop ;
2008-08-09 12:40:17 -04:00
: sequence>deque ( sequence -- deque )
<deque> [ push-back ] sequences:reduce ;
2008-08-09 12:40:17 -04:00
: deque>sequence ( deque -- sequence )
[ dup deque-empty? not ] [ pop-front swap ] [ ] sequences:produce nip ;