16 #ifndef OPENKALMAN_COORDINATE_COMPARES_WITH_HPP 17 #define OPENKALMAN_COORDINATE_COMPARES_WITH_HPP 26 template<
auto comp,
bool op_is_and =
false,
typename...Ords>
30 if constexpr (op_is_and)
return (... and stdex::invoke(comp, ords));
31 else return (... or stdex::invoke(comp, ords));
36 inc_bank(std::size_t bank, std::size_t inc)
38 return (bank == stdex::dynamic_extent or inc == stdex::dynamic_extent) ? stdex::dynamic_extent : bank + inc;
43 template<
typename A,
typename B>
45 template<
typename A,
typename B,
typename =
void>
50 template<
typename A,
typename B> requires
51 std::bool_constant<internal::get_descriptor_hash_code(
A{}) == internal::get_descriptor_hash_code(B{})>::
value 54 template<typename A, typename B>
56 std::bool_constant<internal::get_descriptor_hash_code(
A{}) == internal::get_descriptor_hash_code(B{})>::
value>>
62 template<
typename A,
typename B>
64 template<
typename A,
typename B,
typename =
void>
69 template<
typename A,
typename B> requires
70 std::bool_constant<internal::get_descriptor_hash_code(
A{}) != internal::get_descriptor_hash_code(B{})>::
value 73 template<typename A, typename B>
75 std::bool_constant<internal::get_descriptor_hash_code(
A{}) != internal::get_descriptor_hash_code(B{})>::
value>>
81 std::size_t ia = 0, std::size_t ib = 0, std::size_t abank = 0, std::size_t bbank = 0>
87 if constexpr (ia < collections::size_of_v<A>)
89 using Ai = std::decay_t<collections::collection_element_t<ia, A>>;
90 constexpr
bool ae = euclidean_pattern<Ai>;
91 constexpr std::size_t dim_Ai = dimension_of_v<Ai>;
92 if constexpr (ib < collections::size_of_v<B>)
94 using Bi = std::decay_t<collections::collection_element_t<ib, B>>;
95 constexpr
bool be = euclidean_pattern<Bi>;
96 constexpr std::size_t dim_Bi = dimension_of_v<Bi>;
98 if constexpr (ae and be)
100 return compares_with_iter<A, B, comp, app, ia + 1, ib + 1, inc_bank(abank, dim_Ai), bbank + dim_Bi>();
102 else if constexpr (ae)
104 return compares_with_iter<A, B, comp, app, ia + 1, ib, inc_bank(abank, dim_Ai), bbank>();
106 else if constexpr (be)
108 return compares_with_iter<A, B, comp, app, ia, ib + 1, abank, inc_bank(bbank, dim_Bi)>();
110 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
112 return app ==
applicability::permitted and do_comps<comp>(partial_ordering::equivalent, partial_ordering::unordered);
114 else if constexpr (abank != bbank)
116 return do_comps<comp>(partial_ordering::unordered);
120 return compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
124 return do_comps<comp>(partial_ordering::unordered);
126 else if constexpr (do_comps<comp>(partial_ordering::equivalent))
129 compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
131 else if constexpr (do_comps<comp>(partial_ordering::unordered))
134 compares_with_iter<A, B, comp, app, ia + 1, ib + 1>();
136 else if constexpr (do_comps<comp>(partial_ordering::less))
139 (dim_Ai == stdex::dynamic_extent or dim_Ai == 0) and
140 compares_with_iter<A, B, comp, app, ia + 1, ib + 1, dim_Ai, dim_Bi>();
145 (dim_Bi == stdex::dynamic_extent or dim_Bi == 0) and
146 compares_with_iter<A, B, comp, app, ia + 1, ib + 1, dim_Ai, dim_Bi>();
149 else if constexpr (euclidean_pattern<Ai>)
151 return compares_with_iter<A, B, comp, app, ia + 1, ib, inc_bank(abank, dim_Ai), bbank>();
153 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
155 return (dim_Ai != stdex::dynamic_extent and do_comps<comp>(partial_ordering::unordered)) or
156 (app ==
applicability::permitted and (dim_Ai == stdex::dynamic_extent or do_comps<comp>(partial_ordering::greater)));
158 else if (abank >= bbank)
160 return do_comps<comp>(partial_ordering::greater);
162 else if constexpr (dim_Ai == stdex::dynamic_extent)
165 ( do_comps<comp>(partial_ordering::unordered, partial_ordering::greater, partial_ordering::equivalent) or
166 (do_comps<comp>(partial_ordering::less) and bbank > 0));
170 return do_comps<comp>(partial_ordering::unordered);
173 else if constexpr (ib < collections::size_of_v<B>)
175 using Bi = std::decay_t<collections::collection_element_t<ib, B>>;
176 constexpr std::size_t dim_Bi = dimension_of_v<Bi>;
178 if constexpr (euclidean_pattern<Bi>)
180 return compares_with_iter<A, B, comp, app, ia, ib + 1, abank, inc_bank(bbank, dim_Bi)>();
182 else if constexpr (abank == stdex::dynamic_extent or bbank == stdex::dynamic_extent)
184 return (dim_Bi != stdex::dynamic_extent and do_comps<comp>(partial_ordering::unordered)) or
187 else if (abank <= bbank)
189 return do_comps<comp>(partial_ordering::less);
191 else if constexpr (dim_Bi == stdex::dynamic_extent)
194 ( do_comps<comp>(partial_ordering::unordered, partial_ordering::less, partial_ordering::equivalent) or
195 (do_comps<comp>(partial_ordering::greater) and abank > 0));
199 return do_comps<comp>(partial_ordering::unordered);
202 else if constexpr (abank != stdex::dynamic_extent and bbank != stdex::dynamic_extent)
206 else if constexpr (abank == 0)
208 return do_comps<comp, app == applicability::guaranteed>(partial_ordering::less, partial_ordering::equivalent);
210 else if constexpr (bbank == 0)
212 return do_comps<comp, app == applicability::guaranteed>(partial_ordering::greater, partial_ordering::equivalent);
214 else if constexpr (abank != stdex::dynamic_extent or bbank != stdex::dynamic_extent)
216 return app ==
applicability::permitted and do_comps<comp>(partial_ordering::less, partial_ordering::greater, partial_ordering::equivalent);
225 template<
typename T,
typename U, auto comp, applicability a>
233 if constexpr (descriptor<T>)
235 return compares_with_impl<std::tuple<stdex::unwrap_ref_decay_t<T>>, U, comp, a>();
237 else if constexpr (descriptor<U>)
239 return compares_with_impl<T, std::tuple<stdex::unwrap_ref_decay_t<U>>, comp, a>();
248 using DT = stdex::ranges::range_value_t<T>;
249 using DU = stdex::ranges::range_value_t<U>;
250 if constexpr ((euclidean_pattern<DT> and euclidean_pattern<DU>))
251 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
252 else if constexpr (dimension_of_v<DT> == 0 or dimension_of_v<DU> == 0)
253 return values::size_compares_with<dimension_of<DT>,
dimension_of<DU>, comp, a>;
254 else if constexpr (dimension_of_v<DT> == stdex::dynamic_extent or dimension_of_v<DU> == stdex::dynamic_extent)
256 else if constexpr (compares_with_impl<DT, DU, &stdex::is_eq, a>())
257 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
263 using DT = stdex::ranges::range_value_t<T>;
264 if constexpr (euclidean_pattern<DT> and euclidean_pattern<U>)
266 return detail::do_comps<comp>(stdex::partial_ordering::greater);
268 else if constexpr (dimension_of_v<U> == 0)
270 if constexpr (dimension_of_v<DT> == stdex::dynamic_extent)
271 return detail::do_comps<comp, a == applicability::guaranteed>(
272 stdex::partial_ordering::greater, stdex::partial_ordering::equivalent);
274 return detail::do_comps<comp>(stdex::partial_ordering::greater);
276 else if constexpr (dimension_of_v<DT> == stdex::dynamic_extent)
280 else if constexpr (dimension_of_v<U> == stdex::dynamic_extent)
282 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
284 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
285 return compares_with_impl<DT, stdex::ranges::range_value_t<U>, &stdex::is_eq, a>();
291 return compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U> + 1, DT>, U, comp, a>();
296 using DU = stdex::ranges::range_value_t<U>;
297 if constexpr (euclidean_pattern<T> and euclidean_pattern<DU>)
299 return detail::do_comps<comp>(stdex::partial_ordering::less);
305 else if constexpr (dimension_of_v<T> == 0)
307 if constexpr (dimension_of_v<DU> == stdex::dynamic_extent)
308 return detail::do_comps<comp, a == applicability::guaranteed>(
309 stdex::partial_ordering::less, stdex::partial_ordering::equivalent);
311 return detail::do_comps<comp>(stdex::partial_ordering::less);
313 else if constexpr (dimension_of_v<DU> == stdex::dynamic_extent)
317 else if constexpr (dimension_of_v<T> == stdex::dynamic_extent)
319 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
321 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
322 return compares_with_impl<stdex::ranges::range_value_t<T>, DU, &stdex::is_eq, a>();
328 return compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T> + 1, DU>, comp, a>();
336 else if constexpr (dimension_of_v<T> == 0 and dimension_of_v<U> == 0)
338 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
340 else if constexpr (dimension_of_v<T> == 0 and collections::size_of_v<U> == stdex::dynamic_extent)
342 return detail::do_comps<comp, a == applicability::guaranteed>(stdex::partial_ordering::less, stdex::partial_ordering::equivalent);
344 else if constexpr (dimension_of_v<U> == 0 and collections::size_of_v<T> == stdex::dynamic_extent)
346 return detail::do_comps<comp, a == applicability::guaranteed>(stdex::partial_ordering::greater, stdex::partial_ordering::equivalent);
348 else if constexpr (collections::size_of_v<T> != stdex::dynamic_extent and collections::size_of_v<U> != stdex::dynamic_extent)
351 return detail::do_comps<comp>(stdex::partial_ordering::equivalent);
353 return detail::compares_with_iter<T, U, comp, a>();
355 else if constexpr (collections::size_of_v<T> != stdex::dynamic_extent)
357 using DU = stdex::ranges::range_value_t<U>;
358 if constexpr (dimension_of_v<DU> == 0)
360 return detail::do_comps<comp>(stdex::partial_ordering::greater);
362 else if constexpr (dimension_of_v<T> != stdex::dynamic_extent and dimension_of_v<DU> != stdex::dynamic_extent)
364 if constexpr (euclidean_pattern<T> and euclidean_pattern<DU>)
366 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
368 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less, stdex::partial_ordering::greater))
370 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::equivalent))
375 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
378 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, comp, a>();
380 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
384 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
387 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, &stdex::is_eq, a>();
392 compares_with_impl<T, collections::repeat_tuple_view<collections::size_of_v<T>, DU>, comp, a>();
400 else if constexpr (collections::size_of_v<U> != stdex::dynamic_extent)
402 using DT = stdex::ranges::range_value_t<T>;
403 if constexpr (dimension_of_v<DT> == 0)
405 return detail::do_comps<comp>(stdex::partial_ordering::less);
407 else if constexpr (dimension_of_v<DT> != stdex::dynamic_extent and dimension_of_v<U> != stdex::dynamic_extent)
409 if constexpr (euclidean_pattern<DT> and euclidean_pattern<U>)
411 if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
413 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less, stdex::partial_ordering::greater))
415 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::equivalent))
420 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::unordered))
423 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, comp, a>();
425 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::less))
429 else if constexpr (detail::do_comps<comp>(stdex::partial_ordering::greater))
432 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, &stdex::is_eq, a>();
437 compares_with_impl<collections::repeat_tuple_view<collections::size_of_v<U>, DT>, U, comp, a>();
468 template<
typename T,
typename U, auto comp = &stdex::is_eq, applicability a = applicability::guaranteed>
469 #ifdef __cpp_concepts 472 constexpr
bool compares_with =
474 pattern<T> and pattern<U> and
475 std::is_invocable_r_v<bool, decltype(comp), stdex::partial_ordering> and
476 detail::compares_with_impl<T, U, comp, a>();
Definition: comparison.hpp:104
The size of a patterns::pattern.
Definition: dimension_of.hpp:36
Definition: compares_with.hpp:66
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...
constexpr bool compares_with
Compares two patterns::pattern objects.
Definition: compares_with.hpp:472
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 patterns::pattern.
The namespace for features relating to patterns::pattern object.
Definition: collection_compares_with.hpp:24
Inclusion file for collections.
constexpr bool compares_with_impl()
Definition: compares_with.hpp:227
Definition: compares_with.hpp:47
constexpr bool fixed
T has a value that is determinable at compile time.
Definition: fixed.hpp:65
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:292