Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

162 lignes
7.5 KiB

  1. /*!
  2. * \file TmetaDetection.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 TmetaDetection {
  24. using namespace utl;
  25. using namespace meta;
  26. /*
  27. * Types to behave like Fixtures
  28. */
  29. struct Foo {};
  30. struct Bar {};
  31. template <typename T> struct A {
  32. using type = T; // nested type
  33. A(int i, double d) : i_(i), d_(d) {} // declare a non-trivial constructor
  34. A& operator++() { ++i_; return *this; } // declare an operator
  35. // A sfinae function
  36. template <typename TT = T, typename = when<std::is_integral<TT>::type::value>>
  37. TT sfun () { return TT{}; }
  38. private:
  39. int i_; double d_;
  40. };
  41. // A binary metafunction
  42. template <typename T1, typename T2>
  43. struct mFun {
  44. using type = std::is_same <T1, T2>;
  45. };
  46. // detectors
  47. template <typename T> using try_type = typename T::type;
  48. template <typename T> using try_none = typename T::none;
  49. template <typename T> using try_ctor1= decltype (T(std::declval<int>(), std::declval<double>()));
  50. template <typename T> using try_ctor2= decltype (T(std::declval<int>()));
  51. template <typename T> using try_ppT = decltype (++(std::declval<T>()));
  52. template <typename T> using try_Tpp = decltype (std::declval<T>()++);
  53. template <typename T> using try_sfun = decltype (std::declval<T>().sfun());
  54. /*
  55. * void_t
  56. */
  57. TEST(TmetaDetection, VoidType) {
  58. EXPECT_EQ(true, (std::is_same<void, void_t<int, long, void*, void, Foo, Bar>>()));
  59. EXPECT_EQ(true, (std::is_same<void, void_t<>>()));
  60. }
  61. /*
  62. * not a type
  63. */
  64. TEST(TmetaDetection, NotAType) {
  65. EXPECT_EQ(false, (std::is_default_constructible<nat_>()));
  66. EXPECT_EQ(false, (std::is_destructible<nat_>()));
  67. EXPECT_EQ(false, (std::is_copy_constructible<nat_>()));
  68. EXPECT_EQ(false, (std::is_copy_assignable<nat_>()));
  69. }
  70. /*
  71. * Idiom
  72. */
  73. TEST(TmetaDetection, IsDetected) {
  74. EXPECT_EQ (true, (std::is_same< true_, is_detected<try_type, A<int>> >()));
  75. EXPECT_EQ (true, (std::is_same< false_, is_detected<try_none, A<int>> >()));
  76. EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ctor1, A<int>> >()));
  77. EXPECT_EQ (true, (std::is_same< false_, is_detected<try_ctor2, A<int>> >()));
  78. EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ppT, A<int>> >()));
  79. EXPECT_EQ (true, (std::is_same< false_, is_detected<try_Tpp, A<int>> >()));
  80. EXPECT_EQ (true, (std::is_same< true_, is_detected<try_sfun, A<int>> >()));
  81. EXPECT_EQ (true, (std::is_same< false_, is_detected<try_sfun, A<double>> >()));
  82. EXPECT_EQ (true, (std::is_same< true_, is_detected<mFun, int, void> >()));
  83. EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char> >()));
  84. EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char, void, void> >()));
  85. EXPECT_EQ (true, (is_detected_v<try_type, A<int>>));
  86. EXPECT_EQ (false,(is_detected_v<try_none, A<int>>));
  87. EXPECT_EQ (true, (is_detected_v<mFun, int, void>));
  88. }
  89. /*
  90. * Idiom
  91. */
  92. TEST(TmetaDetection, Toolkit) {
  93. // detected_t
  94. EXPECT_EQ (true, (std::is_same< int, detected_t<try_type, A<int>> >()));
  95. EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_none, A<int>> >()));
  96. EXPECT_EQ (true, (std::is_same< A<int>, detected_t< try_ctor1, A<int>> >()));
  97. EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_ctor2, A<int>> >()));
  98. EXPECT_EQ (true, (std::is_same< A<int>&,detected_t< try_ppT, A<int>> >()));
  99. EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_Tpp, A<int>> >()));
  100. EXPECT_EQ (true, (std::is_same< int, detected_t< try_sfun, A<int>> >()));
  101. EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_sfun, A<double>> >()));
  102. EXPECT_EQ (true, (std::is_same< nat_, detected_t<mFun, void> >()));
  103. EXPECT_EQ (true, (std::is_same< mFun<int, int>,
  104. detected_t<mFun, int, int> >()));
  105. // detected_or_t
  106. EXPECT_EQ (true, (std::is_same< int, detected_or_t<Foo, try_type, A<int>> >()));
  107. EXPECT_EQ (true, (std::is_same< Foo, detected_or_t<Foo, try_none, A<int>> >()));
  108. EXPECT_EQ (true, (std::is_same< A<int>, detected_or_t<void, try_ctor1, A<int>> >()));
  109. EXPECT_EQ (true, (std::is_same< void, detected_or_t<void, try_ctor2, A<int>> >()));
  110. EXPECT_EQ (true, (std::is_same< A<int>&,detected_or_t<nil_, try_ppT, A<int>> >()));
  111. EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, try_Tpp, A<int>> >()));
  112. EXPECT_EQ (true, (std::is_same< int, detected_or_t<void*, try_sfun, A<int>> >()));
  113. EXPECT_EQ (true, (std::is_same< void*, detected_or_t<void*, try_sfun, A<double>> >()));
  114. EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, mFun, int> >()));
  115. EXPECT_EQ (true, (std::is_same< mFun<char, int>,
  116. detected_or_t<void, mFun, char, int> >()));
  117. // is_detected_exact
  118. EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_type, A<int>> >()));
  119. EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_none, A<int>> >()));
  120. EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>, try_ctor1, A<int>> >()));
  121. EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>, try_ctor2, A<int>> >()));
  122. EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>&,try_ppT, A<int>> >()));
  123. EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>&,try_Tpp, A<int>> >()));
  124. EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_sfun, A<int>> >()));
  125. EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_sfun, A<double>> >()));
  126. EXPECT_EQ (true, (std::is_same<true_, is_detected_exact<mFun<char, int>, mFun, char, int> >()));
  127. EXPECT_EQ (true, (std::is_same<false_, is_detected_exact<mFun<int, int>, mFun, int> >())); // it would be better to check against mFun<int>
  128. EXPECT_EQ (true, (is_detected_exact_v< int, try_type, A<int>> ));
  129. EXPECT_EQ (false,(is_detected_exact_v< int, try_none, A<int>> ));
  130. // is_detected_convertible
  131. EXPECT_EQ (true, (std::is_same<true_, is_detected_convertible< int, try_type, A<char>> >()));
  132. EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< int, try_none, A<int>> >()));
  133. EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< mFun<int, int>, mFun, char, int> >()));
  134. EXPECT_EQ (true, (is_detected_convertible_v< int, try_type, A<char>> ));
  135. EXPECT_EQ (false,(is_detected_convertible_v< int, try_none, A<int>> ));
  136. }
  137. }