GENERIC: like ( seq exemplar -- newseq ) flushable
GENERIC: clone-like ( seq exemplar -- newseq ) flushable
+: lengthd ( seq obj -- n obj ) [ length ] dip ; inline
+
: new-sequence-like ( len-exemplar type-exemplar -- newseq )
- [ length ] dip new-sequence ; inline
+ lengthd new-sequence ; inline
: new-resizable-like ( len-exemplar type-exemplar -- newseq )
- [ length ] dip new-resizable ; inline
+ lengthd new-resizable ; inline
: new-like ( len exemplar quot -- seq )
over [ [ new-sequence ] dip call ] dip like ; inline
M: sequence lengthen 2dup length > [ set-length ] [ 2drop ] if ; inline
M: sequence shorten 2dup length < [ set-length ] [ 2drop ] if ; inline
+GENERIC#: seq-lengthen 1 ( seq n -- seq )
+GENERIC#: seq-shorten 1 ( seq n -- seq )
+
+: seq-set-length ( seq n -- seq ) [ swap set-length ] keepd ; inline
+: seq-nth ( seq n -- elt ) swap nth ; inline
+: seq-set-nth ( seq n elt -- seq ) swap rot [ set-nth ] keep ; inline
+
+M: sequence seq-lengthen 2dup lengthd < [ seq-set-length ] [ drop ] if ; inline
+M: sequence seq-shorten 2dup lengthd > [ seq-set-length ] [ drop ] if ; inline
+
: 2length ( seq1 seq2 -- n1 n2 ) [ length ] bi@ ; inline
: 3length ( seq1 seq2 seq3 -- n1 n2 n3 ) [ length ] tri@ ; inline
: push ( elt seq -- ) [ length ] [ set-nth ] bi ;
+: seq-push ( seq elt -- seq ) [ dup length ] dip seq-set-nth ;
+
ERROR: bounds-error index seq ;
GENERIC#: bounds-check? 1 ( n seq -- ? )
M: integer bounds-check?
dupd length < [ 0 >= ] [ drop f ] if ; inline
+GENERIC: seq-bounds-check? ( seq n -- ? )
+
+M: integer seq-bounds-check?
+ tuck lengthd > [ 0 >= ] [ drop f ] if ; inline
+
: bounds-check ( n seq -- n seq )
2dup bounds-check? [ bounds-error ] unless ; inline
+: seq-bounds-check ( seq n -- seq n )
+ 2dup seq-bounds-check? [ swap bounds-error ] unless ; inline
+
MIXIN: immutable-sequence
ERROR: immutable element index sequence ;
M: sequence nth-unsafe nth ; inline
M: sequence set-nth-unsafe set-nth ; inline
+: seq-nth-unsafe ( seq n -- elt ) swap nth-unsafe ; inline
+
+: seq-set-nth-unsafe ( seq n elt -- seq ) swap pick set-nth-unsafe ; inline
+
: change-nth-unsafe ( i seq quot -- )
[ [ nth-unsafe ] dip call ] 2keepd set-nth-unsafe ; inline
+: change-seq-nth-unsafe ( seq i quot -- seq )
+ [ [ seq-nth-unsafe ] dip call ] 2keepd rot seq-set-nth-unsafe ; inline
+
PRIVATE>
! The f object supports the sequence protocol trivially
[ [ src-i>> + ] [ src>> ] bi nth-unsafe ]
[ [ dst-i>> + ] [ dst>> ] bi set-nth-unsafe ] 2bi ; inline
+: copy-seq-nth-unsafe ( dst dst-i src src-i -- )
+ seq-nth-unsafe seq-set-nth-unsafe drop ; inline
+
: (copy) ( n copy -- dst )
over 0 <= [ nip dst>> ] [
[ 1 - ] dip [ copy-nth-unsafe ] [ (copy) ] 2bi
] if ; inline recursive
+: seq-copy-loop ( dst dst-i src src-i src-stop -- dst )
+ 2dup >= [
+ 4drop
+ ] [
+ [
+ [ copy-seq-nth-unsafe ] 4keep
+ [ 1 + ] 2dip 1 +
+ ] dip seq-copy-loop
+ ] if ; inline recursive
+
: subseq>copy ( from to seq -- n copy )
[ over - check-length swap ] dip
3dup nip new-sequence 0 swap <copier> ; inline
: bounds-check-head ( n seq -- n seq )
over 0 < [ bounds-error ] when ; inline
-: check-copy ( src n dst -- src n dst )
- 3dup bounds-check-head
- [ swap length + ] dip lengthen ; inline
+: check-grow-copy ( dst n src -- dst src n )
+ over [ lengthd + lengthen ] 2keep ; inline
+
+: seq-grow-copy ( dst n -- dst dst-n )
+ [ over length + seq-lengthen ] keep 1 - ; inline
: copy-unsafe ( src i dst -- )
[ [ length check-length 0 ] keep ] 2dip <copier> (copy) drop ; inline
+: seq-copy-unsafe ( dst dst-i src -- dst )
+ 0 over length check-length seq-copy-loop ; inline
+
: subseq-unsafe-as ( from to seq exemplar -- subseq )
[ subseq>copy (copy) ] dip like ; inline
: but-last ( seq -- headseq ) 1 head* ;
-: copy ( src i dst -- ) check-copy copy-unsafe ; inline
+: copy ( src i dst -- )
+ 3dup bounds-check-head
+ [ swap length + ] dip lengthen
+ copy-unsafe ; inline
+
+: seq-copy ( dst dst-n src -- dst ) check-grow-copy seq-copy-unsafe ; inline
M: sequence clone-like
dupd new-sequence-like [ 0 swap copy-unsafe ] keep ; inline
: push-all ( src dst -- ) [ length ] [ copy ] bi ; inline
+: seq-push-all ( dst src -- dst ) [ length seq-grow-copy ] keep seq-copy-unsafe ; inline
+
<PRIVATE
: (append) ( seq1 seq2 accum -- accum )
[ 0 swap copy-unsafe ]
[ ] tri ; inline
+: (seq-append) ( accum seq1 seq2 -- accum )
+ [
+ [ 0 ] dip [ seq-copy-unsafe ] [ length ] bi
+ ] dip seq-copy-unsafe ; inline
+
PRIVATE>
+: seq-append-as ( seq1 seq2 exemplar -- newseq )
+ [ 2dup 2length + ] dip
+ [ -rot (seq-append) ] new-like ; inline
+
: append-as ( seq1 seq2 exemplar -- newseq )
[ 2dup 2length + ] dip
[ (append) ] new-like ; inline
: partition ( ... seq quot: ( ... elt -- ... ? ) -- ... trueseq falseseq )
over [ 2selector [ each ] 2dip ] dip [ like ] curry bi@ ; inline
-: collector-for-as ( seq quot exemplar -- seq quot' vec )
- overd new-resizable-like [ [ push ] curry compose ] keep ; inline
-
: collector-as ( quot exemplar -- quot' vec )
dup new-resizable-like [ [ push ] curry compose ] keep ; inline
-: collector-for ( seq quot -- seq quot' vec )
- V{ } collector-for-as ; inline
-
: collector ( quot -- quot' vec )
V{ } collector-as ; inline
! Copyright (C) 2005, 2009 Slava Pestov.
-! See https://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs growable.private hashtables
-kernel kernel.private math math.order sequences
-sequences.private vectors ;
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs combinators growable.private
+hashtables kernel kernel.private math math.order math.private
+sequences sequences.private vectors ;
IN: sorting
! Optimized merge-sort:
: r-done? ( merge -- ? ) [ from2>> ] [ to2>> ] bi eq? ; inline
: dump-l ( merge -- )
- [ [ from1>> ] [ to1>> ] [ seq>> ] tri ] [ accum>> ] bi
- push-all-unsafe ; inline
+ {
+ [ accum>> ]
+ [ [ to1>> ] [ from1>> fixnum-fast ] [ accum>> length integer>fixnum-strict ] tri [ fixnum+fast >>length ] 2keep ]
+ [ seq>> ]
+ [ from1>> roll dupd fixnum+fast ]
+ } cleave seq-copy-loop drop ; inline
: dump-r ( merge -- )
- [ [ from2>> ] [ to2>> ] [ seq>> ] tri ] [ accum>> ] bi
- push-all-unsafe ; inline
+ {
+ [ accum>> ]
+ [ [ to2>> ] [ from2>> fixnum-fast ] [ accum>> length integer>fixnum-strict ] tri [ fixnum+fast >>length ] 2keep ]
+ [ seq>> ]
+ [ from2>> roll dupd fixnum+fast ]
+ } cleave seq-copy-loop drop ; inline
: l-next ( merge -- )
[ l-elt ] [ [ 1 + ] change-from1 accum>> ] bi push-unsafe ; inline