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) Lumiera.org
5  2017, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
31 #include "lib/format-cout.hpp"
32 #include "lib/meta/util.hpp"
33 
34 #include <memory>
35 
36 
37 namespace lib {
38 namespace meta{
39 namespace test{
40 
41  using lib::test::showType;
42 
43 
44  namespace { // test fixture
45 
46  template<class T>
47  struct Outer
48  {
49  struct Inner
50  {
51  T val;
52  };
53 
54  typedef T value_type;
55  typedef Inner & reference;
57  };
58 
59  struct Space { };
60 
61  }//(end)fixture
62 
63 
64 
65 
66  /**********************************************************************************/
81  : public Test
82  {
83  void
84  run (Arg)
85  {
86  // verify the type diagnostics helper...
87  CHECK (showType<int >() == "int"_expect );
88  CHECK (showType<int& >() == "int&"_expect );
89  CHECK (showType<int&& >() == "int &&"_expect );
90  CHECK (showType<int const& >() == "int const&"_expect );
91  CHECK (showType<int const&& >() == "const int &&"_expect );
92  CHECK (showType<int * >() == "int *"_expect );
93  CHECK (showType<int const * >() == "const int *"_expect );
94  CHECK (showType<int const * const >() == "const int * const"_expect );
95  CHECK (showType<int const * &>() == "int const*&"_expect );
96  CHECK (showType<int const * const&>() == "int const* const&"_expect );
97 
98 
99  // Test fixture: the template Outer<T> provides nested value type bindings
100  CHECK (showType<Outer<Space>::value_type>() == "Space"_expect );
101  CHECK (showType<Outer<Space>::reference>() == "Outer<Space>::Inner&"_expect );
102  CHECK (showType<Outer<Space>::pointer>() == "shared_ptr<Space>"_expect );
103 
104 
105  // ...such nested type bindings will be picked up
106  CHECK (showType<ValueTypeBinding<Outer<Space>>::value_type>() == "Space"_expect );
107  CHECK (showType<ValueTypeBinding<Outer<Space>>::reference>() == "Outer<Space>::Inner&"_expect );
108  CHECK (showType<ValueTypeBinding<Outer<Space>>::pointer>() == "shared_ptr<Space>"_expect );
109 
110  CHECK (showType<ValueTypeBinding<Outer<short>>::value_type>() == "short"_expect );
111  CHECK (showType<ValueTypeBinding<Outer<short>>::reference>() == "Outer<short>::Inner&"_expect );
112  CHECK (showType<ValueTypeBinding<Outer<short>>::pointer>() == "shared_ptr<short>"_expect );
113 
114  // contrast this to a type without such nested bindings
115  CHECK (showType<ValueTypeBinding<Space>::value_type>() == "Space"_expect );
116  CHECK (showType<ValueTypeBinding<Space>::reference>() == "Space&"_expect );
117  CHECK (showType<ValueTypeBinding<Space>::pointer>() == "Space *"_expect );
118 
119  // when checking for nested bindings, reference will be stripped and just the binding returned as-is
120  CHECK (showType<ValueTypeBinding<Outer<Space>&>::_SrcType>() == "Outer<Space>"_expect ); // internal: this is the type probed for nested bindings
121  CHECK (showType<ValueTypeBinding<Outer<Space>&>::value_type>() == "Space"_expect );
122  CHECK (showType<ValueTypeBinding<Outer<Space>&>::reference>() == "Outer<Space>::Inner&"_expect );
123  CHECK (showType<ValueTypeBinding<Outer<Space>&>::pointer>() == "shared_ptr<Space>"_expect );
124 
125  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::_SrcType>() == "Outer<Space>"_expect ); // likewise for &&
126  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::value_type>() == "Space"_expect );
127  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::reference>() == "Outer<Space>::Inner&"_expect );
128  CHECK (showType<ValueTypeBinding<Outer<Space>&&>::pointer>() == "shared_ptr<Space>"_expect );
129 
130  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::value_type>() == "Space"_expect );
131  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::reference>() == "Outer<Space>::Inner&"_expect );
132  CHECK (showType<ValueTypeBinding<Outer<Space> const&>::pointer>() == "shared_ptr<Space>"_expect );
133 
134  // but a pointer counts as different, primitive type. No magic here
135  CHECK (showType<ValueTypeBinding< Outer<Space> * >::value_type>() == "Outer<Space> *"_expect );
136  CHECK (showType<ValueTypeBinding< Outer<Space> * >::reference>() == "Outer<Space>*&"_expect );
137  CHECK (showType<ValueTypeBinding< Outer<Space> * >::pointer>() == "Outer<Space>* *"_expect );
138 
139  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::value_type>() == "const Outer<Space> *"_expect );
140  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::reference>() == "Outer<Space> const*&"_expect );
141  CHECK (showType<ValueTypeBinding<const Outer<Space> * >::pointer>() == "Outer<Space> const* *"_expect );
142 
143  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::value_type>() == "const Outer<Space> * const"_expect );
144  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::reference>() == "Outer<Space> const* const&"_expect );
145  CHECK (showType<ValueTypeBinding<const Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
146 
147  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::value_type>() == "Outer<Space> * const"_expect );
148  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::reference>() == "Outer<Space>* const&"_expect );
149  CHECK (showType<ValueTypeBinding< Outer<Space> * const>::pointer>() == "Outer<Space> * const *"_expect );
150 
151  // yet for a type without nested type bindings: references are levelled
152  CHECK (showType<ValueTypeBinding<short>::value_type>() == "short"_expect );
153  CHECK (showType<ValueTypeBinding<short>::reference>() == "short&"_expect );
154  CHECK (showType<ValueTypeBinding<short>::pointer>() == "short *"_expect );
155 
156  CHECK (showType<ValueTypeBinding<short&>::value_type>() == "short"_expect );
157  CHECK (showType<ValueTypeBinding<short&>::reference>() == "short&"_expect );
158  CHECK (showType<ValueTypeBinding<short&>::pointer>() == "short *"_expect );
159 
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<short const&>::value_type>() == "const short"_expect );
165  CHECK (showType<ValueTypeBinding<short const&>::reference>() == "short const&"_expect );
166  CHECK (showType<ValueTypeBinding<short const&>::pointer>() == "const short *"_expect );
167 
168  //... but pointer types are not treated special in any way
169  CHECK (showType<ValueTypeBinding< short * >::value_type>() == "short *"_expect );
170  CHECK (showType<ValueTypeBinding< short * >::reference>() == "short*&"_expect );
171  CHECK (showType<ValueTypeBinding< short * >::pointer>() == "short* *"_expect );
172 
173  CHECK (showType<ValueTypeBinding<const short * >::value_type>() == "const short *"_expect );
174  CHECK (showType<ValueTypeBinding<const short * >::reference>() == "short const*&"_expect );
175  CHECK (showType<ValueTypeBinding<const short * >::pointer>() == "short const* *"_expect );
176 
177  CHECK (showType<ValueTypeBinding<const short * const>::value_type>() == "const short * const"_expect );
178  CHECK (showType<ValueTypeBinding<const short * const>::reference>() == "short const* const&"_expect );
179  CHECK (showType<ValueTypeBinding<const short * const>::pointer>() == "short * const *"_expect );
180 
181  CHECK (showType<ValueTypeBinding< short * const>::value_type>() == "short * const"_expect );
182  CHECK (showType<ValueTypeBinding< short * const>::reference>() == "short* const&"_expect );
183  CHECK (showType<ValueTypeBinding< short * const>::pointer>() == "short * const *"_expect );
184  }
185  };
186 
187  LAUNCHER (ValueTypeBinding_test, "unit common");
188 
189 
190 }}} // namespace lib::meta::test
191 
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:49
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.
Simple 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...