# IterationBuffer is used when the list/iteration implementation needs a # lightweight way to store/transmit values. Replaces the use of nqp::list in # the list guts, which is an impediment to introspectability and also to # allowing the implementation of custom iterators (though in reality most # folks won't implement Iterator directly, but instead use gather/take or lazy # loops). It doesn't make Scalar containers, and only supports mutation # through implementing push and BIND-POS, and access by implementing AT-POS. # Hot-paths are free to use the nqp:: op set directly on this, and do things # outside the scope of the method API it exposes. This type is engineered for # performance over friendliness, and should not be encountered in normal use # of Raku. Do NOT add any checks and validation to methods in here. They # need to remain trivially inlinable for performance reasons. my class IterationBuffer { multi method new(IterationBuffer:U: Iterable:D \iterable) { iterable.iterator.push-all(my \buffer := nqp::create(self)); buffer } method clear(IterationBuffer:D: --> Nil) { nqp::setelems(self, 0) } method elems() { nqp::elems(self) } method push(Mu \value) { nqp::push(self, value) } method append(IterationBuffer:D $buffer) { nqp::splice(self,$buffer,nqp::elems(self),0) } method unshift(Mu \value) { nqp::unshift(self, value) } method prepend(IterationBuffer:D $buffer) { nqp::splice(self,$buffer,0,0) } proto method AT-POS(|) {*} multi method AT-POS(IterationBuffer:D: int $pos) is raw { nqp::atpos(self, $pos) } multi method AT-POS(IterationBuffer:D: Int:D $pos) is raw { nqp::atpos(self, $pos) } proto method BIND-POS(|) {*} multi method BIND-POS(IterationBuffer:D: int $pos, Mu \value) { nqp::bindpos(self, $pos, value) } multi method BIND-POS(IterationBuffer:D: Int:D $pos, Mu \value) { nqp::bindpos(self, $pos, value) } # For maintainability mainly, and possibly for creating smaller, more # inlinable candidates method Slip(IterationBuffer:D:) { nqp::p6bindattrinvres(nqp::create(Slip),List,'$!reified',self) } # For maintainability mainly, and possibly for creating smaller, more # inlinable candidates method List(IterationBuffer:D:) { nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',self) } # For maintainability mainly, and possibly for creating smaller, more # inlinable candidates method Seq(IterationBuffer:D:) { Seq.new(Rakudo::Iterator.ReifiedList(self)) } # For maintainability mainly, and possibly for creating smaller, more # inlinable candidates method iterator(IterationBuffer:D:) { Rakudo::Iterator.ReifiedList(self) } # For core debugging purposes only: basically warp the IterationBuffer # into a full-fledged List and .raku that. We don't care that it will # not round-trip. multi method raku(IterationBuffer:D:) { self.List.raku ~ '.IterationBuffer' } } #?if jvm nqp::p6setiterbuftype(IterationBuffer); #?endif # vim: expandtab shiftwidth=4