#pragma once #include #include #include #include #include template struct DereferenceVisitor : public boost::static_visitor { template reference operator()(T Iterator) const { return *Iterator; } }; struct IncrementVisitor : public boost::static_visitor { template void operator()(T &Value) const { ++Value; } }; struct DecrementVisitor : public boost::static_visitor { template void operator()(T &Value) const { --Value; } }; template ::type > class ConcatIterator : public boost::iterator_facade, TValue, boost::bidirectional_traversal_tag> { public: template ConcatIterator(TIterator It, size_t Range /* 0 for the first range, 1 for the second range */, TIterator1 End1, TIterator2 Begin2) : It(It), Range(Range), End1(End1), Begin2(Begin2) { Stabilize(); } private: void Stabilize() { if ((Range == 0) && (It == End1)) { It = Begin2; Range = 1; } } public: reference dereference() const { return boost::apply_visitor(DereferenceVisitor(), It); } void increment() { boost::apply_visitor(IncrementVisitor(), It); if ((Range == 0) && (It == End1)) { It = Begin2; Range = 1; } } void decrement() { if ((Range == 1) && (It == Begin2)) { It = End1; Range = 0; } boost::apply_visitor(DecrementVisitor(), It); } bool equal(const ConcatIterator& lhs) const { return (Range == lhs.Range) && (It == lhs.It); } private: size_t Range; boost::variant It, End1, Begin2; }; template boost::iterator_range > Concatenate(TRange1 &Range1, TRange2 &Range2) { typedef ConcatIterator TIterator; return boost::make_iterator_range( TIterator(Range1.begin(), 0, Range1.end(), Range2.begin()), TIterator(Range2.end (), 1, Range1.end(), Range2.begin())); } template boost::iterator_range > Concatenate(TRange1 const &Range1, TRange2 const &Range2) { typedef ConcatIterator TIterator; return boost::make_iterator_range( TIterator(Range1.begin(), 0, Range1.end(), Range2.begin()), TIterator(Range2.end (), 1, Range1.end(), Range2.begin())); }