FunctionalBasic.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "UserTypes.h"
  9. #include <AzCore/std/functional_basic.h>
  10. #include <AzCore/std/tuple.h>
  11. namespace UnitTest
  12. {
  13. class FunctionalBasicTest
  14. : public LeakDetectionFixture
  15. {
  16. };
  17. namespace Internal
  18. {
  19. struct FunctionalOperatorConfig
  20. {
  21. template<typename OperandType, typename T, typename U, typename TupleType>
  22. static void PerformOperation(T&& lhs, U&& rhs, const TupleType& expectedValues)
  23. {
  24. // Arithmetic
  25. EXPECT_EQ(AZStd::get<0>(expectedValues), AZStd::plus<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  26. EXPECT_EQ(AZStd::get<1>(expectedValues), AZStd::minus<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  27. EXPECT_EQ(AZStd::get<2>(expectedValues), AZStd::multiplies<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  28. EXPECT_EQ(AZStd::get<3>(expectedValues), AZStd::divides<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  29. EXPECT_EQ(AZStd::get<4>(expectedValues), AZStd::modulus<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  30. EXPECT_EQ(AZStd::get<5>(expectedValues), AZStd::negate<OperandType>{}(AZStd::forward<T>(lhs)));
  31. // Comparison
  32. EXPECT_EQ(AZStd::get<6>(expectedValues), AZStd::equal_to<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  33. EXPECT_EQ(AZStd::get<7>(expectedValues), AZStd::not_equal_to<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  34. EXPECT_EQ(AZStd::get<8>(expectedValues), AZStd::greater<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  35. EXPECT_EQ(AZStd::get<9>(expectedValues), AZStd::less<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  36. EXPECT_EQ(AZStd::get<10>(expectedValues), AZStd::greater_equal<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  37. EXPECT_EQ(AZStd::get<11>(expectedValues), AZStd::less_equal<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  38. // Logical
  39. EXPECT_EQ(AZStd::get<12>(expectedValues), AZStd::logical_and<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  40. EXPECT_EQ(AZStd::get<13>(expectedValues), AZStd::logical_or<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  41. EXPECT_EQ(AZStd::get<14>(expectedValues), AZStd::logical_not<OperandType>{}(AZStd::forward<T>(lhs)));
  42. // Bitwise
  43. EXPECT_EQ(AZStd::get<15>(expectedValues), AZStd::bit_and<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  44. EXPECT_EQ(AZStd::get<16>(expectedValues), AZStd::bit_or<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  45. EXPECT_EQ(AZStd::get<17>(expectedValues), AZStd::bit_xor<OperandType>{}(AZStd::forward<T>(lhs), AZStd::forward<U>(rhs)));
  46. EXPECT_EQ(AZStd::get<18>(expectedValues), AZStd::bit_not<OperandType>{}(AZStd::forward<T>(lhs)));
  47. }
  48. };
  49. struct IntWrapper
  50. {
  51. int32_t m_value;
  52. };
  53. // arithmetic operators
  54. int32_t operator+(IntWrapper lhs, int32_t rhs)
  55. {
  56. return lhs.m_value + rhs;
  57. }
  58. int32_t operator+(int32_t lhs, IntWrapper rhs)
  59. {
  60. return lhs + rhs.m_value;
  61. }
  62. int32_t operator-(IntWrapper lhs, int32_t rhs)
  63. {
  64. return lhs.m_value - rhs;
  65. }
  66. int32_t operator-(int32_t lhs, IntWrapper rhs)
  67. {
  68. return lhs - rhs.m_value;
  69. }
  70. int32_t operator*(IntWrapper lhs, int32_t rhs)
  71. {
  72. return lhs.m_value * rhs;
  73. }
  74. int32_t operator*(int32_t lhs, IntWrapper rhs)
  75. {
  76. return lhs * rhs.m_value;
  77. }
  78. int32_t operator/(IntWrapper lhs, int32_t rhs)
  79. {
  80. return lhs.m_value / rhs;
  81. }
  82. int32_t operator/(int32_t lhs, IntWrapper rhs)
  83. {
  84. return lhs / rhs.m_value;
  85. }
  86. int32_t operator%(IntWrapper lhs, int32_t rhs)
  87. {
  88. return lhs.m_value % rhs;
  89. }
  90. int32_t operator%(int32_t lhs, IntWrapper rhs)
  91. {
  92. return lhs % rhs.m_value;
  93. }
  94. int32_t operator-(IntWrapper lhs)
  95. {
  96. return -lhs.m_value;
  97. }
  98. // comparison operators
  99. bool operator==(IntWrapper lhs, int32_t rhs)
  100. {
  101. return lhs.m_value == rhs;
  102. }
  103. bool operator==(int32_t lhs, IntWrapper rhs)
  104. {
  105. return lhs == rhs.m_value;
  106. }
  107. bool operator!=(IntWrapper lhs, int32_t rhs)
  108. {
  109. return lhs.m_value != rhs;
  110. }
  111. bool operator!=(int32_t lhs, IntWrapper rhs)
  112. {
  113. return lhs != rhs.m_value;
  114. }
  115. bool operator>(IntWrapper lhs, int32_t rhs)
  116. {
  117. return lhs.m_value > rhs;
  118. }
  119. bool operator>(int lhs, IntWrapper rhs)
  120. {
  121. return lhs > rhs.m_value;
  122. }
  123. bool operator<(IntWrapper lhs, int32_t rhs)
  124. {
  125. return lhs.m_value < rhs;
  126. }
  127. bool operator<(int lhs, IntWrapper rhs)
  128. {
  129. return lhs < rhs.m_value;
  130. }
  131. bool operator>=(IntWrapper lhs, int32_t rhs)
  132. {
  133. return lhs.m_value >= rhs;
  134. }
  135. bool operator>=(int lhs, IntWrapper rhs)
  136. {
  137. return lhs >= rhs.m_value;
  138. }
  139. bool operator<=(IntWrapper lhs, int32_t rhs)
  140. {
  141. return lhs.m_value <= rhs;
  142. }
  143. bool operator<=(int lhs, IntWrapper rhs)
  144. {
  145. return lhs <= rhs.m_value;
  146. }
  147. // logical operators
  148. bool operator&&(IntWrapper lhs, int32_t rhs)
  149. {
  150. return lhs.m_value && rhs;
  151. }
  152. bool operator&&(int lhs, IntWrapper rhs)
  153. {
  154. return lhs && rhs.m_value;
  155. }
  156. bool operator||(IntWrapper lhs, int32_t rhs)
  157. {
  158. return lhs.m_value || rhs;
  159. }
  160. bool operator||(int lhs, IntWrapper rhs)
  161. {
  162. return lhs || rhs.m_value;
  163. }
  164. bool operator!(IntWrapper lhs)
  165. {
  166. return !lhs.m_value;
  167. }
  168. // bitwise operators
  169. int32_t operator&(IntWrapper lhs, int32_t rhs)
  170. {
  171. return lhs.m_value & rhs;
  172. }
  173. int32_t operator&(int lhs, IntWrapper rhs)
  174. {
  175. return lhs & rhs.m_value;
  176. }
  177. int32_t operator|(IntWrapper lhs, int32_t rhs)
  178. {
  179. return lhs.m_value | rhs;
  180. }
  181. int32_t operator|(int lhs, IntWrapper rhs)
  182. {
  183. return lhs | rhs.m_value;
  184. }
  185. int32_t operator^(IntWrapper lhs, int32_t rhs)
  186. {
  187. return lhs.m_value ^ rhs;
  188. }
  189. int32_t operator^(int lhs, IntWrapper rhs)
  190. {
  191. return lhs ^ rhs.m_value;
  192. }
  193. int32_t operator~(IntWrapper lhs)
  194. {
  195. return ~lhs.m_value;
  196. }
  197. void RawTestFunc(int) {};
  198. }
  199. TEST_F(FunctionalBasicTest, FunctionalOperators_ReturnsExpectedValue)
  200. {
  201. Internal::FunctionalOperatorConfig::PerformOperation<int>(7, 11, AZStd::make_tuple(18, -4, 77, 0, 7, -7, false, true, false, true, false, true, true, true, false, 3, 15, 12, ~7));
  202. Internal::FunctionalOperatorConfig::PerformOperation<int>(45, 34, AZStd::make_tuple(79, 11, 1530, 1, 11, -45, false, true, true, false, true, false, true, true, false, 32, 47, 15, ~45));
  203. Internal::FunctionalOperatorConfig::PerformOperation<int>(24, 24, AZStd::make_tuple(48, 0, 576, 1, 0, -24, true, false, false, false, true, true, true, true, false, 24, 24, 0, ~24));
  204. }
  205. TEST_F(FunctionalBasicTest, FunctionalOperators_TransparentOperands)
  206. {
  207. Internal::FunctionalOperatorConfig::PerformOperation<void>(7, Internal::IntWrapper{ 11 }, AZStd::make_tuple(18, -4, 77, 0, 7, -7, false, true, false, true, false, true, true, true, false, 3, 15, 12, ~7));
  208. Internal::FunctionalOperatorConfig::PerformOperation<void>(Internal::IntWrapper{ 45 }, 34, AZStd::make_tuple(79, 11, 1530, 1, 11, -45, false, true, true, false, true, false, true, true, false, 32, 47, 15, ~45));
  209. Internal::FunctionalOperatorConfig::PerformOperation<void>(24, Internal::IntWrapper{ 24 }, AZStd::make_tuple(48, 0, 576, 1, 0, -24, true, false, false, false, true, true, true, true, false, 24, 24, 0, ~24));
  210. }
  211. TEST_F(FunctionalBasicTest, DeductionGuide_Compiles)
  212. {
  213. AZStd::function rawFuncDeduce(&Internal::RawTestFunc);
  214. AZStd::function functionObjectDeduce([](int) -> double { return {}; });
  215. }
  216. }