16 #ifndef OPENKALMAN_COORDINATE_COMPARES_WITH_HPP 17 #define OPENKALMAN_COORDINATE_COMPARES_WITH_HPP 29 template<
auto comp,
bool op_is_and =
false,
typename...Ords>
33 if constexpr (op_is_and)
return (... and stdex::invoke(comp, ords));
34 else return (... or stdex::invoke(comp, ords));
39 inc_bank(std::size_t bank, std::size_t inc)
41 return (bank == stdex::dynamic_extent or inc == stdex::dynamic_extent) ? stdex::dynamic_extent : bank + inc;
46 template<
typename A,
typename B>
48 template<
typename A,
typename B,
typename =
void>
53 template<
typename A,
typename B> requires
54 std::bool_constant<internal::get_descriptor_hash_code(A{}) == internal::get_descriptor_hash_code(B{})>::
value 57 template<typename A, typename B>
59 std::bool_constant<internal::get_descriptor_hash_code(A{}) == internal::get_descriptor_hash_code(B{})>::
value>>
65 template<
typename A,
typename B>
67 template<
typename A,
typename B,
typename =
void>
72 template<
typename A,
typename B> requires
73 std::bool_constant<internal::get_descriptor_hash_code(A{}) != internal::get_descriptor_hash_code(B{})>::
value 76 template<typename A, typename B>
78 std::bool_constant<internal::get_descriptor_hash_code(A{}) != internal::get_descriptor_hash_code(B{})>::
value>>
83 template<
typename A,
typename B,
auto comp,
applicability app,
84 std::size_t ia = 0, std::size_t ib = 0, std::size_t abank = 0, std::size_t bbank = 0>
90 if constexpr (ia < collections::size_of_v<A>)
92 using Ai = std::decay_t<collections::collection_element_t<ia, A>>;
93 constexpr
bool ae = euclidean_pattern<Ai>;
94 constexpr std::size_t dim_Ai = dimension_of_v<Ai>;
95 if constexpr (ib < collections::size_of_v<B>)
97 using Bi = std::decay_t<collections::collection_element_t<ib, B>>;
98 constexpr
bool be = euclidean_pattern<Bi>;
99 constexpr std::size_t dim_Bi = dimension_of_v<Bi>;
101 if constexpr (ae and be)
103 return compares_with_iter<A, B, comp, app, ia + 1, ib + 1, inc_bank(abank, dim_Ai), bbank + dim_Bi>();
105 else if constexpr (ae)
107 return compares_with_iter<A, B, comp, app, ia + 1, ib, inc_bank(abank, dim_Ai), bbank>();
109 else if constexpr (be)
111 return compares_with_iter<A, B, comp, app, ia, ib + 1, abank, inc_bank(bbank, dim_Bi)>();
113 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
115 return app ==
applicability::permitted and do_comps<comp>(partial_ordering::equivalent, partial_ordering::unordered);
117 else if constexpr (abank != bbank)
119 return do_comps<comp>(partial_ordering::unordered);
123 return compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
127 return do_comps<comp>(partial_ordering::unordered);
129 else if constexpr (do_comps<comp>(partial_ordering::equivalent))
132 compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
134 else if constexpr (do_comps<comp>(partial_ordering::unordered))
137 compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
139 else if constexpr (do_comps<comp>(partial_ordering::less))
142 (dim_Ai == stdex::dynamic_extent or dim_Ai == 0) and
143 compares_with_iter<A, B, comp, app, ia + 1, ib + 1, dim_Ai, dim_Bi>();
148 (dim_Bi == stdex::dynamic_extent or dim_Bi == 0) and
149 compares_with_iter<A, B, comp, app, ia + 1, ib + 1, dim_Ai, dim_Bi>();
152 else if constexpr (euclidean_pattern<Ai>)
154 return compares_with_iter<A, B, comp, app, ia + 1, ib, inc_bank(abank, dim_Ai), bbank>();
156 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
158 return (dim_Ai != stdex::dynamic_extent and do_comps<comp>(partial_ordering::unordered)) or
159 (app ==
applicability::permitted and (dim_Ai == stdex::dynamic_extent or do_comps<comp>(partial_ordering::greater)));
161 else if (abank >= bbank)
163 return do_comps<comp>(partial_ordering::greater);
165 else if constexpr (dim_Ai == stdex::dynamic_extent)
168 ( do_comps<comp>(partial_ordering::unordered, partial_ordering::greater, partial_ordering::equivalent) or
169 (do_comps<comp>(partial_ordering::less) and bbank > 0));
173 return do_comps<comp>(partial_ordering::unordered);
176 else if constexpr (ib < collections::size_of_v<B>)
178 using Bi = std::decay_t<collections::collection_element_t<ib, B>>;
179 constexpr std::size_t dim_Bi = dimension_of_v<Bi>;
181 if constexpr (euclidean_pattern<Bi>)
183 return compares_with_iter<A, B, comp, app, ia, ib + 1, abank, inc_bank(bbank, dim_Bi)>();
185 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
187 return (dim_Bi != stdex::dynamic_extent and do_comps<comp>(partial_ordering::unordered)) or
190 else if (abank <= bbank)
192 return do_comps<comp>(partial_ordering::less);
194 else if constexpr (dim_Bi == stdex::dynamic_extent)
197 ( do_comps<comp>(partial_ordering::unordered, partial_ordering::less, partial_ordering::equivalent) or
198 (do_comps<comp>(partial_ordering::greater) and abank > 0));
202 return do_comps<comp>(partial_ordering::unordered);
205 else if constexpr (abank != stdex::dynamic_extent and bbank != stdex::dynamic_extent)
209 else if constexpr (abank == 0)
211 return do_comps<comp, app == applicability::guaranteed>(partial_ordering::less, partial_ordering::equivalent);
213 else if constexpr (bbank == 0)
215 return do_comps<comp, app == applicability::guaranteed>(partial_ordering::greater, partial_ordering::equivalent);
217 else if constexpr (abank != stdex::dynamic_extent or bbank != stdex::dynamic_extent)
219 return app ==
applicability::permitted and do_comps<comp>(partial_ordering::less, partial_ordering::greater, partial_ordering::equivalent);
228 template<
typename T,
typename U, auto comp, applicability a>
236 if constexpr (descriptor<T>)
238 return compares_with_impl<std::tuple<stdex::unwrap_ref_decay_t<T>>, U, comp, a>();
240 else if constexpr (descriptor<U>)
242 return compares_with_impl<T, std::tuple<stdex::unwrap_ref_decay_t<U>>, comp, a>();
251 using DT = stdex::ranges::range_value_t<T>;
252 using DU = stdex::ranges::range_value_t<U>;
253 if constexpr ((euclidean_pattern<DT> and euclidean_pattern<DU>))
254 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
255 else if constexpr (dimension_of_v<DT> == 0 or dimension_of_v<DU> == 0)
256 return values::size_compares_with<dimension_of<DT>,
dimension_of<DU>, comp, a>;
257 else if constexpr (dimension_of_v<DT> == stdex::dynamic_extent or dimension_of_v<DU> == stdex::dynamic_extent)
259 else if constexpr (compares_with_impl<DT, DU, &stdex::is_eq, a>())
260 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
266 using DT = stdex::ranges::range_value_t<T>;
267 if constexpr (euclidean_pattern<DT> and euclidean_pattern<U>)
269 return detail::do_comps<comp>(stdex::partial_ordering::greater);
271 else if constexpr (dimension_of_v<U> == 0)
273 if constexpr (dimension_of_v<DT> == stdex::dynamic_extent)
274 return detail::do_comps<comp, a == applicability::guaranteed>(
275 stdex::partial_ordering::greater, stdex::partial_ordering::equivalent);
277 return detail::do_comps<comp>(stdex::partial_ordering::greater);
279 else if constexpr (dimension_of_v<DT> == stdex::dynamic_extent)
283 else if constexpr (dimension_of_v<U> == stdex::dynamic_extent)
285 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
287 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
288 return compares_with_impl<DT, stdex::ranges::range_value_t<U>, &stdex::is_eq, a>();
294 return compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U> + 1, DT>, U, comp, a>();
299 using DU = stdex::ranges::range_value_t<U>;
300 if constexpr (euclidean_pattern<T> and euclidean_pattern<DU>)
302 return detail::do_comps<comp>(stdex::partial_ordering::less);
308 else if constexpr (dimension_of_v<T> == 0)
310 if constexpr (dimension_of_v<DU> == stdex::dynamic_extent)
311 return detail::do_comps<comp, a == applicability::guaranteed>(
312 stdex::partial_ordering::less, stdex::partial_ordering::equivalent);
314 return detail::do_comps<comp>(stdex::partial_ordering::less);
316 else if constexpr (dimension_of_v<DU> == stdex::dynamic_extent)
320 else if constexpr (dimension_of_v<T> == stdex::dynamic_extent)
322 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
324 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
325 return compares_with_impl<stdex::ranges::range_value_t<T>, DU, &stdex::is_eq, a>();
331 return compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T> + 1, DU>, comp, a>();
339 else if constexpr (dimension_of_v<T> == 0 and dimension_of_v<U> == 0)
341 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
343 else if constexpr (dimension_of_v<T> == 0 and collections::size_of_v<U> == stdex::dynamic_extent)
345 return detail::do_comps<comp, a == applicability::guaranteed>(stdex::partial_ordering::less, stdex::partial_ordering::equivalent);
347 else if constexpr (dimension_of_v<U> == 0 and collections::size_of_v<T> == stdex::dynamic_extent)
349 return detail::do_comps<comp, a == applicability::guaranteed>(stdex::partial_ordering::greater, stdex::partial_ordering::equivalent);
351 else if constexpr (collections::size_of_v<T> != stdex::dynamic_extent and collections::size_of_v<U> != stdex::dynamic_extent)
354 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
356 return detail::compares_with_iter<T, U, comp, a>();
358 else if constexpr (collections::size_of_v<T> != stdex::dynamic_extent)
360 using DU = stdex::ranges::range_value_t<U>;
361 if constexpr (dimension_of_v<DU> == 0)
363 return detail::do_comps<comp>(stdex::partial_ordering::greater);
365 else if constexpr (dimension_of_v<T> != stdex::dynamic_extent and dimension_of_v<DU> != stdex::dynamic_extent)
367 if constexpr (euclidean_pattern<T> and euclidean_pattern<DU>)
369 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
371 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less, stdex::partial_ordering::greater))
373 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::equivalent))
378 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
381 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, comp, a>();
383 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
387 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
390 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, &stdex::is_eq, a>();
395 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, comp, a>();
403 else if constexpr (collections::size_of_v<U> != stdex::dynamic_extent)
405 using DT = stdex::ranges::range_value_t<T>;
406 if constexpr (dimension_of_v<DT> == 0)
408 return detail::do_comps<comp>(stdex::partial_ordering::less);
410 else if constexpr (dimension_of_v<DT> != stdex::dynamic_extent and dimension_of_v<U> != stdex::dynamic_extent)
412 if constexpr (euclidean_pattern<DT> and euclidean_pattern<U>)
414 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
416 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less, stdex::partial_ordering::greater))
418 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::equivalent))
423 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
426 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, comp, a>();
428 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
432 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
435 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, &stdex::is_eq, a>();
440 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, comp, a>();
471 template<
typename T,
typename U, auto comp = &stdex::is_eq, applicability a = applicability::guaranteed>
472 #ifdef __cpp_concepts 475 constexpr
bool compares_with =
477 pattern<T> and pattern<U> and
478 std::is_invocable_r_v<bool, decltype(comp), stdex::partial_ordering> and
479 detail::compares_with_impl<T, U, comp, a>();
Definition: comparison.hpp:104
Definition for coordinates::dynamic_pattern.
applicability
The applicability of a concept, trait, or restraint.
Definition: constants.hpp:35
The concept, trait, or restraint is permitted, but whether it applies is not necessarily known at com...
Definition: comparison.hpp:176
The size of a sized object (including a collection).
Definition: size_of.hpp:33
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition for coordinates::pattern.
The size of a coordinates::pattern.
Definition: dimension_of.hpp:36
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Inclusion file for collections.
constexpr bool compares_with_impl()
Definition: compares_with.hpp:230
Definition of coordinates::compare_three_way.
constexpr bool fixed
T is a value that is determinable at compile time.
Definition: fixed.hpp:66
Definition: compares_with.hpp:50
Definition: compares_with.hpp:69
constexpr bool compares_with
Compares two coordinates::pattern objects.
Definition: compares_with.hpp:475
Definition for collections::common_descriptor_type.