#pragma once #include namespace sibs { template class Function; template class FunctionIterator { public: FunctionIterator(T *_it, Function *_func, std::size_t _funcIndex) : it(_it), func(_func), funcIndex(_funcIndex) { } bool operator == (FunctionIterator &rhs) const { return it == rhs.it && funcIndex == rhs.funcIndex; } bool operator != (FunctionIterator &rhs) const { return !(*this == rhs); } T& operator * () { return *it; } void operator ++ () { ++it; if(it == func->endIt) { if(funcIndex < func->connections.size()) { it = func->connections[funcIndex].beginIt; ++funcIndex; } } } private: T *it; Function *func; std::size_t funcIndex; }; template class Function { friend class FunctionIterator; public: typedef FunctionIterator iterator; typedef const FunctionIterator const_iterator; Function(T *begin, T *end) : beginIt(begin), endIt(end) { } Function(std::vector &vec) : beginIt(vec.data()), endIt(vec.data() + vec.size()) { } Function& merge(const Function &otherFunc) { connections.push_back(otherFunc); return *this; } iterator begin() { return FunctionIterator(beginIt, this, 0); } iterator end() { T *it = endIt; if(!connections.empty()) it = connections.back().endIt; return FunctionIterator(it, this, connections.size()); } const_iterator begin() const { return FunctionIterator(beginIt, this, 0); } const_iterator end() const { T *it = endIt; if(!connections.empty()) it = connections.back().endIt; return FunctionIterator(it, this, connections.size()); } private: T *beginIt; T *endIt; std::vector connections; }; template static Function makeFunction(T *begin, T *end) { return Function(begin, end); } template static Function makeFunction(std::vector &vec) { return Function(vec.data(), vec.data() + vec.size()); } }