16 #ifndef OPENKALMAN_COORDINATES_COMPARE_THREE_WAY_HPP 17 #define OPENKALMAN_COORDINATES_COMPARE_THREE_WAY_HPP 31 template<std::
size_t ia = 0, std::
size_t ib = 0,
typename A,
typename B,
typename C>
33 compare_three_way_fixed(
const A& a,
const B& b,
const C& c, std::size_t abank = 0, std::size_t bbank = 0)
35 if constexpr (ia < collections::size_of_v<A>)
37 auto ai = collections::get<ia>(a);
38 if constexpr (ib < collections::size_of_v<B>)
40 auto bi = collections::get<ib>(b);
41 constexpr
bool ae = euclidean_pattern<decltype(ai)>;
42 constexpr
bool be = euclidean_pattern<decltype(bi)>;
43 if constexpr (ae and be)
45 else if constexpr (ae)
46 return compare_three_way_fixed<ia + 1, ib>(a, b, c, abank +
get_dimension(ai), bbank);
47 else if constexpr (be)
48 return compare_three_way_fixed<ia, ib + 1>(a, b, c, abank, bbank +
get_dimension(bi));
52 if (internal::get_descriptor_hash_code(ai) == internal::get_descriptor_hash_code(bi))
53 return values::cast_to<stdex::partial_ordering>(compare_three_way_fixed<ia + 1, ib + 1>(a, b, c));
54 return stdex::partial_ordering::unordered;
58 return compare_three_way_fixed<ia + 1, ib>(a, b, c, abank +
get_dimension(ai), bbank);
59 else if (abank >= bbank)
60 return stdex::partial_ordering::greater;
62 return stdex::partial_ordering::unordered;
64 else if constexpr (ib < collections::
size_of_v<B>)
66 auto bi = collections::get<ib>(b);
68 else if (abank <= bbank) return stdex::partial_ordering::less;
69 else return stdex::partial_ordering::unordered;
73 return stdex::invoke(c, abank, bbank);
78 template<
typename A,
typename B,
typename C,
typename Ia = std::
integral_constant<std::
size_t, 0>,
typename Ib = std::
integral_constant<std::
size_t, 0>>
79 constexpr stdex::partial_ordering
80 compare_three_way_impl(
const A& a,
const B& b,
const C& c, Ia ia = {}, Ib ib = {}, std::size_t abank = 0, std::size_t bbank = 0)
91 return compare_three_way_impl(a, b, c,
96 else if (internal::get_descriptor_hash_code(a_i) == internal::get_descriptor_hash_code(b_i) and abank == bbank)
97 return compare_three_way_impl(a, b, c, ia + 1_uz, ib + 1_uz);
99 return stdex::partial_ordering::unordered;
104 return compare_three_way_impl(a, b, c, ia + 1_uz, ib, abank +
get_dimension(a_i), bbank);
105 else if (abank >= bbank)
106 return stdex::partial_ordering::greater;
108 return stdex::partial_ordering::unordered;
115 return compare_three_way_impl(a, b, c, ia, ib + 1_uz, abank, bbank +
get_dimension(b_i));
116 else if (abank <= bbank)
117 return stdex::partial_ordering::less;
119 return stdex::partial_ordering::unordered;
121 else return stdex::invoke(c, abank, bbank);
132 #ifdef __cpp_concepts 133 template<pattern A, pattern B,
typename Comparison = stdex::compare_three_way>
134 requires std::is_invocable_r_v<stdex::partial_ordering, Comparison, std::size_t, std::size_t>
135 constexpr std::convertible_to<stdex::partial_ordering>
auto 138 std::enable_if_t<pattern<A> and pattern<B> and
144 if constexpr (euclidean_pattern<A> and euclidean_pattern<B> and
145 (descriptor<A> or collections::sized<A>) and (descriptor<B> or collections::sized<B>))
150 else if constexpr (descriptor<A> and descriptor<B>)
154 else if (stdex::is_eq(stdex::invoke(c, internal::get_descriptor_hash_code(a), internal::get_descriptor_hash_code(b))))
155 return stdex::partial_ordering::equivalent;
157 return stdex::partial_ordering::unordered;
159 else if constexpr (descriptor<A>)
163 else if constexpr (descriptor<B>)
168 else if constexpr (not collections::sized<A> and not collections::sized<B>)
170 using RA = stdex::ranges::range_value_t<A>;
171 using RB = stdex::ranges::range_value_t<B>;
177 else if constexpr (
values::fixed<decltype(internal::get_descriptor_hash_code(std::declval<RA>()))> and
178 values::fixed<decltype(internal::get_descriptor_hash_code(std::declval<RB>()))>)
195 else if constexpr (not collections::sized<A>)
197 using RA = stdex::ranges::range_value_t<A>;
204 auto offset = std::integral_constant<std::size_t, 0>{};
209 else if constexpr (not collections::sized<B>)
211 using RB = stdex::ranges::range_value_t<B>;
218 auto offset = std::integral_constant<std::size_t, 0>{};
224 else if constexpr (collections::size_of_v<A> != stdex::dynamic_extent and collections::size_of_v<B> != stdex::dynamic_extent)
226 if constexpr (collections::size_of_v<A> == 0 or collections::size_of_v<B> == 0)
229 return detail::compare_three_way_fixed(a, b, c);
231 else if constexpr (collections::size_of_v<A> != stdex::dynamic_extent)
234 if constexpr (collections::size_of_v<A> == 0)
235 return size_b_is_zero ? stdex::partial_ordering::equivalent : stdex::partial_ordering::less;
236 else if (size_b_is_zero)
237 return stdex::partial_ordering::greater;
241 else if constexpr (collections::size_of_v<B> != stdex::dynamic_extent)
244 if constexpr (collections::size_of_v<B> == 0)
245 return size_a_is_zero ? stdex::partial_ordering::equivalent : stdex::partial_ordering::greater;
246 else if (size_a_is_zero)
247 return stdex::partial_ordering::less;
256 return size_b_is_zero ? stdex::partial_ordering::equivalent : stdex::partial_ordering::less;
257 else if (size_b_is_zero)
258 return stdex::partial_ordering::greater;
260 return detail::compare_three_way_impl(a, b, c);
Definition for coordinates::euclidean_pattern.
Definition: comparison.hpp:104
constexpr auto fixed_value_of_v
Helper template for fixed_value_of.
Definition: fixed_value_of.hpp:84
Definition of the Dimensions class.
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
The size of a sized object (including a collection).
Definition: size_of.hpp:33
The fixed value associated with a fixed.
Definition: fixed_value_of.hpp:44
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
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of coordinates::pattern Arg.
Definition: get_dimension.hpp:54
constexpr auto get_is_euclidean(const Arg &arg)
Determine, whether coordinates::pattern Arg is euclidean.
Definition: get_is_euclidean.hpp:65
Definition for coordinates::descriptor.
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Definition for get_descriptor_hash_code.
constexpr detail::all_closure all
a std::ranges::range_adaptor_closure which returns a view to all members of its collection argument...
Definition: all.hpp:72
Inclusion file for collections.
constexpr detail::slice_adapter slice
a RangeAdapterObject associated with slice_view.
Definition: slice.hpp:364
Definition for coordinates::get_dimension.
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
constexpr bool fixed_value_compares_with
T has a fixed value that compares with N in a particular way based on parameter comp.
Definition: fixed_value_compares_with.hpp:74
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:122
constexpr auto compare_three_way(A &&a, B &&b, const Comparison &c={})
Compare two coordinates::pattern objects lexicographically.
Definition: compare_three_way.hpp:142
constexpr bool fixed
T is a value that is determinable at compile time.
Definition: fixed.hpp:66
A fixed version of std::partial_ordering::unordered.
Definition: fixed-constants.hpp:167
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:188
constexpr bool euclidean_pattern
A coordinates::pattern for a normal Euclidean vector.
Definition: euclidean_pattern.hpp:49
constexpr std::size_t size_of_v
Helper for collections::size_of.
Definition: size_of.hpp:60
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98