! Copyright (C) 2005, 2006 Alex Chapman, Daniel Ehrenberg ! See https://factorcode.org/license.txt for BSD license USING: accessors arrays kernel math sequences strings ; IN: circular TUPLE: circular < sequence-view { start integer } ; : ( seq -- circular ) 0 circular boa ; inline > + ] keep [ seq>> length rem ] keep ; inline PRIVATE> M: circular virtual@ circular-wrap seq>> ; inline M: circular minimum seq>> minimum ; inline M: circular maximum seq>> maximum ; inline : change-circular-start ( n circular -- ) ! change start to (start + n) mod length circular-wrap start<< ; inline : rotate-circular ( circular -- ) [ 1 ] dip change-circular-start ; inline : circular-push ( elt circular -- ) [ set-first ] [ rotate-circular ] bi ; : ( n -- circular ) 0 ; inline TUPLE: growing-circular < circular { length integer } ; M: growing-circular length length>> ; inline > length ] bi = ; inline PRIVATE> : growing-circular-push ( elt circular -- ) dup full? [ circular-push ] [ [ 1 + ] change-length set-last ] if ; : ( capacity -- growing-circular ) f 0 0 growing-circular boa ; inline TUPLE: circular-iterator { circular read-only } { n integer } { last-start integer } ; : ( circular -- obj ) 0 -1 circular-iterator boa ; inline > ] [ circular>> ] bi nth ] dip call ] 2keep rot [ [ dup n>> >>last-start ] dip ] when over [ n>> ] [ [ last-start>> ] [ circular>> length ] bi + ] bi = [ 2drop ] [ [ [ 1 + ] change-n ] dip (circular-while) ] if ; inline recursive PRIVATE> : circular-while ( ... circular quot: ( ... obj -- ... ? ) -- ... ) [ clone ] dip [ ] dip (circular-while) ; inline : circular-loop ( ... circular quot: ( ... obj -- ... ? ) -- ... ) [ clone ] dip '[ [ first @ ] [ rotate-circular ] bi ] curry loop ; inline