diff --git a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp index 018f684..dd5ee8f 100644 --- a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp @@ -1165,12 +1165,24 @@ void TestFunction() } { - always_check(TPlus ()(4, 2) == 6); - always_check(TMinus ()(4, 2) == 2); - always_check(TMultiplies()(4, 2) == 8); - always_check(TDivides ()(4, 2) == 2); - always_check(TModulus ()(4, 2) == 0); + always_check(TPromote ()(4 ) == 4); always_check(TNegate ()(4 ) == -4); + always_check(TPlus ()(4, 2) == 6); + always_check(TMinus ()(4, 2) == 2); + always_check(TMultiplies()(4, 2) == 8); + always_check(TDivides ()(4, 2) == 2); + always_check(TModulus ()(4, 2) == 0); + + always_check(TBitNot()(4 ) == -5); + always_check(TBitAnd()(4, 2) == 0); + always_check(TBitOr ()(4, 2) == 6); + always_check(TBitXor()(4, 2) == 6); + always_check(TBitLsh()(4, 2) == 16); + always_check(TBitRsh()(4, 2) == 1); + + always_check(TLogicalAnd()(4, 2) == true); + always_check(TLogicalOr ()(4, 2) == true); + always_check(TLogicalNot()(4 ) == false); always_check(TEqualTo ()(4, 2) == false); always_check(TNotEqualTo ()(4, 2) == true); @@ -1178,15 +1190,6 @@ void TestFunction() always_check(TLess ()(4, 2) == false); always_check(TGreaterEqual()(4, 2) == true); always_check(TLessEqual ()(4, 2) == false); - - always_check(TLogicalAnd()(4, 2) == true); - always_check(TLogicalOr ()(4, 2) == true); - always_check(TLogicalNot()(4 ) == false); - - always_check(TBitAnd()(4, 2) == 0); - always_check(TBitOr ()(4, 2) == 6); - always_check(TBitXor()(4, 2) == 6); - always_check(TBitNot()(4 ) == -5); } { diff --git a/Redcraft.Utility/Source/Public/Templates/Function.h b/Redcraft.Utility/Source/Public/Templates/Function.h index 939ad4f..74cdc0c 100644 --- a/Redcraft.Utility/Source/Public/Templates/Function.h +++ b/Redcraft.Utility/Source/Public/Templates/Function.h @@ -537,51 +537,54 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& return NAMESPACE_PRIVATE::NotFunctionType::Type>(Forward(Func)); } -#define FUNCTOR_UNARY_OPERATOR_IMPL(Name, Operator, ReturnType, ConceptT, ConceptU) \ - template requires (CSameAs || ConceptT) \ - struct Name \ - { \ - constexpr ReturnType operator()(const T& InValue) const { \ - return Operator InValue; \ - } \ - }; \ - \ - template <> \ - struct Name \ - { \ - template requires ConceptU \ - constexpr auto operator()(U&& InValue) const \ - -> decltype(Operator Forward(InValue)) \ - { \ - return Operator Forward(InValue); \ - } \ +#define FUNCTOR_UNARY_OPERATOR_IMPL(Name, Operator, ConceptT, ConceptU) \ + template requires (CSameAs || ConceptT) \ + struct Name \ + { \ + constexpr auto operator()(const T& InValue) const \ + -> decltype(Operator InValue) \ + { \ + return Operator InValue; \ + } \ + }; \ + \ + template <> \ + struct Name \ + { \ + template requires ConceptU \ + constexpr auto operator()(U&& InValue) const \ + -> decltype(Operator Forward(InValue)) \ + { \ + return Operator Forward(InValue); \ + } \ } -#define FUNCTOR_BINARY_OPERATOR_IMPL(Name, Operator, ReturnType, ConceptT, ConceptTU) \ - template requires (CSameAs || ConceptT) \ - struct Name \ - { \ - constexpr ReturnType operator()(const T& LHS, const T& RHS) const \ - { \ - return LHS Operator RHS; \ - } \ - }; \ - \ - template <> \ - struct Name \ - { \ - template requires ConceptTU \ - constexpr auto operator()(T&& LHS, U&& RHS) const \ - -> decltype(Forward(LHS) Operator Forward(RHS)) \ - { \ - return Forward(LHS) Operator Forward(RHS); \ - } \ +#define FUNCTOR_BINARY_OPERATOR_IMPL(Name, Operator, ConceptT, ConceptTU) \ + template requires (CSameAs || ConceptT) \ + struct Name \ + { \ + constexpr auto operator()(const T& LHS, const T& RHS) const \ + -> decltype(LHS Operator RHS) \ + { \ + return LHS Operator RHS; \ + } \ + }; \ + \ + template <> \ + struct Name \ + { \ + template requires ConceptTU \ + constexpr auto operator()(T&& LHS, U&& RHS) const \ + -> decltype(Forward(LHS) Operator Forward(RHS)) \ + { \ + return Forward(LHS) Operator Forward(RHS); \ + } \ } #define FUNCTOR_UNARY_OPERATOR_A_IMPL(Name, Operator) \ FUNCTOR_UNARY_OPERATOR_IMPL \ ( \ - Name, Operator, T, \ + Name, Operator, \ (requires(const T& InValue) { { Operator InValue } -> CConvertibleTo; }), \ (requires(U&& InValue) { Operator Forward(InValue); }) \ ) @@ -589,7 +592,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& #define FUNCTOR_BINARY_OPERATOR_A_IMPL(Name, Operator) \ FUNCTOR_BINARY_OPERATOR_IMPL \ ( \ - Name, Operator, T, \ + Name, Operator, \ (requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CConvertibleTo; }), \ (requires(T&& LHS, U&& RHS) { Forward(LHS) Operator Forward(RHS); }) \ ) @@ -597,7 +600,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& #define FUNCTOR_UNARY_OPERATOR_B_IMPL(Name, Operator) \ FUNCTOR_UNARY_OPERATOR_IMPL \ ( \ - Name, Operator, bool, \ + Name, Operator, \ (requires(const T& InValue) { { Operator InValue } -> CBooleanTestable; }), \ (requires(U&& InValue) { { Operator Forward(InValue) } -> CBooleanTestable; }) \ ) @@ -605,7 +608,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& #define FUNCTOR_BINARY_OPERATOR_B_IMPL(Name, Operator) \ FUNCTOR_BINARY_OPERATOR_IMPL \ ( \ - Name, Operator, bool, \ + Name, Operator, \ (requires(const T& LHS, const T& RHS) { { LHS Operator RHS } -> CBooleanTestable; }), \ (requires(T&& LHS, U&& RHS) { { Forward(LHS) Operator Forward(RHS) } -> CBooleanTestable; }) \ ) @@ -613,7 +616,7 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& #define FUNCTOR_BINARY_OPERATOR_C_IMPL(Name, Operator) \ FUNCTOR_BINARY_OPERATOR_IMPL \ ( \ - Name, Operator, bool, \ + Name, Operator, \ (CEqualityComparable), \ (CEqualityComparableWith) \ ) @@ -621,17 +624,29 @@ constexpr NAMESPACE_PRIVATE::NotFunctionType::Type> NotFn(F&& #define FUNCTOR_BINARY_OPERATOR_D_IMPL(Name, Operator) \ FUNCTOR_BINARY_OPERATOR_IMPL \ ( \ - Name, Operator, bool, \ + Name, Operator, \ (CTotallyOrdered), \ (CTotallyOrderedWith) \ ) +FUNCTOR_UNARY_OPERATOR_A_IMPL (TPromote, +); +FUNCTOR_UNARY_OPERATOR_A_IMPL (TNegate, -); FUNCTOR_BINARY_OPERATOR_A_IMPL(TPlus, +); FUNCTOR_BINARY_OPERATOR_A_IMPL(TMinus, -); FUNCTOR_BINARY_OPERATOR_A_IMPL(TMultiplies, *); FUNCTOR_BINARY_OPERATOR_A_IMPL(TDivides, /); 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(TNotEqualTo, !=); @@ -640,15 +655,6 @@ FUNCTOR_BINARY_OPERATOR_D_IMPL(TLess, < ); FUNCTOR_BINARY_OPERATOR_D_IMPL(TGreaterEqual, >=); 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_C_IMPL