1 // Copyright 2003 David Abrahams and Jeremy Siek
2 // Copyright 2019 Hans Dembinski
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_HISTOGRAM_TEST_ITERATOR_TESTS_HPP
9 #define BOOST_HISTOGRAM_TEST_ITERATOR_TESTS_HPP
11 // This file contains adapted code from
12 // - boost::core::iterator; boost/pending/iterator_tests.hpp
13 // - boost::core::conversion; boost/implicit_cast.hpp
15 #include <boost/core/ignore_unused.hpp>
16 #include <boost/core/lightweight_test.hpp>
18 #include <type_traits>
25 struct icast_identity {
31 inline T implicit_cast(typename detail::icast_identity<T>::type x) {
35 // use this for the value type
39 dummyT(int x) : m_x(x) {}
40 int foo() const { return m_x; }
41 bool operator==(const dummyT& d) const { return m_x == d.m_x; }
45 // Tests whether type Iterator satisfies the requirements for a
47 // Preconditions: i != j, *i == val
48 template <class Iterator, class T>
49 void trivial_iterator_test(const Iterator i, const Iterator j, T val) {
54 typename std::iterator_traits<Iterator>::value_type v = *i;
57 BOOST_TEST(v == i->foo());
62 BOOST_TEST(*k == val);
66 // Preconditions: i != j
67 template <class Iterator, class T>
68 void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val) {
70 trivial_iterator_test(i, j, val);
73 // Preconditions: *i == v1, *++i == v2
74 template <class Iterator, class T>
75 void input_iterator_test(Iterator i, T v1, T v2) {
79 BOOST_TEST(!(i != i1));
81 // I can see no generic way to create an input iterator
82 // that is in the domain of== of i and != i.
83 // The following works for istream_iterator but is not
84 // guaranteed to work for arbitrary input iterators.
88 // BOOST_TEST(i != i2);
89 // BOOST_TEST(!(i == i2));
91 BOOST_TEST(*i1 == v1);
94 // we cannot test for equivalence of (void)++i & (void)i++
95 // as i is only guaranteed to be single pass.
96 BOOST_TEST(*i++ == v1);
102 BOOST_TEST(!(i != i1));
104 BOOST_TEST(*i1 == v2);
105 BOOST_TEST(*i == v2);
108 // i is dereferencable, so it must be incrementable.
111 // how to test for operator-> ?
114 template <class Iterator, class T>
115 void forward_iterator_test(Iterator i, T v1, T v2) {
116 input_iterator_test(i, v1, v2);
118 Iterator i1 = i, i2 = i;
120 BOOST_TEST(i == i1++);
121 BOOST_TEST(i != ++i2);
123 trivial_iterator_test(i, i1, v1);
124 trivial_iterator_test(i, i2, v1);
132 trivial_iterator_test(i, i1, v2);
133 trivial_iterator_test(i, i2, v2);
135 typedef typename std::iterator_traits<Iterator>::reference reference;
136 typedef typename std::iterator_traits<Iterator>::value_type value_type;
137 BOOST_TEST(std::is_reference<reference>::value);
138 BOOST_TEST((std::is_same<reference, value_type&>::value ||
139 std::is_same<reference, const value_type&>::value));
142 // Preconditions: *i == v1, *++i == v2
143 template <class Iterator, class T>
144 void bidirectional_iterator_test(Iterator i, T v1, T v2) {
145 forward_iterator_test(i, v1, v2);
148 Iterator i1 = i, i2 = i;
150 BOOST_TEST(i == i1--);
151 BOOST_TEST(i != --i2);
153 trivial_iterator_test(i, i1, v2);
154 trivial_iterator_test(i, i2, v2);
162 trivial_iterator_test(i, i1, v1);
163 trivial_iterator_test(i, i2, v1);
166 // mutable_bidirectional_iterator_test
171 // Preconditions: [i,i+N) is a valid range
172 template <class Iterator, class TrueVals>
173 void random_access_iterator_test(Iterator i, int N, TrueVals vals) {
174 bidirectional_iterator_test(i, vals[0], vals[1]);
175 const Iterator j = i;
178 typedef typename std::iterator_traits<Iterator>::value_type value_type;
179 ignore_unused<value_type>();
181 for (c = 0; c < N - 1; ++c) {
182 BOOST_TEST(i == j + c);
183 BOOST_TEST(*i == vals[c]);
184 BOOST_TEST(*i == implicit_cast<value_type>(j[c]));
185 BOOST_TEST(*i == *(j + c));
186 BOOST_TEST(*i == *(c + j));
194 Iterator k = j + N - 1;
195 for (c = 0; c < N - 1; ++c) {
196 BOOST_TEST(i == k - c);
197 BOOST_TEST(*i == vals[N - 1 - c]);
198 BOOST_TEST(*i == implicit_cast<value_type>(j[N - 1 - c]));
201 BOOST_TEST(*i == *q);
210 // Precondition: i != j
211 template <class Iterator, class ConstIterator>
212 void const_nonconst_iterator_test(Iterator i, ConstIterator j) {
226 } // namespace histogram
229 #endif // BOOST_HISTOGRAM_TEST_ITERATOR_TESTS_HPP