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.
 
 
 
 

197 lines
8.3 KiB

  1. /*!
  2. * \file Tmeta.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 test_meta {
  24. using namespace utl;
  25. using namespace meta;
  26. /*
  27. * Test integral constant
  28. */
  29. // Test type_of fixture
  30. template<class T> struct TestTypeOf {
  31. using type = T;
  32. };
  33. TEST(Tmeta_integral, Integreal_type_) {
  34. EXPECT_EQ(true, (std::is_same<int, type_<TestTypeOf<int>>>::value));
  35. }
  36. TEST(Tmeta_integral, IntegrealConstant) {
  37. EXPECT_EQ(true, (std::is_same<int, integral_constant<int, 42>::value_type>::value));
  38. EXPECT_EQ(true, (std::is_same<int, integral_constant<int, 42>::type::value_type>::value));
  39. EXPECT_EQ(42, (integral_constant<int, 0>::value_type(42)));
  40. EXPECT_EQ(42, (integral_constant<int, 42>()));
  41. }
  42. TEST(Tmeta_integral, BasicTypes) {
  43. EXPECT_EQ(true, (std::is_same<bool, bool_<false>::value_type>::value));
  44. EXPECT_EQ(true, bool_<true>::value);
  45. EXPECT_EQ(true, (std::is_same<bool, false_::value_type>::value));
  46. EXPECT_EQ(false, false_::value);
  47. EXPECT_EQ(true, (std::is_same<bool, true_::value_type>::value));
  48. EXPECT_EQ(true, true_::value);
  49. EXPECT_EQ(true, (std::is_same<int8_t, int8_<0>::value_type>::value));
  50. EXPECT_EQ(42, int8_<42>::value);
  51. EXPECT_EQ(true, (std::is_same<uint8_t, uint8_<0>::value_type>::value));
  52. EXPECT_EQ(42u, uint8_<42u>::value);
  53. EXPECT_EQ(true, (std::is_same<int16_t, int16_<0>::value_type>::value));
  54. EXPECT_EQ(42, int16_<42>::value);
  55. EXPECT_EQ(true, (std::is_same<uint16_t, uint16_<0>::value_type>::value));
  56. EXPECT_EQ(42u, uint16_<42u>::value);
  57. EXPECT_EQ(true, (std::is_same<int32_t, int32_<0>::value_type>::value));
  58. EXPECT_EQ(42, int32_<42>::value);
  59. EXPECT_EQ(true, (std::is_same<uint32_t, uint32_<0>::value_type>::value));
  60. EXPECT_EQ(42u, uint32_<42u>::value);
  61. EXPECT_EQ(true, (std::is_same<char, char_<0>::value_type>::value));
  62. EXPECT_EQ(42, char_<42>::value);
  63. EXPECT_EQ(true, (std::is_same<int, int_<0>::value_type>::value));
  64. EXPECT_EQ(42, int_<42>::value);
  65. EXPECT_EQ(true, (std::is_same<long, long_<0>::value_type>::value));
  66. EXPECT_EQ(42, long_<42>::value);
  67. EXPECT_EQ(true, (std::is_same<index_t, index_t_<0>::value_type>::value));
  68. EXPECT_EQ(42U, index_t_<42U>::value);
  69. EXPECT_EQ(true, (std::is_same<size_t, size_t_<0>::value_type>::value));
  70. EXPECT_EQ(42U, size_t_<42U>::value);
  71. EXPECT_EQ(sizeof(int), sizeof_<int>::value);
  72. EXPECT_EQ(alignof(int), alignof_<int>::value);
  73. EXPECT_EQ(static_cast<index_t>(-1), Npos::value);
  74. }
  75. /*
  76. * Test integral constant arithmetic operations
  77. */
  78. TEST(Tmeta_integral, ArithmeticOperations) {
  79. EXPECT_EQ (int_<42>(), inc<int_<41>>());
  80. EXPECT_EQ (int_<42>(), dec<int_<43>>());
  81. EXPECT_EQ (int_<42>(), (add<int_<23>, add<int_<17>, int_<2>>>()));
  82. EXPECT_EQ (int_<42>(), (sub<int_<108>, int_<66>>()));
  83. EXPECT_EQ (int_<42>(), (mult<int_<7>, mult<int_<3>, int_<2>>>()));
  84. EXPECT_EQ (int_<42>(), (divide<int_<210>, int_<5>>()));
  85. EXPECT_EQ (int_<42>(), negate<int_<-42>>());
  86. EXPECT_EQ (int_< 1>(), (modulo<int_<43>, int_<42>>()));
  87. }
  88. /*
  89. * Test logical
  90. */
  91. TEST(Tmeta_logical, ComparisonOperations) {
  92. EXPECT_EQ (true, (std::is_same<bool_<true>, not_c<false>>::value));
  93. EXPECT_EQ (true, (comp_eq<int_<7>, int_<7>>()));
  94. EXPECT_EQ (true, (comp_ne<int_<42>, int_<7>>()));
  95. EXPECT_EQ (true, (comp_lt<int_<42>, int_<43>>()));
  96. EXPECT_EQ (true, (comp_gt<int_<43>, int_<42>>()));
  97. EXPECT_EQ (true, (comp_le<int_<42>, int_<42>>()));
  98. EXPECT_EQ (true, (comp_ge<int_<42>, int_<42>>()));
  99. }
  100. TEST(Tmeta_logical, BitOperations) {
  101. EXPECT_EQ (0x00, (bitand_<uint8_<0x55>, uint8_<0xAA>>()));
  102. EXPECT_EQ (0xFF, (bitor_ <uint8_<0x55>, uint8_<0xAA>>()));
  103. EXPECT_EQ (0xFA, (bitxor_<uint8_<0x55>, uint8_<0xAF>>()));
  104. EXPECT_EQ (0x00, (bitnot_<uint8_<-1>>()));
  105. EXPECT_EQ (0x04, (shift_left<uint8_<0x01>, uint8_<2>>()));
  106. EXPECT_EQ (0x00, (shift_left<uint8_<0x80>, uint8_<1>>()));
  107. EXPECT_EQ (0x02, (shift_right<uint8_<0x08>, uint8_<2>>()));
  108. EXPECT_EQ (0x00, (shift_right<uint8_<0x01>, uint8_<1>>()));
  109. }
  110. TEST(Tmeta_logical, TypeOperations) {
  111. struct Foo {};
  112. struct Bar {};
  113. EXPECT_EQ (true, (std::is_same<bool_<true>, not_<bool_<false>>>()));
  114. EXPECT_EQ (true, (std::is_same<int_<42>, if_c<true, int_<42>, bool_<false>>>()));
  115. EXPECT_EQ (true, (std::is_same<int_<42>, if_<bool_<true>, int_<42>, bool_<false>>>()));
  116. EXPECT_EQ (true, (std::is_same<true_, or_<true_, false_>>()));
  117. EXPECT_EQ (true, (std::is_same<false_, or_<false_, false_>>()));
  118. EXPECT_EQ (true, (std::is_same<false_, and_<true_, false_>>()));
  119. EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_>>()));
  120. EXPECT_EQ (true, (same_<Foo, Foo>()));
  121. EXPECT_EQ (false, (same_<Foo, Bar>()));
  122. EXPECT_EQ (true, (not_same_<Foo, Bar>()));
  123. }
  124. /*
  125. * Test void
  126. */
  127. TEST(Tmeta_void, VoidType) {
  128. struct Foo {};
  129. struct Bar {};
  130. EXPECT_EQ(true, (std::is_same<void, void_t<int, long, Foo, Bar>>()));
  131. }
  132. /*
  133. * Test invoke
  134. */
  135. template<class T1, class T2> struct MetaFunction { using type = int; };
  136. template<typename... Args> struct MetaClass {using apply = int; };
  137. TEST(Tmeta_invoke, Invoke) {
  138. //EXPECT_EQ (true, (is_evaluable<MetaFunction, int .long>()));
  139. }
  140. /*
  141. * Test typelist
  142. */
  143. template<class T1, class T2> struct F {};
  144. TEST(Tmeta_typelist, List_fold) {
  145. struct X1 {};
  146. struct X2 {};
  147. struct X3 {};
  148. struct X4 {};
  149. using Q = quote<F>;
  150. EXPECT_EQ(true, (std::is_same<fold<typelist<>, void, Q>, void>()));
  151. EXPECT_EQ(true, (std::is_same<fold<typelist<X1>, void, Q>, F<void, X1>>()));
  152. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2>, void, Q>, F<F<void, X1>, X2>>()));
  153. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3>, void, Q>, F<F<F<void, X1>, X2>, X3>>()));
  154. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3, X4>, void, Q>, F<F<F<F<void, X1>, X2>, X3>, X4>>()));
  155. //EXPECT_EQ(true, (std::is_same<rev_fold<typelist<>, void, Q>, void>()));
  156. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1>, void, Q>, F<X1, void>>()));
  157. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2>, void, Q>, F<X1, F<X2, void>>>()));
  158. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3>, void, Q>, F<X1, F<X2, F<X3, void>>>>()));
  159. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3, X4>, void, Q>, F<X1, F<X2, F<X3, F<X4, void>>>>>()));
  160. }
  161. TEST(Tmeta_typelist, ListOperations) {
  162. using l1 = typelist<int, short, long>;
  163. using l2 = typelist<>;
  164. using l3 = typelist<float, double, long double>;
  165. using l4 = typelist<void*, char*>;
  166. using conc = typelist<int, short, long, float, double, long double, void*, char*>;
  167. using rep = typelist<int, int, int>;
  168. EXPECT_EQ(3, size<l1>());
  169. EXPECT_EQ(true, empty<l2>());
  170. EXPECT_EQ(true, (std::is_same<conc, concat<l1, l2, l3, l4>>()));
  171. EXPECT_EQ(true, (std::is_same<rep, repeat_n<int_<3>, int>>()));
  172. EXPECT_EQ(true, (std::is_same<int, front<l1>>()));
  173. EXPECT_EQ(true, (std::is_same<long, back<l1>>()));
  174. EXPECT_EQ(true, (std::is_same<double, at<l3, int_<1>>>()));
  175. EXPECT_EQ(true, (std::is_same<typelist<short, long>, pop_front<l1>>()));
  176. }
  177. }