UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
predicate.hpp
1
42#ifndef UFO_CONTAINER_TREE_PREDICATE_PREDICATE_HPP
43#define UFO_CONTAINER_TREE_PREDICATE_PREDICATE_HPP
44
45// UFO
46#include <ufo/container/tree/predicate/filter.hpp>
47
48// STL
49#include <memory>
50#include <type_traits>
51
52namespace ufo::pred
53{
54namespace detail
55{
56template <class Tree, class = void>
58{
59 public:
60 virtual ~Dynamic() {}
61
62 virtual void init(Tree const&) = 0;
63
64 [[nodiscard]] virtual bool returnable(Tree const&,
65 typename Tree::Node const&) const = 0;
66
67 [[nodiscard]] virtual bool traversable(Tree const&,
68 typename Tree::Node const&) const = 0;
69
70 [[nodiscard]] virtual bool returnableRay(Tree const&, typename Tree::Node const&,
71 typename Tree::Ray const&) const = 0;
72
73 [[nodiscard]] virtual bool traversableRay(Tree const&, typename Tree::Node const&,
74 typename Tree::Ray const&) const = 0;
75
76 [[nodiscard]] virtual Dynamic* clone() const = 0;
77};
78
79template <class Tree>
80class Dynamic<Tree, std::void_t<typename Tree::value_type>>
81{
82 public:
83 virtual ~Dynamic() {}
84
85 virtual void init(Tree const&) = 0;
86
87 [[nodiscard]] virtual bool returnableValue(typename Tree::value_type const&) const = 0;
88
89 [[nodiscard]] virtual bool returnable(Tree const&,
90 typename Tree::Node const&) const = 0;
91
92 [[nodiscard]] virtual bool traversable(Tree const&,
93 typename Tree::Node const&) const = 0;
94
95 [[nodiscard]] virtual bool returnableRay(Tree const&, typename Tree::Node const&,
96 typename Tree::Ray const&) const = 0;
97
98 [[nodiscard]] virtual bool traversableRay(Tree const&, typename Tree::Node const&,
99 typename Tree::Ray const&) const = 0;
100
101 [[nodiscard]] virtual Dynamic* clone() const = 0;
102};
103
104template <class Tree, class Predicate, class = void>
106 : public Dynamic<Tree>
107 , public Predicate
108{
109 public:
110 using Predicate::Predicate;
111
112 DynamicPredicate(Tree const&, Predicate const& pred) : Predicate(pred) {}
113
114 DynamicPredicate(Tree const&, Predicate&& pred) : Predicate(std::move(pred)) {}
115
116 virtual ~DynamicPredicate() {}
117
118 void init(Tree const& t) override
119 {
120 Filter<Predicate>::init(static_cast<Predicate&>(*this), t);
121 }
122
123 [[nodiscard]] bool returnable(Tree const& t,
124 typename Tree::Node const& n) const override
125 {
126 return Filter<Predicate>::returnable(static_cast<Predicate const&>(*this), t, n);
127 }
128
129 [[nodiscard]] bool traversable(Tree const& t,
130 typename Tree::Node const& n) const override
131 {
132 return Filter<Predicate>::traversable(static_cast<Predicate const&>(*this), t, n);
133 }
134
135 [[nodiscard]] bool returnableRay(Tree const& t, typename Tree::Node const& n,
136 typename Tree::Ray const& r) const override
137 {
138 return Filter<Predicate>::returnableRay(static_cast<Predicate const&>(*this), t, n,
139 r);
140 }
141
142 [[nodiscard]] bool traversableRay(Tree const& t, typename Tree::Node const& n,
143 typename Tree::Ray const& r) const override
144 {
145 return Filter<Predicate>::traversableRay(static_cast<Predicate const&>(*this), t, n,
146 r);
147 }
148
149 protected:
150 [[nodiscard]] DynamicPredicate* clone() const override
151 {
152 return new DynamicPredicate(*this);
153 }
154};
155
156template <class Tree, class Predicate>
157class DynamicPredicate<Tree, Predicate, std::void_t<typename Tree::value_type>>
158 : public Dynamic<Tree>
159 , public Predicate
160{
161 public:
162 using Predicate::Predicate;
163
164 DynamicPredicate(Tree const&, Predicate const& pred) : Predicate(pred) {}
165
166 DynamicPredicate(Tree const&, Predicate&& pred) : Predicate(std::move(pred)) {}
167
168 virtual ~DynamicPredicate() {}
169
170 void init(Tree const& t) override
171 {
172 Filter<Predicate>::init(static_cast<Predicate&>(*this), t);
173 }
174
175 [[nodiscard]] bool returnableValue(typename Tree::value_type const& v) const override
176 {
177 return Filter<Predicate>::returnableValue(static_cast<Predicate const&>(*this), v);
178 }
179
180 [[nodiscard]] bool returnable(Tree const& t,
181 typename Tree::Node const& n) const override
182 {
183 return Filter<Predicate>::returnable(static_cast<Predicate const&>(*this), t, n);
184 }
185
186 [[nodiscard]] bool traversable(Tree const& t,
187 typename Tree::Node const& n) const override
188 {
189 return Filter<Predicate>::traversable(static_cast<Predicate const&>(*this), t, n);
190 }
191
192 [[nodiscard]] bool returnableRay(Tree const& t, typename Tree::Node const& n,
193 typename Tree::Ray const& r) const override
194 {
195 return Filter<Predicate>::returnableRay(static_cast<Predicate const&>(*this), t, n,
196 r);
197 }
198
199 [[nodiscard]] bool traversableRay(Tree const& t, typename Tree::Node const& n,
200 typename Tree::Ray const& r) const override
201 {
202 return Filter<Predicate>::traversableRay(static_cast<Predicate const&>(*this), t, n,
203 r);
204 }
205
206 protected:
207 [[nodiscard]] DynamicPredicate* clone() const override
208 {
209 return new DynamicPredicate(*this);
210 }
211};
212} // namespace detail
213
214template <class Tree>
216{
217 public:
218 Predicate() = default;
219
220 Predicate(Predicate const& other)
221 {
222 if (other.hasPredicate()) {
223 predicate_.reset(other.predicate_->clone());
224 }
225 }
226
227 template <class Pred>
229 Predicate(Pred&& pred)
230 : predicate_(
231 std::make_unique<detail::DynamicPredicate<Tree, std::remove_cvref_t<Pred>>>(
232 std::forward<Pred>(pred)))
233 {
234 }
235
236 Predicate(Predicate&&) = default;
237
238 Predicate(detail::Dynamic<Tree> const& pred) : predicate_(pred.clone()) {}
239
240 Predicate& operator=(Predicate const& rhs)
241 {
242 if (rhs.hasPredicate()) {
243 predicate_.reset(rhs.predicate_->clone());
244 } else {
245 predicate_.reset();
246 }
247 return *this;
248 }
249
250 Predicate& operator=(Predicate&&) = default;
251
252 Predicate& operator=(detail::Dynamic<Tree> const& rhs)
253 {
254 predicate_.reset(rhs.clone());
255 return *this;
256 }
257
258 template <class Pred>
260 Predicate& operator=(Pred&& pred)
261 {
262 predicate_ =
263 std::make_unique<detail::DynamicPredicate<Tree, std::remove_cvref_t<Pred>>>(
264 std::forward<Pred>(pred));
265 return *this;
266 }
267
268 Predicate& operator&=(Predicate const& rhs)
269 {
270 if (rhs.hasPredicate()) {
271 if (hasPredicate()) {
272 *this = (*this && rhs);
273 } else {
274 predicate_.reset(rhs.predicate_->clone());
275 }
276 }
277 return *this;
278 }
279
280 Predicate& operator|=(Predicate const& rhs)
281 {
282 if (rhs.hasPredicate()) {
283 if (hasPredicate()) {
284 *this = (*this || rhs);
285 } else {
286 predicate_.reset(rhs.predicate_->clone());
287 }
288 }
289 return *this;
290 }
291
292 [[nodiscard]] bool hasPredicate() const { return !!predicate_; }
293
294 void init(Tree const& t)
295 {
296 if (hasPredicate()) {
297 predicate_->init(t);
298 }
299 }
300
301 [[nodiscard]] bool returnableValue(typename Tree::value_type const& v) const
302 requires requires { typename Tree::value_type; }
303 {
304 return !hasPredicate() || predicate_->returnableValue(v);
305 }
306
307 [[nodiscard]] bool returnable(Tree const& t, typename Tree::Node const& n) const
308 {
309 return !hasPredicate() || predicate_->returnable(t, n);
310 }
311
312 [[nodiscard]] bool traversable(Tree const& t, typename Tree::Node const& n) const
313 {
314 return !hasPredicate() || predicate_->traversable(t, n);
315 }
316
317 [[nodiscard]] bool returnableRay(Tree const& t, typename Tree::Node const& n,
318 typename Tree::Ray const& r) const
319 {
320 return !hasPredicate() || predicate_->returnableRay(t, n, r);
321 }
322
323 [[nodiscard]] bool traversableRay(Tree const& t, typename Tree::Node const& n,
324 typename Tree::Ray const& r) const
325 {
326 return !hasPredicate() || predicate_->traversableRay(t, n, r);
327 }
328
329 private:
330 std::unique_ptr<detail::Dynamic<Tree>> predicate_;
331};
332
333//
334// Filter
335//
336
337template <class Tree>
339 using Pred = Predicate<Tree>;
340
341 static void init(Pred& p, Tree const& t) { p.init(t); }
342
343 [[nodiscard]] static bool returnableValue(Pred const& p,
344 typename Tree::value_type const& v)
345 requires requires { typename Tree::value_type; }
346 {
347 return p.returnableValue(v);
348 }
349
350 [[nodiscard]] static bool returnable(Pred const& p, Tree const& t,
351 typename Tree::Node const& n)
352 {
353 return p.returnable(t, n);
354 }
355
356 [[nodiscard]] static bool traversable(Pred const& p, Tree const& t,
357 typename Tree::Node const& n)
358 {
359 return p.traversable(t, n);
360 }
361
362 [[nodiscard]] static bool returnableRay(Pred const& p, Tree const& t,
363 typename Tree::Node const& n,
364 typename Tree::Ray const& r)
365 {
366 return p.returnableRay(t, n, r);
367 }
368
369 [[nodiscard]] static bool traversableRay(Pred const& p, Tree const& t,
370 typename Tree::Node const& n,
371 typename Tree::Ray const& r)
372 {
373 return p.traversableRay(t, n, r);
374 }
375};
376} // namespace ufo::pred
377
378#endif // UFO_CONTAINER_TREE_PREDICATE_PREDICATE_HPP
Utilizing curiously recurring template pattern (CRTP)
Definition tree.hpp:104
STL namespace.