uTL
micro Template library
TmetaDetection.cpp
Go to the documentation of this file.
1 
20 #include <utl/meta/meta.h>
21 #include <gtest/gtest.h>
22 #include <type_traits>
23 
24 namespace TmetaDetection {
25  using namespace utl;
26  using namespace meta;
27 
28  /*
29  * Types to behave like Fixtures
30  */
31  struct Foo {};
32  struct Bar {};
33 
34  template <typename T> struct A {
35  using type = T; // nested type
36  A(int i, double d) : i_(i), d_(d) {} // declare a non-trivial constructor
37  A& operator++() { ++i_; return *this; } // declare an operator
38 
39  // A sfinae function
40  template <typename TT = T, typename = when<std::is_integral<TT>::type::value>>
41  TT sfun () { return TT{}; }
42  private:
43  int i_; double d_;
44  };
45 
46  // A binary metafunction
47  template <typename T1, typename T2>
48  struct mFun {
49  using type = std::is_same <T1, T2>;
50  };
51 
52  // detectors
53  template <typename T> using try_type = typename T::type;
54  template <typename T> using try_none = typename T::none;
55  template <typename T> using try_ctor1= decltype (T(std::declval<int>(), std::declval<double>()));
56  template <typename T> using try_ctor2= decltype (T(std::declval<int>()));
57  template <typename T> using try_ppT = decltype (++(std::declval<T>()));
58  template <typename T> using try_Tpp = decltype (std::declval<T>()++);
59  template <typename T> using try_sfun = decltype (std::declval<T>().sfun());
60 
61  /*
62  * void_t
63  */
64  TEST(TmetaDetection, VoidType) {
65  EXPECT_EQ(true, (std::is_same<void, void_t<int, long, void*, void, Foo, Bar>>()));
66  EXPECT_EQ(true, (std::is_same<void, void_t<>>()));
67  }
68 
69  /*
70  * not a type
71  */
72  TEST(TmetaDetection, NotAType) {
73  EXPECT_EQ(false, (std::is_default_constructible<nat_>()));
74  EXPECT_EQ(false, (std::is_destructible<nat_>()));
75  EXPECT_EQ(false, (std::is_copy_constructible<nat_>()));
76  EXPECT_EQ(false, (std::is_copy_assignable<nat_>()));
77  }
78 
79  /*
80  * Idiom
81  */
82  TEST(TmetaDetection, IsDetected) {
83 
84  EXPECT_EQ (true, (std::is_same< true_, is_detected<try_type, A<int>> >()));
85  EXPECT_EQ (true, (std::is_same< false_, is_detected<try_none, A<int>> >()));
86  EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ctor1, A<int>> >()));
87  EXPECT_EQ (true, (std::is_same< false_, is_detected<try_ctor2, A<int>> >()));
88  EXPECT_EQ (true, (std::is_same< true_, is_detected<try_ppT, A<int>> >()));
89  EXPECT_EQ (true, (std::is_same< false_, is_detected<try_Tpp, A<int>> >()));
90  EXPECT_EQ (true, (std::is_same< true_, is_detected<try_sfun, A<int>> >()));
91  EXPECT_EQ (true, (std::is_same< false_, is_detected<try_sfun, A<double>> >()));
92 
93  EXPECT_EQ (true, (std::is_same< true_, is_detected<mFun, int, void> >()));
94  EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char> >()));
95  EXPECT_EQ (true, (std::is_same< false_, is_detected<mFun, char, void, void> >()));
96 
99  EXPECT_EQ (true, (is_detected_v<mFun, int, void>));
100 
101  }
102 
103  /*
104  * Idiom
105  */
106  TEST(TmetaDetection, Toolkit) {
107 
108  // detected_t
109  EXPECT_EQ (true, (std::is_same< int, detected_t<try_type, A<int>> >()));
110  EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_none, A<int>> >()));
111  EXPECT_EQ (true, (std::is_same< A<int>, detected_t< try_ctor1, A<int>> >()));
112  EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_ctor2, A<int>> >()));
113  EXPECT_EQ (true, (std::is_same< A<int>&,detected_t< try_ppT, A<int>> >()));
114  EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_Tpp, A<int>> >()));
115  EXPECT_EQ (true, (std::is_same< int, detected_t< try_sfun, A<int>> >()));
116  EXPECT_EQ (true, (std::is_same< nat_, detected_t< try_sfun, A<double>> >()));
117 
118  EXPECT_EQ (true, (std::is_same< nat_, detected_t<mFun, void> >()));
119  EXPECT_EQ (true, (std::is_same< mFun<int, int>,
121 
122  // detected_or_t
123  EXPECT_EQ (true, (std::is_same< int, detected_or_t<Foo, try_type, A<int>> >()));
124  EXPECT_EQ (true, (std::is_same< Foo, detected_or_t<Foo, try_none, A<int>> >()));
125  EXPECT_EQ (true, (std::is_same< A<int>, detected_or_t<void, try_ctor1, A<int>> >()));
126  EXPECT_EQ (true, (std::is_same< void, detected_or_t<void, try_ctor2, A<int>> >()));
127  EXPECT_EQ (true, (std::is_same< A<int>&,detected_or_t<nil_, try_ppT, A<int>> >()));
128  EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, try_Tpp, A<int>> >()));
129  EXPECT_EQ (true, (std::is_same< int, detected_or_t<void*, try_sfun, A<int>> >()));
130  EXPECT_EQ (true, (std::is_same< void*, detected_or_t<void*, try_sfun, A<double>> >()));
131 
132  EXPECT_EQ (true, (std::is_same< nil_, detected_or_t<nil_, mFun, int> >()));
133  EXPECT_EQ (true, (std::is_same< mFun<char, int>,
135 
136  // is_detected_exact
137  EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_type, A<int>> >()));
138  EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_none, A<int>> >()));
139  EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>, try_ctor1, A<int>> >()));
140  EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>, try_ctor2, A<int>> >()));
141  EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< A<int>&,try_ppT, A<int>> >()));
142  EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< A<int>&,try_Tpp, A<int>> >()));
143  EXPECT_EQ (true, (std::is_same<true_, is_detected_exact< int, try_sfun, A<int>> >()));
144  EXPECT_EQ (true, (std::is_same<false_, is_detected_exact< int, try_sfun, A<double>> >()));
145 
146  EXPECT_EQ (true, (std::is_same<true_, is_detected_exact<mFun<char, int>, mFun, char, int> >()));
147  EXPECT_EQ (true, (std::is_same<false_, is_detected_exact<mFun<int, int>, mFun, int> >())); // it would be better to check against mFun<int>
148 
149  EXPECT_EQ (true, (is_detected_exact_v< int, try_type, A<int>> ));
150  EXPECT_EQ (false,(is_detected_exact_v< int, try_none, A<int>> ));
151 
152  // is_detected_convertible
153  EXPECT_EQ (true, (std::is_same<true_, is_detected_convertible< int, try_type, A<char>> >()));
154  EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< int, try_none, A<int>> >()));
155  EXPECT_EQ (true, (std::is_same<false_, is_detected_convertible< mFun<int, int>, mFun, char, int> >()));
156 
159 
160  }
161 }
decltype(std::declval< T >().sfun()) try_sfun
Include all meta library.
void void_t
void_t type alias
Definition: detection.h:55
constexpr bool is_detected_exact_v
evaluates to true if evaluation of Op<Args...> is Expected and to false if not
Definition: detection.h:204
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
std::is_same< T1, T2 > type
eval< std::is_convertible< detected_t< Op, Args... >, To > > is_detected_convertible
Definition: detection.h:231
typename T::none try_none
TEST(TmetaDetection, VoidType)
decltype(std::declval< T >()++) try_Tpp
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
constexpr bool is_detected_convertible_v
Definition: detection.h:237
STL&#39;s core language concepts.
Definition: _1wire.h:30
eval< detail::detector< nat_, void, Op, Args... > > detected_t
Definition: detection.h:146
typename T::type try_type
decltype(T(std::declval< int >())) try_ctor2
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:16643
A(int i, double d)
eval< same_< Expected, detected_t< Op, Args... > > > is_detected_exact
Definition: detection.h:199
typename detail::detector< nat_, void, Op, Args... >::detected is_detected
Definition: detection.h:118
decltype(++(std::declval< T >())) try_ppT
constexpr bool is_detected_v
Detection predicate.
Definition: detection.h:122
eval< detail::detected_or< Default, Op, Args... > > detected_or_t
Definition: detection.h:172
decltype(T(std::declval< int >(), std::declval< double >())) try_ctor1