Micro template library A library for building device drivers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

240 lines
10 KiB

  1. /*!
  2. * \file TmetaBasic.cpp
  3. *
  4. * Copyright (C) 2018 Christos Choutouridis
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as
  8. * published by the Free Software Foundation, either version 3
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include <utl/meta/meta.h>
  21. #include <gtest/gtest.h>
  22. #include <type_traits>
  23. namespace TmetaBasic {
  24. using namespace utl;
  25. using namespace meta;
  26. /*
  27. * Types to behave like Fixtures
  28. */
  29. // Test type_of fixture
  30. template<class T> struct Identity {
  31. using type = T;
  32. };
  33. /*
  34. * Test integral constant
  35. */
  36. TEST(TmetaBasic, IntegrealType) {
  37. EXPECT_EQ(true, (std::is_same<int, eval<Identity<int>>>::value));
  38. EXPECT_EQ(true, (std::is_same<nil_, eval<nil_>>::value));
  39. EXPECT_EQ(true, (std::is_same<nil_, eval<eval<nil_>>>::value));
  40. EXPECT_EQ(true, (std::is_same<nil_, eval<eval<eval<nil_>>>>::value));
  41. }
  42. TEST(TmetaBasic, IntegrealConstant) {
  43. EXPECT_EQ(true, (std::is_same<int, integral_<int, 42>::value_type>::value));
  44. EXPECT_EQ(true, (std::is_same<int, integral_<int, 42>::type::value_type>::value));
  45. EXPECT_EQ(42, (integral_<int, 0>::value_type(42)));
  46. EXPECT_EQ(42, (integral_<int, 42>()));
  47. }
  48. TEST(TmetaBasic, BasicTypes) {
  49. EXPECT_EQ(true, (std::is_same<bool, bool_<false>::value_type>::value));
  50. EXPECT_EQ(true, bool_<true>::value);
  51. EXPECT_EQ(true, (std::is_same<bool, false_::value_type>::value));
  52. EXPECT_EQ(false, false_::value);
  53. EXPECT_EQ(true, (std::is_same<bool, true_::value_type>::value));
  54. EXPECT_EQ(true, true_::value);
  55. EXPECT_EQ(true, (std::is_same<int8_t, int8_<0>::value_type>::value));
  56. EXPECT_EQ(42, int8_<42>::value);
  57. EXPECT_EQ(true, (std::is_same<uint8_t, uint8_<0>::value_type>::value));
  58. EXPECT_EQ(42u, uint8_<42u>::value);
  59. EXPECT_EQ(true, (std::is_same<int16_t, int16_<0>::value_type>::value));
  60. EXPECT_EQ(42, int16_<42>::value);
  61. EXPECT_EQ(true, (std::is_same<uint16_t, uint16_<0>::value_type>::value));
  62. EXPECT_EQ(42u, uint16_<42u>::value);
  63. EXPECT_EQ(true, (std::is_same<int32_t, int32_<0>::value_type>::value));
  64. EXPECT_EQ(42, int32_<42>::value);
  65. EXPECT_EQ(true, (std::is_same<uint32_t, uint32_<0>::value_type>::value));
  66. EXPECT_EQ(42u, uint32_<42u>::value);
  67. EXPECT_EQ(true, (std::is_same<char, char_<0>::value_type>::value));
  68. EXPECT_EQ(42, char_<42>::value);
  69. EXPECT_EQ(true, (std::is_same<int, int_<0>::value_type>::value));
  70. EXPECT_EQ(42, int_<42>::value);
  71. EXPECT_EQ(true, (std::is_same<long, long_<0>::value_type>::value));
  72. EXPECT_EQ(42, long_<42>::value);
  73. EXPECT_EQ(true, (std::is_same<index_t, index_<0>::value_type>::value));
  74. EXPECT_EQ(42U, index_<42U>::value);
  75. EXPECT_EQ(true, (std::is_same<size_t, size_<0>::value_type>::value));
  76. EXPECT_EQ(42U, size_<42U>::value);
  77. EXPECT_EQ(sizeof(int), sizeof_<int>::value);
  78. EXPECT_EQ(alignof(int), alignof_<int>::value);
  79. EXPECT_EQ(static_cast<index_t>(-1), Npos::value);
  80. }
  81. /*
  82. * Test integral constant selection operations
  83. */
  84. TEST(TmetaBasic, Selection) {
  85. struct Foo {};
  86. struct Bar {};
  87. EXPECT_EQ (true, (std::is_same<int_<42>, if_c<true, int_<42>, false_>>()));
  88. EXPECT_EQ (true, (std::is_same<Foo, if_c<false, int_<42>, Foo>>()));
  89. EXPECT_EQ (true, (std::is_same<Foo, if_c<(bool)42, Foo, Bar>>()));
  90. EXPECT_EQ (true, (std::is_same<int_<42>, if_<true_, int_<42>, Bar>>()));
  91. EXPECT_EQ (true, (std::is_same<Bar, if_<false_, int_<42>, Bar>>()));
  92. EXPECT_EQ (true, (std::is_same<int_<42>, if_<int_<1>, int_<42>, Bar>>()));
  93. EXPECT_EQ (true, (std::is_same<Foo, if_<int_<0>, int_<42>, Foo>>()));
  94. EXPECT_EQ (true, (std::is_same<true_, first_of<true_, false_>>()));
  95. EXPECT_EQ (false,(std::is_same<true_, first_of<false_, true_>>()));
  96. EXPECT_EQ (false,(std::is_same<true_, second_of<true_, false_>>()));
  97. EXPECT_EQ (true, (std::is_same<true_, second_of<false_, true_>>()));
  98. }
  99. TEST(TmetaBasic, LogicalOperations) {
  100. struct Foo {};
  101. struct Bar {};
  102. EXPECT_EQ (true, (std::is_same<true_, not_c<false>>::value));
  103. EXPECT_EQ (true, (std::is_same<false_, not_c<true>>::value));
  104. EXPECT_EQ (true, (std::is_same<false_, not_c<1>>::value));
  105. EXPECT_EQ (true, (std::is_same<true_, not_c<0>>::value));
  106. EXPECT_EQ (true, (std::is_same<true_, not_<false_>>()));
  107. EXPECT_EQ (true, (std::is_same<false_, not_<true_>>()));
  108. EXPECT_EQ (true, (std::is_same<true_, not_<int_<0>>>()));
  109. EXPECT_EQ (true, (std::is_same<false_, not_<int_<1>>>()));
  110. EXPECT_EQ (true, (std::is_same<false_, or_<false_, false_, not_c<true>, int_<0>, not_<true_>>>()));
  111. EXPECT_EQ (true, (std::is_same<false_, or_<>>()));
  112. EXPECT_EQ (true, (std::is_same<int_<1>,or_<int_<1>>>()));
  113. EXPECT_EQ (true, (std::is_same<true_, or_<true_>>()));
  114. EXPECT_EQ (true, (std::is_same<true_, or_<false_, true_>>()));
  115. EXPECT_EQ (true, (std::is_same<true_, or_<false_, false_, true_>>()));
  116. EXPECT_EQ (true, (std::is_same<int_<1>,or_<int_<0>, false_, not_<true_>, not_c<true>, int_<1>>>()));
  117. EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_, int_<1>, not_<false_>, not_c<false>>>()));
  118. EXPECT_EQ (true, (std::is_same<true_, and_<>>()));
  119. EXPECT_EQ (true, (std::is_same<true_, and_<true_>>()));
  120. EXPECT_EQ (true, (std::is_same<false_, and_<false_>>()));
  121. EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_>>()));
  122. EXPECT_EQ (true, (std::is_same<false_, and_<true_, false_>>()));
  123. EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_, true_>>()));
  124. EXPECT_EQ (true, (std::is_same<false_, and_<true_, true_, false_>>()));
  125. EXPECT_EQ (true, (same<Foo, Foo>()));
  126. EXPECT_EQ (false, (same<Foo, Bar>()));
  127. EXPECT_EQ (true, (not_same<Foo, Bar>()));
  128. }
  129. /*
  130. * Test integral constant arithmetic operations
  131. */
  132. TEST(TmetaBasic, ArithmeticOperations) {
  133. EXPECT_EQ (int_<42>(), inc<int_<41>>());
  134. EXPECT_EQ (int_<42>(), dec<int_<43>>());
  135. EXPECT_EQ (int_<42>(), (add<int_<23>, add<int_<17>, int_<2>>>()));
  136. EXPECT_EQ (int_<42>(), (sub<int_<108>, int_<66>>()));
  137. EXPECT_EQ (int_<42>(), (mult<int_<7>, mult<int_<3>, int_<2>>>()));
  138. EXPECT_EQ (int_<42>(), (divide<int_<210>, int_<5>>()));
  139. EXPECT_EQ (int_<42>(), negate<int_<-42>>());
  140. EXPECT_EQ (int_< 1>(), (modulo<int_<43>, int_<42>>()));
  141. }
  142. /*
  143. * Test integral constant comparison operations
  144. */
  145. TEST(TmetaBasic, ComparisonOperations) {
  146. EXPECT_EQ (true, (comp_eq<int_<7>, int_<7>>()));
  147. EXPECT_EQ (true, (comp_eq<int_<-7>, int_<-7>>()));
  148. EXPECT_EQ (false, (comp_eq<int_<42>, int_<7>>()));
  149. EXPECT_EQ (true, (comp_ne<int_<42>, int_<7>>()));
  150. EXPECT_EQ (false, (comp_ne<int_<42>, int_<42>>()));
  151. EXPECT_EQ (true, (comp_ne<int_<42>, int_<-42>>()));
  152. EXPECT_EQ (true, (comp_lt<int_<42>, int_<43>>()));
  153. EXPECT_EQ (true, (comp_lt<int_<-7>, int_<-5>>()));
  154. EXPECT_EQ (false, (comp_lt<int_<43>, int_<42>>()));
  155. EXPECT_EQ (true, (comp_gt<int_<42>, int_<7>>()));
  156. EXPECT_EQ (true, (comp_gt<int_<7>, int_<-42>>()));
  157. EXPECT_EQ (false, (comp_gt<int_<7>, int_<42>>()));
  158. EXPECT_EQ (true, (comp_le<int_<7>, int_<42>>()));
  159. EXPECT_EQ (true, (comp_le<int_<-7>, int_<42>>()));
  160. EXPECT_EQ (true, (comp_le<int_<42>, int_<42>>()));
  161. EXPECT_EQ (true, (comp_le<int_<-7>, int_<-7>>()));
  162. EXPECT_EQ (false, (comp_le<int_<42>, int_<7>>()));
  163. EXPECT_EQ (false, (comp_le<int_<7>, int_<-42>>()));
  164. EXPECT_EQ (true, (comp_ge<int_<42>, int_<7>>()));
  165. EXPECT_EQ (true, (comp_ge<int_<42>, int_<-7>>()));
  166. EXPECT_EQ (true, (comp_ge<int_<42>, int_<42>>()));
  167. EXPECT_EQ (true, (comp_ge<int_<-7>, int_<-7>>()));
  168. EXPECT_EQ (false, (comp_ge<int_<42>, int_<43>>()));
  169. EXPECT_EQ (false, (comp_ge<int_<-7>, int_<42>>()));
  170. }
  171. /*
  172. * Test integral constant bit operations
  173. */
  174. TEST(TmetaBasic, BitOperations) {
  175. EXPECT_EQ (0x00, (bitand_<uint8_<0x55>, uint8_<0xAA>>()));
  176. EXPECT_EQ (0xFF, (bitor_ <uint8_<0x55>, uint8_<0xAA>>()));
  177. EXPECT_EQ (0xFA, (bitxor_<uint8_<0x55>, uint8_<0xAF>>()));
  178. EXPECT_EQ (0x00, (bitnot_<uint8_<(uint8_t)-1>>()));
  179. EXPECT_EQ (0x0000, (bitand_<uint16_<0x5555>, uint16_<0xAAAA>>()));
  180. EXPECT_EQ (0xFFFF, (bitor_ <uint16_<0x5555>, uint16_<0xAAAA>>()));
  181. EXPECT_EQ (0xFFAA, (bitxor_<uint16_<0x5555>, uint16_<0xAAFF>>()));
  182. EXPECT_EQ (0x0000, (bitnot_<uint16_<(uint16_t)-1>>()));
  183. EXPECT_EQ (0x04, (shift_left<uint8_<0x01>, uint8_<2>>()));
  184. EXPECT_EQ (0x00, (shift_left<uint8_<0x80>, uint8_<1>>()));
  185. EXPECT_EQ (0x02, (shift_right<uint8_<0x08>, uint8_<2>>()));
  186. EXPECT_EQ (0x00, (shift_right<uint8_<0x01>, uint8_<1>>()));
  187. }
  188. /*
  189. * SFINAE
  190. */
  191. template <typename T, typename =when<same<T, int>::type::value>>
  192. int check1 (T x) { return x; }
  193. int check1 (...) { return 0; }
  194. template <typename T, typename =enable_if_t<same<T, int>::type::value, void>>
  195. int check2 (T x) { return x; }
  196. int check2 (...) { return 0; }
  197. TEST(TmetaBasic, Sfinae) {
  198. EXPECT_EQ (42, check1(42));
  199. EXPECT_EQ (0, check1(42.0));
  200. EXPECT_EQ (0, check1());
  201. EXPECT_EQ (42, check2(42));
  202. EXPECT_EQ (0, check2(42.0));
  203. EXPECT_EQ (0, check2());
  204. }
  205. }