feat(templates): add common functors outside STD and the corresponding testing

This commit is contained in:
_Redstone_c_ 2022-04-10 10:25:42 +08:00
parent bb89dd6509
commit a80860f107
2 changed files with 76 additions and 67 deletions

View File

@ -1165,12 +1165,24 @@ void TestFunction()
} }
{ {
always_check(TPlus <int32>()(4, 2) == 6); always_check(TPromote <int32>()(4 ) == 4);
always_check(TMinus <int32>()(4, 2) == 2);
always_check(TMultiplies<int32>()(4, 2) == 8);
always_check(TDivides <int32>()(4, 2) == 2);
always_check(TModulus <int32>()(4, 2) == 0);
always_check(TNegate <int32>()(4 ) == -4); always_check(TNegate <int32>()(4 ) == -4);
always_check(TPlus <int32>()(4, 2) == 6);
always_check(TMinus <int32>()(4, 2) == 2);
always_check(TMultiplies<int32>()(4, 2) == 8);
always_check(TDivides <int32>()(4, 2) == 2);
always_check(TModulus <int32>()(4, 2) == 0);
always_check(TBitNot<int32>()(4 ) == -5);
always_check(TBitAnd<int32>()(4, 2) == 0);
always_check(TBitOr <int32>()(4, 2) == 6);
always_check(TBitXor<int32>()(4, 2) == 6);
always_check(TBitLsh<int32>()(4, 2) == 16);
always_check(TBitRsh<int32>()(4, 2) == 1);
always_check(TLogicalAnd<int32>()(4, 2) == true);
always_check(TLogicalOr <int32>()(4, 2) == true);
always_check(TLogicalNot<int32>()(4 ) == false);
always_check(TEqualTo <int32>()(4, 2) == false); always_check(TEqualTo <int32>()(4, 2) == false);
always_check(TNotEqualTo <int32>()(4, 2) == true); always_check(TNotEqualTo <int32>()(4, 2) == true);
@ -1178,15 +1190,6 @@ void TestFunction()
always_check(TLess <int32>()(4, 2) == false); always_check(TLess <int32>()(4, 2) == false);
always_check(TGreaterEqual<int32>()(4, 2) == true); always_check(TGreaterEqual<int32>()(4, 2) == true);
always_check(TLessEqual <int32>()(4, 2) == false); always_check(TLessEqual <int32>()(4, 2) == false);
always_check(TLogicalAnd<int32>()(4, 2) == true);
always_check(TLogicalOr <int32>()(4, 2) == true);
always_check(TLogicalNot<int32>()(4 ) == false);
always_check(TBitAnd<int32>()(4, 2) == 0);
always_check(TBitOr <int32>()(4, 2) == 6);
always_check(TBitXor<int32>()(4, 2) == 6);
always_check(TBitNot<int32>()(4 ) == -5);
} }
{ {

View File

@ -537,51 +537,54 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
return NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type>(Forward<F>(Func)); return NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type>(Forward<F>(Func));
} }
#define FUNCTOR_UNARY_OPERATOR_IMPL(Name, Operator, ReturnType, ConceptT, ConceptU) \ #define FUNCTOR_UNARY_OPERATOR_IMPL(Name, Operator, ConceptT, ConceptU) \
template <typename T = void> requires (CSameAs<T, void> || ConceptT) \ template <typename T = void> requires (CSameAs<T, void> || ConceptT) \
struct Name \ struct Name \
{ \ { \
constexpr ReturnType operator()(const T& InValue) const { \ constexpr auto operator()(const T& InValue) const \
return Operator InValue; \ -> decltype(Operator InValue) \
} \ { \
}; \ return Operator InValue; \
\ } \
template <> \ }; \
struct Name<void> \ \
{ \ template <> \
template <typename U> requires ConceptU \ struct Name<void> \
constexpr auto operator()(U&& InValue) const \ { \
-> decltype(Operator Forward<U>(InValue)) \ template <typename U> requires ConceptU \
{ \ constexpr auto operator()(U&& InValue) const \
return Operator Forward<U>(InValue); \ -> decltype(Operator Forward<U>(InValue)) \
} \ { \
return Operator Forward<U>(InValue); \
} \
} }
#define FUNCTOR_BINARY_OPERATOR_IMPL(Name, Operator, ReturnType, ConceptT, ConceptTU) \ #define FUNCTOR_BINARY_OPERATOR_IMPL(Name, Operator, ConceptT, ConceptTU) \
template <typename T = void> requires (CSameAs<T, void> || ConceptT) \ template <typename T = void> requires (CSameAs<T, void> || ConceptT) \
struct Name \ struct Name \
{ \ { \
constexpr ReturnType operator()(const T& LHS, const T& RHS) const \ constexpr auto operator()(const T& LHS, const T& RHS) const \
{ \ -> decltype(LHS Operator RHS) \
return LHS Operator RHS; \ { \
} \ return LHS Operator RHS; \
}; \ } \
\ }; \
template <> \ \
struct Name<void> \ template <> \
{ \ struct Name<void> \
template <typename T, typename U> requires ConceptTU \ { \
constexpr auto operator()(T&& LHS, U&& RHS) const \ template <typename T, typename U> requires ConceptTU \
-> decltype(Forward<T>(LHS) Operator Forward<U>(RHS)) \ constexpr auto operator()(T&& LHS, U&& RHS) const \
{ \ -> decltype(Forward<T>(LHS) Operator Forward<U>(RHS)) \
return Forward<T>(LHS) Operator Forward<U>(RHS); \ { \
} \ return Forward<T>(LHS) Operator Forward<U>(RHS); \
} \
} }
#define FUNCTOR_UNARY_OPERATOR_A_IMPL(Name, Operator) \ #define FUNCTOR_UNARY_OPERATOR_A_IMPL(Name, Operator) \
FUNCTOR_UNARY_OPERATOR_IMPL \ FUNCTOR_UNARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, T, \ Name, Operator, \
(requires(const T& InValue) { { Operator InValue } -> CConvertibleTo<T>; }), \ (requires(const T& InValue) { { Operator InValue } -> CConvertibleTo<T>; }), \
(requires(U&& InValue) { Operator Forward<U>(InValue); }) \ (requires(U&& InValue) { Operator Forward<U>(InValue); }) \
) )
@ -589,7 +592,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
#define FUNCTOR_BINARY_OPERATOR_A_IMPL(Name, Operator) \ #define FUNCTOR_BINARY_OPERATOR_A_IMPL(Name, Operator) \
FUNCTOR_BINARY_OPERATOR_IMPL \ FUNCTOR_BINARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, T, \ Name, Operator, \
(requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CConvertibleTo<T>; }), \ (requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CConvertibleTo<T>; }), \
(requires(T&& LHS, U&& RHS) { Forward<T>(LHS) Operator Forward<U>(RHS); }) \ (requires(T&& LHS, U&& RHS) { Forward<T>(LHS) Operator Forward<U>(RHS); }) \
) )
@ -597,7 +600,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
#define FUNCTOR_UNARY_OPERATOR_B_IMPL(Name, Operator) \ #define FUNCTOR_UNARY_OPERATOR_B_IMPL(Name, Operator) \
FUNCTOR_UNARY_OPERATOR_IMPL \ FUNCTOR_UNARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, bool, \ Name, Operator, \
(requires(const T& InValue) { { Operator InValue } -> CBooleanTestable; }), \ (requires(const T& InValue) { { Operator InValue } -> CBooleanTestable; }), \
(requires(U&& InValue) { { Operator Forward<U>(InValue) } -> CBooleanTestable; }) \ (requires(U&& InValue) { { Operator Forward<U>(InValue) } -> CBooleanTestable; }) \
) )
@ -605,7 +608,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
#define FUNCTOR_BINARY_OPERATOR_B_IMPL(Name, Operator) \ #define FUNCTOR_BINARY_OPERATOR_B_IMPL(Name, Operator) \
FUNCTOR_BINARY_OPERATOR_IMPL \ FUNCTOR_BINARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, bool, \ Name, Operator, \
(requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CBooleanTestable; }), \ (requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CBooleanTestable; }), \
(requires(T&& LHS, U&& RHS) { { Forward<T>(LHS) Operator Forward<U>(RHS) } -> CBooleanTestable; }) \ (requires(T&& LHS, U&& RHS) { { Forward<T>(LHS) Operator Forward<U>(RHS) } -> CBooleanTestable; }) \
) )
@ -613,7 +616,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
#define FUNCTOR_BINARY_OPERATOR_C_IMPL(Name, Operator) \ #define FUNCTOR_BINARY_OPERATOR_C_IMPL(Name, Operator) \
FUNCTOR_BINARY_OPERATOR_IMPL \ FUNCTOR_BINARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, bool, \ Name, Operator, \
(CEqualityComparable<T>), \ (CEqualityComparable<T>), \
(CEqualityComparableWith<T, U>) \ (CEqualityComparableWith<T, U>) \
) )
@ -621,17 +624,29 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType<typename TDecay<F>::Type> NotFn(F&&
#define FUNCTOR_BINARY_OPERATOR_D_IMPL(Name, Operator) \ #define FUNCTOR_BINARY_OPERATOR_D_IMPL(Name, Operator) \
FUNCTOR_BINARY_OPERATOR_IMPL \ FUNCTOR_BINARY_OPERATOR_IMPL \
( \ ( \
Name, Operator, bool, \ Name, Operator, \
(CTotallyOrdered<T>), \ (CTotallyOrdered<T>), \
(CTotallyOrderedWith<T, U>) \ (CTotallyOrderedWith<T, U>) \
) )
FUNCTOR_UNARY_OPERATOR_A_IMPL (TPromote, +);
FUNCTOR_UNARY_OPERATOR_A_IMPL (TNegate, -);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TPlus, +); FUNCTOR_BINARY_OPERATOR_A_IMPL(TPlus, +);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TMinus, -); FUNCTOR_BINARY_OPERATOR_A_IMPL(TMinus, -);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TMultiplies, *); FUNCTOR_BINARY_OPERATOR_A_IMPL(TMultiplies, *);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TDivides, /); FUNCTOR_BINARY_OPERATOR_A_IMPL(TDivides, /);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TModulus, %); FUNCTOR_BINARY_OPERATOR_A_IMPL(TModulus, %);
FUNCTOR_UNARY_OPERATOR_A_IMPL (TNegate, -);
FUNCTOR_UNARY_OPERATOR_A_IMPL (TBitNot, ~ );
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitAnd, & );
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitOr, | );
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitXor, ^ );
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitLsh, <<);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitRsh, >>);
FUNCTOR_BINARY_OPERATOR_B_IMPL(TLogicalAnd, &&);
FUNCTOR_BINARY_OPERATOR_B_IMPL(TLogicalOr, ||);
FUNCTOR_UNARY_OPERATOR_B_IMPL (TLogicalNot, ! );
FUNCTOR_BINARY_OPERATOR_C_IMPL(TEqualTo, ==); FUNCTOR_BINARY_OPERATOR_C_IMPL(TEqualTo, ==);
FUNCTOR_BINARY_OPERATOR_C_IMPL(TNotEqualTo, !=); FUNCTOR_BINARY_OPERATOR_C_IMPL(TNotEqualTo, !=);
@ -640,15 +655,6 @@ FUNCTOR_BINARY_OPERATOR_D_IMPL(TLess, < );
FUNCTOR_BINARY_OPERATOR_D_IMPL(TGreaterEqual, >=); FUNCTOR_BINARY_OPERATOR_D_IMPL(TGreaterEqual, >=);
FUNCTOR_BINARY_OPERATOR_D_IMPL(TLessEqual, <=); FUNCTOR_BINARY_OPERATOR_D_IMPL(TLessEqual, <=);
FUNCTOR_BINARY_OPERATOR_B_IMPL(TLogicalAnd, &&);
FUNCTOR_BINARY_OPERATOR_B_IMPL(TLogicalOr, ||);
FUNCTOR_UNARY_OPERATOR_B_IMPL (TLogicalNot, ! );
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitAnd, &);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitOr, |);
FUNCTOR_BINARY_OPERATOR_A_IMPL(TBitXor, ^);
FUNCTOR_UNARY_OPERATOR_A_IMPL (TBitNot, ~);
#undef FUNCTOR_BINARY_OPERATOR_D_IMPL #undef FUNCTOR_BINARY_OPERATOR_D_IMPL
#undef FUNCTOR_BINARY_OPERATOR_C_IMPL #undef FUNCTOR_BINARY_OPERATOR_C_IMPL