|
1 /* |
|
2 Copyright 2014 Teemu Piippo |
|
3 All rights reserved. |
|
4 |
|
5 Redistribution and use in source and binary forms, with or without |
|
6 modification, are permitted provided that the following conditions |
|
7 are met: |
|
8 |
|
9 1. Redistributions of source code must retain the above copyright |
|
10 notice, this list of conditions and the following disclaimer. |
|
11 2. Redistributions in binary form must reproduce the above copyright |
|
12 notice, this list of conditions and the following disclaimer in the |
|
13 documentation and/or other materials provided with the distribution. |
|
14 3. Neither the name of the copyright holder nor the names of its |
|
15 contributors may be used to endorse or promote products derived from |
|
16 this software without specific prior written permission. |
|
17 |
|
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
20 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
|
21 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER |
|
22 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 */ |
|
30 |
|
31 #pragma once |
|
32 #include <algorithm> |
|
33 #include <memory> |
|
34 |
|
35 // |
|
36 // ------------------------------------------------------------------------------------------------- |
|
37 // |
|
38 |
|
39 template<typename T> |
|
40 class Range |
|
41 { |
|
42 T m_a; |
|
43 T m_b; |
|
44 T m_step; |
|
45 |
|
46 public: |
|
47 struct Iterator |
|
48 { |
|
49 T value; |
|
50 T step; |
|
51 inline METHOD operator*() -> T&; |
|
52 inline METHOD operator== (const Iterator& other) const -> bool; |
|
53 inline METHOD operator!= (const Iterator& other) const -> bool; |
|
54 inline METHOD operator++() -> Iterator&; |
|
55 }; |
|
56 |
|
57 Range (const T& a, const T& b, const T& step = 1); |
|
58 Range(); |
|
59 |
|
60 METHOD begin() const -> Iterator; |
|
61 METHOD end() const -> Iterator; |
|
62 METHOD min() const -> T; |
|
63 METHOD max() const -> T; |
|
64 METHOD check_bounds() -> void; |
|
65 METHOD contains (const T& c) const -> bool; |
|
66 METHOD contains_exclusive (const T& c) const -> bool; |
|
67 METHOD overlaps (Range<T> const& other) const -> bool; |
|
68 METHOD operator== (Range<T> const& other) const -> bool; |
|
69 METHOD operator!= (Range<T> const& other) const -> bool; |
|
70 }; |
|
71 |
|
72 // |
|
73 // ------------------------------------------------------------------------------------------------- |
|
74 // |
|
75 |
|
76 template<typename T> inline METHOD |
|
77 Range<T>::Iterator::operator*() -> T& |
|
78 { |
|
79 return value; |
|
80 } |
|
81 |
|
82 // |
|
83 // ------------------------------------------------------------------------------------------------- |
|
84 // |
|
85 |
|
86 template<typename T> inline METHOD |
|
87 Range<T>::Iterator::operator== (const Iterator& other) const -> bool |
|
88 { |
|
89 return value == other.value; |
|
90 } |
|
91 |
|
92 // |
|
93 // ------------------------------------------------------------------------------------------------- |
|
94 // |
|
95 |
|
96 template<typename T> inline METHOD |
|
97 Range<T>::Iterator::operator!= (const Iterator& other) const -> bool |
|
98 { |
|
99 return value != other.value; |
|
100 } |
|
101 |
|
102 // |
|
103 // ------------------------------------------------------------------------------------------------- |
|
104 // |
|
105 |
|
106 template<typename T> inline METHOD |
|
107 Range<T>::Iterator::operator++() -> Iterator& |
|
108 { |
|
109 value += step; |
|
110 return *this; |
|
111 } |
|
112 |
|
113 // |
|
114 // ------------------------------------------------------------------------------------------------- |
|
115 // |
|
116 |
|
117 template<typename T> |
|
118 Range<T>::Range (const T& a, const T& b, const T& step) : |
|
119 m_a (a), |
|
120 m_b (b), |
|
121 m_step (step) |
|
122 { |
|
123 check_bounds(); |
|
124 } |
|
125 |
|
126 // |
|
127 // ------------------------------------------------------------------------------------------------- |
|
128 // |
|
129 |
|
130 template<typename T> |
|
131 Range<T>::Range() : |
|
132 m_a (T()), |
|
133 m_b (T()) {} |
|
134 |
|
135 // |
|
136 // ------------------------------------------------------------------------------------------------- |
|
137 // |
|
138 |
|
139 template<typename T> METHOD |
|
140 Range<T>::check_bounds() -> void |
|
141 { |
|
142 if (m_b < m_a) |
|
143 std::swap (m_a, m_b); |
|
144 } |
|
145 |
|
146 // |
|
147 // ------------------------------------------------------------------------------------------------- |
|
148 // |
|
149 |
|
150 template<typename T> METHOD |
|
151 Range<T>::contains (const T& c) const -> bool |
|
152 { |
|
153 return (c >= m_a) and (c <= m_b); |
|
154 } |
|
155 |
|
156 // |
|
157 // ------------------------------------------------------------------------------------------------- |
|
158 // |
|
159 |
|
160 template<typename T> METHOD |
|
161 Range<T>::contains_exclusive (const T& c) const -> bool |
|
162 { |
|
163 return (c > m_a) and (c < m_b); |
|
164 } |
|
165 |
|
166 // |
|
167 // ------------------------------------------------------------------------------------------------- |
|
168 // |
|
169 |
|
170 template<typename T> METHOD |
|
171 Range<T>::overlaps (Range<T> const& other) const -> bool |
|
172 { |
|
173 return contains (other.m_a) or contains (other.m_b); |
|
174 } |
|
175 |
|
176 // |
|
177 // ------------------------------------------------------------------------------------------------- |
|
178 // |
|
179 |
|
180 template<typename T> METHOD |
|
181 Range<T>::operator== (Range<T> const& other) const -> bool |
|
182 { |
|
183 return m_a == other.m_a and m_b == other.m_b; |
|
184 } |
|
185 |
|
186 // |
|
187 // ------------------------------------------------------------------------------------------------- |
|
188 // |
|
189 |
|
190 template<typename T> METHOD |
|
191 Range<T>::operator!= (Range<T> const& other) const -> bool |
|
192 { |
|
193 return not operator== (other); |
|
194 } |
|
195 |
|
196 // |
|
197 // ------------------------------------------------------------------------------------------------- |
|
198 // |
|
199 |
|
200 template<typename T> METHOD |
|
201 Range<T>::min() const -> T |
|
202 { |
|
203 return m_a; |
|
204 } |
|
205 |
|
206 // |
|
207 // ------------------------------------------------------------------------------------------------- |
|
208 // |
|
209 |
|
210 template<typename T> METHOD |
|
211 Range<T>::max() const -> T |
|
212 { |
|
213 return m_b; |
|
214 } |
|
215 |
|
216 // |
|
217 // ------------------------------------------------------------------------------------------------- |
|
218 // |
|
219 |
|
220 template<typename T> METHOD |
|
221 Range<T>::begin() const -> Iterator |
|
222 { |
|
223 Iterator it; |
|
224 it.value = min(); |
|
225 it.step = m_step; |
|
226 return it; |
|
227 } |
|
228 |
|
229 // |
|
230 // ------------------------------------------------------------------------------------------------- |
|
231 // |
|
232 |
|
233 template<typename T> METHOD |
|
234 Range<T>::end() const -> Iterator |
|
235 { |
|
236 Iterator it; |
|
237 it.value = max() + 1; |
|
238 it.step = m_step; |
|
239 return it; |
|
240 } |