16 #define BOOST_TEST_MODULE ( RangeForWrapper_test )
17 #include <boost/test/unit_test.hpp>
23 #include <type_traits>
24 #include <initializer_list>
31 template <
typename Value>
37 using pointer =
typename traits_t::pointer;
54 {
return ptr - other.
ptr; }
58 template <
typename ValueL,
typename ValueR>
81 Data(std::initializer_list<int> data): data(data) {}
88 bool empty()
const {
return data.empty(); }
89 auto size()
const {
return data.size(); }
91 {
return data[index]; }
92 auto operator[](std::size_t index)
const -> decltype(
auto)
93 {
return data[index]; }
98 T
copy(T
const& v) {
return v; }
103 template <
typename DataColl>
107 !std::is_lvalue_reference
109 "util::range_for on a rvalue should return a rvalue"
115 BOOST_TEST(total == expected_total);
121 BOOST_TEST(total == expected_total);
126 template <
typename DataColl>
127 void test(DataColl& data,
int expected_total) {
129 !std::is_lvalue_reference
131 "util::range_for on a rvalue should return a rvalue"
140 BOOST_TEST(total == expected_total);
148 BOOST_TEST(total == expected_total);
156 BOOST_TEST(total == 3 * expected_total);
162 BOOST_TEST(total == expected_total);
172 BOOST_TEST(total == 3 * expected_total);
180 template <
typename Iter,
typename RefIter>
182 (Iter iter, RefIter refIter, RefIter refEnd)
190 (std::is_move_constructible<Iter>(),
"Iterator concept violation");
192 (std::is_copy_constructible<Iter>(),
"Iterator concept violation");
194 (std::is_copy_assignable<Iter>(),
"Iterator concept violation");
196 (std::is_destructible<Iter>(),
"Iterator concept violation");
201 const bool isEnd = refIter == refEnd;
202 const bool isSingular = (iter == Iter());
203 const bool isDereferenciable = !isEnd && !isSingular;
204 const bool isLast = (std::next(refIter) == refEnd);
207 BOOST_TEST(
bool(ia == iter));
209 if (isDereferenciable) {
211 BOOST_TEST((*iter == *refIter));
213 if (!isLast && !isEnd && !isSingular) {
215 BOOST_TEST((*++iter == *++refIter));
221 template <
typename Iter,
typename RefIter>
223 (Iter iter, RefIter refIter, RefIter refEnd)
225 const bool isEnd = refIter == refEnd;
226 const bool isSingular = (iter == Iter());
227 const bool isNormal = !isEnd && !isSingular;
229 const bool isLast = (std::next(refIter) == refEnd);
231 static_assert(std::is_same<
232 typename std::iterator_traits<Iter>::reference,
233 decltype(Iter(iter).
operator*())
234 >(),
"Inconsistent return type for dereference operator");
238 if (!isSingular) BOOST_TEST(++ia != iter);
242 auto ia = iter, ib = iter;
244 BOOST_TEST(ia == ib);
247 BOOST_TEST(*(ia++) == *iter);
260 template <
typename Iter,
typename RefIter>
262 (Iter iter, RefIter refIter, RefIter refEnd)
268 template <
typename Iter,
typename RefIter>
270 (Iter iter, RefIter refIter, RefIter refEnd)
272 const bool isEnd = refIter == refEnd;
273 const bool isSingular = (iter == Iter());
274 const bool isNormal = !isEnd && !isSingular;
278 static_assert(std::is_same<
279 typename std::iterator_traits<Iter>::reference,
280 decltype(Iter(iter).
operator*())
281 >(),
"Inconsistent return type for dereference operator");
287 BOOST_TEST((++ia != iter));
288 BOOST_TEST((&++ia == addr));
293 auto ia = iter, ib = iter;
295 BOOST_TEST(ia == ib);
300 if (!isEnd) (
void)ia++;
306 template <
typename Iter,
typename RefIter>
308 (Iter iter, RefIter refIter, RefIter refEnd)
310 const bool isEnd = refIter == refEnd;
317 auto newValue = std::numeric_limits<typename Iter::value_type>::max();
324 BOOST_TEST((*iter == newValue));
327 BOOST_TEST((*iter ==
value));
329 auto ia = iter, ib = iter;
333 BOOST_TEST((*iter == newValue));
334 BOOST_TEST(ia == ib);
337 BOOST_TEST((*iter ==
value));
343 template <
typename Iter,
typename RefIter>
345 (Iter iter, RefIter refIter, RefIter refEnd)
347 const bool isEnd = refIter == refEnd;
348 const bool isSingular = (iter == Iter());
349 const bool isNormal = !isEnd && !isSingular;
350 const bool isDereferenciable = isNormal;
352 static_assert(std::is_default_constructible<Iter>(),
353 "Forward iterator concept violation");
355 using traits_t = std::iterator_traits<Iter>;
356 using dereference_t = std::remove_reference_t<decltype(*iter)>;
357 constexpr
bool isConst = std::is_const<dereference_t>();
361 typename traits_t::reference,
362 std::add_lvalue_reference_t<
363 std::conditional_t<isConst,
364 std::add_const_t<typename traits_t::value_type>,
365 typename traits_t::value_type
369 "Forward iterator concept violation"
372 if (isDereferenciable) {
373 auto ia = iter, ib = iter;
375 BOOST_TEST((ia == ib));
377 BOOST_TEST((&*ia == &*ib));
379 BOOST_TEST((++ia == ++ib));
385 template <
typename Iter,
typename RefIter>
387 (Iter iter, RefIter refIter, RefIter refEnd)
393 template <
typename Iter,
typename RefIter>
395 (Iter iter, RefIter refIter, RefIter refEnd)
397 const bool isEnd = refIter == refEnd;
399 const bool isSingular = (iter == Iter());
400 const bool isNormal = !isEnd && !isSingular;
401 const bool isDereferenciable = isNormal;
403 auto ia = isEnd? iter: std::next(iter);
404 auto iaRef = isEnd? refIter: std::next(refIter);
408 BOOST_TEST((ib != ia));
409 BOOST_TEST((*ib == *std::prev(iaRef)));
410 BOOST_TEST((++ib == ia));
411 if (isDereferenciable) BOOST_TEST((*ib == *iaRef));
414 BOOST_TEST((ib != ia));
415 BOOST_TEST((*ib == *std::prev(iaRef)));
416 BOOST_TEST((++ib == ia));
417 if (isDereferenciable) BOOST_TEST((*ib == *iaRef));
421 template <
typename Iter,
typename RefIter>
423 (Iter iter, RefIter refIter, RefIter refEnd)
429 template <
typename Iter,
typename RefIter>
431 (Iter iter, RefIter refIter, RefIter refEnd)
435 template <
typename Iter,
typename RefIter>
437 (Iter iter, RefIter refIter, RefIter refEnd)
446 template <
bool IsConst,
typename Iter,
typename RefIter>
448 (Iter iter, RefIter refIter, RefIter refEnd, std::input_iterator_tag)
455 template <
bool IsConst,
typename Iter,
typename RefIter>
457 (Iter iter, RefIter refIter, RefIter refEnd, std::input_iterator_tag tag)
464 template <
bool IsConst,
typename Iter,
typename RefIter>
466 (Iter iter, RefIter refIter, RefIter refEnd, std::output_iterator_tag)
473 template <
bool IsConst,
typename Iter,
typename RefIter>
475 (Iter iter, RefIter refIter, RefIter refEnd, std::output_iterator_tag tag)
482 template <
bool IsConst,
typename Iter,
typename RefIter>
484 (Iter iter, RefIter refIter, RefIter refEnd, std::forward_iterator_tag)
486 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::input_iterator_tag{});
487 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::output_iterator_tag{});
492 template <
bool IsConst,
typename Iter,
typename RefIter>
494 (Iter iter, RefIter refIter, RefIter refEnd, std::forward_iterator_tag tag)
496 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::input_iterator_tag{});
497 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::output_iterator_tag{});
502 template <
bool IsConst,
typename Iter,
typename RefIter>
504 (Iter iter, RefIter refIter, RefIter refEnd, std::bidirectional_iterator_tag)
506 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::forward_iterator_tag{});
511 template <
bool IsConst,
typename Iter,
typename RefIter>
513 (Iter iter, RefIter refIter, RefIter refEnd, std::bidirectional_iterator_tag tag)
515 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::forward_iterator_tag{});
520 template <
bool IsConst,
typename Iter,
typename RefIter>
522 (Iter iter, RefIter refIter, RefIter refEnd, std::random_access_iterator_tag)
524 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::bidirectional_iterator_tag{});
529 template <
bool IsConst,
typename Iter,
typename RefIter>
531 (Iter iter, RefIter refIter, RefIter refEnd, std::random_access_iterator_tag tag)
533 iterator_test_impl<IsConst>(iter, refIter, refEnd, std::bidirectional_iterator_tag{});
538 template <
typename Iter,
typename RefIter>
543 using traits_t = std::iterator_traits<Iter>;
544 constexpr
bool IsConst
545 = std::is_const<std::remove_reference_t<decltype(*iter)>>();
547 iterator_test_impl<IsConst>
548 (iter, refIter, refEnd,
typename traits_t::iterator_category{});
553 template <
bool IsConst>
556 using base_reference_container_t = std::vector<int>;
557 using reference_container_t = std::conditional_t
558 <IsConst, base_reference_container_t
const, base_reference_container_t>;
559 reference_container_t vdata = { 2, 3, 4 };
560 using basic_container_t =
Data;
562 static_assert(std::is_same<basic_container_t::begin_iterator::reference, int&>());
563 static_assert(std::is_same<
typename std::iterator_traits<basic_container_t::begin_iterator>::reference,
int&>());
565 static_assert(std::is_same<basic_container_t::begin_const_iterator::reference, std::add_const_t<int>&>());
566 static_assert(std::is_same<
typename std::iterator_traits<basic_container_t::begin_const_iterator>::reference, std::add_const_t<int>&>());
569 = std::conditional_t<IsConst, basic_container_t const, basic_container_t>;
573 container_t data = { 2, 3, 4 };
577 auto rbegin =
begin(range);
578 auto rend =
end(range);
580 auto vbegin = vdata.begin();
581 auto vend = vdata.end();
583 BOOST_TEST((
unsigned)
std::distance(rbegin, rend) == vdata.size());
594 auto rcbegin =
cbegin(range);
595 auto rcend =
cend(range);
597 auto vcbegin = vdata.cbegin();
598 auto vcend = vdata.cend();
600 BOOST_TEST((
unsigned)
std::distance(rcbegin, rcend) == vdata.size());
608 BOOST_TEST(range.size() == data.size());
609 BOOST_TEST(range.empty() == data.empty());
610 for (std::size_t i = 0; i < data.size(); ++i) {
611 BOOST_TEST(range[i] == data[i]);
623 static_assert(std::is_same<
624 std::decay_t<decltype(vdata)>,
627 "util::range_for should be pass-through!"
631 "Pass-through on a lvalue should return a lvalue reference"
635 !std::is_lvalue_reference
637 "Pass-through on a rvalue should return a rvalue (or its reference)"
642 auto const expected_total = std::accumulate(vdata.begin(), vdata.end(), 0);
646 test(vdata, expected_total);
655 Data data { 2, 3, 4 };
657 auto expected_total = std::accumulate(vdata.begin(), vdata.end(), 0);
660 static_assert(!std::is_same<
661 std::decay_t<decltype(data)>,
664 "util::range_for should generate a wrapper!"
671 test(data, expected_total);
678 RangeForWrapperIteratorStandardsTest<false>();
679 RangeForWrapperIteratorStandardsTest<true>();
void const_bidirectional_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
base_iterator & operator--()
auto operator[](std::size_t index) const -> decltype(auto)
void const_random_access_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
std::enable_if_t< IsConst > iterator_test_impl(Iter iter, RefIter refIter, RefIter refEnd, std::input_iterator_tag)
typename traits_t::value_type value_type
Utility function to enable range-for on different type iterators.
base_iterator & operator++()
reference operator[](difference_type offset) const
typename traits_t::reference reference
void const_output_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
end_const_iterator end() const
auto cbegin(FixedBins< T, C > const &) noexcept
void random_access_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
auto cend(FixedBins< T, C > const &) noexcept
auto operator[](std::size_t index) -> decltype(auto)
typename traits_t::iterator_category iterator_category
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void RangeForWrapperIteratorStandardsTest()
void forward_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
constexpr RangeForWrapperTag range_for
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void const_input_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
auto end(FixedBins< T, C > const &) noexcept
bool operator!=(base_iterator< ValueL > const &a, base_iterator< ValueR > const &b)
void const_test(DataColl const &data, int expected_total)
typename traits_t::pointer pointer
void const_forward_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
void output_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
auto begin(FixedBins< T, C > const &) noexcept
difference_type operator-(base_iterator const &other) const
pointer operator->() const
void input_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
base_iterator(pointer ptr=nullptr)
void iterator_test(Iter iter, RefIter refIter, RefIter refEnd)
Data(std::initializer_list< int > data)
typename traits_t::difference_type difference_type
begin_const_iterator begin() const
void iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
reference operator*() const
void bidirectional_iterator_tests(Iter iter, RefIter refIter, RefIter refEnd)
std::iterator_traits< int const * > traits_t