MetaUtils_test.cc
Go to the documentation of this file.
1 /**
2  * @file MetaUtils_test.cc
3  * @brief Unit test for some of the utilities in MetaUtils.h
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date March 22, 2019
6  * @see `larcorealg/CoreUtils/MetaUtils.h`
7  */
8 
9 // Boost libraries
10 #define BOOST_TEST_MODULE ( MetaUtils_test )
11 #include <boost/test/unit_test.hpp>
12 
13 // LArSoft libraries
16 
17 // C/C++ standard libraries
18 #include <array>
19 #include <string>
20 #include <string_view>
21 #include <memory> // std::unique_ptr, std::shared_ptr
22 #include <type_traits>
23 
24 
25 //------------------------------------------------------------------------------
26 //--- static tests (would fail at compile time)
27 //------------------------------------------------------------------------------
28 // util::find_next_type_v
29 //------------------------------------------------------------------------------
30 static_assert(util::find_next_type_v<int, 0U, int, int, float> == 0U);
31 static_assert(util::find_next_type_v<float, 0U, int, int, float> == 2U);
32 static_assert(util::find_next_type_v<const float, 0U, int, int, float> == 3U);
33 static_assert(util::find_next_type_v<int, 1U, int, int, float> == 1U);
34 static_assert(util::find_next_type_v<float, 1U, int, int, float> == 2U);
35 static_assert(util::find_next_type_v<const float, 1U, int, int, float> == 3U);
36 static_assert(util::find_next_type_v<int, 2U, int, int, float> == 3U);
37 static_assert(util::find_next_type_v<float, 2U, int, int, float> == 2U);
38 static_assert(util::find_next_type_v<const float, 2U, int, int, float> == 3U);
39 static_assert(util::find_next_type_v<int, 3U, int, int, float> == 3U);
40 static_assert(util::find_next_type_v<float, 3U, int, int, float> == 3U);
41 static_assert(util::find_next_type_v<const float, 3U, int, int, float> == 3U);
42 static_assert(util::find_next_type_v<int, 4U, int, int, float> == 3U);
43 static_assert(util::find_next_type_v<float, 4U, int, int, float> == 3U);
44 static_assert(util::find_next_type_v<const float, 4U, int, int, float> == 3U);
45 
46 
47 //------------------------------------------------------------------------------
48 // util::find_type_v
49 //------------------------------------------------------------------------------
50 static_assert(util::find_type_v<int, int, int, float> == 0U);
51 static_assert(util::find_type_v<float, int, int, float> == 2U);
52 static_assert(util::find_type_v<const float, int, int, float> == 3U);
53 
54 
55 //------------------------------------------------------------------------------
56 // util::is_any_of_v
57 //------------------------------------------------------------------------------
58 static_assert( util::is_any_of_v<int, int, int, float>);
59 static_assert( util::is_any_of_v<float, int, int, float>);
60 static_assert(!util::is_any_of_v<const float, int, int, float>);
61 
62 
63 //------------------------------------------------------------------------------
64 // util::is_same_decay_v
65 //------------------------------------------------------------------------------
66 static_assert( util::is_same_decay_v<int, int>);
67 static_assert( util::is_same_decay_v<int const, int>);
68 static_assert( util::is_same_decay_v<int const, int&>);
69 static_assert( util::is_same_decay_v<int const, int volatile&>);
70 static_assert(!util::is_same_decay_v<int const, float&>);
71 static_assert(!util::is_same_decay_v<unsigned int const, int volatile&>);
72 
73 
74 //------------------------------------------------------------------------------
75 // util::is_instance_of_v
76 //------------------------------------------------------------------------------
77 static_assert( util::is_instance_of_v<std::unique_ptr, std::unique_ptr<int>>);
78 static_assert( util::is_instance_of_v<std::unique_ptr, std::unique_ptr<int> const&>);
79 static_assert(!util::is_instance_of_v<std::unique_ptr, std::shared_ptr<int>>);
80 static_assert(!util::is_instance_of_v<std::unique_ptr, int>);
81 
82 
83 //------------------------------------------------------------------------------
84 // util::is_character_type_v
85 //------------------------------------------------------------------------------
86 static_assert( util::is_character_type_v<char>);
87 static_assert( util::is_character_type_v<signed char>);
88 static_assert( util::is_character_type_v<unsigned char>);
89 static_assert( util::is_character_type_v<wchar_t>);
90 static_assert(!util::is_character_type_v<short int>);
91 static_assert(!util::is_character_type_v<std::string>);
92 
93 
94 //------------------------------------------------------------------------------
95 // util::is_string_type_v
96 //------------------------------------------------------------------------------
97 static_assert(!util::is_string_type_v<short int>);
98 static_assert(!util::is_string_type_v<std::vector<int>>);
99 static_assert( util::is_string_type_v<std::vector<wchar_t>>);
100 static_assert( util::is_string_type_v<std::string>);
101 static_assert( util::is_string_type_v<std::string_view>);
102 static_assert( util::is_string_type_v<char const*>);
103 static_assert( util::is_string_type_v<char const*&>);
104 static_assert( util::is_string_type_v<wchar_t*>);
105 static_assert( util::is_string_type_v<char[]>);
106 static_assert( util::is_string_type_v<wchar_t const[10U]>);
107 
108 
109 //------------------------------------------------------------------------------
110 // util::is_basic_string_type_v
111 //------------------------------------------------------------------------------
112 static_assert(!util::is_basic_string_type_v<short int>);
113 static_assert(!util::is_basic_string_type_v<std::vector<int>>);
114 static_assert(!util::is_basic_string_type_v<std::vector<wchar_t>>);
115 static_assert( util::is_basic_string_type_v<std::string>);
116 static_assert(!util::is_basic_string_type_v<std::string_view>);
117 static_assert( util::is_basic_string_type_v<std::wstring>);
118 static_assert(!util::is_basic_string_type_v<std::wstring_view>);
119 static_assert( util::is_basic_string_type_v<std::string const&>);
120 static_assert(!util::is_basic_string_type_v<std::string_view const&>);
121 static_assert( util::is_basic_string_type_v<std::wstring const&>);
122 static_assert(!util::is_basic_string_type_v<std::wstring_view const&>);
123 static_assert(!util::is_basic_string_type_v<char const*>);
124 static_assert(!util::is_basic_string_type_v<char const*&>);
125 static_assert(!util::is_basic_string_type_v<wchar_t*>);
126 static_assert(!util::is_basic_string_type_v<char[]>);
127 static_assert(!util::is_basic_string_type_v<wchar_t const[10U]>);
128 
129 
130 //------------------------------------------------------------------------------
131 // util::is_basic_string_type_v
132 //------------------------------------------------------------------------------
133 static_assert(!util::is_basic_string_view_type_v<short int>);
134 static_assert(!util::is_basic_string_view_type_v<std::vector<int>>);
135 static_assert(!util::is_basic_string_view_type_v<std::vector<wchar_t>>);
136 static_assert(!util::is_basic_string_view_type_v<std::string>);
137 static_assert( util::is_basic_string_view_type_v<std::string_view>);
138 static_assert(!util::is_basic_string_view_type_v<std::wstring>);
139 static_assert( util::is_basic_string_view_type_v<std::wstring_view>);
140 static_assert(!util::is_basic_string_view_type_v<std::string const&>);
141 static_assert( util::is_basic_string_view_type_v<std::string_view const&>);
142 static_assert(!util::is_basic_string_view_type_v<std::wstring const&>);
143 static_assert( util::is_basic_string_view_type_v<std::wstring_view const&>);
144 static_assert(!util::is_basic_string_view_type_v<char const*>);
145 static_assert(!util::is_basic_string_view_type_v<char const*&>);
146 static_assert(!util::is_basic_string_view_type_v<wchar_t*>);
147 static_assert(!util::is_basic_string_view_type_v<char[]>);
148 static_assert(!util::is_basic_string_view_type_v<wchar_t const[10U]>);
149 
150 
151 //------------------------------------------------------------------------------
152 // util::is_STLarray_v
153 //------------------------------------------------------------------------------
154 
155 static_assert(!util::is_STLarray_v<int>);
156 static_assert(!util::is_STLarray_v<int[3]>);
157 static_assert( util::is_STLarray_v<std::array<int, 3>>);
158 
159 
160 //------------------------------------------------------------------------------
161 // util::is_reference_wrapper_v
162 //------------------------------------------------------------------------------
163 
164 static_assert(!util::is_reference_wrapper_v<int>);
165 static_assert( util::is_reference_wrapper_v<std::reference_wrapper<int>>);
166 static_assert( util::is_reference_wrapper_v<std::reference_wrapper<int> const&>);
167 
168 
169 //------------------------------------------------------------------------------
170 // util::is_unique_ptr_v
171 //------------------------------------------------------------------------------
172 
173 static_assert(!util::is_unique_ptr_v<int>);
174 static_assert(!util::is_unique_ptr_v<int*>);
175 static_assert(!util::is_unique_ptr_v<int const*>);
176 static_assert( util::is_unique_ptr_v<std::unique_ptr<int>>);
177 static_assert( util::is_unique_ptr_v<std::unique_ptr<int> const>);
178 static_assert( util::is_unique_ptr_v<std::unique_ptr<int> const&>);
179 static_assert( util::is_unique_ptr_v<std::unique_ptr<int const>&>);
180 
181 
182 //------------------------------------------------------------------------------
183 // util::with_const_as_t
184 //------------------------------------------------------------------------------
185 
186 // simple type
187 static_assert(std::is_same_v<util::with_const_as_t<double , int >, double >);
188 static_assert(std::is_same_v<util::with_const_as_t<double const, int >, double >);
189 static_assert(std::is_same_v<util::with_const_as_t<double , int const>, double const>);
190 static_assert(std::is_same_v<util::with_const_as_t<double const, int const>, double const>);
191 static_assert(std::is_same_v<util::with_const_as_t<double volatile , int >, double volatile >);
192 static_assert(std::is_same_v<util::with_const_as_t<double volatile const, int >, double volatile >);
193 static_assert(std::is_same_v<util::with_const_as_t<double volatile , int const>, double volatile const>);
194 static_assert(std::is_same_v<util::with_const_as_t<double volatile const, int const>, double volatile const>);
195 
196 // l-value reference type
197 static_assert(std::is_same_v<util::with_const_as_t<double &, int >, double &>);
198 static_assert(std::is_same_v<util::with_const_as_t<double const&, int >, double &>);
199 static_assert(std::is_same_v<util::with_const_as_t<double &, int const>, double const&>);
200 static_assert(std::is_same_v<util::with_const_as_t<double const&, int const>, double const&>);
201 static_assert(std::is_same_v<util::with_const_as_t<double volatile &, int >, double volatile &>);
202 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&, int >, double volatile &>);
203 static_assert(std::is_same_v<util::with_const_as_t<double volatile &, int const>, double volatile const&>);
204 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&, int const>, double volatile const&>);
205 
206 // r-value reference type
207 static_assert(std::is_same_v<util::with_const_as_t<double &&, int >, double &&>);
208 static_assert(std::is_same_v<util::with_const_as_t<double const&&, int >, double &&>);
209 static_assert(std::is_same_v<util::with_const_as_t<double &&, int const>, double const&&>);
210 static_assert(std::is_same_v<util::with_const_as_t<double const&&, int const>, double const&&>);
211 static_assert(std::is_same_v<util::with_const_as_t<double volatile &&, int >, double volatile &&>);
212 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&&, int >, double volatile &&>);
213 static_assert(std::is_same_v<util::with_const_as_t<double volatile &&, int const>, double volatile const&&>);
214 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&&, int const>, double volatile const&&>);
215 
216 
217 // simple type (key is reference)
218 static_assert(std::is_same_v<util::with_const_as_t<double , int &>, double >);
219 static_assert(std::is_same_v<util::with_const_as_t<double const, int &>, double >);
220 static_assert(std::is_same_v<util::with_const_as_t<double , int const&>, double const>);
221 static_assert(std::is_same_v<util::with_const_as_t<double const, int const&>, double const>);
222 static_assert(std::is_same_v<util::with_const_as_t<double volatile , int &>, double volatile >);
223 static_assert(std::is_same_v<util::with_const_as_t<double volatile const, int &>, double volatile >);
224 static_assert(std::is_same_v<util::with_const_as_t<double volatile , int const&>, double volatile const>);
225 static_assert(std::is_same_v<util::with_const_as_t<double volatile const, int const&>, double volatile const>);
226 
227 // l-value reference type
228 static_assert(std::is_same_v<util::with_const_as_t<double &, int &>, double &>);
229 static_assert(std::is_same_v<util::with_const_as_t<double const&, int &>, double &>);
230 static_assert(std::is_same_v<util::with_const_as_t<double &, int const&>, double const&>);
231 static_assert(std::is_same_v<util::with_const_as_t<double const&, int const&>, double const&>);
232 static_assert(std::is_same_v<util::with_const_as_t<double volatile &, int &>, double volatile &>);
233 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&, int &>, double volatile &>);
234 static_assert(std::is_same_v<util::with_const_as_t<double volatile &, int const&>, double volatile const&>);
235 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&, int const&>, double volatile const&>);
236 
237 // r-value reference type
238 static_assert(std::is_same_v<util::with_const_as_t<double &&, int &>, double &&>);
239 static_assert(std::is_same_v<util::with_const_as_t<double const&&, int &>, double &&>);
240 static_assert(std::is_same_v<util::with_const_as_t<double &&, int const&>, double const&&>);
241 static_assert(std::is_same_v<util::with_const_as_t<double const&&, int const&>, double const&&>);
242 static_assert(std::is_same_v<util::with_const_as_t<double volatile &&, int &>, double volatile &&>);
243 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&&, int &>, double volatile &&>);
244 static_assert(std::is_same_v<util::with_const_as_t<double volatile &&, int const&>, double volatile const&&>);
245 static_assert(std::is_same_v<util::with_const_as_t<double volatile const&&, int const&>, double volatile const&&>);
246 
247 //------------------------------------------------------------------------------
248 //--- util::strip_referenceness_type
249 //------------------------------------------------------------------------------
250 static_assert(std::is_same_v<util::strip_referenceness_t<int >, int >);
251 static_assert(std::is_same_v<util::strip_referenceness_t<int const >, int const>);
252 static_assert(std::is_same_v<util::strip_referenceness_t<int const& >, int const>);
253 static_assert(std::is_same_v<util::strip_referenceness_t<int &&>, int >);
254 static_assert(std::is_same_v<util::strip_referenceness_t<std::reference_wrapper<int > >, int >);
255 static_assert(std::is_same_v<util::strip_referenceness_t<std::reference_wrapper<int > const& >, int >);
256 static_assert(std::is_same_v<util::strip_referenceness_t<std::reference_wrapper<std::reference_wrapper<int>> >, int >);
257 
258 
259 //------------------------------------------------------------------------------
260 //--- util::lvalue_reference_into_wrapper_type
261 //------------------------------------------------------------------------------
262 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int >, int >);
263 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int const >, int const >);
264 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int & >, std::reference_wrapper<int > >);
265 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int const & >, std::reference_wrapper<int const> >);
266 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int &&>, int >);
267 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t< int const &&>, int const >);
268 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int > >, std::reference_wrapper<int > >);
269 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int > const >, std::reference_wrapper<int > const>);
270 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int const> >, std::reference_wrapper<int const> >);
271 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int const> const >, std::reference_wrapper<int const> const>);
272 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int > & >, std::reference_wrapper<int > >);
273 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int > const& >, std::reference_wrapper<int > const>);
274 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int const> & >, std::reference_wrapper<int const> >);
275 static_assert(std::is_same_v<util::lvalue_reference_into_wrapper_t<std::reference_wrapper<int const> const& >, std::reference_wrapper<int const> const>);
276 
277 
278 //------------------------------------------------------------------------------
280 
281  int v;
282  int& ref = v;
283  int const& cref = v;
284  auto refw = std::ref(v);
285  auto crefw = std::cref(v);
286 
287  BOOST_TEST(util::referenced_address(ref ) == std::addressof(v));
288  BOOST_TEST(util::referenced_address(cref ) == std::addressof(v));
289  BOOST_TEST(util::referenced_address(refw ) == std::addressof(v));
290  BOOST_TEST(util::referenced_address(crefw) == std::addressof(v));
291 
292 } // referenced_address_test()
293 
294 
295 //------------------------------------------------------------------------------
297 
298  /*
299  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
300  * std::vector<int> data(4U, 0);
301  * std::vector<int const*> dataPtr;
302  * std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtr),
303  * util::reference_addresser());
304  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305  */
306 
307  std::vector<int> data(4U, 0);
308  std::vector<int const*> dataPtr;
309  std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtr),
311 
312  // test
313  for (auto&& [ data, dataPtr ]: util::zip(data, dataPtr)) {
314  BOOST_TEST(dataPtr == &data);
315  } // for
316 
317 } // referenced_addresser_documentation_testreferenced_addresser_documentation_test()
318 
319 
320 //------------------------------------------------------------------------------
322 
323  int obj = 1;
324  int & ref = obj;
325  int const& cref = obj;
326  auto refw = std::ref(obj);
327  auto crefw = std::cref(obj);
328 
329  decltype(auto) ref_obj = util::lvalue_reference_into_wrapper(obj );
330  decltype(auto) ref_ref = util::lvalue_reference_into_wrapper(ref );
331  decltype(auto) ref_cref = util::lvalue_reference_into_wrapper(cref );
332  decltype(auto) ref_refw = util::lvalue_reference_into_wrapper(refw );
333  decltype(auto) ref_crefw = util::lvalue_reference_into_wrapper(crefw);
334 
335  // since we have already verified the correctness of
336  // util::lvalue_reference_into_wrapper_t<>, we just check for consistency:
337  static_assert(std::is_same_v<decltype(ref_obj ), util::lvalue_reference_into_wrapper_t<int& >>);
338  static_assert(std::is_same_v<decltype(ref_ref ), util::lvalue_reference_into_wrapper_t<decltype(ref )>>);
339  static_assert(std::is_same_v<decltype(ref_cref ), util::lvalue_reference_into_wrapper_t<decltype(cref )>>);
340  static_assert(std::is_same_v<decltype(ref_refw ), util::lvalue_reference_into_wrapper_t<decltype(refw )>>);
341  static_assert(std::is_same_v<decltype(ref_crefw), util::lvalue_reference_into_wrapper_t<decltype(crefw)>>);
342 
343  BOOST_TEST(util::referenced_address(ref_obj ) == util::referenced_address(obj));
344  BOOST_TEST(util::referenced_address(ref_ref ) == util::referenced_address(obj));
345  BOOST_TEST(util::referenced_address(ref_cref ) == util::referenced_address(obj));
346  BOOST_TEST(util::referenced_address(ref_refw ) == util::referenced_address(obj));
347  BOOST_TEST(util::referenced_address(ref_crefw) == util::referenced_address(obj));
348 
349 } // lvalue_reference_into_wrapper_test()
350 
351 
352 //------------------------------------------------------------------------------
353 
354 BOOST_AUTO_TEST_CASE(ReferencesTestCase) {
355 
359 
360 } // BOOST_AUTO_TEST_CASE(ReferencesTestCase)
361 
362 //------------------------------------------------------------------------------
constexpr bool is_string_type_v
Whether type T is a character string type (see util::is_string_type).
Definition: MetaUtils.h:466
Definition of util::zip().
typename strip_referenceness_type< T >::type strip_referenceness_t
The type T stripped of all known reference types.
Definition: MetaUtils.h:574
Functor applying the proper referenced_address() function.
Definition: MetaUtils.h:609
Basic C++ metaprogramming utilities.
constexpr bool is_basic_string_type_v
Definition: MetaUtils.h:483
void referenced_addresser_documentation_test()
typename with_const_as< Base, Key >::type with_const_as_t
The type Base, plus the constantness as in Key.
Definition: MetaUtils.h:549
constexpr bool is_reference_wrapper_v
A constant describing whether the specified type is a std::reference_wrapper.
Definition: MetaUtils.h:411
constexpr bool is_basic_string_view_type_v
Definition: MetaUtils.h:501
void referenced_address_test()
constexpr bool is_unique_ptr_v
A constant describing whether the specified type is a std::unique_ptr.
Definition: MetaUtils.h:430
void lvalue_reference_into_wrapper_test()
auto lvalue_reference_into_wrapper(T &&obj)
Converts a l-value reference object into a std::reference_wrapper.
Definition: MetaUtils.h:660
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
auto referenced_address(Ref &&ref)
Returns the address of the referenced object.
Definition: MetaUtils.h:1013
constexpr bool is_STLarray_v
A constant describing whether the specified type is a STL array.
Definition: MetaUtils.h:392
BOOST_AUTO_TEST_CASE(ReferencesTestCase)
typename lvalue_reference_into_wrapper_type< T >::type lvalue_reference_into_wrapper_t
The type T stripped of all known reference types.
Definition: MetaUtils.h:645
constexpr bool is_instance_of_v
Definition: MetaUtils.h:374