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.

Tmeta.cpp 7.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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<int, int_<0>::value_type>::value));
  50. EXPECT_EQ(42, int_<42>::value);
  51. EXPECT_EQ(true, (std::is_same<index_t, index_t_<0>::value_type>::value));
  52. EXPECT_EQ(42U, index_t_<42U>::value);
  53. EXPECT_EQ(true, (std::is_same<size_t, size_t_<0>::value_type>::value));
  54. EXPECT_EQ(42U, size_t_<42U>::value);
  55. EXPECT_EQ(sizeof(int), sizeof_<int>::value);
  56. EXPECT_EQ(alignof(int), alignof_<int>::value);
  57. EXPECT_EQ(static_cast<index_t>(-1), Npos::value);
  58. }
  59. /*
  60. * Test integral constant arithmetic operations
  61. */
  62. TEST(Tmeta_integral, ArithmeticOperations) {
  63. EXPECT_EQ (int_<42>(), inc<int_<41>>());
  64. EXPECT_EQ (int_<42>(), dec<int_<43>>());
  65. EXPECT_EQ (int_<42>(), (add<int_<23>, add<int_<17>, int_<2>>>()));
  66. EXPECT_EQ (int_<42>(), (sub<int_<108>, int_<66>>()));
  67. EXPECT_EQ (int_<42>(), (mult<int_<7>, mult<int_<3>, int_<2>>>()));
  68. EXPECT_EQ (int_<42>(), (divide<int_<210>, int_<5>>()));
  69. EXPECT_EQ (int_<42>(), negate<int_<-42>>());
  70. EXPECT_EQ (int_< 1>(), (modulo<int_<43>, int_<42>>()));
  71. }
  72. /*
  73. * Test logical
  74. */
  75. TEST(Tmeta_logical, ComparisonOperations) {
  76. EXPECT_EQ (true, (std::is_same<bool_<true>, not_c<false>>::value));
  77. EXPECT_EQ (true, (comp_eq<int_<7>, int_<7>>()));
  78. EXPECT_EQ (true, (comp_ne<int_<42>, int_<7>>()));
  79. EXPECT_EQ (true, (comp_lt<int_<42>, int_<43>>()));
  80. EXPECT_EQ (true, (comp_gt<int_<43>, int_<42>>()));
  81. EXPECT_EQ (true, (comp_le<int_<42>, int_<42>>()));
  82. EXPECT_EQ (true, (comp_ge<int_<42>, int_<42>>()));
  83. }
  84. TEST(Tmeta_logical, BitOperations) {
  85. EXPECT_EQ (0x00, (bitand_<int_<0x55>, int_<0xAA>>()));
  86. EXPECT_EQ (0xFF, (bitor_<int_<0x55>, int_<0xAA>>()));
  87. EXPECT_EQ (0xFA, (bitxor_<int_<0x55>, int_<0xAF>>()));
  88. EXPECT_EQ (0x00, (bitnot_<int_<-1>>()));
  89. //XXX: add shifts
  90. }
  91. TEST(Tmeta_logical, TypeOperations) {
  92. struct Foo {};
  93. struct Bar {};
  94. EXPECT_EQ (true, (std::is_same<bool_<true>, not_<bool_<false>>>()));
  95. EXPECT_EQ (true, (std::is_same<int_<42>, if_c<true, int_<42>, bool_<false>>>()));
  96. EXPECT_EQ (true, (std::is_same<int_<42>, if_<bool_<true>, int_<42>, bool_<false>>>()));
  97. EXPECT_EQ (true, (std::is_same<bool_<true>, or_<bool_<true>, bool_<false>>>()));
  98. EXPECT_EQ (true, (std::is_same<bool_<false>, or_<bool_<false>, bool_<false>>>()));
  99. EXPECT_EQ (true, (std::is_same<bool_<false>, and_<bool_<true>, bool_<false>>>()));
  100. EXPECT_EQ (true, (std::is_same<bool_<true>, and_<bool_<true>, bool_<true>>>()));
  101. EXPECT_EQ (true, (same_<Foo, Foo>()));
  102. EXPECT_EQ (false, (same_<Foo, Bar>()));
  103. EXPECT_EQ (true, (not_same_<Foo, Bar>()));
  104. }
  105. /*
  106. * Test void
  107. */
  108. TEST(Tmeta_void, VoidType) {
  109. struct Foo {};
  110. struct Bar {};
  111. EXPECT_EQ(true, (std::is_same<void, void_t<int, long, Foo, Bar>>()));
  112. }
  113. /*
  114. * Test invoke
  115. */
  116. template<class T1, class T2> struct MetaFunction { using type = int; };
  117. template<typename... Args> struct MetaClass {using apply = int; };
  118. TEST(Tmeta_invoke, Invoke) {
  119. //EXPECT_EQ (true, (is_evaluable<MetaFunction, int .long>()));
  120. }
  121. /*
  122. * Test typelist
  123. */
  124. template<class T1, class T2> struct F {};
  125. TEST(Tmeta_typelist, List_fold) {
  126. struct X1 {};
  127. struct X2 {};
  128. struct X3 {};
  129. struct X4 {};
  130. using Q = quote<F>;
  131. EXPECT_EQ(true, (std::is_same<fold<typelist<>, void, Q>, void>()));
  132. EXPECT_EQ(true, (std::is_same<fold<typelist<X1>, void, Q>, F<void, X1>>()));
  133. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2>, void, Q>, F<F<void, X1>, X2>>()));
  134. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3>, void, Q>, F<F<F<void, X1>, X2>, X3>>()));
  135. EXPECT_EQ(true, (std::is_same<fold<typelist<X1, X2, X3, X4>, void, Q>, F<F<F<F<void, X1>, X2>, X3>, X4>>()));
  136. //EXPECT_EQ(true, (std::is_same<rev_fold<typelist<>, void, Q>, void>()));
  137. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1>, void, Q>, F<X1, void>>()));
  138. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2>, void, Q>, F<X1, F<X2, void>>>()));
  139. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3>, void, Q>, F<X1, F<X2, F<X3, void>>>>()));
  140. EXPECT_EQ(true, (std::is_same<rev_fold<typelist<X1, X2, X3, X4>, void, Q>, F<X1, F<X2, F<X3, F<X4, void>>>>>()));
  141. }
  142. TEST(Tmeta_typelist, ListOperations) {
  143. using l1 = typelist<int, short, long>;
  144. using l2 = typelist<>;
  145. using l3 = typelist<float, double, long double>;
  146. using l4 = typelist<void*, char*>;
  147. using conc = typelist<int, short, long, float, double, long double, void*, char*>;
  148. using rep = typelist<int, int, int>;
  149. EXPECT_EQ(3, size<l1>());
  150. EXPECT_EQ(true, empty<l2>());
  151. EXPECT_EQ(true, (std::is_same<conc, concat<l1, l2, l3, l4>>()));
  152. EXPECT_EQ(true, (std::is_same<rep, repeat_n<int_<3>, int>>()));
  153. EXPECT_EQ(true, (std::is_same<int, front<l1>>()));
  154. EXPECT_EQ(true, (std::is_same<long, back<l1>>()));
  155. EXPECT_EQ(true, (std::is_same<double, at<l3, int_<1>>>()));
  156. EXPECT_EQ(true, (std::is_same<typelist<short, long>, pop_front<l1>>()));
  157. }
  158. }