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"
103 template <
typename ARG_T,
typename COMPARE_FUNCTION>
104 struct ExtractComparisonTraits_ {};
105 template <
typename ARG_T,
typename COMPARE_FUNCTION>
106 requires requires (COMPARE_FUNCTION) {
107 { COMPARE_FUNCTION::kComparisonRelationKind } -> convertible_to<ComparisonRelationType>;
109 struct ExtractComparisonTraits_<ARG_T, COMPARE_FUNCTION> {
110 static constexpr ComparisonRelationType kComparisonRelationKind = COMPARE_FUNCTION::kComparisonRelationKind;
112 template <
typename ARG_T,
typename COMPARE_FUNCTION>
114 requires (COMPARE_FUNCTION c, ARG_T l, ARG_T r) {
115 { c (l, r) } -> convertible_to<strong_ordering>;
117 not
requires (COMPARE_FUNCTION) {
118 { COMPARE_FUNCTION::kComparisonRelationKind } -> convertible_to<ComparisonRelationType>;
120 struct ExtractComparisonTraits_<ARG_T, COMPARE_FUNCTION> {
123 template <
typename ARG_T>
124 struct ExtractComparisonTraits_<ARG_T, equal_to<ARG_T>> {
127 template <
typename ARG_T>
128 struct ExtractComparisonTraits_<ARG_T, less<ARG_T>> {
131 template <
typename ARG_T>
132 struct ExtractComparisonTraits_<ARG_T, greater<ARG_T>> {
135 template <
typename ARG_T>
136 struct ExtractComparisonTraits_<ARG_T, less_equal<ARG_T>> {
139 template <
typename ARG_T>
140 struct ExtractComparisonTraits_<ARG_T, greater_equal<ARG_T>> {
143 template <
typename ARG_T>
144 struct ExtractComparisonTraits_<ARG_T, compare_three_way> {
156 template <
typename COMPARER,
typename ARG_T>
157 concept IPotentiallyComparer = relation<COMPARER, ARG_T, ARG_T> or (same_as<COMPARER, compare_three_way> and three_way_comparable<ARG_T>) or
158 (regular_invocable<COMPARER, ARG_T, ARG_T> and
requires (COMPARER c, ARG_T l, ARG_T r) {
159 { c (l, r) } -> convertible_to<strong_ordering>;
169 template <
typename POTENTIALLY_COMPARER,
typename ARG_T>
170 concept IComparer =
requires (POTENTIALLY_COMPARER, ARG_T) {
172 Private_::ExtractComparisonTraits_<ARG_T, remove_cvref_t<POTENTIALLY_COMPARER>>::kComparisonRelationKind
173 } -> convertible_to<ComparisonRelationType>;
184 template <
typename ARG_T, IComparer<ARG_T> COMPARE_FUNCTION>
186 Private_::ExtractComparisonTraits_<ARG_T, remove_cvref_t<COMPARE_FUNCTION>>::kComparisonRelationKind;
210 template <
typename COMPARER,
typename ARG_T>
212 ExtractComparisonTraits_v<ARG_T, remove_cvref_t<COMPARER>> == ComparisonRelationType::eEquals;
223 template <
typename COMPARER,
typename ARG_T>
235 template <
typename COMPARER,
typename ARG_T>
253 template <
typename COMPARER,
typename ARG_T>
267 template <ComparisonRelationType KIND>
286 template <ComparisonRelationType KIND,
typename ACTUAL_COMPARER>
287 requires (not is_reference_v<ACTUAL_COMPARER>)
293 template <
typename... ARGS>
295#if !qCompilerAndStdLib_template_Requires_constraint_not_treated_constexpr_Buggy
296 requires (constructible_from<ACTUAL_COMPARER, ARGS...>)
318 template <typename FUNCTOR>
347 template <typename FUNCTOR>
358 template <typename ARG_T,
IComparer<ARG_T> BASE_COMPARER>
367 template <
typename LT,
typename RT>
368 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
373 template <
typename BASE_COMPARER>
385 template <
typename T, IComparer<T> BASE_COMPARER>
397 template <
typename LT,
typename RT>
398 constexpr bool operator() (LT&& lhs, RT&& rhs)
const;
403 template <
typename BASE_COMPARER>
416 template <
typename T, ITotallyOrderingComparer<T> BASE_COMPARER>
425 template <
typename LT,
typename RT>
426 constexpr strong_ordering operator() (LT&& lhs, RT&& rhs)
const;
431 template <
typename BASE_COMPARER>
442 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER = std::compare_three_way>
446 constexpr strong_ordering operator() (
const optional<ARG_T>& lhs,
const optional<ARG_T>& rhs)
const;
456 template <
typename FROM_INT_TYPE>
461 constexpr int ToInt (strong_ordering f)
463 if (f == strong_ordering::less) {
466 else if (f == strong_ordering::equal or f == strong_ordering::equivalent) {
486#include "Compare.inl"
#define Stroika_Define_Enum_Bounds(FIRST_ITEM, LAST_ITEM)
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
@ 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.