1 ! Copyright (C) 2005, 2006 Alex Chapman, Daniel Ehrenberg
2 ! See https://factorcode.org/license.txt for BSD license
3 USING: accessors arrays kernel math sequences strings ;
6 TUPLE: circular < sequence-view { start integer } ;
8 : <circular> ( seq -- circular )
9 0 circular boa ; inline
13 : circular-wrap ( n circular -- n circular )
15 [ seq>> length rem ] keep ; inline
19 M: circular virtual@ circular-wrap seq>> ; inline
21 : change-circular-start ( n circular -- )
22 ! change start to (start + n) mod length
23 circular-wrap start<< ; inline
25 : rotate-circular ( circular -- )
26 [ 1 ] dip change-circular-start ; inline
28 : circular-push ( elt circular -- )
29 [ set-first ] [ rotate-circular ] bi ;
31 : <circular-string> ( n -- circular )
32 0 <string> <circular> ; inline
34 TUPLE: growing-circular < circular { length integer } ;
36 M: growing-circular length length>> ; inline
40 : full? ( circular -- ? )
41 [ length ] [ seq>> length ] bi = ; inline
45 : growing-circular-push ( elt circular -- )
46 dup full? [ circular-push ]
47 [ [ 1 + ] change-length set-last ] if ;
49 : <growing-circular> ( capacity -- growing-circular )
50 f <array> 0 0 growing-circular boa ; inline
52 TUPLE: circular-iterator
53 { circular read-only } { n integer } { last-start integer } ;
55 : <circular-iterator> ( circular -- obj )
56 0 -1 circular-iterator boa ; inline
60 : (circular-while) ( ... iterator quot: ( ... obj -- ... ? ) -- ... )
61 [ [ [ n>> ] [ circular>> ] bi nth ] dip call ] 2keep
62 rot [ [ dup n>> >>last-start ] dip ] when
63 over [ n>> ] [ [ last-start>> ] [ circular>> length ] bi + ] bi = [
66 [ [ 1 + ] change-n ] dip (circular-while)
67 ] if ; inline recursive
71 : circular-while ( ... circular quot: ( ... obj -- ... ? ) -- ... )
72 [ clone ] dip [ <circular-iterator> ] dip (circular-while) ; inline
74 : circular-loop ( ... circular quot: ( ... obj -- ... ? ) -- ... )
75 [ clone ] dip '[ [ first @ ] [ rotate-circular ] bi ] curry loop ; inline