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;
207 template <
typename COMPARER,
typename ARG_T>
209 ExtractComparisonTraits_v<ARG_T, remove_cvref_t<COMPARER>> == ComparisonRelationType::eEquals;
220 template <
typename COMPARER,
typename ARG_T>
232 template <
typename COMPARER,
typename ARG_T>
250 template <
typename COMPARER,
typename ARG_T>
264 template <ComparisonRelationType KIND>
283 template <ComparisonRelationType KIND,
typename ACTUAL_COMPARER>
284 requires (not is_reference_v<ACTUAL_COMPARER>)
290 template <
typename... ARGS>
292#if !qCompilerAndStdLib_template_Requires_constraint_not_treated_constexpr_Buggy
293 requires (constructible_from<ACTUAL_COMPARER, ARGS...>)
315 template <typename FUNCTOR>
344 template <typename FUNCTOR>
355 template <typename ARG_T,
IComparer<ARG_T> BASE_COMPARER>
364 template <
typename LT,
typename RT>
365 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
368 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
370 template <
typename BASE_COMPARER>
382 template <
typename T, IComparer<T> BASE_COMPARER>
394 template <
typename LT,
typename RT>
395 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
398 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
400 template <
typename BASE_COMPARER>
413 template <
typename T, ITotallyOrderingComparer<T> BASE_COMPARER>
422 template <
typename LT,
typename RT>
423 constexpr strong_ordering operator() (LT&& lhs, RT&& rhs)
const;
426 [[no_unique_address]] BASE_COMPARER fBASE_COMPARER_;
428 template <
typename BASE_COMPARER>
439 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER = std::compare_three_way>
443 constexpr strong_ordering operator() (
const optional<ARG_T>& lhs,
const optional<ARG_T>& rhs)
const;
446 [[no_unique_address]] TCOMPARER fTComparer_;
453 template <
typename FROM_INT_TYPE>
458 constexpr int ToInt (strong_ordering f)
460 if (f == strong_ordering::less) {
463 else if (f == strong_ordering::equal or f == strong_ordering::equivalent) {
483#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.