ContainerMeta_test.cc
Go to the documentation of this file.
1 /**
2  * @file ContainerMeta_test.cc
3  * @brief Unit test for some of the utilities in `ContainerMeta.h`
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date March 25, 2019
6  * @see `larcorealg/CoreUtils/ContainerMeta.h`
7  */
8 
9 // Boost libraries
10 #define BOOST_TEST_MODULE ( ContainerMeta_test )
11 #include <boost/test/unit_test.hpp>
12 
13 // LArSoft libraries
15 
16 // C/C++ standard libraries
17 #include <list>
18 #include <memory> // std::unique_ptr<>
19 #include <functional> // std::reference_wrapper
20 #include <type_traits>
21 
22 
23 //------------------------------------------------------------------------------
24 //--- static tests (would fail at compile time)
25 //------------------------------------------------------------------------------
26 struct O {
27  int value = 0;
28 };
29 
30 static_assert(std::is_same_v<util::collection_value_t <std::list<O > >, O >);
31 static_assert(std::is_same_v<util::collection_value_t <std::list<O * > >, O * >);
32 static_assert(std::is_same_v<util::collection_value_t <std::list<O const* > >, O const* >);
33 
34 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O > >, O &>);
35 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O * > >, O * &>);
36 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O const* > >, O const* &>);
37 
38 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O > >, O const&>);
39 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O * > >, O * const&>);
40 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O const* > >, O const* const&>);
41 
42 static_assert(std::is_same_v<util::collection_value_t <std::list<O > const>, O >);
43 static_assert(std::is_same_v<util::collection_value_t <std::list<O * > const>, O * >);
44 static_assert(std::is_same_v<util::collection_value_t <std::list<O const* > const>, O const* >);
45 
46 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O > const>, O const&>);
47 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O * > const>, O * const&>);
48 static_assert(std::is_same_v<util::collection_value_access_t <std::list<O const* > const>, O const* const&>);
49 
50 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O > const>, O const&>);
51 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O * > const>, O * const&>);
52 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::list<O const* > const>, O const* const&>);
53 
54 //
55 // std::reference_wrapper content
56 //
57 static_assert(std::is_same_v<util::collection_value_t <std::list<std::reference_wrapper<O >> >, O >);
58 static_assert(std::is_same_v<util::collection_value_t <std::list<std::reference_wrapper<O >> const>, O >);
59 static_assert(std::is_same_v<util::collection_value_t <std::list<std::reference_wrapper<O const>> >, O const >);
60 static_assert(std::is_same_v<util::collection_value_t <std::list<std::reference_wrapper<O const>> const>, O const >);
61 
62 //
63 // std::reference_wrapper container
64 //
65 static_assert(std::is_same_v<util::collection_value_t < std::list<O >& >, O >);
66 static_assert(std::is_same_v<util::collection_value_t < std::list<O > const&>, O >);
67 static_assert(std::is_same_v<util::collection_value_t <std::reference_wrapper<std::list<O >> >, O >);
68 static_assert(std::is_same_v<util::collection_value_t <std::reference_wrapper<std::list<O >> &>, O >);
69 static_assert(std::is_same_v<util::collection_value_t <std::reference_wrapper<std::list<O >>const&>, O >);
70 static_assert(std::is_same_v<util::collection_value_t <std::reference_wrapper<std::list<O> const>const&>, O >);
71 
72 static_assert(std::is_same_v<util::collection_value_access_t < std::list<O >& >, O &>);
73 static_assert(std::is_same_v<util::collection_value_access_t < std::list<O > const&>, O const&>);
74 static_assert(std::is_same_v<util::collection_value_access_t <std::reference_wrapper<std::list<O >> >, O &>);
75 static_assert(std::is_same_v<util::collection_value_access_t <std::reference_wrapper<std::list<O >> &>, O &>);
76 static_assert(std::is_same_v<util::collection_value_access_t <std::reference_wrapper<std::list<O >>const&>, O &>);
77 static_assert(std::is_same_v<util::collection_value_access_t <std::reference_wrapper<std::list<O> const>const&>, O const&>);
78 
79 static_assert(std::is_same_v<util::collection_value_constant_access_t< std::list<O >& >, O const&>);
80 static_assert(std::is_same_v<util::collection_value_constant_access_t< std::list<O > const&>, O const&>);
81 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::reference_wrapper<std::list<O >> >, O const&>);
82 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::reference_wrapper<std::list<O >> &>, O const&>);
83 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::reference_wrapper<std::list<O >>const&>, O const&>);
84 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::reference_wrapper<std::list<O> const>const&>, O const&>);
85 
86 //
87 // C array container
88 //
89 static_assert(std::is_same_v<util::collection_value_t <O *>, O >);
90 static_assert(std::is_same_v<util::collection_value_access_t <O *>, O &>);
91 static_assert(std::is_same_v<util::collection_value_constant_access_t<O *>, O const&>);
92 
93 static_assert(std::is_same_v<util::collection_value_t <O const*>, O const >);
94 static_assert(std::is_same_v<util::collection_value_access_t <O const*>, O const&>);
95 static_assert(std::is_same_v<util::collection_value_constant_access_t<O const*>, O const&>);
96 
97 static_assert(std::is_same_v<util::collection_value_t <O[10U] >, O >);
98 static_assert(std::is_same_v<util::collection_value_access_t <O[10U] >, O &>);
99 static_assert(std::is_same_v<util::collection_value_constant_access_t<O[10U] >, O const&>);
100 
101 static_assert(std::is_same_v<util::collection_value_t <std::unique_ptr<O >>, O >);
102 static_assert(std::is_same_v<util::collection_value_access_t <std::unique_ptr<O >>, O &>);
103 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::unique_ptr<O >>, O const&>);
104 
105 static_assert(std::is_same_v<util::collection_value_t <std::unique_ptr<O const>>, O const >);
106 static_assert(std::is_same_v<util::collection_value_access_t <std::unique_ptr<O const>>, O const&>);
107 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::unique_ptr<O const>>, O const&>);
108 
109 static_assert(std::is_same_v<util::collection_value_t <std::unique_ptr<O[10U] >>, O [10U]>);
110 static_assert(std::is_same_v<util::collection_value_access_t <std::unique_ptr<O[10U] >>, O(&) [10U]>);
111 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::unique_ptr<O[10U] >>, O const(&)[10U]>);
112 
113 static_assert(std::is_same_v<util::collection_value_t <std::unique_ptr<O[] >>, O >);
114 static_assert(std::is_same_v<util::collection_value_access_t <std::unique_ptr<O[] >>, O &>);
115 static_assert(std::is_same_v<util::collection_value_constant_access_t<std::unique_ptr<O[] >>, O const&>);
116 
117 //
118 // util::collection_reference_t
119 //
120 static_assert(std::is_same_v<util::collection_reference_t< std::list<O> >, std::reference_wrapper<std::list<O> >>);
121 static_assert(std::is_same_v<util::collection_reference_t< std::list<O>& >, std::reference_wrapper<std::list<O> >>);
122 static_assert(std::is_same_v<util::collection_reference_t<std::reference_wrapper<std::list<O>> >, std::reference_wrapper<std::list<O> >>);
123 static_assert(std::is_same_v<util::collection_reference_t< O* >, O* >);
124 static_assert(std::is_same_v<util::collection_reference_t< O const* >, O const* >);
125 static_assert(std::is_same_v<util::collection_reference_t< O const* &>, O const* >);
126 static_assert(std::is_same_v<util::collection_reference_t< O const* const&>, O const* >);
127 static_assert(std::is_same_v<util::collection_reference_t< O[10U] >, O* >);
128 
129 
130 //------------------------------------------------------------------------------
132 
133  /*
134  * `std::unique_ptr<T[N]>` is a strange beast which really deals with pointers
135  * to whole C arrays (`T(*)[N]`).
136  * It should be understood that this is not the same as `T*`
137  */
138  constexpr std::size_t Size = 10U;
139 
140  // BUG the double brace syntax is required to work around clang bug 21629
141  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
142  std::list<O> list {{ O{} }};
143  O array [Size];
144  O* ptr = array;
145  O const* cptr = ptr;
146  O const* const cptrc = ptr;
147  O const* const& cptrcr = cptrc;
148  auto refw = std::ref(list);
149  auto crefw = std::cref(list);
150  auto const uptr = std::unique_ptr<O>(new O[Size]);
151  auto array_uptr = std::unique_ptr<O[Size]>();
152  auto garray_uptr = std::unique_ptr<O[]>(new O[Size]);
153 
154  static_assert(std::is_same_v<decltype(util::make_collection_reference(list )), decltype(std::ref(list))>);
155  static_assert(std::is_same_v<decltype(util::make_collection_reference(array )), decltype(ptr )>);
156  static_assert(std::is_same_v<decltype(util::make_collection_reference(ptr )), decltype(ptr )>);
157  static_assert(std::is_same_v<decltype(util::make_collection_reference(cptr )), decltype(cptr )>);
158  static_assert(std::is_same_v<decltype(util::make_collection_reference(cptrc )), decltype(cptr )>);
159  static_assert(std::is_same_v<decltype(util::make_collection_reference(cptrcr )), decltype(cptr )>);
160  static_assert(std::is_same_v<decltype(util::make_collection_reference(refw )), decltype(refw )>);
161  static_assert(std::is_same_v<decltype(util::make_collection_reference(crefw )), decltype(crefw )>);
162  static_assert(std::is_same_v<decltype(util::make_collection_reference(uptr )), decltype(ptr )>);
163  static_assert(std::is_same_v<decltype(util::make_collection_reference(array_uptr )), decltype(&array )>);
164  static_assert(std::is_same_v<decltype(util::make_collection_reference(garray_uptr)), decltype(ptr )>);
165 
166  BOOST_TEST(&(util::make_collection_reference(list ).get().front()) == &list.front() );
167  BOOST_TEST(&(util::make_collection_reference(array )[0] ) == &array[0] );
168  BOOST_TEST(&(util::make_collection_reference(ptr )[0] ) == ptr );
169  BOOST_TEST(&(util::make_collection_reference(cptr )[0] ) == cptr );
170  BOOST_TEST(&(util::make_collection_reference(cptrc )[0] ) == cptr );
171  BOOST_TEST(&(util::make_collection_reference(cptrcr )[0] ) == cptr );
172  BOOST_TEST(&(util::make_collection_reference(refw ).get().front()) == &list.front() );
173  BOOST_TEST(&(util::make_collection_reference(crefw ).get().front()) == &list.front() );
174  BOOST_TEST(&(util::make_collection_reference(uptr )[0] ) == uptr.get() );
175  BOOST_TEST(&(util::make_collection_reference(array_uptr )[0] ) == array_uptr.get() );
176  BOOST_TEST(&(util::make_collection_reference(garray_uptr)[0] ) == garray_uptr.get() );
177 
178 } // make_collection_reference_test()
179 
180 
181 //------------------------------------------------------------------------------
183 
184  constexpr std::size_t Size = 10U;
185 
186  // BUG the double brace syntax is required to work around clang bug 21629
187  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
188  std::list<O> list {{ O{} }};
189  std::list<O> & ref = list;
190  std::list<O> const& cref = list;
191  auto refw = std::ref(list);
192  auto crefw = std::cref(list);
193 
194  O array [Size];
195  O* ptr = array;
196  O const* cptr = ptr;
197 
198  auto const uptr = std::unique_ptr<O>(new O[Size]);
199  auto array_uptr = std::unique_ptr<O[Size]>();
200  auto const array_uptrc = std::unique_ptr<O[Size]>();
201  auto garray_uptr = std::unique_ptr<O[]>(new O[Size]);
202 
203  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(list )>, decltype(ref )>);
204  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(ref )>, decltype(ref )>);
205  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(cref )>, decltype(cref)>);
206  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(refw )>, decltype(ref )>);
207  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(crefw )>, decltype(cref)>);
208 
209  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(array )>, O * >);
210  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(ptr )>, O * >);
211  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(cptr )>, O const* >);
212 
213  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(uptr )>, O * >);
214  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(array_uptr )>, O(*)[Size] >);
215  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(array_uptrc)>, O(*)[Size] >);
216  static_assert(std::is_same_v<util::collection_from_reference_t<decltype(garray_uptr)>, O * >);
217 
218  static_assert(std::is_same_v<decltype(util::collection_from_reference(list )), decltype(ref )>);
219  static_assert(std::is_same_v<decltype(util::collection_from_reference(ref )), decltype(ref )>);
220  static_assert(std::is_same_v<decltype(util::collection_from_reference(cref )), decltype(cref)>);
221  static_assert(std::is_same_v<decltype(util::collection_from_reference(refw )), decltype(ref )>);
222  static_assert(std::is_same_v<decltype(util::collection_from_reference(crefw )), decltype(cref)>);
223 
224  static_assert(std::is_same_v<decltype(util::collection_from_reference(array )), O * >);
225  static_assert(std::is_same_v<decltype(util::collection_from_reference(ptr )), O * >);
226  static_assert(std::is_same_v<decltype(util::collection_from_reference(cptr )), O const* >);
227 
228  static_assert(std::is_same_v<decltype(util::collection_from_reference(uptr )), O * >);
229  static_assert(std::is_same_v<decltype(util::collection_from_reference(array_uptr )), O(*)[Size] >);
230  static_assert(std::is_same_v<decltype(util::collection_from_reference(array_uptrc)), O(*)[Size] >);
231  static_assert(std::is_same_v<decltype(util::collection_from_reference(garray_uptr)), O * >);
232 
233  BOOST_TEST(&util::collection_from_reference(list ) == &list );
234  BOOST_TEST(&util::collection_from_reference(ref ) == &list );
235  BOOST_TEST(&util::collection_from_reference(cref ) == &list );
236  BOOST_TEST(&util::collection_from_reference(refw ) == &list );
237  BOOST_TEST(&util::collection_from_reference(crefw ) == &list );
238 
239  BOOST_TEST( util::collection_from_reference(array ) == array );
240  BOOST_TEST( util::collection_from_reference(ptr ) == ptr );
241  BOOST_TEST( util::collection_from_reference(cptr ) == cptr );
242 
243  BOOST_TEST( util::collection_from_reference(uptr ) == uptr.get() );
244  BOOST_TEST( util::collection_from_reference(array_uptr ) == array_uptr.get() );
245  BOOST_TEST( util::collection_from_reference(array_uptrc) == array_uptrc.get());
246  BOOST_TEST( util::collection_from_reference(garray_uptr) == garray_uptr.get());
247 
248 } // collection_from_reference_test()
249 
250 
251 //------------------------------------------------------------------------------
252 
253 BOOST_AUTO_TEST_CASE(CollectionReferenceTestCase) {
256 } // BOOST_AUTO_TEST_CASE(CollectionReferenceTestCase)
257 
258 //------------------------------------------------------------------------------
auto make_collection_reference(Coll &&coll)
Returns an object referencing to the data contained in coll.
typename collection_value_access_type< Coll >::type collection_value_access_t
Type obtained by constant access to element of collection Coll.
Definition: ContainerMeta.h:76
void collection_from_reference_test()
BOOST_AUTO_TEST_CASE(CollectionReferenceTestCase)
typename collection_reference_type< Coll >::type collection_reference_t
The type contained in util::collection_reference_type trait.
void make_collection_reference_test()
typename collection_from_reference_type< Cont >::type collection_from_reference_t
Type contained in util::collection_from_reference_type trait.
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:228
typename collection_value_type< Coll >::type collection_value_t
Type contained in the collection Coll.
Definition: ContainerMeta.h:65
decltype(auto) collection_from_reference(CollRef &collRef)
Returns the object referenced by collRef as a C++ reference.
C++ metaprogramming utilities for dealing with containers.
typename collection_value_constant_access_type< Coll >::type collection_value_constant_access_t
Type obtained by constant access to element of collection Coll.
Definition: ContainerMeta.h:87