template T *DeclPtr__(); template using ValueTypeOf = typename std::remove_reference::type>()->begin())>::type; template using IteratorOf = decltype(DeclPtr__::type>()->begin()); template using ConstIteratorOf = decltype(DeclPtr__::type>()->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) { ASSERT(i >= 0 && i < count); return l[i]; } const 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); } #ifndef CPP_20 template bool operator!=(const B& b) const { return !operator==(b); } #endif 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)) {} SubRangeClass() {} // MSC bug workaround }; 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 SubRangeFrom(C&& c, int pos) -> decltype(SubRange(c.begin() + pos, c.GetCount() - pos)) { return SubRange(c.begin() + pos, c.GetCount() - pos); } 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); } #ifndef CPP_20 template bool operator!=(const B& b) const { return !operator==(b); } #endif 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) {} ConstRangeClass() {} // MSC bug workaround }; template ConstRangeClass ConstRange(const T& value, int count) { return ConstRangeClass(value, count); } template ConstRangeClass ConstRange(int count) { return ConstRangeClass(count); } template struct ReverseRangeClass { typename std::remove_reference::type& r; typedef ValueTypeOf value_type; typedef value_type ValueType; const value_type& operator[](int i) const { return r[r.GetCount() - i - 1]; } value_type& operator[](int i) { return r[r.GetCount() - i - 1]; } int GetCount() const { return r.GetCount(); } typedef IIterator Iterator; typedef ConstIIterator ConstIterator; ReverseRangeClass& Write() { return *this; } ConstIterator begin() const { return ConstIterator(*this, 0); } ConstIterator end() const { return ConstIterator(*this, r.GetCount()); } Iterator begin() { return Iterator(*this, 0); } Iterator end() { return Iterator(*this, r.GetCount()); } String ToString() const { return AsStringArray(*this); } template bool operator==(const B& b) const { return IsEqualRange(*this, b); } #ifndef CPP_20 template bool operator!=(const B& b) const { return !operator==(b); } #endif 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; } ReverseRangeClass(BaseRange& r) : r(r) {} ReverseRangeClass() {} // MSC bug workaround }; template ReverseRangeClass ReverseRange(BaseRange&& r) { return ReverseRangeClass(r); } template struct ViewRangeClass { typename std::remove_reference::type *r; Vector ndx; typedef ValueTypeOf 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); } #ifndef CPP_20 template bool operator!=(const B& b) const { return !operator==(b); } #endif 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)) {} ViewRangeClass() {} // MSC bug workaround }; 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)); } template ViewRangeClass SortedRange(BaseRange&& r, Predicate p) { return ViewRangeClass(r, GetSortOrder(r, p)); } template ViewRangeClass SortedRange(BaseRange&& r) { return ViewRangeClass(r, GetSortOrder(r)); }