template using ValueTypeOf = typename std::remove_referencebegin())>::type; template using IteratorOf = decltype(((Range *)0)->begin()); template using ConstIteratorOf = decltype(((const Range *)0)->begin()); template class SubRangeClass { I l; int count; public: typedef typename std::remove_reference::type value_type; int GetCount() const { return count; } SubRangeClass& Write() { return *this; } value_type& operator[](int i) const { ASSERT(i >= 0 && i < count); return l[i]; } I begin() const { return l; } I end() const { return l + count; } String ToString() const { return AsStringArray(*this); } template bool operator==(const B& b) const { return IsEqualRange(*this, b); } template bool operator!=(const B& b) const { return !operator==(b); } template int Compare(const B& b) const { return CompareRanges(*this, b); } template bool operator<=(const B& x) const { return Compare(x) <= 0; } template bool operator>=(const B& x) const { return Compare(x) >= 0; } template bool operator<(const B& x) const { return Compare(x) < 0; } template bool operator>(const B& x) const { return Compare(x) > 0; } SubRangeClass(I begin, int count) : l(begin), count(count) {} SubRangeClass(I begin, I end) : l(begin), count(int(end - begin)) {} }; template SubRangeClass SubRange(I l, I h) { return SubRangeClass(l, h); } template SubRangeClass SubRange(I l, int count) { return SubRangeClass(l, count); } template auto SubRange(C& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count)) { return SubRange(c.begin() + pos, count); } template auto SubRange(const C& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count)) { return SubRange(c.begin() + pos, count); } template using SubRangeOf = decltype(SubRange(((C *)0)->begin(), ((C *)0)->end())); template struct ConstRangeClass { T value; int count; typedef T value_type; typedef value_type ValueType; const value_type& operator[](int i) const { return value; } int GetCount() const { return count; } typedef ConstIIterator Iterator; Iterator begin() const { return Iterator(*this, 0); } Iterator end() const { return Iterator(*this, count); } String ToString() const { return AsStringArray(*this); } template bool operator==(const B& b) const { return IsEqualRange(*this, b); } template bool operator!=(const B& b) const { return !operator==(b); } template int Compare(const B& b) const { return CompareRanges(*this, b); } template bool operator<=(const B& x) const { return Compare(x) <= 0; } template bool operator>=(const B& x) const { return Compare(x) >= 0; } template bool operator<(const B& x) const { return Compare(x) < 0; } template bool operator>(const B& x) const { return Compare(x) > 0; } ConstRangeClass(const T& value, int count) : value(value), count(count) {} ConstRangeClass(int count) : count(count) {} }; template ConstRangeClass ConstRange(const T& value, int count) { return ConstRangeClass(value, count); } template ConstRangeClass ConstRange(int count) { return ConstRangeClass(count); } template struct ViewRangeClass { BaseRange *r; Vector ndx; typedef typename BaseRange::value_type value_type; typedef value_type ValueType; const value_type& operator[](int i) const { return (*r)[ndx[i]]; } value_type& operator[](int i) { return (*r)[ndx[i]]; } int GetCount() const { return ndx.GetCount(); } typedef IIterator Iterator; typedef ConstIIterator ConstIterator; ViewRangeClass& Write() { return *this; } ConstIterator begin() const { return ConstIterator(*this, 0); } ConstIterator end() const { return ConstIterator(*this, ndx.GetCount()); } Iterator begin() { return Iterator(*this, 0); } Iterator end() { return Iterator(*this, ndx.GetCount()); } String ToString() const { return AsStringArray(*this); } template bool operator==(const B& b) const { return IsEqualRange(*this, b); } template bool operator!=(const B& b) const { return !operator==(b); } template int Compare(const B& b) const { return CompareRanges(*this, b); } template bool operator<=(const B& x) const { return Compare(x) <= 0; } template bool operator>=(const B& x) const { return Compare(x) >= 0; } template bool operator<(const B& x) const { return Compare(x) < 0; } template bool operator>(const B& x) const { return Compare(x) > 0; } ViewRangeClass(BaseRange& r, Vector&& ndx) : r(&r), ndx(pick(ndx)) {} }; template ViewRangeClass ViewRange(BaseRange& r, Vector&& ndx) { return ViewRangeClass(r, pick(ndx)); } template ViewRangeClass FilterRange(BaseRange& r, Predicate p) { return ViewRangeClass(r, FindAll(r, p)); }