Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
intervals.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_MATH_INTERVALS_H
7#define ELEMENTA_MATH_INTERVALS_H
8
9#include <string>
11
12namespace elementa
13{
14
15namespace math
16{
17
18
20/* *************************************************************************/
36/* *****************************************************************************
37
38 Enum class: IntervalClosedness
39
40*******************************************************************************/
41
43enum class IntervalCl: uint8_t {
44 CLOSED,
45 OPENED,
46 LEFT_CLOSED,
47 RIGHT_CLOSED
48 };
49
50
51/* *****************************************************************************
52
53 Template class: Interval
54
55*******************************************************************************/
56
58
60template <typename ELEMTYPE>
62{
63 public:
64
66
69 static Interval fromWidth(ELEMTYPE mi, ELEMTYPE width,
70 IntervalCl cl = IntervalCl::CLOSED)
71 { return(Interval{mi,static_cast<ELEMTYPE>(mi + width),cl}); }
72
73
75 Interval(void): closedl_{false},
76 closedr_{false},
77 allclosed_{false},
78 min_{ELEMTYPE{}}, // if numerical, gets 0
79 max_{ELEMTYPE{}} {}
80
82 Interval(ELEMTYPE mi, ELEMTYPE ma,
83 IntervalCl cl = IntervalCl::CLOSED):
84 closedl_{(cl == IntervalCl::CLOSED) ||
85 (cl == IntervalCl::LEFT_CLOSED)},
86 closedr_{(cl == IntervalCl::CLOSED) ||
87 (cl == IntervalCl::RIGHT_CLOSED)},
88 allclosed_{cl == IntervalCl::CLOSED},
89 min_{mi},max_{ma}
90 { if (ma < mi) ELE_CODE_INVARG(
91 "Invalid interval (max " +
92 std::to_string(ma) + " is < min " +
93 std::to_string(mi) + ")");
94 if ((closedl_ != closedr_) && (ma == mi))
95 ELE_CODE_INVARG("Invalid semi-closed interval"); }
96
97
98 Interval(const Interval & o) { copyFrom(o); }
99 Interval(Interval && o) { copyFrom(o); }
100 Interval & operator=(const Interval & o) { copyFrom(o); return(*this); }
101 Interval & operator=(Interval && o) { copyFrom(o); return(*this); }
102
103
104 ELEMTYPE minimum(void) const noexcept { return(min_); }
106
107 ELEMTYPE maximum(void) const noexcept { return(max_); }
109
110 ELEMTYPE width(void) const noexcept { return(max_ - min_); }
112
113 IntervalCl closedness(void) const noexcept
115 { return(closednessFromCloses(closedl_,closedr_)); }
116
117 bool closedMin(void) const noexcept { return(closedl_); }
119
120 bool closedMax(void) const noexcept { return(closedr_); }
122
123 bool empty(void) const noexcept { return((!allclosed_) && (min_ == max_)); }
125
128 Interval intersect(const Interval & oth) const noexcept
130 {
131 if ( ((oth.min_ > max_) || (oth.max_ < min_)) ||
132 ((oth.closedl_ != closedr_) && (oth.min_ == max_)) ||
133 ((oth.closedr_ != closedl_) && (oth.max_ == min_)) )
134 return(Interval{});
135 ELEMTYPE a,b;
136 bool cl,cr;
137 if ((oth.min_ > min_) || (oth.min_ == min_))
138 {
139 a = oth.min_;
140 cl = oth.closedl_;
141 b = std::min(oth.max_,max_);
142 cr = closedr_;
143 }
144 else
145 {
146 a = min_;
147 cl = closedl_;
148 b = std::min(oth.max_,max_);
149 cr = oth.closedr_;
150 }
151 return(Interval{a,b,closednessFromCloses(cl,cr)});
152 }
154 bool containPoint(ELEMTYPE e) const noexcept
156 { return( ((e > min_) && (e < max_)) ||
157 ((e == min_) && (closedl_)) ||
158 ((e == max_) && (closedr_)) ); }
160 std::string to_string(void) const
162 { return(std::string(1, closedl_ ? '[' : '(') +
163 std::to_string(min_) + ".." + std::to_string(max_) +
164 std::string(1, closedl_ ? ']' : ')')); }
165
166
167 private:
168
169 static IntervalCl closednessFromCloses(bool l, bool r) noexcept
170 { return(l == r ?
171 (l ? IntervalCl::CLOSED : IntervalCl::OPENED) :
172 (l ? IntervalCl::LEFT_CLOSED : IntervalCl::RIGHT_CLOSED)); }
173
174 bool closedl_,closedr_,allclosed_;
175
176 ELEMTYPE min_,max_;
177
178 void copyFrom(const Interval & o)
179 { closedl_ = o.closedl_; closedr_ = o.closedr_; allclosed_ = o.allclosed_;
180 min_ = o.min_; max_ = o.max_; }
181};
182
183
186} // end math namespace
187
188} // end elementa namespace
189
190
191#endif
192
193
#define ELE_CODE_INVARG(expl)
To throw an invalid-argument exception with an explanation.
Definition: exceptions.h:310
A numeric interval, either closed, opened or semi-closed.
Definition: intervals.h:62
bool closedMin(void) const noexcept
Return the closedness of the minimum bound.
Definition: intervals.h:117
static Interval fromWidth(ELEMTYPE mi, ELEMTYPE width, IntervalCl cl=IntervalCl::CLOSED)
Factory constructor from the minimum and width of the interval.
Definition: intervals.h:69
bool closedMax(void) const noexcept
Return the closedness of the maximum bound.
Definition: intervals.h:120
IntervalCl closedness(void) const noexcept
< Return the closedness of the interval.
Definition: intervals.h:113
Interval(ELEMTYPE mi, ELEMTYPE ma, IntervalCl cl=IntervalCl::CLOSED)
Constructor from the minimum and maximum of the interval.
Definition: intervals.h:82
std::string to_string(void) const
< Return a string describing the interval.
Definition: intervals.h:159
bool containPoint(ELEMTYPE e) const noexcept
< Return true if E is inside the interval.
Definition: intervals.h:153
ELEMTYPE minimum(void) const noexcept
Return the minimum value.
Definition: intervals.h:104
bool empty(void) const noexcept
Return true if the interval is empty.
Definition: intervals.h:123
IntervalCl
Kinds of closedness for numeric intervals.
Definition: intervals.h:43
Interval intersect(const Interval &oth) const noexcept
< Return the interval that is the intersection of both, or empty if none.
Definition: intervals.h:127
ELEMTYPE width(void) const noexcept
Return the distance from the minimum to the maximum.
Definition: intervals.h:110
ELEMTYPE maximum(void) const noexcept
Return the maximum value.
Definition: intervals.h:107
Interval(void)
Default constructor: empty interval.
Definition: intervals.h:75