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
PartialOrdering.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <concepts>
// std::constructible_from<>, std::equality_comparable<>, std::invocable<>
4
#include <list>
// std::list<>
5
6
namespace
bux
{
7
8
//
9
// Types
10
//
11
enum
E_MakeLinearPolicy
12
{
13
MLP_BREADTH_FIRST
,
14
MLP_DEPTH_FIRST
15
};
16
17
template
<std::equality_comparable T>
18
class
C_PartialOrdering
24
{
25
public
:
26
27
// Types
28
typedef
std::list<T>
C_ValList
;
29
30
// Nonvirtuals
31
template
<
class
T1,
class
T2>
32
[[nodiscard]]
bool
addOrder
(T1 a, T2 b);
33
// Return true if given order (a,b) is successfully added
34
template
<
class
T2>
35
bool
anyLeft
(
const
T2 &R)
const
;
36
template
<
class
T2>
37
bool
anyRight
(
const
T2 &L)
const
;
38
void
clear
() { m_Relation.clear(); }
39
std::size_t
depthToLeft
(T t)
const
;
40
// Return 0 for the leftmosts.
41
bool
empty
()
const
{
return
m_Relation.empty(); }
42
template
<
class
T2,
class
F>
43
void
getRelated
(T2 L, F R, std::size_t maxDepth = 0) const requires std::constructible_from<T,T2> && std::invocable<F,T>;
44
template<class F>
45
void
getRelated
(
C_ValList
L, F R, std::
size_t
maxDepth = 0) const requires std::invocable<F,T>;
46
template<class F, class T2>
47
void
getRelated
(F L, T2 R, std::
size_t
maxDepth = 0) const requires std::constructible_from<T,T2> && std::invocable<F,T>;
48
template<class F>
49
void
getRelated
(F L,
C_ValList
R, std::
size_t
maxDepth = 0) const requires std::invocable<F,T>;
50
template<class F>
51
void
makeLinear
(F apply,
E_MakeLinearPolicy
policy =
MLP_BREADTH_FIRST
) const requires std::invocable<F,T>;
52
bool
related
(const T &a, const T &b) const;
53
54
private:
55
56
// Data
57
std::list<std::pair<T,T>> m_Relation;
58
59
// Nonvirtuals
60
bool
find(const
C_ValList
&src, T t) const;
61
void
pruneLeftmost(
C_ValList
&l, const
C_ValList
&r) const;
62
};
63
64
//
65
// Function Templates
66
//
67
template<class C, class T>
68
void
addUnique
(C &c, T &&value)
69
{
70
for
(
auto
&i: c)
71
if
(i == value)
72
return
;
73
74
c.emplace_back(std::forward<T>(value));
75
}
76
77
//
78
// Implement Class Templates
79
//
80
template
<std::equality_comparable T>
81
template
<
class
T1,
class
T2>
82
bool
C_PartialOrdering<T>::addOrder
(T1 a, T2 b)
83
{
84
if
(a == b)
85
return
false
;
86
87
if
(
related
(b, a))
88
// Looping
89
return
false
;
90
91
for
(
auto
&i: m_Relation)
92
if
(a == i.first && b == i.second)
93
// Already added
94
return
true
;
95
96
m_Relation.emplace_back(a, b);
97
return
true
;
98
}
99
100
template
<std::equality_comparable T>
101
std::size_t
C_PartialOrdering<T>::depthToLeft
(T t)
const
102
{
103
std::size_t ret =0;
104
for
(
auto
&i: m_Relation)
105
if
(t == i.second)
106
{
107
const
std::size_t cur =
depthToLeft
(i.first) +1;
108
if
(cur > ret)
109
ret = cur;
110
}
111
return
ret;
112
}
113
114
template
<std::equality_comparable T>
115
bool
C_PartialOrdering<T>::find(
const
C_ValList
&src, T t)
const
116
{
117
for
(
auto
&i: src)
118
if
(t == i)
119
return
true
;
120
121
return
false
;
122
}
123
124
template
<std::equality_comparable T>
125
template
<
class
T2>
126
bool
C_PartialOrdering<T>::anyLeft
(
const
T2 &R)
const
127
{
128
for
(
auto
&i: m_Relation)
129
if
(i.second == R)
130
return
true
;
131
132
return
false
;
133
}
134
135
template
<std::equality_comparable T>
136
template
<
class
T2>
137
bool
C_PartialOrdering<T>::anyRight
(
const
T2 &L)
const
138
{
139
for
(
auto
&i: m_Relation)
140
if
(L == i.first)
141
return
true
;
142
143
return
false
;
144
}
145
146
template
<std::equality_comparable T>
147
template
<
class
T2,
class
F>
148
void
C_PartialOrdering<T>::getRelated
(T2 L, F R, std::size_t maxDepth)
const
requires
std::constructible_from<T,T2> && std::invocable<F,T>
149
{
150
getRelated
({1, std::forward<T2>(L)}, R, maxDepth);
151
}
152
153
template
<std::equality_comparable T>
154
template
<
class
F,
class
T2>
155
void
C_PartialOrdering<T>::getRelated
(F L, T2 R, std::size_t maxDepth)
const
requires
std::constructible_from<T,T2> && std::invocable<F,T>
156
{
157
getRelated
(L, {1, std::forward<T2>(R)}, maxDepth);
158
}
159
160
template
<std::equality_comparable T>
161
template
<
class
F>
162
void
C_PartialOrdering<T>::getRelated
(
C_ValList
L, F R, std::size_t maxDepth)
const
requires
std::invocable<F,T>
163
{
164
std::size_t oldSize = 0;
165
C_ValList
dst;
166
for
(std::size_t depth = 0; !maxDepth || depth < maxDepth; ++depth)
167
{
168
for
(
auto
&i: m_Relation)
169
for
(
auto
&j: L)
170
if
(j == i.first)
171
addUnique
(dst, i.second);
172
173
if
(oldSize == dst.size())
174
break
;
175
176
auto
iDst = dst.begin();
177
std::advance(iDst, oldSize);
178
L.assign(iDst, dst.end());
179
oldSize = dst.size();
180
}
181
for
(
auto
&i: dst)
182
R(i);
183
}
184
185
template
<std::equality_comparable T>
186
template
<
class
F>
187
void
C_PartialOrdering<T>::getRelated
(F L,
C_ValList
R, std::size_t maxDepth)
const
requires
std::invocable<F,T>
188
{
189
std::size_t oldSize = 0;
190
C_ValList
dst;
191
for
(std::size_t depth = 0; !maxDepth || depth < maxDepth; ++depth)
192
{
193
for
(
auto
&i: m_Relation)
194
for
(
auto
&j: R)
195
if
(j == i.second)
196
addUnique
(dst, i.first);
197
198
if
(oldSize == dst.size())
199
break
;
200
201
auto
iDst = dst.begin();
202
std::advance(iDst, oldSize);
203
R.assign(iDst, dst.end());
204
oldSize = dst.size();
205
}
206
for
(
auto
&i: dst)
207
L(i);
208
}
209
210
template
<std::equality_comparable T>
211
template
<
class
F>
212
void
C_PartialOrdering<T>::makeLinear
(F apply,
E_MakeLinearPolicy
policy)
const
requires
std::invocable<F,T>
213
{
237
C_ValList
q, r;
238
auto
mapping = m_Relation;
239
for
(
auto
&i: mapping)
240
{
241
addUnique
(q, i.first);
242
addUnique
(r, i.second);
243
}
244
pruneLeftmost(q, r);
245
246
while
(!q.empty())
247
{
248
const
T t =q.front();
249
q.pop_front();
250
apply(t);
251
252
C_ValList
l;
253
r.clear();
254
for
(
auto
i = mapping.begin(), end = mapping.end(); i != end;)
255
{
256
if
(t == i->first)
257
{
258
addUnique
(l, i->second);
259
i = mapping.erase(i);
260
}
261
else
262
{
263
addUnique
(r, i->second);
264
++i;
265
}
266
}
267
268
pruneLeftmost(l, r);
269
switch
(policy)
270
{
271
case
MLP_BREADTH_FIRST
:
272
q.splice(q.end(), l);
273
break
;
274
case
MLP_DEPTH_FIRST
:
275
q.splice(q.begin(), l);
276
break
;
277
}
278
}
279
}
280
281
template
<std::equality_comparable T>
282
void
C_PartialOrdering<T>::pruneLeftmost(
C_ValList
&l,
const
C_ValList
&r)
const
283
{
284
for
(
auto
i = l.begin(), end = l.end(); i != end;)
285
{
286
if
(find(r, *i))
287
i = l.erase(i);
288
else
289
++i;
290
}
291
}
292
293
template
<std::equality_comparable T>
294
bool
C_PartialOrdering<T>::related
(
const
T &a,
const
T &b)
const
295
{
296
for
(
auto
&i: m_Relation)
297
if
(a == i.first)
298
{
299
if
(i.second == b)
300
// aRb
301
return
true
;
302
303
if
(
related
(i.second, b))
304
// aRt && tRb
305
return
true
;
306
}
307
return
false
;
308
}
309
310
}
// namespace bux
bux::C_PartialOrdering
Definition
PartialOrdering.h:24
bux::C_PartialOrdering::clear
void clear()
Definition
PartialOrdering.h:38
bux::C_PartialOrdering::makeLinear
void makeLinear(F apply, E_MakeLinearPolicy policy=MLP_BREADTH_FIRST) const
Definition
PartialOrdering.h:212
bux::C_PartialOrdering::anyLeft
bool anyLeft(const T2 &R) const
Definition
PartialOrdering.h:126
bux::C_PartialOrdering::getRelated
void getRelated(T2 L, F R, std::size_t maxDepth=0) const
Definition
PartialOrdering.h:148
bux::C_PartialOrdering::depthToLeft
std::size_t depthToLeft(T t) const
Definition
PartialOrdering.h:101
bux::C_PartialOrdering::related
bool related(const T &a, const T &b) const
Definition
PartialOrdering.h:294
bux::C_PartialOrdering::empty
bool empty() const
Definition
PartialOrdering.h:41
bux::C_PartialOrdering::anyRight
bool anyRight(const T2 &L) const
Definition
PartialOrdering.h:137
bux::C_PartialOrdering::C_ValList
std::list< T > C_ValList
Definition
PartialOrdering.h:28
bux::C_PartialOrdering::addOrder
bool addOrder(T1 a, T2 b)
Definition
PartialOrdering.h:82
bux
THE common namespace of bux library.
Definition
AtomiX.cpp:3
bux::E_MakeLinearPolicy
E_MakeLinearPolicy
Definition
PartialOrdering.h:12
bux::MLP_DEPTH_FIRST
@ MLP_DEPTH_FIRST
Definition
PartialOrdering.h:14
bux::MLP_BREADTH_FIRST
@ MLP_BREADTH_FIRST
Definition
PartialOrdering.h:13
bux::addUnique
void addUnique(C &c, T &&value)
Definition
PartialOrdering.h:68
Generated by
1.18.0