31#ifndef LIB2GEOM_SEEN_GENERIC_INTERVAL_H
32#define LIB2GEOM_SEEN_GENERIC_INTERVAL_H
39#include <boost/functional/hash.hpp>
45class GenericOptInterval;
82 template <
typename InputIterator>
97 constexpr C
min()
const {
return _b[0]; }
98 constexpr C
max()
const {
return _b[1]; }
105 return std::clamp(val,
min(),
max());
109 C dmin = std::abs(val -
min()), dmax = std::abs(val -
max());
110 return dmin <= dmax ?
min() :
max();
113 template <
size_t I>
constexpr C
get()
const {
static_assert(I < 2);
return _b[I]; }
120 return min() <= val && val <=
max();
124 return min() <= val.min() && val.max() <=
max();
167 if (val <
_b[0])
_b[0] = val;
168 if (val >
_b[1])
_b[1] = val;
179 C halfway = (
_b[0] +
_b[1]) / 2;
180 _b[0] =
_b[1] = halfway;
188 if (a._b[0] <
_b[0])
_b[0] = a._b[0];
189 if (a._b[1] >
_b[1])
_b[1] = a._b[1];
200 _b[0] += amnt;
_b[1] += amnt;
205 _b[0] -= amnt;
_b[1] -= amnt;
239 return min() == other.min() &&
max() == other.max();
257 :
public std::optional<typename CoordTraits<C>::IntervalType>
258 , boost::orable< GenericOptInterval<C>
259 , boost::andable< GenericOptInterval<C>
264 using Base = std::optional<CInterval>;
285 template <
typename InputIterator>
290 return CInterval::from_range(
start,
end);
295 constexpr bool empty()
const {
return !*
this; }
301 (*this)->unionWith(*a);
309 C u = std::max((*this)->min(), o->min());
310 C v = std::min((*this)->max(), o->max());
330 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<Base, U>>>
332 return static_cast<Base const &
>(*this) ==
static_cast<Base const &
>(other);
334 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<Base, U>>>
336 return static_cast<Base const &
>(*this) !=
static_cast<Base const &
>(other);
356 return out <<
"Interval(" << I.min() <<
", " << I.max() <<
")";
362 return I ? (out << *I) : (out <<
"Interval (empty)");
368template <
typename C>
struct std::tuple_size<
Geom::GenericInterval<C>> : std::integral_constant<size_t, 2> {};
369template <
size_t I,
typename C>
struct std::tuple_element<I,
Geom::GenericInterval<C>> {
using type = C; };
372template <
typename C>
struct std::hash<
Geom::GenericInterval<C>>
376 boost::hash_combine(hash, a.min());
377 boost::hash_combine(hash, a.max());
A range of numbers which is never empty.
constexpr void setMin(C val)
Set the lower boundary of the interval.
constexpr C operator[](Dim2 d) const
C operator[](unsigned i) const
constexpr C extent() const
static CInterval from_range(InputIterator start, InputIterator end)
Create an interval containing a range of values.
constexpr bool contains(CInterval const &val) const
Check whether the interval includes the given interval.
static CInterval from_array(C const *c, unsigned n)
Create an interval from a C-style array of values it should contain.
constexpr bool operator==(CInterval const &other) const
Test for interval equality.
constexpr Self & operator+=(CInterval const &o)
Add two intervals.
constexpr void setEnds(C a, C b)
Set both ends of the interval simultaneously.
constexpr GenericInterval(C u, C v)
Create an interval that contains all points between u and v.
constexpr void expandTo(C val)
Extend the interval to include the given number.
constexpr Self & operator|=(CInterval const &o)
Union two intervals.
constexpr C clamp(C val) const
constexpr GenericInterval()=default
Create an interval that contains only zero.
constexpr Self & operator+=(C amnt)
Offset the interval by a specified amount.
constexpr bool isSingular() const
constexpr Self operator-() const
Return an interval mirrored about 0.
constexpr Self & operator-=(C amnt)
Offset the interval by the negation of the specified amount.
constexpr bool intersects(CInterval const &val) const
Check whether the intervals have any common elements.
constexpr GenericInterval(C u)
Create an interval that contains a single point.
C nearestEnd(C val) const
Return the closer end of the interval.
GenericInterval< C > unify(GenericInterval< C > const &a, GenericInterval< C > const &b)
Union two intervals.
constexpr Self & operator-=(CInterval const &o)
Subtract two intervals.
constexpr void unionWith(CInterval const &a)
Union the interval with another one.
constexpr bool contains(C val) const
Check whether the interval includes this number.
constexpr void setMax(C val)
Set the upper boundary of the interval.
constexpr void expandBy(C amount)
Expand or shrink the interval in both directions by the given amount.
typename CoordTraits< C >::IntervalType CInterval
constexpr C middle() const
A range of numbers that can be empty.
constexpr GenericOptInterval< C > & operator&=(OptCInterval const &o)
constexpr void unionWith(GenericOptInterval< C > const &a)
Union with another interval, gracefully handling empty ones.
constexpr GenericOptInterval(C u)
Create an interval containing a single point.
constexpr GenericOptInterval(C u, C v)
Create an interval containing a range of numbers.
constexpr bool operator!=(U const &other) const
constexpr GenericOptInterval(GenericInterval< C > const &a)
Wrap an existing interval.
typename CoordTraits< C >::OptIntervalType OptCInterval
constexpr GenericOptInterval< C > & operator|=(OptCInterval const &o)
GenericOptInterval< C > intersect(GenericInterval< C > const &a, GenericInterval< C > const &b)
Intersect two intervals and return a possibly empty range of numbers.
static GenericOptInterval< C > from_range(InputIterator start, InputIterator end)
Create a possibly empty interval containing a range of values.
GenericOptInterval< C > operator&(GenericInterval< C > const &a, GenericInterval< C > const &b)
Intersect two intervals and return a possibly empty range of numbers.
constexpr void intersectWith(GenericOptInterval< C > const &o)
typename CoordTraits< C >::IntervalType CInterval
std::optional< CInterval > Base
constexpr GenericOptInterval()=default
Create an empty interval.
constexpr bool operator==(U const &other) const
constexpr bool empty() const
Check whether this interval is empty.
Integral and real coordinate types and some basic utilities.
Dim2
2D axis enumeration (X or Y).
Various utility functions.
std::ostream & operator<<(std::ostream &os, const Bezier &b)
Traits class used with coordinate types.
size_t operator()(Geom::GenericInterval< C > const &a) const noexcept