bux API Reference
1.12.6
Static library of whatever are seen required in general purpose but not directly supported from Modern C++. Or whatever reusable originated from my side projects.
Toggle main menu visibility
Loading...
Searching...
No Matches
include
bux
Intervals.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <concepts>
// std::integral<>
4
#include <iterator>
// std::input_iterator<>
5
#include <limits>
// std::numeric_limits<>
6
#include <ostream>
// std::basic_ostream<>
7
#include <stdexcept>
// std::runtime_error
8
#include <utility>
// std::cmp_less_equal()
9
#include <vector>
// std::vector<>
10
11
namespace
bux
{
12
13
//
14
// Types
15
//
16
template
<
class
T>
17
concept
IntervalPt
= std::integral<T> && !std::same_as<char,T>;
18
19
template
<IntervalPt T>
20
class
C_Intervals
21
{
22
public
:
23
24
// Types
25
typedef
std::pair<T,T>
value_type
;
26
typedef
typename
std::vector<value_type>::const_iterator
const_iterator
;
27
28
// Ctors
29
C_Intervals
() {}
30
C_Intervals
(
const
C_Intervals
&other): m_Intervals(other.m_Intervals) {}
31
C_Intervals
(
C_Intervals
&&other) {
swap
(other); }
32
C_Intervals
(T
id
);
33
C_Intervals
(
value_type
i);
34
C_Intervals
(T start, T
end
):
C_Intervals
(
value_type
(start,
end
)) {}
35
template
<std::input_iterator I>
36
C_Intervals
(I start, I
end
)
requires
std::same_as<char, std::remove_cvref_t<
decltype
(*start)>>
37
{
38
while
(start !=
end
)
39
operator|=
(T(*start++));
// The cast can be an undefined behavior but I don't care for now.
40
}
41
template
<std::input_iterator I>
42
C_Intervals
(I start, I
end
)
requires
43
std::same_as<
value_type
, std::remove_cvref_t<
decltype
(*start)>> ||
44
(
45
!std::same_as<char,std::remove_cvref_t<
decltype
(*start)>> &&
46
std::integral<std::remove_cvref_t<
decltype
(*start)>> &&
47
std::cmp_less_equal(std::numeric_limits<T>::min(), std::numeric_limits<std::remove_cvref_t<
decltype
(*start)>>::min()) &&
48
std::cmp_less_equal(std::numeric_limits<std::remove_cvref_t<
decltype
(*start)>>::max(), std::numeric_limits<T>::max())
49
)
50
{
51
while
(start !=
end
)
52
operator|=
(*start++);
53
}
54
55
// Nonvirtuals - Assignments
56
void
operator=
(
const
C_Intervals
&other) { m_Intervals =other.m_Intervals; }
57
void
operator=
(
C_Intervals
&&other) {
swap
(other); }
58
void
operator|=
(
const
C_Intervals
&other);
59
void
operator&=
(
const
C_Intervals
&other);
60
void
operator-=
(
const
C_Intervals
&other);
61
bool
operator==
(
const
C_Intervals
&other)
const
{
return
m_Intervals == other.m_Intervals; }
62
63
// Nonvirtuals - Immutables
64
const_iterator
begin
()
const
{
return
m_Intervals.begin(); }
65
const_iterator
end
()
const
{
return
m_Intervals.end(); }
66
bool
empty
()
const
{
return
m_Intervals.empty(); }
67
size_t
size
()
const
{
return
m_Intervals.size(); }
68
69
// Nonvirtuals - Mutables
70
void
complement
();
71
void
swap
(
C_Intervals
&other) { m_Intervals.swap(other.m_Intervals); }
72
73
private
:
74
75
// Data
76
std::vector<value_type> m_Intervals;
77
};
78
79
//
80
// Function Templates
81
//
82
template
<IntervalPt T,
class
char
T,
class
traits=std::
char
_traits<
char
T>>
83
std::basic_ostream<charT,traits> &
84
operator<<
(std::basic_ostream<charT,traits> &out,
const
C_Intervals<T> &x)
85
{
86
bool
first =
true
;
87
for
(
auto
i: x)
88
{
89
out <<(first?
"{["
:
", ["
) <<i.first <<
','
<<i.second <<
']'
;
90
first =
false
;
91
}
92
if
(first)
93
out <<
'{'
;
94
95
return
out <<
'}'
;
96
}
97
98
//
99
// Implement Class Templates
100
//
101
template
<IntervalPt T>
102
C_Intervals<T>::C_Intervals
(T
id
)
103
{
104
m_Intervals.emplace_back(
id
,
id
);
105
}
106
107
template
<IntervalPt T>
108
C_Intervals<T>::C_Intervals
(
value_type
i)
109
{
110
if
(i.first > i.second)
111
throw
std::runtime_error{
'('
+std::to_string(i.first)+
','
+std::to_string(i.second)};
112
113
m_Intervals.emplace_back(i);
114
}
115
116
template
<IntervalPt T>
117
void
C_Intervals<T>::operator|=
(
const
C_Intervals<T>
&other)
118
{
119
decltype
(m_Intervals) dst;
120
const_iterator
121
ia =other.m_Intervals.begin(), ea =other.m_Intervals.end(),
122
ib =m_Intervals.begin(), eb =m_Intervals.end();
123
124
value_type
temp;
125
bool
tempInUse =
false
;
126
while
(ia != ea && ib != eb)
127
{
128
if
(ia->first > ib->first)
129
{
130
std::swap(ia, ib);
131
std::swap(ea, eb);
132
}
133
// ia->first <= ib->first for sure
134
if
(ia->second >= ib->second)
135
// (*ib) devoured
136
++ib;
137
else
if
(ia->second < ib->first && ia->second +1 < ib->first)
138
// (*ia) and (*ib) disjointed
139
{
140
if
(!tempInUse)
141
dst.emplace_back(*ia);
142
else
143
// Pending is over
144
{
145
if
(temp.second +1 >= ia->first)
146
{
147
temp.second = ia->second;
148
dst.emplace_back(temp);
149
}
150
else
151
{
152
dst.emplace_back(temp);
153
dst.emplace_back(*ia);
154
}
155
tempInUse =
false
;
156
}
157
++ia;
158
}
159
else
160
// Pending interval
161
{
162
if
(!tempInUse)
163
{
164
temp.first = ia->first;
165
tempInUse =
true
;
166
}
167
temp.second = ib->second;
168
++ia;
169
++ib;
170
}
171
}
172
173
if
(ib != eb)
174
{
175
ia =ib;
176
ea =eb;
177
}
178
if
(tempInUse)
179
{
180
while
(ia != ea)
181
{
182
if
(temp.second < ia->first && temp.second +1 < ia->first)
183
break
;
184
185
temp.second = ia->second;
186
++ia;
187
}
188
dst.emplace_back(temp);
189
}
190
dst.insert(dst.end(), ia, ea);
191
dst.swap(m_Intervals);
192
}
193
194
template
<IntervalPt T>
195
void
C_Intervals<T>::operator&=
(
const
C_Intervals<T>
&other)
196
{
197
decltype
(m_Intervals) dst;
198
const_iterator
ia = other.m_Intervals.begin();
199
const_iterator
ea =other.m_Intervals.end();
200
const_iterator
ib =m_Intervals.begin();
201
const_iterator
eb =m_Intervals.end();
202
203
while
(ia != ea && ib != eb)
204
{
205
if
(ia->first > ib->first)
206
{
207
std::swap(ia, ib);
208
std::swap(ea, eb);
209
}
210
// ia->first <= ib->first for sure
211
if
(ia->second >= ib->second)
212
// (*ib) devoured
213
dst.emplace_back(*ib++);
214
else
if
(ia->second < ib->first)
215
// (*ia) and (*ib) disjointed
216
++ia;
217
else
218
// ia->first <= ib->first <= ia->second < ib->second
219
{
220
dst.emplace_back(ib->first, ia->second);
221
++ia;
222
}
223
}
224
dst.swap(m_Intervals);
225
}
226
227
template
<IntervalPt T>
228
void
C_Intervals<T>::operator-=
(
const
C_Intervals<T>
&other)
229
{
230
auto
ib =other.m_Intervals.begin(),
231
eb =other.m_Intervals.end();
232
233
for
(
auto
ia =m_Intervals.begin(); ia != m_Intervals.end() && ib != eb;)
234
{
235
if
(ib->second < ia->first)
236
{
237
++ib;
238
continue
;
239
}
240
241
// ib->first <= ib->second
242
// ia->first <= ib->second
243
// ia->first <= ia->second
244
if
(ib->first <= ia->first)
245
{
246
if
(ia->second <= ib->second)
247
// (*ia) devoured by (*ib)
248
ia = m_Intervals.erase(ia);
249
else
250
// LB of (*ia) is increased
251
{
252
ia->first = ib->second +1;
253
++ib;
254
}
255
}
256
else
// ib->first > ia->first
257
{
258
if
(ia->second <= ib->second)
259
{
260
if
(ia->second >= ib->first)
261
ia->second = ib->first -1;
262
263
++ia;
264
}
265
else
// ia->second > ib->second
266
{
267
ia = m_Intervals.insert(ia,
value_type
(ia->first, ib->first-1));
268
(++ia)->first = ib->second +1;
269
++ib;
270
}
271
}
272
}
// for (auto ia =m_Intervals.begin(); ia != m_Intervals.end() && ib != eb;)
273
}
274
275
template
<IntervalPt T>
276
void
C_Intervals<T>::complement
()
277
{
278
if
(m_Intervals.empty())
279
{
280
m_Intervals.emplace_back(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
281
return
;
282
}
283
decltype
(m_Intervals) dst;
284
value_type
t;
285
t.first = std::numeric_limits<T>::min();
286
for
(
const
auto
&i: m_Intervals)
287
{
288
if
(i.first > std::numeric_limits<T>::min())
289
{
290
t.second = i.first -1;
291
dst.emplace_back(t);
292
}
293
t.first = i.second +1;
294
}
295
if
(t.first < std::numeric_limits<T>::max())
296
{
297
t.second = std::numeric_limits<T>::max();
298
dst.emplace_back(t);
299
}
300
dst.swap(m_Intervals);
301
}
302
303
}
// namespace bux
bux::C_Intervals
Definition
Intervals.h:21
bux::C_Intervals::operator=
void operator=(const C_Intervals &other)
Definition
Intervals.h:56
bux::C_Intervals::C_Intervals
C_Intervals()
Definition
Intervals.h:29
bux::C_Intervals::value_type
std::pair< T, T > value_type
Definition
Intervals.h:25
bux::C_Intervals::C_Intervals
C_Intervals(const C_Intervals &other)
Definition
Intervals.h:30
bux::C_Intervals::C_Intervals
C_Intervals(T start, T end)
Definition
Intervals.h:34
bux::C_Intervals::operator=
void operator=(C_Intervals &&other)
Definition
Intervals.h:57
bux::C_Intervals::C_Intervals
C_Intervals(I start, I end)
Definition
Intervals.h:42
bux::C_Intervals::operator-=
void operator-=(const C_Intervals &other)
Definition
Intervals.h:228
bux::C_Intervals::C_Intervals
C_Intervals(C_Intervals &&other)
Definition
Intervals.h:31
bux::C_Intervals::swap
void swap(C_Intervals &other)
Definition
Intervals.h:71
bux::C_Intervals::size
size_t size() const
Definition
Intervals.h:67
bux::C_Intervals::complement
void complement()
Definition
Intervals.h:276
bux::C_Intervals::const_iterator
std::vector< value_type >::const_iterator const_iterator
Definition
Intervals.h:26
bux::C_Intervals::C_Intervals
C_Intervals(I start, I end)
Definition
Intervals.h:36
bux::C_Intervals::end
const_iterator end() const
Definition
Intervals.h:65
bux::C_Intervals::operator|=
void operator|=(const C_Intervals &other)
Definition
Intervals.h:117
bux::C_Intervals::empty
bool empty() const
Definition
Intervals.h:66
bux::C_Intervals::begin
const_iterator begin() const
Definition
Intervals.h:64
bux::C_Intervals::operator&=
void operator&=(const C_Intervals &other)
Definition
Intervals.h:195
bux::C_Intervals::operator==
bool operator==(const C_Intervals &other) const
Definition
Intervals.h:61
bux::IntervalPt
Definition
Intervals.h:17
bux
THE common namespace of bux library.
Definition
AtomiX.cpp:3
bux::operator<<
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, const C_Intervals< T > &x)
Definition
Intervals.h:84
Generated by
1.18.0