Interval.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty. In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  * claim that you wrote the original software. If you use this software
14  * in a product, an acknowledgment in the product documentation would be
15  * appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  * misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  */
20 
21 #ifndef PLAYRHO_COMMON_INTERVAL_HPP
22 #define PLAYRHO_COMMON_INTERVAL_HPP
23 
25 #include <algorithm>
26 #include <limits>
27 #include <iostream>
28 
29 namespace playrho {
30 
38 template <typename T>
39 class Interval
40 {
41 public:
42 
46  using value_type = T;
47 
49  using limits = std::numeric_limits<value_type>;
50 
54  static PLAYRHO_CONSTEXPR inline value_type GetLowest() noexcept
55  {
56  return (limits::has_infinity)? -limits::infinity(): limits::lowest();
57  }
58 
62  static PLAYRHO_CONSTEXPR inline value_type GetHighest() noexcept
63  {
64  return (limits::has_infinity)? limits::infinity(): limits::max();
65  }
66 
71  PLAYRHO_CONSTEXPR inline Interval() = default;
72 
76  PLAYRHO_CONSTEXPR inline Interval(const Interval& other) = default;
77 
81  PLAYRHO_CONSTEXPR inline Interval(Interval&& other) = default;
82 
86  PLAYRHO_CONSTEXPR inline explicit Interval(const value_type& v) noexcept:
87  Interval(pair_type{v, v})
88  {
89  // Intentionally empty.
90  }
91 
93  PLAYRHO_CONSTEXPR inline Interval(const value_type& a, const value_type& b) noexcept:
94  Interval(std::minmax(a, b))
95  {
96  // Intentionally empty.
97  }
98 
100  PLAYRHO_CONSTEXPR inline Interval(const std::initializer_list<T> ilist) noexcept:
101  Interval(std::minmax(ilist))
102  {
103  // Intentionally empty.
104  }
105 
106  ~Interval() noexcept = default;
107 
111  Interval& operator= (const Interval& other) = default;
112 
116  Interval& operator= (Interval&& other) = default;
117 
121  PLAYRHO_CONSTEXPR inline Interval& Move(const value_type& v) noexcept
122  {
123  m_min += v;
124  m_max += v;
125  return *this;
126  }
127 
129  PLAYRHO_CONSTEXPR inline value_type GetMin() const noexcept
130  {
131  return m_min;
132  }
133 
135  PLAYRHO_CONSTEXPR inline value_type GetMax() const noexcept
136  {
137  return m_max;
138  }
139 
145  PLAYRHO_CONSTEXPR inline Interval& Include(const value_type& v) noexcept
146  {
147  m_min = std::min(v, GetMin());
148  m_max = std::max(v, GetMax());
149  return *this;
150  }
151 
158  PLAYRHO_CONSTEXPR inline Interval& Include(const Interval& v) noexcept
159  {
160  m_min = std::min(v.GetMin(), GetMin());
161  m_max = std::max(v.GetMax(), GetMax());
162  return *this;
163  }
164 
166  PLAYRHO_CONSTEXPR inline Interval& Intersect(const Interval& v) noexcept
167  {
168  const auto min = std::max(v.GetMin(), GetMin());
169  const auto max = std::min(v.GetMax(), GetMax());
170  *this = (min <= max)? Interval{pair_type{min, max}}: Interval{};
171  return *this;
172  }
173 
181  PLAYRHO_CONSTEXPR inline Interval& Expand(const value_type& v) noexcept
182  {
183  if (v < value_type{})
184  {
185  m_min += v;
186  }
187  else
188  {
189  m_max += v;
190  }
191  return *this;
192  }
193 
202  {
203  const auto amount = value_type{v};
204  m_min -= amount;
205  m_max += amount;
206  return *this;
207  }
208 
209 private:
213  using pair_type = std::pair<value_type, value_type>;
214 
216  PLAYRHO_CONSTEXPR inline explicit Interval(pair_type pair) noexcept:
217  m_min{std::get<0>(pair)}, m_max{std::get<1>(pair)}
218  {
219  // Intentionally empty.
220  }
221 
222  value_type m_min = GetHighest();
223  value_type m_max = GetLowest();
224 };
225 
231 template <typename T>
232 PLAYRHO_CONSTEXPR inline T GetSize(const Interval<T>& v) noexcept
233 {
234  return v.GetMax() - v.GetMin();
235 }
236 
241 template <typename T>
242 PLAYRHO_CONSTEXPR inline T GetCenter(const Interval<T>& v) noexcept
243 {
244  // Rounding may cause issues...
245  return (v.GetMin() + v.GetMax()) / 2;
246 }
247 
250 template <typename T>
251 PLAYRHO_CONSTEXPR inline bool IsIntersecting(const Interval<T>& a, const Interval<T>& b) noexcept
252 {
253  const auto maxOfMins = std::max(a.GetMin(), b.GetMin());
254  const auto minOfMaxs = std::min(a.GetMax(), b.GetMax());
255  return minOfMaxs >= maxOfMins;
256 }
257 
260 template <typename T>
262 {
263  return a.Intersect(b);
264 }
265 
267 template <typename T>
269 {
270  return a.GetMax() < b.GetMin();
271 }
272 
274 template <typename T>
276 {
277  return a.GetMin() > b.GetMax();
278 }
279 
281 template <typename T>
283 {
284  return a.GetMin() <= b.GetMin() && a.GetMax() >= b.GetMax();
285 }
286 
291 template <typename T>
292 PLAYRHO_CONSTEXPR inline bool operator== (const Interval<T>& a, const Interval<T>& b) noexcept
293 {
294  return (a.GetMin() == b.GetMin()) && (a.GetMax() == b.GetMax());
295 }
296 
301 template <typename T>
302 PLAYRHO_CONSTEXPR inline bool operator!= (const Interval<T>& a, const Interval<T>& b) noexcept
303 {
304  return !(a == b);
305 }
306 
317 template <typename T>
318 PLAYRHO_CONSTEXPR inline bool operator< (const Interval<T>& lhs, const Interval<T>& rhs) noexcept
319 {
320  return (lhs.GetMin() < rhs.GetMin()) ||
321  (lhs.GetMin() == rhs.GetMin() && lhs.GetMax() < rhs.GetMax());
322 }
323 
329 template <typename T>
330 PLAYRHO_CONSTEXPR inline bool operator<= (const Interval<T>& lhs, const Interval<T>& rhs) noexcept
331 {
332  return (lhs.GetMin() < rhs.GetMin()) ||
333  (lhs.GetMin() == rhs.GetMin() && lhs.GetMax() <= rhs.GetMax());
334 }
335 
341 template <typename T>
342 PLAYRHO_CONSTEXPR inline bool operator> (const Interval<T>& lhs, const Interval<T>& rhs) noexcept
343 {
344  return (lhs.GetMin() > rhs.GetMin()) ||
345  (lhs.GetMin() == rhs.GetMin() && lhs.GetMax() > rhs.GetMax());
346 }
347 
353 template <typename T>
354 PLAYRHO_CONSTEXPR inline bool operator>= (const Interval<T>& lhs, const Interval<T>& rhs) noexcept
355 {
356  return (lhs.GetMin() > rhs.GetMin()) ||
357  (lhs.GetMin() == rhs.GetMin() && lhs.GetMax() >= rhs.GetMax());
358 }
359 
361 template <typename T>
362 ::std::ostream& operator<< (::std::ostream& os, const Interval<T>& value)
363 {
364  return os << '{' << value.GetMin() << "..." << value.GetMax() << '}';
365 }
366 
367 } // namespace playrho
368 
369 #endif // PLAYRHO_COMMON_INTERVAL_HPP