
import sequences.handle.*;



//
// wrapSequence
//

define wrapSequence;

inline overload wrapSequence(rvalue x) = move(x);
inline overload wrapSequence(ref x) = sequenceHandle(x);

[A | LightweightSequence?(A)]
inline overload wrapSequence(ref x:A) = x;



//
// packSequences, unpackSequences
//

inline packSequences(forward ..args) = [..mapValues(wrapSequence, ..args)];

[..T]
inline unpackSequences(x:Tuple[..T]) = ref ..unpackTupleRef(x);



//
// CapturedElementsType
//

alias CapturedElementsType(packedSeq) =
    Type(captureValues(..dummyElements(..unpackTupleRef(packedSeq))));


private inline dummyElement(seq) = forward next(iterator(seq));

inline dummyElements(..seqs) = forward ..mapValues(dummyElement, ..seqs);



//
// multiIterators, multiReverseIterators
//

inline multiIterators(packedSeq) =
    [..mapValues(iterator, ..unpackTupleRef(packedSeq))];

inline multiReverseIterators(packedSeq) =
    [..mapValues(reverseIterator, ..unpackTupleRef(packedSeq))];



//
// multiValueAll?
//

define multiValueAll?;

inline overload multiValueAll?(predicate, forward first, forward ..rest) =
    predicate(first) and multiValueAll?(predicate, ..rest);

inline overload multiValueAll?(predicate) = true;



//
// multiHasNext?
//

inline multiHasNext?(multiIter) =
    multiValueAll?(hasNext?, ..unpackTupleRef(multiIter));



//
// multiNext
//

inline multiNext(multiIter) =
    captureValues(..mapValues(next, ..unpackTupleRef(multiIter)));
