4#ifndef _Stroika_Foundation_Common_Compare_h_
5#define _Stroika_Foundation_Common_Compare_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
15#include "Stroika/Foundation/Common/Common.h"
16#include "Stroika/Foundation/Common/Concepts.h"
102 template <
typename ARG_T,
typename COMPARE_FUNCTION>
103 struct ExtractComparisonTraits_ {};
104 template <
typename ARG_T,
typename COMPARE_FUNCTION>
105 requires requires (COMPARE_FUNCTION) {
106 { COMPARE_FUNCTION::kComparisonRelationKind } -> convertible_to<ComparisonRelationType>;
108 struct ExtractComparisonTraits_<ARG_T, COMPARE_FUNCTION> {
109 static constexpr ComparisonRelationType kComparisonRelationKind = COMPARE_FUNCTION::kComparisonRelationKind;
111 template <
typename ARG_T,
typename COMPARE_FUNCTION>
113 requires (COMPARE_FUNCTION c, ARG_T l, ARG_T r) {
114 { c (l, r) } -> convertible_to<strong_ordering>;
116 not
requires (COMPARE_FUNCTION) {
117 { COMPARE_FUNCTION::kComparisonRelationKind } -> convertible_to<ComparisonRelationType>;
119 struct ExtractComparisonTraits_<ARG_T, COMPARE_FUNCTION> {
122 template <
typename ARG_T>
123 struct ExtractComparisonTraits_<ARG_T, equal_to<ARG_T>> {
126 template <
typename ARG_T>
127 struct ExtractComparisonTraits_<ARG_T, less<ARG_T>> {
130 template <
typename ARG_T>
131 struct ExtractComparisonTraits_<ARG_T, greater<ARG_T>> {
134 template <
typename ARG_T>
135 struct ExtractComparisonTraits_<ARG_T, less_equal<ARG_T>> {
138 template <
typename ARG_T>
139 struct ExtractComparisonTraits_<ARG_T, greater_equal<ARG_T>> {
142 template <
typename ARG_T>
143 struct ExtractComparisonTraits_<ARG_T, compare_three_way> {
155 template <
typename COMPARER,
typename ARG_T>
156 concept IPotentiallyComparer = relation<COMPARER, ARG_T, ARG_T> or (same_as<COMPARER, compare_three_way> and three_way_comparable<ARG_T>) or
157 (regular_invocable<COMPARER, ARG_T, ARG_T> and
requires (COMPARER c, ARG_T l, ARG_T r) {
158 { c (l, r) } -> convertible_to<strong_ordering>;
168 template <
typename POTENTIALLY_COMPARER,
typename ARG_T>
169 concept IComparer =
requires (POTENTIALLY_COMPARER, ARG_T) {
171 Private_::ExtractComparisonTraits_<ARG_T, remove_cvref_t<POTENTIALLY_COMPARER>>::kComparisonRelationKind
172 } -> convertible_to<ComparisonRelationType>;
183 template <
typename ARG_T, IComparer<ARG_T> COMPARE_FUNCTION>
185 Private_::ExtractComparisonTraits_<ARG_T, remove_cvref_t<COMPARE_FUNCTION>>::kComparisonRelationKind;
209 template <
typename COMPARER,
typename ARG_T>
211 ExtractComparisonTraits_v<ARG_T, remove_cvref_t<COMPARER>> == ComparisonRelationType::eEquals;
222 template <
typename COMPARER,
typename ARG_T>
234 template <
typename COMPARER,
typename ARG_T>
252 template <
typename COMPARER,
typename ARG_T>
266 template <ComparisonRelationType KIND>
285 template <ComparisonRelationType KIND,
typename ACTUAL_COMPARER>
286 requires (not is_reference_v<ACTUAL_COMPARER>)
292 template <
typename... ARGS>
294#if !qCompilerAndStdLib_template_Requires_constraint_not_treated_constexpr_Buggy
295 requires (constructible_from<ACTUAL_COMPARER, ARGS...>)
317 template <typename FUNCTOR>
346 template <typename FUNCTOR>
357 template <typename ARG_T,
IComparer<ARG_T> BASE_COMPARER>
366 template <
typename LT,
typename RT>
367 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
370 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
372 template <
typename BASE_COMPARER>
384 template <
typename T, IComparer<T> BASE_COMPARER>
396 template <
typename LT,
typename RT>
397 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
400 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
402 template <
typename BASE_COMPARER>
415 template <
typename T, ITotallyOrderingComparer<T> BASE_COMPARER>
424 template <
typename LT,
typename RT>
425 constexpr strong_ordering operator() (LT&& lhs, RT&& rhs)
const;
428 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
430 template <
typename BASE_COMPARER>
441 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER = std::compare_three_way>
445 constexpr strong_ordering operator() (
const optional<ARG_T>& lhs,
const optional<ARG_T>& rhs)
const;
448 [[no_unique_address]] TCOMPARER fTComparer_;
455 template <
typename FROM_INT_TYPE>
460 constexpr int ToInt (strong_ordering f)
462 if (f == strong_ordering::less) {
465 else if (f == strong_ordering::equal or f == strong_ordering::equivalent) {
485#include "Compare.inl"
#define Stroika_Define_Enum_Bounds(FIRST_ITEM, LAST_ITEM)
@ eInOrderOrEquals
<=, or >=, e.g. less_equal<T>, or greater_equal<T>
constexpr Common::ComparisonRelationDeclaration< ComparisonRelationType::eStrictInOrder, remove_cvref_t< FUNCTOR > > DeclareInOrderComparer(FUNCTOR &&f)
DeclareInOrderComparer () marks a FUNCTOR (lambda or not) as being a FUNCTOR which compares for in-or...
constexpr Common::ComparisonRelationDeclaration< ComparisonRelationType::eEquals, remove_cvref_t< FUNCTOR > > DeclareEqualsComparer(FUNCTOR &&f)
DeclareEqualsComparer () marks a FUNCTOR (lambda or not) as being a FUNCTOR which compares for equali...
constexpr strong_ordering CompareResultNormalizer(FROM_INT_TYPE f)
constexpr strong_ordering ReverseCompareOrder(strong_ordering so)
static constexpr ComparisonRelationType ExtractComparisonTraits_v
ExtractComparisonTraits_v<> extracts the @ComparisonRelationType for the given argument comparer.
Use this to wrap any basic comparer, and produce an Equals comparer.
Use this to wrap any basic comparer, and produce a Less comparer.
ThreeWayComparer for optional types, like builtin one, except this lets you pass in explicit 'T' comp...
Use this to wrap a basic (ITotallyOrderingComparer) comparer, and produce a Three-Way comparer.