Gazebo Math

API Reference

7.5.1
gz/math/Interval.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef GZ_MATH_INTERVAL_HH_
18 #define GZ_MATH_INTERVAL_HH_
19 
20 #include <cmath>
21 #include <limits>
22 #include <ostream>
23 #include <type_traits>
24 #include <utility>
25 
26 #include <gz/math/config.hh>
27 
28 namespace gz::math
29 {
30  // Inline bracket to help doxygen filtering.
31  inline namespace GZ_MATH_VERSION_NAMESPACE {
32  //
41  template <typename T>
42  class Interval
43  {
45  public: static const Interval<T> &Unbounded;
46 
48  public: Interval() = default;
49 
57  public: constexpr Interval(
58  T _leftValue, bool _leftClosed,
59  T _rightValue, bool _rightClosed)
60  : leftValue(std::move(_leftValue)),
61  rightValue(std::move(_rightValue)),
62  leftClosed(_leftClosed),
63  rightClosed(_rightClosed)
64  {
65  }
66 
71  public: static constexpr Interval<T>
72  Open(T _leftValue, T _rightValue)
73  {
74  return Interval<T>(
75  std::move(_leftValue), false,
76  std::move(_rightValue), false);
77  }
78 
83  public: static constexpr Interval<T>
84  LeftClosed(T _leftValue, T _rightValue)
85  {
86  return Interval<T>(
87  std::move(_leftValue), true,
88  std::move(_rightValue), false);
89  }
90 
95  public: static constexpr Interval<T>
96  RightClosed(T _leftValue, T _rightValue)
97  {
98  return Interval<T>(
99  std::move(_leftValue), false,
100  std::move(_rightValue), true);
101  }
102 
107  public: static constexpr Interval<T>
108  Closed(T _leftValue, T _rightValue)
109  {
110  return Interval<T>{
111  std::move(_leftValue), true,
112  std::move(_rightValue), true};
113  }
114 
117  public: const T &LeftValue() const { return this->leftValue; }
118 
121  public: bool IsLeftClosed() const { return this->leftClosed; }
122 
125  public: const T &RightValue() const { return this->rightValue; }
126 
129  public: bool IsRightClosed() const { return this->rightClosed; }
130 
135  public: bool Empty() const
136  {
137  if (this->leftClosed && this->rightClosed)
138  {
139  return this->rightValue < this->leftValue;
140  }
141  return this->rightValue <= this->leftValue;
142  }
143 
147  public: bool Contains(const T &_value) const
148  {
149  if (this->leftClosed && this->rightClosed)
150  {
151  return this->leftValue <= _value && _value <= this->rightValue;
152  }
153  if (this->leftClosed)
154  {
155  return this->leftValue <= _value && _value < this->rightValue;
156  }
157  if (this->rightClosed)
158  {
159  return this->leftValue < _value && _value <= this->rightValue;
160  }
161  return this->leftValue < _value && _value < this->rightValue;
162  }
163 
167  public: bool Contains(const Interval<T> &_other) const
168  {
169  if (this->Empty() || _other.Empty())
170  {
171  return false;
172  }
173  if (!this->leftClosed && _other.leftClosed)
174  {
175  if (_other.leftValue <= this->leftValue)
176  {
177  return false;
178  }
179  }
180  else
181  {
182  if (_other.leftValue < this->leftValue)
183  {
184  return false;
185  }
186  }
187  if (!this->rightClosed && _other.rightClosed)
188  {
189  if (this->rightValue <= _other.rightValue)
190  {
191  return false;
192  }
193  }
194  else
195  {
196  if (this->rightValue < _other.rightValue)
197  {
198  return false;
199  }
200  }
201  return true;
202  }
203 
207  public: bool Intersects(const Interval<T> &_other) const
208  {
209  if (this->Empty() || _other.Empty())
210  {
211  return false;
212  }
213  if (this->rightClosed && _other.leftClosed)
214  {
215  if (this->rightValue < _other.leftValue)
216  {
217  return false;
218  }
219  }
220  else
221  {
222  if (this->rightValue <= _other.leftValue)
223  {
224  return false;
225  }
226  }
227  if (_other.rightClosed && this->leftClosed)
228  {
229  if (_other.rightValue < this->leftValue)
230  {
231  return false;
232  }
233  }
234  else
235  {
236  if (_other.rightValue <= this->leftValue)
237  {
238  return false;
239  }
240  }
241  return true;
242  }
243 
247  public: bool operator==(const Interval<T> &_other) const
248  {
249  return this->Contains(_other) && _other.Contains(*this);
250  }
251 
255  public: bool operator!=(const Interval<T> &_other) const
256  {
257  return !this->Contains(_other) || !_other.Contains(*this);
258  }
259 
264  public: friend std::ostream &operator<<(
265  std::ostream &_out, const gz::math::Interval<T> &_interval)
266  {
267  return _out << (_interval.leftClosed ? "[" : "(")
268  << _interval.leftValue << ", " << _interval.rightValue
269  << (_interval.rightClosed ? "]" : ")");
270  }
271 
273  private: T leftValue{0};
275  private: T rightValue{0};
277  private: bool leftClosed{false};
279  private: bool rightClosed{false};
280  };
281 
282  namespace detail {
283  template<typename T>
284  constexpr Interval<T> gUnboundedInterval =
287  } // namespace detail
288  template<typename T>
289  const Interval<T> &Interval<T>::Unbounded = detail::gUnboundedInterval<T>;
290 
293  } // namespace GZ_MATH_VERSION_NAMESPACE
294 } // namespace gz::math
295 #endif // GZ_MATH_INTERVAL_HH_