Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
value-type-binding-test.cpp
Go to the documentation of this file.
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"
22#include "lib/format-cout.hpp"
23#include "lib/meta/util.hpp"
24
25#include <memory>
26
27
28namespace lib {
29namespace meta{
30namespace test{
31
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;
47 typedef std::shared_ptr<T> pointer;
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
179
180
181}}} // namespace lib::meta::test
182
Automatically use custom string conversion in C++ stream output.
Simple and lightweight helpers for metaprogramming and type detection.
RefTraits< TY >::Reference reference
RefTraits< TY >::Value value_type
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
RefTraits< TY >::Pointer pointer
Type re-binding helper template for creating nested typedefs usable by custom containers and iterator...
string showType()
diagnostic type output, including const and similar adornments
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
Type re-binding helper template for custom containers and adapters.