4#include "Stroika/Foundation/Common/Concepts.h"
14 template <ComparisonRelationType KIND,
typename ACTUAL_COMPARER>
15 requires (not is_reference_v<ACTUAL_COMPARER>)
16 template <typename... ARGS>
17 inline constexpr ComparisonRelationDeclaration<KIND, ACTUAL_COMPARER>::ComparisonRelationDeclaration (ARGS... args)
18#if !qCompilerAndStdLib_template_Requires_constraint_not_treated_constexpr_Buggy
19 requires (constructible_from<ACTUAL_COMPARER, ARGS...>)
21 : ACTUAL_COMPARER{
std::forward<ARGS> (args)...}
30 template <
typename FUNCTOR>
42 template <
typename FUNCTOR>
55 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
56 constexpr EqualsComparerAdapter<ARG_T, BASE_COMPARER>::EqualsComparerAdapter (
const BASE_COMPARER& baseComparer)
57 : fBASE_COMPARER_{baseComparer}
60 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
61 constexpr EqualsComparerAdapter<ARG_T, BASE_COMPARER>::EqualsComparerAdapter (BASE_COMPARER&& baseComparer)
62 : fBASE_COMPARER_{move (baseComparer)}
65 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
66 template <
typename LT,
typename RT>
67 constexpr bool EqualsComparerAdapter<ARG_T, BASE_COMPARER>::operator() (LT&& lhs, RT&& rhs)
const
73 constexpr auto kRelationKind = ExtractComparisonTraits_v<ARG_T, BASE_COMPARER>;
74 auto baseComparison = fBASE_COMPARER_ (forward<LT> (lhs), forward<RT> (rhs));
75 if constexpr (kRelationKind == ComparisonRelationType::eEquals) {
76 return baseComparison;
78 if constexpr (kRelationKind == ComparisonRelationType::eStrictInOrder) {
83 return not fBASE_COMPARER_ (forward<RT> (rhs), forward<LT> (lhs));
86 if constexpr (kRelationKind == ComparisonRelationType::eInOrderOrEquals) {
88 return fBASE_COMPARER_ (forward<RT> (rhs), forward<LT> (lhs));
94 if constexpr (kRelationKind == ComparisonRelationType::eThreeWayCompare) {
95 return baseComparison == strong_ordering::equal;
106 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
107 requires (ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eStrictInOrder or
108 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eInOrderOrEquals or
109 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eThreeWayCompare)
110 constexpr inline InOrderComparerAdapter<ARG_T, BASE_COMPARER>::InOrderComparerAdapter (
const BASE_COMPARER& baseComparer)
111 : fBASE_COMPARER_{baseComparer}
114 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
115 requires (ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eStrictInOrder or
116 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eInOrderOrEquals or
117 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eThreeWayCompare)
118 constexpr inline InOrderComparerAdapter<ARG_T, BASE_COMPARER>::InOrderComparerAdapter (BASE_COMPARER&& baseComparer)
119 : fBASE_COMPARER_{move (baseComparer)}
122 template <
typename ARG_T, IComparer<ARG_T> BASE_COMPARER>
123 requires (ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eStrictInOrder or
124 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eInOrderOrEquals or
125 ExtractComparisonTraits_v<ARG_T, BASE_COMPARER> == ComparisonRelationType::eThreeWayCompare)
126 template <typename LT, typename RT>
127 constexpr inline bool InOrderComparerAdapter<ARG_T, BASE_COMPARER>::operator() (LT&& lhs, RT&& rhs)
const
133 constexpr auto kRelationKind = ExtractComparisonTraits_v<ARG_T, BASE_COMPARER>;
134 auto baseComparison = fBASE_COMPARER_ (forward<LT> (lhs), forward<RT> (rhs));
135 if constexpr (kRelationKind == ComparisonRelationType::eStrictInOrder) {
136 return baseComparison;
138 if constexpr (kRelationKind == ComparisonRelationType::eInOrderOrEquals) {
139 return baseComparison and not fBASE_COMPARER_ (forward<RT> (rhs), forward<LT> (lhs));
141 if constexpr (kRelationKind == ComparisonRelationType::eThreeWayCompare) {
142 return baseComparison == strong_ordering::less;
153 template <
typename ARG_T, ITotallyOrderingComparer<ARG_T> BASE_COMPARER>
154 constexpr ThreeWayComparerAdapter<ARG_T, BASE_COMPARER>::ThreeWayComparerAdapter (
const BASE_COMPARER& baseComparer)
155 : fBASE_COMPARER_{baseComparer}
158 template <
typename ARG_T, ITotallyOrderingComparer<ARG_T> BASE_COMPARER>
159 constexpr ThreeWayComparerAdapter<ARG_T, BASE_COMPARER>::ThreeWayComparerAdapter (BASE_COMPARER&& baseComparer)
160 : fBASE_COMPARER_{move (baseComparer)}
163 template <
typename ARG_T, ITotallyOrderingComparer<ARG_T> BASE_COMPARER>
164 template <
typename LT,
typename RT>
165 constexpr strong_ordering ThreeWayComparerAdapter<ARG_T, BASE_COMPARER>::operator() (LT&& lhs, RT&& rhs)
const
171 constexpr auto kRelationKind = ExtractComparisonTraits_v<ARG_T, BASE_COMPARER>;
172 auto baseComparison = fBASE_COMPARER_ (forward<LT> (lhs), forward<RT> (rhs));
173 if constexpr (kRelationKind == ComparisonRelationType::eThreeWayCompare) {
174 return baseComparison;
176 if constexpr (kRelationKind == ComparisonRelationType::eStrictInOrder) {
177 if (baseComparison) {
178 return strong_ordering::less;
181 return fBASE_COMPARER_ (forward<RT> (rhs), forward<LT> (lhs)) ? strong_ordering::greater : strong_ordering::equal;
184 return strong_ordering::equal;
192 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER>
193 constexpr OptionalThreeWayComparer<ARG_T, TCOMPARER>::OptionalThreeWayComparer (TCOMPARER&& comparer)
194 : fTComparer_{move (comparer)}
197 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER>
198 constexpr OptionalThreeWayComparer<ARG_T, TCOMPARER>::OptionalThreeWayComparer (
const TCOMPARER& comparer)
199 : fTComparer_{comparer}
202 template <
typename ARG_T, IComparer<ARG_T> TCOMPARER>
203 constexpr strong_ordering OptionalThreeWayComparer<ARG_T, TCOMPARER>::operator() (
const optional<ARG_T>& lhs,
const optional<ARG_T>& rhs)
const
206 return fTComparer_ (*lhs, *rhs);
208 if (not lhs and not rhs) {
209 return strong_ordering::equal;
213 return strong_ordering::greater;
216 return strong_ordering::less;
225 template <
typename FROM_INT_TYPE>
229 return strong_ordering::equal;
232 Assert (f < 0 or f > 0);
233 return f < 0 ? strong_ordering::less : strong_ordering::greater;
244 if (so == strong_ordering::less) {
245 return strong_ordering::greater;
247 else if (so == strong_ordering::greater) {
248 return strong_ordering::less;
259#if __cpp_lib_three_way_comparison < 201907L
260 struct [[deprecated (
"Since Stroika 3.0d1 - use std::compare_three_way")]] ThreeWayComparer {
261 template <
typename LT,
typename RT>
262 constexpr auto operator() (LT&& lhs, RT&& rhs)
const
264 using CT = common_type_t<LT, RT>;
267 if (equal_to<CT>{}(forward<LT> (lhs), forward<RT> (rhs))) {
268 return strong_ordering::equal;
270 return less<CT>{}(forward<LT> (lhs), forward<RT> (rhs)) ? strong_ordering::less : strong_ordering::greater;
274 struct [[deprecated (
"Since Stroika 3.0d1 - use std::compare_three_way")]] ThreeWayComparer {
275 template <
typename LT,
typename RT>
276 constexpr auto operator() (LT&& lhs, RT&& rhs)
const
278 return compare_three_way{}(forward<LT> (lhs), forward<RT> (rhs));
282 DISABLE_COMPILER_GCC_WARNING_START (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"")
283 DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated-declarations\"");
284 DISABLE_COMPILER_MSC_WARNING_START (4996)
286 template <
typename ARG_T>
287 struct ExtractComparisonTraits_<ARG_T, ThreeWayComparer> {
288 static constexpr ComparisonRelationType kComparisonRelationKind = ComparisonRelationType::eThreeWayCompare;
291 DISABLE_COMPILER_MSC_WARNING_END (4996)
292 DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated-declarations\"");
293 DISABLE_COMPILER_GCC_WARNING_END ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
295 constexpr
std::strong_ordering kLess [[deprecated ("Since Stroika 3.0d1 - use
std::strong_ordering")]] =
std::strong_ordering::less;
296 constexpr
std::strong_ordering kEqual [[deprecated ("Since Stroika 3.0d1 - use
std::strong_ordering")]] =
std::strong_ordering::equal;
297 constexpr
std::strong_ordering kGreater [[deprecated ("Since Stroika 3.0d1 - use
std::strong_ordering")]] =
std::strong_ordering::greater;
299 template <typename FUNCTOR, typename FUNCTOR_ARG>
300 [[deprecated ("Since Stroika v3.0d1 - use IPotentiallyComparer ")]] constexpr
bool IsPotentiallyComparerRelation ()
302 return IPotentiallyComparer<FUNCTOR, FUNCTOR_ARG>;
304 template <
typename FUNCTOR>
305 [[deprecated (
"Since Stroika v3.0d1 - use IPotentiallyComparer ")]]
constexpr bool IsPotentiallyComparerRelation ()
307 if constexpr (FunctionTraits<FUNCTOR>::kArity == 2) {
308 using TRAITS = FunctionTraits<FUNCTOR>;
309 return same_as<typename TRAITS::template arg<0>::type,
typename TRAITS::template arg<1>::type> and
310 IsPotentiallyComparerRelation<FUNCTOR, typename FunctionTraits<FUNCTOR>::template arg<0>::type> ();
316 template <
typename FUNCTOR>
317 [[deprecated (
"Since Stroika v3.0d1 - use IPotentiallyComparer ")]]
constexpr bool IsPotentiallyComparerRelation (
const FUNCTOR& f)
319 return IsPotentiallyComparerRelation<FUNCTOR> ();
321 template <
typename LT,
typename RT>
322 [[deprecated (
"Since Stroika 3.0d1 - use compare_three_way{} or <=>")]]
constexpr strong_ordering ThreeWayCompare (LT&& lhs, RT&& rhs)
324 return compare_three_way{}(forward<LT> (lhs), forward<RT> (rhs));
327 template <
typename COMPARER>
328 [[deprecated (
"Since Stroika 3.0d1 - use IEqualsComparer")]]
constexpr bool IsEqualsComparer ()
330 return ExtractComparisonTraits_v<int, std::remove_cvref_t<COMPARER>> == ComparisonRelationType::eEquals;
332 template <
typename COMPARER,
typename ARG_T>
333 [[deprecated (
"Since Stroika 3.0d1 - use IEqualsComparer")]]
constexpr bool IsEqualsComparer ()
335 if constexpr (not IsPotentiallyComparerRelation<COMPARER, ARG_T> ()) {
339 return ExtractComparisonTraits_v<int, std::remove_cvref_t<COMPARER>> == ComparisonRelationType::eEquals;
342 template <
typename COMPARER>
343 [[deprecated (
"Since Stroika 3.0d1 - use IEqualsComparer")]]
constexpr bool IsEqualsComparer (
const COMPARER&)
345 return IsEqualsComparer<COMPARER> ();
347 template <
typename COMPARER>
348 [[deprecated (
"Since Stroika 3.0d1 - use IInOrderComparer")]]
constexpr bool IsStrictInOrderComparer ()
350 return ExtractComparisonTraits_v<int, std::remove_cvref_t<COMPARER>> == ComparisonRelationType::eStrictInOrder;
352 template <
typename COMPARER,
typename ARG_T>
353 [[deprecated (
"Since Stroika 3.0d1 - use IInOrderComparer")]]
constexpr bool IsStrictInOrderComparer ()
355 if constexpr (not IsPotentiallyComparerRelation<COMPARER, ARG_T> ()) {
359 return ExtractComparisonTraits_v<int, std::remove_cvref_t<COMPARER>> == ComparisonRelationType::eStrictInOrder;
362 template <
typename COMPARER>
363 [[deprecated (
"Since Stroika 3.0d1 - use IInOrderComparer")]]
constexpr bool IsStrictInOrderComparer (
const COMPARER&)
365 return ExtractComparisonTraits_v<int, std::remove_cvref_t<COMPARER>> == ComparisonRelationType::eStrictInOrder;
368 template <
typename COMPARE_FUNCTION>
369 using ExtractComparisonTraits [[deprecated (
"Since Stroika v3.0d1 - use ExtractComparisonTraits_v instead")]] =
370 Private_::ExtractComparisonTraits_<int, COMPARE_FUNCTION>;
#define AssertNotReached()
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)
Extract the number of arguments, return type, and each individual argument type from a lambda or simp...