1 template <class Range>
2 using ValueTypeOf = typename std::remove_reference<decltype(*((typename std::remove_reference<Range>::type *)0)->begin())>::type;
3
4 template <class Range>
5 using IteratorOf = decltype(((typename std::remove_reference<Range>::type *)0)->begin());
6
7 template <class Range>
8 using ConstIteratorOf = decltype(((const typename std::remove_reference<Range>::type *)0)->begin());
9
10 template <class I>
11 class SubRangeClass {
12 I l;
13 int count;
14
15 public:
16 typedef typename std::remove_reference<decltype(*l)>::type value_type;
17
GetCount()18 int GetCount() const { return count; }
19
Write()20 SubRangeClass& Write() { return *this; }
21
22 value_type& operator[](int i) const { ASSERT(i >= 0 && i < count); return l[i]; }
begin()23 I begin() const { return l; }
end()24 I end() const { return l + count; }
25
ToString()26 String ToString() const { return AsStringArray(*this); }
27 template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
28 template <class B> bool operator!=(const B& b) const { return !operator==(b); }
Compare(const B & b)29 template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
30 template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
31 template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
32 template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
33 template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
34
SubRangeClass(I begin,int count)35 SubRangeClass(I begin, int count) : l(begin), count(count) {}
SubRangeClass(I begin,I end)36 SubRangeClass(I begin, I end) : l(begin), count(int(end - begin)) {}
SubRangeClass()37 SubRangeClass() {} // MSC bug workaround
38 };
39
40 template <class I>
SubRange(I l,I h)41 SubRangeClass<I> SubRange(I l, I h)
42 {
43 return SubRangeClass<I>(l, h);
44 }
45
46 template <class I>
SubRange(I l,int count)47 SubRangeClass<I> SubRange(I l, int count)
48 {
49 return SubRangeClass<I>(l, count);
50 }
51
52 template <class C>
53 auto SubRange(C&& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count))
54 {
55 return SubRange(c.begin() + pos, count);
56 }
57
58 template <class C> using SubRangeOf = decltype(SubRange(((C *)0)->begin(), ((C *)0)->end()));
59
60 template <class T>
61 struct ConstRangeClass {
62 T value;
63 int count;
64
65 typedef T value_type;
66 typedef value_type ValueType;
67
68 const value_type& operator[](int i) const { return value; }
GetCountConstRangeClass69 int GetCount() const { return count; }
70
71 typedef ConstIIterator<ConstRangeClass> Iterator;
72
beginConstRangeClass73 Iterator begin() const { return Iterator(*this, 0); }
endConstRangeClass74 Iterator end() const { return Iterator(*this, count); }
75
ToStringConstRangeClass76 String ToString() const { return AsStringArray(*this); }
77 template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
78 template <class B> bool operator!=(const B& b) const { return !operator==(b); }
CompareConstRangeClass79 template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
80 template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
81 template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
82 template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
83 template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
84
ConstRangeClassConstRangeClass85 ConstRangeClass(const T& value, int count) : value(value), count(count) {}
ConstRangeClassConstRangeClass86 ConstRangeClass(int count) : count(count) {}
ConstRangeClassConstRangeClass87 ConstRangeClass() {} // MSC bug workaround
88 };
89
90 template <class T>
ConstRange(const T & value,int count)91 ConstRangeClass<T> ConstRange(const T& value, int count)
92 {
93 return ConstRangeClass<T>(value, count);
94 }
95
96 template <class T>
ConstRange(int count)97 ConstRangeClass<T> ConstRange(int count)
98 {
99 return ConstRangeClass<T>(count);
100 }
101
102 template <class BaseRange>
103 struct ReverseRangeClass {
104 typename std::remove_reference<BaseRange>::type& r;
105
106 typedef ValueTypeOf<BaseRange> value_type;
107 typedef value_type ValueType;
108
109 const value_type& operator[](int i) const { return r[r.GetCount() - i - 1]; }
110 value_type& operator[](int i) { return r[r.GetCount() - i - 1]; }
GetCountReverseRangeClass111 int GetCount() const { return r.GetCount(); }
112
113 typedef IIterator<ReverseRangeClass> Iterator;
114 typedef ConstIIterator<ReverseRangeClass> ConstIterator;
115
WriteReverseRangeClass116 ReverseRangeClass& Write() { return *this; }
117
beginReverseRangeClass118 ConstIterator begin() const { return ConstIterator(*this, 0); }
endReverseRangeClass119 ConstIterator end() const { return ConstIterator(*this, r.GetCount()); }
120
beginReverseRangeClass121 Iterator begin() { return Iterator(*this, 0); }
endReverseRangeClass122 Iterator end() { return Iterator(*this, r.GetCount()); }
123
ToStringReverseRangeClass124 String ToString() const { return AsStringArray(*this); }
125 template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
126 template <class B> bool operator!=(const B& b) const { return !operator==(b); }
CompareReverseRangeClass127 template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
128 template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
129 template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
130 template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
131 template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
132
ReverseRangeClassReverseRangeClass133 ReverseRangeClass(BaseRange& r) : r(r) {}
ReverseRangeClassReverseRangeClass134 ReverseRangeClass() {} // MSC bug workaround
135 };
136
137 template <class BaseRange>
ReverseRange(BaseRange && r)138 ReverseRangeClass<BaseRange> ReverseRange(BaseRange&& r)
139 {
140 return ReverseRangeClass<BaseRange>(r);
141 }
142
143 template <class BaseRange>
144 struct ViewRangeClass {
145 typename std::remove_reference<BaseRange>::type *r;
146 Vector<int> ndx;
147
148 typedef ValueTypeOf<BaseRange> value_type;
149 typedef value_type ValueType;
150
151 const value_type& operator[](int i) const { return (*r)[ndx[i]]; }
152 value_type& operator[](int i) { return (*r)[ndx[i]]; }
GetCountViewRangeClass153 int GetCount() const { return ndx.GetCount(); }
154
155 typedef IIterator<ViewRangeClass> Iterator;
156 typedef ConstIIterator<ViewRangeClass> ConstIterator;
157
WriteViewRangeClass158 ViewRangeClass& Write() { return *this; }
159
beginViewRangeClass160 ConstIterator begin() const { return ConstIterator(*this, 0); }
endViewRangeClass161 ConstIterator end() const { return ConstIterator(*this, ndx.GetCount()); }
162
beginViewRangeClass163 Iterator begin() { return Iterator(*this, 0); }
endViewRangeClass164 Iterator end() { return Iterator(*this, ndx.GetCount()); }
165
ToStringViewRangeClass166 String ToString() const { return AsStringArray(*this); }
167 template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
168 template <class B> bool operator!=(const B& b) const { return !operator==(b); }
CompareViewRangeClass169 template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
170 template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
171 template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
172 template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
173 template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
174
ViewRangeClassViewRangeClass175 ViewRangeClass(BaseRange& r, Vector<int>&& ndx) : r(&r), ndx(pick(ndx)) {}
ViewRangeClassViewRangeClass176 ViewRangeClass() {} // MSC bug workaround
177 };
178
179 template <class BaseRange>
ViewRange(BaseRange && r,Vector<int> && ndx)180 ViewRangeClass<BaseRange> ViewRange(BaseRange&& r, Vector<int>&& ndx)
181 {
182 return ViewRangeClass<BaseRange>(r, pick(ndx));
183 }
184
185 template <class BaseRange, class Predicate>
FilterRange(BaseRange && r,Predicate p)186 ViewRangeClass<BaseRange> FilterRange(BaseRange&& r, Predicate p)
187 {
188 return ViewRangeClass<BaseRange>(r, FindAll(r, p));
189 }
190
191 template <class BaseRange, class Predicate>
SortedRange(BaseRange && r,Predicate p)192 ViewRangeClass<BaseRange> SortedRange(BaseRange&& r, Predicate p)
193 {
194 return ViewRangeClass<BaseRange>(r, GetSortOrder(r, p));
195 }
196
197 template <class BaseRange>
SortedRange(BaseRange && r)198 ViewRangeClass<BaseRange> SortedRange(BaseRange&& r)
199 {
200 return ViewRangeClass<BaseRange>(r, GetSortOrder(r));
201 }
202