UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
or.hpp
1
42#ifndef UFO_CONTAINER_TREE_PREDICATE_OR_HPP
43#define UFO_CONTAINER_TREE_PREDICATE_OR_HPP
44
45// UFO
46#include <ufo/container/tree/predicate/filter.hpp>
47#include <ufo/utility/type_traits.hpp>
48
49// STL
50#include <tuple>
51#include <type_traits>
52#include <utility>
53
54namespace ufo::pred
55{
56template <Filterable... Preds>
57struct Or {
58 Or(Preds&&... preds) noexcept : preds(std::forward<Preds>(preds)...) {}
59
60 std::tuple<Preds...> preds;
61};
62
63namespace detail
64{
65template <class T>
66[[nodiscard]] constexpr auto getOrTuple(T&& t) noexcept
67{
68 if constexpr (is_specialization_of_v<Or, std::remove_cvref_t<T>>) {
69 return std::forward<T>(t).preds;
70 } else {
71 return std::forward_as_tuple(std::forward<T>(t));
72 }
73}
74} // namespace detail
75
76template <Filterable PredLeft, Filterable PredRight>
77[[nodiscard]] constexpr auto operator||(PredLeft&& p1, PredRight&& p2) noexcept
78{
79 return std::apply(
80 [](auto&&... preds) {
81 return Or<std::remove_cvref_t<decltype(preds)>...>(
82 std::forward<decltype(preds)>(preds)...);
83 },
84 std::tuple_cat(detail::getOrTuple(std::forward<PredLeft>(p1)),
85 detail::getOrTuple(std::forward<PredRight>(p2))));
86}
87
88template <Filterable... Preds>
89struct Filter<Or<Preds...>> {
90 using Pred = Or<Preds...>;
91
92 template <class Tree>
93 static constexpr void init(Pred& p, Tree const& t) noexcept
94 {
95 std::apply([&t](auto&&... preds) { (Filter<Preds>::init(preds, t), ...); }, p.preds);
96 }
97
98 template <class Value>
99 [[nodiscard]] static constexpr bool returnableValue(Pred const& p,
100 Value const& v) noexcept
101 {
102 return std::apply(
103 [&v](auto&&... preds) {
104 return (Filter<Preds>::returnableValue(preds, v) || ...);
105 },
106 p.preds);
107 }
108
109 template <class Tree>
110 [[nodiscard]] static constexpr bool returnable(Pred const& p, Tree const& t,
111 typename Tree::Node const& n) noexcept
112 {
113 return std::apply(
114 [&t, &n](auto&&... preds) {
115 return (Filter<Preds>::returnable(preds, t, n) || ...);
116 },
117 p.preds);
118 }
119
120 template <class Tree>
121 [[nodiscard]] static constexpr bool traversable(Pred const& p, Tree const& t,
122 typename Tree::Node const& n) noexcept
123 {
124 return std::apply(
125 [&t, &n](auto&&... preds) {
126 return (Filter<Preds>::traversable(preds, t, n) || ...);
127 },
128 p.preds);
129 }
130
131 template <class Tree>
132 [[nodiscard]] static constexpr bool returnableRay(Pred const& p, Tree const& t,
133 typename Tree::Node const& n,
134 typename Tree::Ray const& r) noexcept
135 {
136 return std::apply(
137 [&t, &n, &r](auto&&... preds) {
138 return (Filter<Preds>::returnableRay(preds, t, n, r) || ...);
139 },
140 p.preds);
141 }
142
143 template <class Tree>
144 [[nodiscard]] static constexpr bool traversableRay(Pred const& p, Tree const& t,
145 typename Tree::Node const& n,
146 typename Tree::Ray const& r) noexcept
147 {
148 return std::apply(
149 [&t, &n, &r](auto&&... preds) {
150 return (Filter<Preds>::traversableRay(preds, t, n, r) || ...);
151 },
152 p.preds);
153 }
154};
155
156namespace detail
157{
158template <Filterable T, Filterable... Ts>
159struct contains_pred<T, Or<Ts...>> : std::disjunction<contains_pred<T, Ts>...> {
160};
161
162template <Filterable T, Filterable... Ts>
163struct contains_always_pred<T, Or<Ts...>>
164 : std::conjunction<contains_always_pred<T, Ts>...> {
165};
166} // namespace detail
167
168} // namespace ufo::pred
169
170#endif // UFO_CONTAINER_TREE_PREDICATE_OR_HPP
Utilizing curiously recurring template pattern (CRTP)
Definition tree.hpp:104