uTL
micro Template library
TConcepts.cpp
Go to the documentation of this file.
1 
20 #include <utl/concepts/concepts.h>
21 #include <utl/meta/meta.h>
22 #include <gtest/gtest.h>
23 
24 
25 namespace test_concepts {
26  using namespace utl;
27 
28  /*
29  * Fixture like types
30  */
31  struct Empty { };
32  struct HaveOnlyCopy {
33  HaveOnlyCopy(const HaveOnlyCopy&) = default;
34  HaveOnlyCopy(HaveOnlyCopy&&) = delete;
35  HaveOnlyCopy& operator= (const HaveOnlyCopy&) = default;
36  HaveOnlyCopy& operator= (HaveOnlyCopy&&) = delete;
37  };
38  struct HaveOnlyMove {
39  HaveOnlyMove(const HaveOnlyMove&) = delete;
40  HaveOnlyMove(HaveOnlyMove&&) = default;
41  HaveOnlyMove& operator= (const HaveOnlyMove&) = delete;
42  HaveOnlyMove& operator= (HaveOnlyMove&&) = default;
43  };
44  struct HaveCopyAndMove {
45  HaveCopyAndMove(const HaveCopyAndMove&) = default;
46  HaveCopyAndMove(HaveCopyAndMove&&) = default;
47  HaveCopyAndMove& operator= (const HaveCopyAndMove&) = default;
48  HaveCopyAndMove& operator= (HaveCopyAndMove&&) = default;
49  };
51  public: template<class T> HavePerfectForwarding(T&&) { }
52  };
53  class Base { };
54  class Derived1 : public Base { };
55  class Derived2 : public Derived1 { };
57  public: operator Base() { return base; }
59  };
60 
61 
62  struct A {
63  int a_;
64  public:
65  A(int a =0) : a_{a} { };
66  A(const A&) = default;
67  A(A&&) = default;
68  };
69  bool operator== (const A& l, const A& r) { return l.a_ == r.a_; }
70  bool operator!= (const A& l, const A& r) { return l.a_ != r.a_; }
71 
72  struct B {
73  int b_;
74  public:
75  B(int b =0) : b_{b} { };
76  B(const B&) = default;
77  B(B&&) = default;
78  B& operator= (const B&) = default;
79  B& operator= (B&&) = default;
80  };
81  bool operator== (const B& l, const B& r) { return l.b_ == r.b_; }
82  bool operator!= (const B& l, const B& r) { return l.b_ != r.b_; }
83  bool operator< (const B& l, const B& r) { return l.b_ < r.b_; }
84  bool operator<= (const B& l, const B& r) { return l.b_ <= r.b_; }
85  bool operator> (const B& l, const B& r) { return l.b_ > r.b_; }
86  bool operator>= (const B& l, const B& r) { return l.b_ >= r.b_; }
87 
88 
89  TEST(TConcepts, Same) {
90  // Same
91  EXPECT_EQ (true, (Same<int, int>));
92  EXPECT_EQ (false, (Same<int, long>));
93  EXPECT_EQ (true, (Same<int*, int*>));
94  EXPECT_EQ (true, (Same<double&, double&>));
95  EXPECT_EQ (false, (Same<int, Empty>));
96  EXPECT_EQ (false, (Same<Base, Derived1>));
97  }
98 
99  TEST(TConcepts, DerivedFrom) {
100  // DerivedFrom
101  EXPECT_EQ (true, (DerivedFrom<Derived1, Base>));
102  EXPECT_EQ (true, (DerivedFrom<Derived2, Derived1>));
103  EXPECT_EQ (true, (DerivedFrom<Derived2, Base>));
104  EXPECT_EQ (false, (DerivedFrom<Base, Derived1>));
105  EXPECT_EQ (false, (DerivedFrom<Base, int>));
106  EXPECT_EQ (false, (DerivedFrom<void, int>));
107  }
108 
109  TEST(TConcepts, ConvertibleTo) {
110  // ConvertibleTo
111  EXPECT_EQ (true, (ConvertibleTo<void, void>));
112  EXPECT_EQ (false, (ConvertibleTo<Base, void>));
113  EXPECT_EQ (false, (ConvertibleTo<Base*, Derived1*>));
114  EXPECT_EQ (true, (ConvertibleTo<Derived1*, Base*>));
115  EXPECT_EQ (true, (ConvertibleTo<HaveOperatorBase, Base>));
116  EXPECT_EQ (true, (ConvertibleTo<Base, HavePerfectForwarding>));
117  }
118 
119  TEST(TConcepts, CommonReference) {
120  // CommonReference
121  EXPECT_EQ (true, (CommonReference<Derived1, Base>));
122  EXPECT_EQ (true, (CommonReference<Derived1&, Base>));
123  EXPECT_EQ (true, (CommonReference<const Empty&&, const Empty&>));
124  EXPECT_EQ (false, (CommonReference<Empty&, const volatile Empty&>));
125  //FIXME: CommonReference needs SFINAE friendly implementation
126  //EXPECT_EQ (false, (CommonReference<Empty&&, const volatile Empty&>)); <- yields compiler error
127 
128  // Common
129  EXPECT_EQ (true, (Common<int, int>));
130  EXPECT_EQ (true, (Common<Base, Derived1>));
131  EXPECT_EQ (true, (Common<Derived1, Derived2>));
132  EXPECT_EQ (true, (Common<Base, HaveOperatorBase>));
133  EXPECT_EQ (true, (Common<Base, HavePerfectForwarding>));
134  }
135 
136  TEST(TConcepts, Integral) {
137  // Integral
138  EXPECT_EQ (false, (Integral<void>));
139  EXPECT_EQ (true, (Integral<int>));
140  EXPECT_EQ (true, (Integral<bool>));
141  EXPECT_EQ (false, (Integral<int*>));
142  EXPECT_EQ (false, (Integral<Base>));
145 
146  // SignedIntegral
147  EXPECT_EQ (false, (SignedIntegral<void>));
148  EXPECT_EQ (true, (SignedIntegral<int>));
149  EXPECT_EQ (false, (SignedIntegral<int*>));
150  EXPECT_EQ (false, (SignedIntegral<unsigned long>));
151  EXPECT_EQ (false, (SignedIntegral<double>));
152  EXPECT_EQ (false, (SignedIntegral<Base>));
154 
155  // UnsignedIntegral
156  EXPECT_EQ (false, (UnsignedIntegral<void>));
157  EXPECT_EQ (true, (UnsignedIntegral<unsigned int>));
158  EXPECT_EQ (false, (UnsignedIntegral<long>));
159  EXPECT_EQ (false, (UnsignedIntegral<double>));
160  EXPECT_EQ (false, (UnsignedIntegral<Base>));
162  }
163 
164  TEST(TConcepts, Assignable) {
165  // MoveAssignable
166  EXPECT_EQ (false, (MoveAssignable<void>));
167  EXPECT_EQ (true, (MoveAssignable<void*>));
168  EXPECT_EQ (true, (MoveAssignable<int>));
169  EXPECT_EQ (true, (MoveAssignable<int*>));
170  EXPECT_EQ (false, (MoveAssignable<HaveOnlyCopy>));
171  EXPECT_EQ (true, (MoveAssignable<HaveOnlyMove>));
172  EXPECT_EQ (true, (MoveAssignable<HaveCopyAndMove>));
173  EXPECT_EQ (true, (MoveAssignable<Empty>));
174  EXPECT_EQ (true, (MoveAssignable<HavePerfectForwarding>));
175 
176  // CopyAssignable
177  EXPECT_EQ (false, (CopyAssignable<void>));
178  EXPECT_EQ (true, (CopyAssignable<void*>));
179  EXPECT_EQ (true, (CopyAssignable<int>));
180  EXPECT_EQ (true, (CopyAssignable<int*>));
181  EXPECT_EQ (true, (CopyAssignable<HaveOnlyCopy>));
182  EXPECT_EQ (false, (CopyAssignable<HaveOnlyMove>));
183  EXPECT_EQ (true, (CopyAssignable<HaveCopyAndMove>));
184  EXPECT_EQ (true, (CopyAssignable<Empty>));
185  EXPECT_EQ (true, (CopyAssignable<HavePerfectForwarding>));
186 
187  // Assignable
188  EXPECT_EQ (false, (Assignable<void, void>));
189  EXPECT_EQ (false, (Assignable<int&, void>));
190  EXPECT_EQ (true, (Assignable<int&, int>));
191  EXPECT_EQ (false, (Assignable<int, int>));
192  EXPECT_EQ (false, (Assignable<int*, int*>));
193  EXPECT_EQ (true, (Assignable<Base&, Derived1>));
194  EXPECT_EQ (false, (Assignable<Derived1&, Base>));
195  EXPECT_EQ (true, (Assignable<HaveOnlyMove&, HaveOnlyMove&&>));
196  EXPECT_EQ (true , (Assignable<HaveOnlyMove&, HaveOnlyMove>));
197  EXPECT_EQ (true, (Assignable<Empty&, Empty>));
198  }
199 
200  TEST(TConcepts, Swappable) {
201  // Swappable, SwappableWith
202  EXPECT_EQ (false, (Swappable<void>));
203  EXPECT_EQ (true, (Swappable<void*>));
204  EXPECT_EQ (true, (Swappable<int>));
205  EXPECT_EQ (true, (Swappable<Base>));
206  EXPECT_EQ (true, (SwappableWith<int, int>));
207  EXPECT_EQ (false, (SwappableWith<int, Base>));
208  EXPECT_EQ (false, (SwappableWith<Base, Derived1>));
209 
210  // Destructible
211  EXPECT_EQ (false, (Destructible<void>));
212  EXPECT_EQ (true, (Destructible<void*>));
213  EXPECT_EQ (true, (Destructible<int>));
214  EXPECT_EQ (true, (Destructible<int&>));
215  EXPECT_EQ (true, (Destructible<Base>));
216  EXPECT_EQ (true, (Destructible<HavePerfectForwarding>));
217  }
218 
219  TEST(TConcepts, Constructible) {
220  // Constructible
221  EXPECT_EQ (false, (Constructible<void>));
222  EXPECT_EQ (true, (Constructible<void*>));
223  EXPECT_EQ (true, (Constructible<Base>));
224  EXPECT_EQ (false, (Constructible<HaveOnlyMove>));
225  EXPECT_EQ (true, (Constructible<HavePerfectForwarding, int>));
226 
227  // DefaultConstructible
228  EXPECT_EQ (false, (DefaultConstructible<void>));
229  EXPECT_EQ (true, (DefaultConstructible<void*>));
230  EXPECT_EQ (false, (DefaultConstructible<int&>));
231  EXPECT_EQ (true, (DefaultConstructible<Base>));
232  EXPECT_EQ (true, (DefaultConstructible<Derived1>));
233  EXPECT_EQ (false, (DefaultConstructible<HaveOnlyCopy>));
234  EXPECT_EQ (false, (DefaultConstructible<HaveOnlyMove>));
235  EXPECT_EQ (false, (DefaultConstructible<HavePerfectForwarding>));
236 
237  // MoveConstructible
238  EXPECT_EQ (false, (MoveConstructible<void>));
239  EXPECT_EQ (true, (MoveConstructible<void*>));
240  EXPECT_EQ (true, (MoveConstructible<Base>));
241  EXPECT_EQ (true, (MoveConstructible<Derived1>));
242  EXPECT_EQ (true, (MoveConstructible<HaveOnlyMove>));
243  EXPECT_EQ (false, (MoveConstructible<HaveOnlyCopy>));
244  EXPECT_EQ (true, (MoveConstructible<HaveCopyAndMove>));
245  EXPECT_EQ (true , (MoveConstructible<HavePerfectForwarding>));
246 
247  // CopyConstructible
248  EXPECT_EQ (false, (CopyConstructible<void>));
249  EXPECT_EQ (true, (CopyConstructible<void*>));
250  EXPECT_EQ (true, (CopyConstructible<Base>));
251  EXPECT_EQ (true, (CopyConstructible<Derived1>));
252  EXPECT_EQ (false, (CopyConstructible<HaveOnlyMove>));
253  EXPECT_EQ (false, (CopyConstructible<HaveOnlyCopy>));
254  EXPECT_EQ (true, (CopyConstructible<HaveCopyAndMove>));
255  EXPECT_EQ (true , (CopyConstructible<HavePerfectForwarding>));
256  }
257 
258  TEST(TConcepts, MovableCopyable) {
259  // Movable
260  EXPECT_EQ (false, (Movable<void>));
261  EXPECT_EQ (true, (Movable<int>));
262  EXPECT_EQ (true, (Movable<Base>));
263  EXPECT_EQ (true, (Movable<Derived1>));
264  EXPECT_EQ (true, (Movable<HaveOnlyMove>));
265  EXPECT_EQ (false, (Movable<HaveOnlyCopy>));
266  EXPECT_EQ (true, (Movable<HaveCopyAndMove>));
267  EXPECT_EQ (true , (Movable<HavePerfectForwarding>));
268 
269  // Copyable
270  EXPECT_EQ (false, (Copyable<void>));
271  EXPECT_EQ (true, (Copyable<int>));
272  EXPECT_EQ (true, (Copyable<Base>));
273  EXPECT_EQ (true, (Copyable<Derived1>));
274  EXPECT_EQ (false, (Copyable<HaveOnlyMove>));
275  EXPECT_EQ (false, (Copyable<HaveOnlyCopy>));
276  EXPECT_EQ (true, (Copyable<HaveCopyAndMove>));
277  EXPECT_EQ (true , (Copyable<HavePerfectForwarding>));
278  }
279 
280  TEST(TConcepts, Boolean) {
281  // Boolean
282  EXPECT_EQ (false, (Boolean<void>));
283  EXPECT_EQ (true, (Boolean<bool>));
284  EXPECT_EQ (true, (Boolean<int>));
285  EXPECT_EQ (true, (Boolean<double>));
286  EXPECT_EQ (true, (Boolean<std::true_type>));
287  EXPECT_EQ (true, (Boolean<meta::true_>));
288  EXPECT_EQ (false, (Boolean<Empty>));
289  }
290 
291  TEST(TConcepts, Comparable) {
292  // EqualityComparable
293  EXPECT_EQ (false, (EqualityComparable<void>));
294  EXPECT_EQ (true, (EqualityComparable<bool>));
295  EXPECT_EQ (true, (EqualityComparable<int>));
296  EXPECT_EQ (false, (EqualityComparable<Empty>));
297  EXPECT_EQ (true, (EqualityComparable<A>));
298 
299  // EqualityComparableWith
300  EXPECT_EQ (false, (EqualityComparableWith<void, bool>));
301  EXPECT_EQ (false, (EqualityComparableWith<void, void>));
302  EXPECT_EQ (true, (EqualityComparableWith<bool, bool>));
303  EXPECT_EQ (true, (EqualityComparableWith<int, int>));
304  EXPECT_EQ (true, (EqualityComparableWith<int, bool>));
305  EXPECT_EQ (false, (EqualityComparableWith<Empty, Empty>));
306  EXPECT_EQ (false, (EqualityComparableWith<int, Empty>));
307  EXPECT_EQ (true, (EqualityComparableWith<A, A>));
308  EXPECT_EQ (false, (EqualityComparableWith<A, B>));
309 
310  // StrictTotallyOrdered
311  EXPECT_EQ (false, (StrictTotallyOrdered<void>));
312  EXPECT_EQ (true, (StrictTotallyOrdered<bool>));
313  EXPECT_EQ (true, (StrictTotallyOrdered<int>));
314  EXPECT_EQ (true, (StrictTotallyOrdered<double>));
315  EXPECT_EQ (false, (StrictTotallyOrdered<Empty>));
316  EXPECT_EQ (false, (StrictTotallyOrdered<A>));
317  EXPECT_EQ (true, (StrictTotallyOrdered<B>));
318 
319  // StrictTotallyOrderedWith
320  EXPECT_EQ (false, (StrictTotallyOrderedWith<void, void>));
321  EXPECT_EQ (false, (StrictTotallyOrderedWith<int, void>));
322  EXPECT_EQ (true, (StrictTotallyOrderedWith<bool, bool>));
323  EXPECT_EQ (true, (StrictTotallyOrderedWith<int, double>));
324  EXPECT_EQ (false, (StrictTotallyOrderedWith<int, Empty>));
325  EXPECT_EQ (false, (StrictTotallyOrderedWith<Base, Derived1>));
326  EXPECT_EQ (false, (StrictTotallyOrderedWith<A, A>));
327  EXPECT_EQ (true, (StrictTotallyOrderedWith<B, B>));
328  EXPECT_EQ (false, (StrictTotallyOrderedWith<A, B>));
329  }
330 
331  TEST(TConcepts, Types) {
332  // Semiregular
333  EXPECT_EQ (false, (Semiregular<void>));
334  EXPECT_EQ (true, (Semiregular<int>));
335  EXPECT_EQ (true, (Semiregular<Empty>));
336  EXPECT_EQ (false, (Semiregular<HaveOnlyMove>));
337  EXPECT_EQ (false, (Semiregular<HaveOnlyCopy>));
338  EXPECT_EQ (false, (Semiregular<HaveCopyAndMove>));
339  EXPECT_EQ (false, (Semiregular<A>));
340  EXPECT_EQ (true, (Semiregular<B>));
341 
342  // Regular
343  EXPECT_EQ (false, (Regular<void>));
344  EXPECT_EQ (true, (Regular<int>));
345  EXPECT_EQ (true, (Regular<int*>));
346  EXPECT_EQ (false, (Regular<Empty>));
347  EXPECT_EQ (false, (Regular<HaveOnlyMove>));
348  EXPECT_EQ (false, (Regular<HaveOnlyCopy>));
349  EXPECT_EQ (false, (Regular<HaveCopyAndMove>));
350  EXPECT_EQ (false, (Regular<A>));
351  EXPECT_EQ (true, (Regular<B>));
352 
353  // Scalar
354  EXPECT_EQ (false, (Scalar<void>));
355  EXPECT_EQ (true, (Scalar<int>));
356  EXPECT_EQ (true, (Scalar<long*>));
357  EXPECT_EQ (false, (Scalar<A>));
358  EXPECT_EQ (false, (Scalar<B>));
359 
360  // Arithmetic
361  EXPECT_EQ (false, (Arithmetic<void>));
362  EXPECT_EQ (true, (Arithmetic<int>));
363  EXPECT_EQ (false, (Arithmetic<long*>));
364  EXPECT_EQ (false, (Arithmetic<A>));
365  EXPECT_EQ (false, (Arithmetic<B>));
366 
367  // FloatingPoint
368  EXPECT_EQ (false, (FloatingPoint<void>));
369  EXPECT_EQ (true, (FloatingPoint<float>));
370  EXPECT_EQ (true, (FloatingPoint<double>));
371  EXPECT_EQ (false, (FloatingPoint<int>));
372  EXPECT_EQ (false, (FloatingPoint<float*>));
373  EXPECT_EQ (false, (FloatingPoint<A>));
374  EXPECT_EQ (false, (FloatingPoint<B>));
375  }
376 
377  struct Inv {
378  void operator() (int) { };
379  void operator() () { };
380  };
381  struct Pred {
382  bool operator () (int) { return true; }
383  bool operator () (int, int) { return true; }
384  };
385  TEST(TConcepts, Callable) {
386  EXPECT_EQ (true, (Invocable<Inv, int>));
387  EXPECT_EQ (true, (Invocable<Inv>));
388  EXPECT_EQ (true, (Invocable<Inv, double>));
389  EXPECT_EQ (false, (Invocable<Inv, Empty>));
390 
391  EXPECT_EQ (true, (RegularInvocable<Inv, int>));
392 
393  EXPECT_EQ (false, (Predicate<Inv, int>));
394  EXPECT_EQ (true, (Predicate<Pred, int>));
395  EXPECT_EQ (false, (Predicate<Pred, Empty>));
396 
397  EXPECT_EQ (true, (Relation<Pred, int, int>));
398  EXPECT_EQ (true, (Relation<Pred, int, double>));
399  EXPECT_EQ (false, (Relation<Pred, Empty, int>));
400 
401  EXPECT_EQ (true, (StrictWeakOrder<Pred, int, int>));
402  EXPECT_EQ (false, (StrictWeakOrder<Pred, int, Empty>));
403  }
404 
405  struct Incr {
406  Incr& operator++() { return *this; }
407  Incr operator++(int) { return *this; }
408  };
409  int type_printer (int* i) { return *i; }
410  TEST(TConcepts, Iterators) {
411 
412 // type_printer(detail::try_ppI<Incr&>{});
413 // type_printer(detail::try_Ipp<Incr&>{});
414 // type_printer(meta::detected_t<detail::try_ppI, int>{});
415  EXPECT_EQ (true, (WeaklyIncrementable<int>));
416  EXPECT_EQ (false, (WeaklyIncrementable<void>));
417  EXPECT_EQ (false, (WeaklyIncrementable<meta::nil_>));
418  EXPECT_EQ (true, (WeaklyIncrementable<Incr>));
419  EXPECT_EQ (false, (WeaklyIncrementable<Incr&>));
420  }
421 }
422 
_utlConcept Swappable
Definition: stl.h:425
bool operator<=(const B &l, const B &r)
Definition: TConcepts.cpp:84
Include all meta library.
_utlConcept Assignable
Definition: stl.h:366
_utlConcept ConvertibleTo
Definition: stl.h:87
_utlConcept Same
Definition: stl.h:62
int type_printer(int *i)
Definition: TConcepts.cpp:409
bool operator!=(const A &l, const A &r)
Definition: TConcepts.cpp:70
integral_< int, v > int_
int_ type: integral constant wrapper for int
Definition: integral.h:98
_utlConcept CommonReference
Definition: stl.h:293
Concepts main include header.
_utlConcept DerivedFrom
Definition: stl.h:71
integral_< uint16_t, v > uint16_
uint16_ type: integral constant wrapper for uint16_t
Definition: integral.h:83
STL&#39;s core language concepts.
Definition: _1wire.h:30
bool operator<(const B &l, const B &r)
Definition: TConcepts.cpp:83
Incr operator++(int)
Definition: TConcepts.cpp:407
_utlConcept Integral
Definition: stl.h:340
bool operator>(const B &l, const B &r)
Definition: TConcepts.cpp:85
_utlConcept UnsignedIntegral
Definition: stl.h:352
_utlConcept Boolean
Definition: stl.h:551
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:16643
bool operator>=(const B &l, const B &r)
Definition: TConcepts.cpp:86
_utlConcept Constructible
Definition: stl.h:438
integral_< int16_t, v > int16_
int16_ type: integral constant wrapper for int16_t
Definition: integral.h:80
TEST(TConcepts, Same)
Definition: TConcepts.cpp:89
_utlConcept SignedIntegral
Definition: stl.h:346
bool operator==(const A &l, const A &r)
Definition: TConcepts.cpp:69