factor/basis/dlists/dlists.factor

156 lines
3.6 KiB
Factor
Raw Normal View History

2008-03-20 21:14:07 -04:00
! Copyright (C) 2007, 2008 Mackenzie Straight, Doug Coleman,
! Slava Pestov.
2007-11-05 02:41:23 -05:00
! See http://factorcode.org/license.txt for BSD license.
2008-07-28 23:03:13 -04:00
USING: combinators kernel math sequences accessors dequeues ;
2007-11-05 02:41:23 -05:00
IN: dlists
TUPLE: dlist front back length ;
2007-11-05 02:41:23 -05:00
: <dlist> ( -- obj )
dlist new
0 >>length ;
2007-11-05 02:41:23 -05:00
M: dlist dequeue-length length>> ;
2007-11-05 02:43:29 -05:00
2007-11-05 02:41:23 -05:00
<PRIVATE
2008-03-20 21:14:07 -04:00
2007-11-05 02:41:23 -05:00
TUPLE: dlist-node obj prev next ;
2008-03-20 21:14:07 -04:00
2007-11-05 02:41:23 -05:00
C: <dlist-node> dlist-node
M: dlist-node node-value obj>> ;
2007-11-05 02:41:23 -05:00
: inc-length ( dlist -- )
2008-03-20 21:14:07 -04:00
[ 1+ ] change-length drop ; inline
2007-11-05 02:41:23 -05:00
: dec-length ( dlist -- )
2008-03-20 21:14:07 -04:00
[ 1- ] change-length drop ; inline
2007-11-05 02:41:23 -05:00
: set-prev-when ( dlist-node dlist-node/f -- )
2008-03-20 21:14:07 -04:00
[ (>>prev) ] [ drop ] if* ;
2007-11-05 02:41:23 -05:00
: set-next-when ( dlist-node dlist-node/f -- )
2008-03-20 21:14:07 -04:00
[ (>>next) ] [ drop ] if* ;
2007-11-05 02:41:23 -05:00
: set-next-prev ( dlist-node -- )
2008-03-20 21:14:07 -04:00
dup next>> set-prev-when ;
2007-11-05 02:41:23 -05:00
: normalize-front ( dlist -- )
2008-03-20 21:14:07 -04:00
dup back>> [ f >>front ] unless drop ;
2007-11-05 02:41:23 -05:00
: normalize-back ( dlist -- )
2008-03-20 21:14:07 -04:00
dup front>> [ f >>back ] unless drop ;
2007-11-05 02:41:23 -05:00
: set-back-to-front ( dlist -- )
2008-03-20 21:14:07 -04:00
dup back>> [ dup front>> >>back ] unless drop ;
2007-11-05 02:41:23 -05:00
: set-front-to-back ( dlist -- )
2008-03-20 21:14:07 -04:00
dup front>> [ dup back>> >>front ] unless drop ;
2007-11-05 02:43:29 -05:00
2008-07-18 20:22:59 -04:00
: (dlist-find-node) ( dlist-node quot: ( node -- ? ) -- node/f ? )
2008-03-20 21:14:07 -04:00
over [
[ call ] 2keep rot
2008-03-20 21:14:07 -04:00
[ drop t ] [ >r next>> r> (dlist-find-node) ] if
2008-07-18 20:22:59 -04:00
] [ 2drop f f ] if ; inline recursive
2007-11-05 02:43:29 -05:00
2008-03-20 21:14:07 -04:00
: dlist-find-node ( dlist quot -- node/f ? )
>r front>> r> (dlist-find-node) ; inline
2007-11-05 02:43:29 -05:00
2008-03-20 21:14:07 -04:00
: dlist-each-node ( dlist quot -- )
[ f ] compose dlist-find-node 2drop ; inline
2007-11-05 02:43:29 -05:00
: unlink-node ( dlist-node -- )
dup prev>> over next>> set-prev-when
dup next>> swap prev>> set-next-when ;
2007-11-05 02:41:23 -05:00
PRIVATE>
M: dlist push-front* ( obj dlist -- dlist-node )
2008-03-20 21:14:07 -04:00
[ front>> f swap <dlist-node> dup dup set-next-prev ] keep
[ (>>front) ] keep
2007-11-05 02:41:23 -05:00
[ set-back-to-front ] keep
inc-length ;
M: dlist push-back* ( obj dlist -- dlist-node )
2008-03-20 21:14:07 -04:00
[ back>> f <dlist-node> ] keep
[ back>> set-next-when ] 2keep
[ (>>back) ] 2keep
[ set-front-to-back ] keep
inc-length ;
ERROR: empty-dlist ;
M: dlist peek-front ( dlist -- obj )
front>> [ obj>> ] [ empty-dlist ] if* ;
M: dlist pop-front* ( dlist -- )
dup front>> [ empty-dlist ] unless
[
dup front>>
2008-03-20 21:14:07 -04:00
dup next>>
f rot (>>next)
2007-11-05 02:41:23 -05:00
f over set-prev-when
2008-03-20 21:14:07 -04:00
swap (>>front)
] keep
[ normalize-back ] keep
dec-length ;
2007-11-05 02:41:23 -05:00
M: dlist peek-back ( dlist -- obj )
back>> [ obj>> ] [ empty-dlist ] if* ;
2007-11-05 02:41:23 -05:00
M: dlist pop-back* ( dlist -- )
dup back>> [ empty-dlist ] unless
[
dup back>>
2008-03-20 21:14:07 -04:00
dup prev>>
f rot (>>prev)
2008-01-23 05:31:30 -05:00
f over set-next-when
2008-03-20 21:14:07 -04:00
swap (>>back)
] keep
[ normalize-front ] keep
dec-length ;
2007-11-05 02:41:23 -05:00
2008-03-20 21:14:07 -04:00
: dlist-find ( dlist quot -- obj/f ? )
[ obj>> ] prepose
2008-03-20 21:14:07 -04:00
dlist-find-node [ obj>> t ] [ drop f f ] if ; inline
2007-11-05 02:41:23 -05:00
2008-03-20 21:14:07 -04:00
: dlist-contains? ( dlist quot -- ? )
2007-11-15 17:21:45 -05:00
dlist-find nip ; inline
2007-11-05 02:41:23 -05:00
M: dlist dequeue-member? ( value dlist -- ? )
2008-07-28 18:55:41 -04:00
[ = ] with dlist-contains? ;
2007-11-16 00:17:34 -05:00
M: dlist delete-node ( dlist-node dlist -- )
2007-11-05 02:41:23 -05:00
{
{ [ 2dup front>> eq? ] [ nip pop-front* ] }
{ [ 2dup back>> eq? ] [ nip pop-back* ] }
[ dec-length unlink-node ]
2007-11-05 02:41:23 -05:00
} cond ;
2008-03-20 21:14:07 -04:00
: delete-node-if* ( dlist quot -- obj/f ? )
dupd dlist-find-node [
dup [
[ swap delete-node ] keep obj>> t
2008-03-20 21:14:07 -04:00
] [
2drop f f
] if
2007-11-05 02:41:23 -05:00
] [
2007-11-05 02:43:29 -05:00
2drop f f
2007-11-15 17:21:45 -05:00
] if ; inline
2007-11-05 02:41:23 -05:00
2008-03-20 21:14:07 -04:00
: delete-node-if ( dlist quot -- obj/f )
[ obj>> ] prepose delete-node-if* drop ; inline
2007-11-15 21:44:10 -05:00
M: dlist clear-dequeue ( dlist -- )
2008-03-20 21:14:07 -04:00
f >>front
f >>back
0 >>length
drop ;
2008-02-06 20:23:39 -05:00
2007-11-05 02:41:23 -05:00
: dlist-each ( dlist quot -- )
[ obj>> ] prepose dlist-each-node ; inline
: 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
INSTANCE: dlist dequeue