UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
xor.hpp
1
42#ifndef UFO_CONTAINER_TREE_PREDICATE_XOR_HPP
43#define UFO_CONTAINER_TREE_PREDICATE_XOR_HPP
44
45// UFO
46#include <ufo/container/tree/predicate/filter.hpp>
47#include <ufo/utility/type_traits.hpp>
48
49// STL
50#include <type_traits>
51#include <utility>
52
53namespace ufo::pred
54{
55template <Filterable PredLeft, Filterable PredRight>
56struct Xor {
57 Xor(PredLeft const& left, PredRight const& right) noexcept : left(left), right(right) {}
58
59 PredLeft left;
60 PredRight right;
61};
62
63template <Filterable PredLeft, Filterable PredRight>
64[[nodiscard]] constexpr Xor<std::remove_cvref_t<PredLeft>, std::remove_cvref_t<PredRight>>
65operator^(PredLeft&& left, PredRight&& right) noexcept
66{
67 return Xor(std::forward<PredLeft>(left), std::forward<PredRight>(right));
68}
69
70template <Filterable PredLeft, Filterable PredRight>
71struct Filter<Xor<PredLeft, PredRight>> {
73
74 template <class Tree>
75 static constexpr void init(Pred& p, Tree const& t) noexcept
76 {
77 Filter<PredLeft>::init(p.left, t);
78 Filter<PredRight>::init(p.right, t);
79 }
80
81 template <class Value>
82 [[nodiscard]] static constexpr bool returnableValue(Pred const& p,
83 Value const& v) noexcept
84 {
85 return Filter<PredLeft>::returnableValue(p.left, v) !=
87 }
88
89 template <class Tree>
90 [[nodiscard]] static constexpr bool returnable(Pred const& p, Tree const& t,
91 typename Tree::Node const& n) noexcept
92 {
93 return Filter<PredLeft>::returnable(p.left, t, n) !=
94 Filter<PredRight>::returnable(p.right, t, n);
95 }
96
97 template <class Tree>
98 [[nodiscard]] static constexpr bool traversable(Pred const& p, Tree const& t,
99 typename Tree::Node const& n) noexcept
100 {
101 // Note: This is not the same as the returnable check! If both predicates
102 // are true, we can still traverse both subtrees. If both are false, we
103 // can't traverse either subtree. If one is true and one is false, we can
104 // traverse the subtree corresponding to the true predicate.
105 return Filter<PredLeft>::traversable(p.left, t, n) ||
106 Filter<PredRight>::traversable(p.right, t, n);
107 }
108
109 template <class Tree>
110 [[nodiscard]] static constexpr bool returnableRay(Pred const& p, Tree const& t,
111 typename Tree::Node const& n,
112 typename Tree::Ray const& r) noexcept
113 {
114 return Filter<PredLeft>::returnableRay(p.left, t, n, r) !=
115 Filter<PredRight>::returnableRay(p.right, t, n, r);
116 }
117
118 template <class Tree>
119 [[nodiscard]] static constexpr bool traversableRay(Pred const& p, Tree const& t,
120 typename Tree::Node const& n,
121 typename Tree::Ray const& r) noexcept
122 {
123 // Note: This is not the same as the returnable check! If both predicates
124 // are true, we can still traverse both subtrees. If both are false, we
125 // can't traverse either subtree. If one is true and one is false, we can
126 // traverse the subtree corresponding to the true predicate.
127 return Filter<PredLeft>::traversableRay(p.left, t, n, r) ||
128 Filter<PredRight>::traversableRay(p.right, t, n, r);
129 }
130};
131
132namespace detail
133{
134template <Filterable T, Filterable L, Filterable R>
135struct contains_pred<T, Xor<L, R>>
136 : std::disjunction<contains_pred<T, L>, contains_pred<T, R>> {
137};
138
139template <Filterable T, Filterable L, Filterable R>
140struct contains_always_pred<T, Xor<L, R>> : std::false_type {
141};
142} // namespace detail
143} // namespace ufo::pred
144
145#endif // UFO_CONTAINER_TREE_PREDICATE_XOR_HPP
Utilizing curiously recurring template pattern (CRTP)
Definition tree.hpp:104