operations_test.cc
Go to the documentation of this file.
1 /**
2  * @file larcorealg/test/CoreUtils/operations_test.cc
3  * @brief Unit test for `larcorealg/CoreUtils/operations.h`.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date June 5, 2019
6  * @see `larcorealg/CoreUtils/operations.h`
7  */
8 
9 
10 // Boost libraries
11 #define BOOST_TEST_MODULE ( operations_test )
12 #include <boost/test/unit_test.hpp>
13 
14 // LArSoft libraries
18 
19 // C/C++ standard libraries
20 #include <vector>
21 #include <algorithm>
22 #include <memory> // std::unique_ptr<>
23 #include <numeric> // std::iota()
24 
25 
26 
27 //------------------------------------------------------------------------------
29 
30  std::vector<int> data(10U);
31  std::iota(data.begin(), data.end(), 0U);
32 
33  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34  /*
35  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
36  * std::vector<int*> ptrs(data.size());
37  * std::transform
38  * (data.begin(), data.end(), ptrs.begin(), util::AddressTaker{});
39  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40  */
41 
42  std::vector<int*> ptrs(data.size());
43  std::transform
44  (data.begin(), data.end(), ptrs.begin(), util::AddressTaker{});
45 
46  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47  // the test
48  BOOST_TEST(ptrs.size() == data.size());
49  for (auto&& [ value, ptr ]: util::zip(data, ptrs)) {
50 
51  BOOST_TEST(ptr);
52  BOOST_TEST(*ptr == value);
53  BOOST_TEST(ptr == &value);
54 
55  } // for
56 
57 
58 } // test_AddressTaker_documentation()
59 
60 
61 //------------------------------------------------------------------------------
63 
64  std::vector<int> data(10U);
65  std::iota(data.begin(), data.end(), 0U);
66 
67  /*
68  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
69  * std::vector<int*> ptrs(data.size());
70  * std::transform
71  * (data.begin(), data.end(), ptrs.begin(), util::takeAddress());
72  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73  */
74 
75  std::vector<int*> ptrs(data.size());
76  std::transform
77  (data.begin(), data.end(), ptrs.begin(), util::takeAddress());
78 
79  // the test
80  BOOST_TEST(ptrs.size() == data.size());
81  for (auto&& [ value, ptr ]: util::zip(data, ptrs)) {
82 
83  BOOST_TEST(ptr);
84  BOOST_TEST(*ptr == value);
85  BOOST_TEST(ptr == &value);
86 
87  } // for
88 
89 
90 } // test_takeAddress_documentation()
91 
92 
93 //------------------------------------------------------------------------------
95 
96  std::vector<int> data(10U);
97  std::iota(data.begin(), data.end(), 0U);
98 
99  std::vector<int const*> dataPtr;
100  std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtr),
102 
103  for (auto&& [ value, ptr ]: util::zip(data, dataPtr)) {
104 
105  BOOST_TEST(ptr);
106  BOOST_TEST(*ptr == value);
107  BOOST_TEST(ptr == &value);
108 
109  } // for
110 
111 } // test_takeAddress()
112 
113 
114 //------------------------------------------------------------------------------
116 
117  std::vector<int> data(10U);
118  std::iota(data.begin(), data.end(), 0U);
119 
120  std::vector<int const*> dataPtr;
121 
122  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123  // `std::addressof()` approach
124  using addressof_t = int const*(*)(int const&);
125 
126  std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtr),
127  ((addressof_t) &std::addressof));
128 
129  for (auto&& [ value, ptr ]: util::zip(data, dataPtr)) {
130 
131  BOOST_TEST(ptr);
132  BOOST_TEST(*ptr == value);
133  BOOST_TEST(ptr == &value);
134 
135  } // for
136 
137  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138  // lambda approach
139  dataPtr.clear();
140 
141  auto takeAddress = [](auto&& ref){ return std::addressof(ref); };
142 
143  std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtr),
144  takeAddress);
145 
146  for (auto&& [ value, ptr ]: util::zip(data, dataPtr)) {
147 
148  BOOST_TEST(ptr);
149  BOOST_TEST(*ptr == value);
150  BOOST_TEST(ptr == &value);
151 
152  } // for
153 
154 } // test_takeAddress_whyBother()
155 
156 
157 //------------------------------------------------------------------------------
159 
160  std::vector<int> data(10U);
161  std::iota(data.begin(), data.end(), 0U);
162 
163  std::vector<int*> ptrs(data.size());
164  std::transform
165  (data.begin(), data.end(), ptrs.begin(), util::takeAddress());
166 
167  /*
168  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
169  * std::vector<int> values(ptrs.size());
170  * std::transform
171  * (ptrs.cbegin(), ptrs.cend(), values.begin(), util::Dereferencer{});
172  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173  */
174 
175  std::vector<int> values(ptrs.size());
176  std::transform
177  (ptrs.cbegin(), ptrs.cend(), values.begin(), util::Dereferencer{});
178 
179  // the test
180  BOOST_TEST(values.size() == data.size());
181  for (auto&& [ value, orig ]: util::zip(data, values)) {
182 
183  BOOST_TEST(value == orig);
184 
185  } // for
186 
187 } // test_Dereferencer_documentation()
188 
189 
190 //------------------------------------------------------------------------------
192 
193  std::vector<int> data(10U);
194  std::iota(data.begin(), data.end(), 0U);
195 
196  std::vector<int*> ptrs(data.size());
197  std::transform
198  (data.begin(), data.end(), ptrs.begin(), util::takeAddress());
199 
200  /*
201  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
202  * std::vector<int> values(ptrs.size());
203  * std::transform
204  * (ptrs.cbegin(), ptrs.cend(), values.begin(), util::dereference());
205  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206  */
207 
208  std::vector<int> values(ptrs.size());
209  std::transform
210  (ptrs.cbegin(), ptrs.cend(), values.begin(), util::dereference());
211 
212  // the test
213  BOOST_TEST(values.size() == data.size());
214  for (auto&& [ value, orig ]: util::zip(data, values)) {
215 
216  BOOST_TEST(value == orig);
217 
218  } // for
219 
220 
221 } // test_dereference_documentation()
222 
223 
224 //------------------------------------------------------------------------------
226 
227  std::vector<int> data(10U);
228  std::iota(data.begin(), data.end(), 0U);
229 
230  std::vector<int const*> dataPtrs;
231  std::transform(data.cbegin(), data.cend(), std::back_inserter(dataPtrs),
233 
234  std::vector<int> dataAgain;
235  std::transform(
236  dataPtrs.cbegin(), dataPtrs.cend(),
237  std::back_inserter(dataAgain),
239  );
240 
241  BOOST_TEST(dataAgain.size() == data.size());
242  for (auto&& [ value, valueAgain ]: util::zip(data, dataAgain)) {
243 
244  BOOST_TEST(valueAgain == value);
245  BOOST_TEST(&valueAgain != &value);
246 
247  } // for
248 
249 } // test_dereference_C_ptr()
250 
251 
252 //------------------------------------------------------------------------------
254 
255  std::vector<int> data(10U);
256  std::iota(data.begin(), data.end(), 0U);
257 
258  std::vector<std::unique_ptr<int>> dataPtrs;
259  dataPtrs.reserve(data.size());
260  for (auto&& value: data) dataPtrs.push_back(std::make_unique<int>(value));
261 
262  std::vector<int> dataAgain;
263  std::transform(
264  dataPtrs.cbegin(), dataPtrs.cend(),
265  std::back_inserter(dataAgain),
267  );
268 
269  BOOST_TEST(dataAgain.size() == data.size());
270  for (auto&& [ value, valueAgain ]: util::zip(data, dataAgain)) {
271 
272  BOOST_TEST(valueAgain == value);
273  BOOST_TEST(&valueAgain != &value);
274 
275  } // for
276 
277 } // test_dereference_unique_ptr()
278 
279 
280 //------------------------------------------------------------------------------
282 
283  struct ToughInt: private lar::UncopiableAndUnmovableClass {
284  int value = 0;
285  }; // ToughInt
286 
287  ToughInt value;
288  ToughInt const* pValue = &value;
289 
290  BOOST_TEST(pValue == &(util::dereference()(pValue)));
291 
292 } // test_dereference_uncopiable()
293 
294 
295 //------------------------------------------------------------------------------
296 BOOST_AUTO_TEST_CASE(takeAddress_testcase) {
297 
302 
303 } // BOOST_AUTO_TEST_CASE(takeAddress_testcase)
304 
305 
306 //------------------------------------------------------------------------------
307 BOOST_AUTO_TEST_CASE(dereference_testcase) {
308 
314 
315 } // BOOST_AUTO_TEST_CASE(dereference_testcase)
316 
317 
318 //------------------------------------------------------------------------------
Definition of util::zip().
An empty class that can&#39;t be copied nor moved.
decltype(auto) takeAddress()
Returns a functor that returns the address of its argument.
Definition: operations.h:86
Defines classes that can&#39;t be copied nor moved.
void test_dereference_documentation()
Functor returning the address in memory of the operand.
Definition: operations.h:36
void test_Dereferencer_documentation()
Provides a few simple operations for use in generic programming.
void test_dereference_unique_ptr()
void test_takeAddress_whyBother()
void test_AddressTaker_documentation()
Q_UINT16 values[128]
decltype(auto) dereference()
Returns a functor that returns *ptr of its argument ptr.
Definition: operations.h:125
void test_dereference_C_ptr()
void test_dereference_uncopiable()
void test_takeAddress_documentation()
BOOST_AUTO_TEST_CASE(takeAddress_testcase)
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
void test_takeAddress()
Functor dereferencing the operand.
Definition: operations.h:103