Lumiera  0.pre.03
»edit your freedom«
value-type-binding-test.cpp
1 /*
2  ValueTypeBinding(Test) - verify handling of value_type definitions on custom containers
3 
4  Copyright (C)
5  2017, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
22 #include "lib/format-cout.hpp"
23 #include "lib/meta/util.hpp"
24 
25 #include <memory>
26 
27 
28 namespace lib {
29 namespace meta{
30 namespace test{
31 
32  using lib::test::showType;
33 
34 
35  namespace { // test fixture
36 
37  template<class T>
38  struct Outer
39  {
40  struct Inner
41  {
42  T val;
43  };
44 
45  typedef T value_type;
46  typedef Inner & reference;
48  };
49 
50  struct Space { };
51 
52  }//(end)fixture
53 
54 
55 
56 
57  /**********************************************************************************/
72  : public Test
73  {
74  void
75  run (Arg)
76  {
77  // verify the type diagnostics helper...
78  CHECK (showType<int >() == "int"_expect );
79  CHECK (showType<int& >() == "int&"_expect );
80  CHECK (showType<int&& >() == "int &&"_expect );
81  CHECK (showType<int const& >() == "int const&"_expect );
82  CHECK (showType<int const&& >() == "const int &&"_expect );
83  CHECK (showType<int * >() == "int *"_expect );
84  CHECK (showType<int const * >() == "const int *"_expect );
85  CHECK (showType<int const * const >() == "const int * const"_expect );
86  CHECK (showType<int const * &>() == "int const*&"_expect );
87  CHECK (showType<int const * const&>() == "int const* const&"_expect );
88 
89 
90  // Test fixture: the template Outer<T> provides nested value type bindings
91  CHECK (showType<Outer<Space>::value_type>() == "Space"_expect );
92  CHECK (showType<Outer<Space>::reference>() == "Outer<Space>::Inner&"_expect );
93  CHECK (showType<Outer<Space>::pointer>() == "shared_ptr<Space>"_expect );
94 
95 
96  // ...such nested type bindings will be picked up
97  CHECK (showType<ValueTypeBinding<Outer<Space>>::value_type>() == "Space"_expect );
98  CHECK (showType<ValueTypeBinding<Outer<Space>>::reference>() == "Outer<Space>::Inner&"_expect );
99  CHECK (showType<ValueTypeBinding<Outer<Space>>::pointer>() == "shared_ptr<Space>"_expect );
100 
101  CHECK (showType<ValueTypeBinding<Outer<short>>::value_type>() == "short"_expect );
102  CHECK (showType<ValueTypeBinding<Outer<short>>::reference>() == "Outer<short>::Inner&"_expect );
103  CHECK (showType<ValueTypeBinding<Outer<short>>::pointer>() == "shared_ptr<short>"_expect );
104 
105  // contrast this to a type without such nested bindings
106  CHECK (showType<ValueTypeBinding<Space>::value_type>() == "Space"_expect );
107  CHECK (showType<ValueTypeBinding<Space>::reference>() == "Space&"_expect );
108  CHECK (showType<ValueTypeBinding<Space>::pointer>() == "Space *"_expect );
109 
110  // when checking for nested bindings, reference will be stripped and just the binding returned as-is
111  CHECK (showType<ValueTypeBinding<Outer<Space>&>::_SrcType>() == "Outer<Space>"_expect ); // internal: this is the type probed for nested bindings
112  CHECK (showType<ValueTypeBinding<Outer<Space>&>::value_type>() == "Space"_expect );
113  CHECK (showType<ValueTypeBinding<Outer<Space>&>::reference>() == "Outer<Space>::Inner&"_expect );
114  CHECK (showType<ValueTypeBinding<Outer<Space>&>::pointer>() == "shared_ptr<Space>"_expect );
115 
116  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::_SrcType>() == "Outer<Space>"_expect ); // likewise for &&
117  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::value_type>() == "Space"_expect );
118  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::reference>() == "Outer<Space>::Inner&"_expect );
119  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::pointer>() == "shared_ptr<Space>"_expect );
120 
121  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::value_type>() == "Space"_expect );
122  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::reference>() == "Outer<Space>::Inner&"_expect );
123  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::pointer>() == "shared_ptr<Space>"_expect );
124 
125  // but a pointer counts as different, primitive type. No magic here
126  CHECK (showType<ValueTypeBinding< Outer<Space> * >::value_type>() == "Outer<Space> *"_expect );
127  CHECK (showType<ValueTypeBinding< Outer<Space> * >::reference>() == "Outer<Space>*&"_expect );
128  CHECK (showType<ValueTypeBinding< Outer<Space> * >::pointer>() == "Outer<Space>* *"_expect );
129 
130  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::value_type>() == "const Outer<Space> *"_expect );
131  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::reference>() == "Outer<Space> const*&"_expect );
132  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::pointer>() == "Outer<Space> const* *"_expect );
133 
134  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::value_type>() == "const Outer<Space> * const"_expect );
135  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::reference>() == "Outer<Space> const* const&"_expect );
136  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
137 
138  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::value_type>() == "Outer<Space> * const"_expect );
139  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::reference>() == "Outer<Space>* const&"_expect );
140  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
141 
142  // yet for a type without nested type bindings: references are levelled
143  CHECK (showType<ValueTypeBinding<short>::value_type>() == "short"_expect );
144  CHECK (showType<ValueTypeBinding<short>::reference>() == "short&"_expect );
145  CHECK (showType<ValueTypeBinding<short>::pointer>() == "short *"_expect );
146 
147  CHECK (showType<ValueTypeBinding<short&>::value_type>() == "short"_expect );
148  CHECK (showType<ValueTypeBinding<short&>::reference>() == "short&"_expect );
149  CHECK (showType<ValueTypeBinding<short&>::pointer>() == "short *"_expect );
150 
151  CHECK (showType<ValueTypeBinding<short&&>::value_type>() == "short"_expect );
152  CHECK (showType<ValueTypeBinding<short&&>::reference>() == "short&"_expect );
153  CHECK (showType<ValueTypeBinding<short&&>::pointer>() == "short *"_expect );
154 
155  CHECK (showType<ValueTypeBinding<short const&>::value_type>() == "const short"_expect );
156  CHECK (showType<ValueTypeBinding<short const&>::reference>() == "short const&"_expect );
157  CHECK (showType<ValueTypeBinding<short const&>::pointer>() == "const short *"_expect );
158 
159  //... but pointer types are not treated special in any way
160  CHECK (showType<ValueTypeBinding< short * >::value_type>() == "short *"_expect );
161  CHECK (showType<ValueTypeBinding< short * >::reference>() == "short*&"_expect );
162  CHECK (showType<ValueTypeBinding< short * >::pointer>() == "short* *"_expect );
163 
164  CHECK (showType<ValueTypeBinding<const short * >::value_type>() == "const short *"_expect );
165  CHECK (showType<ValueTypeBinding<const short * >::reference>() == "short const*&"_expect );
166  CHECK (showType<ValueTypeBinding<const short * >::pointer>() == "short const* *"_expect );
167 
168  CHECK (showType<ValueTypeBinding<const short * const>::value_type>() == "const short * const"_expect );
169  CHECK (showType<ValueTypeBinding<const short * const>::reference>() == "short const* const&"_expect );
170  CHECK (showType<ValueTypeBinding<const short * const>::pointer>() == "short * const *"_expect );
171 
172  CHECK (showType<ValueTypeBinding< short * const>::value_type>() == "short * const"_expect );
173  CHECK (showType<ValueTypeBinding< short * const>::reference>() == "short* const&"_expect );
174  CHECK (showType<ValueTypeBinding< short * const>::pointer>() == "short * const *"_expect );
175  }
176  };
177 
178  LAUNCHER (ValueTypeBinding_test, "unit common");
179 
180 
181 }}} // namespace lib::meta::test
182 
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:40
Simple and lightweight helpers for metaprogramming and type detection.
Type re-binding helper template for custom containers and adapters.
Implementation namespace for support and library code.
Simplistic test class runner.
A collection of frequently used helper functions to support unit testing.
string showType()
diagnostic type output, including const and similar adornments
Type re-binding helper template for creating nested typedefs usable by custom containers and iterator...