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