]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // (C) Copyright Thomas Witt 2003. |
2 | // (C) Copyright Hans Dembinski 2019. | |
3 | ||
4 | // Distributed under the Boost Software License, Version 1.0. (See | |
5 | // accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | // See http://www.boost.org for most recent version including documentation. | |
9 | ||
10 | #include <boost/core/lightweight_test.hpp> | |
11 | #include <boost/core/lightweight_test_trait.hpp> | |
92f5a8d4 | 12 | #include <boost/histogram/detail/iterator_adaptor.hpp> |
92f5a8d4 TL |
13 | #include <deque> |
14 | #include <set> | |
20effc67 | 15 | #include <type_traits> |
92f5a8d4 | 16 | #include <vector> |
20effc67 TL |
17 | #include "std_ostream.hpp" |
18 | #include "utility_iterator.hpp" | |
92f5a8d4 TL |
19 | |
20 | using namespace boost::histogram; | |
21 | using boost::histogram::detail::iterator_adaptor; | |
22 | ||
23 | typedef std::deque<int> storage; | |
24 | typedef std::deque<int*> pointer_deque; | |
25 | typedef std::set<storage::iterator> iterator_set; | |
26 | ||
27 | template <class T> | |
28 | struct foo; | |
29 | ||
30 | void blah(int) {} | |
31 | ||
32 | struct my_gen { | |
33 | typedef int result_type; | |
34 | my_gen() : n(0) {} | |
35 | int operator()() { return ++n; } | |
36 | int n; | |
37 | }; | |
38 | ||
39 | template <class V> | |
40 | struct ptr_iterator : iterator_adaptor<ptr_iterator<V>, V*> { | |
41 | private: | |
42 | typedef iterator_adaptor<ptr_iterator<V>, V*> super_t; | |
43 | ||
44 | public: | |
45 | using base_type = typename super_t::base_type; | |
46 | ||
47 | ptr_iterator() {} | |
48 | ptr_iterator(V* d) : super_t(d) {} | |
49 | ||
20effc67 | 50 | template <class V2, class = std::enable_if_t<std::is_convertible<V2*, V*>::value>> |
92f5a8d4 TL |
51 | ptr_iterator(const ptr_iterator<V2>& x) : super_t(x.base()) {} |
52 | ||
53 | V& operator*() const { return *(this->base()); } | |
54 | }; | |
55 | ||
56 | template <class Iter> | |
57 | struct constant_iterator | |
58 | : iterator_adaptor<constant_iterator<Iter>, Iter, | |
59 | typename std::iterator_traits<Iter>::value_type const&> { | |
60 | typedef iterator_adaptor<constant_iterator<Iter>, Iter, | |
61 | typename std::iterator_traits<Iter>::value_type const&> | |
62 | base_t; | |
63 | ||
64 | constant_iterator() {} | |
65 | constant_iterator(Iter it) : base_t(it) {} | |
66 | ||
67 | typename std::iterator_traits<Iter>::value_type const& operator*() const { | |
68 | this->base().operator*(); | |
69 | } | |
70 | }; | |
71 | ||
72 | struct mutable_it : iterator_adaptor<mutable_it, int*> { | |
73 | typedef iterator_adaptor<mutable_it, int*> super_t; | |
74 | ||
75 | mutable_it(); | |
76 | explicit mutable_it(int* p) : super_t(p) {} | |
77 | ||
78 | bool equal(mutable_it const& rhs) const { return this->base() == rhs.base(); } | |
79 | }; | |
80 | ||
81 | struct constant_it : iterator_adaptor<constant_it, int const*> { | |
82 | typedef iterator_adaptor<constant_it, int const*> super_t; | |
83 | ||
84 | constant_it(); | |
85 | explicit constant_it(int* p) : super_t(p) {} | |
86 | constant_it(mutable_it const& x) : super_t(x.base()) {} | |
87 | ||
88 | bool equal(constant_it const& rhs) const { return this->base() == rhs.base(); } | |
89 | }; | |
90 | ||
91 | template <class T> | |
92 | class static_object { | |
93 | public: | |
94 | static T& get() { | |
95 | static char d[sizeof(T)]; | |
96 | return *reinterpret_cast<T*>(d); | |
97 | } | |
98 | }; | |
99 | ||
100 | int main() { | |
101 | dummyT array[] = {dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5)}; | |
102 | const int N = sizeof(array) / sizeof(dummyT); | |
103 | ||
104 | // Test the iterator_adaptor | |
105 | { | |
106 | ptr_iterator<dummyT> i(array); | |
107 | using reference = typename std::iterator_traits<ptr_iterator<dummyT>>::reference; | |
108 | using pointer = typename std::iterator_traits<ptr_iterator<dummyT>>::pointer; | |
109 | BOOST_TEST_TRAIT_SAME(reference, dummyT&); | |
110 | BOOST_TEST_TRAIT_SAME(pointer, dummyT*); | |
111 | ||
112 | random_access_iterator_test(i, N, array); | |
113 | ||
114 | ptr_iterator<const dummyT> j(array); | |
115 | random_access_iterator_test(j, N, array); | |
116 | const_nonconst_iterator_test(i, ++j); | |
117 | } | |
118 | ||
119 | // Test the iterator_traits | |
120 | { | |
121 | // Test computation of defaults | |
122 | typedef ptr_iterator<int> Iter1; | |
123 | // don't use std::iterator_traits here to avoid VC++ problems | |
124 | BOOST_TEST_TRAIT_SAME(Iter1::value_type, int); | |
125 | BOOST_TEST_TRAIT_SAME(Iter1::reference, int&); | |
126 | BOOST_TEST_TRAIT_SAME(Iter1::pointer, int*); | |
127 | BOOST_TEST_TRAIT_SAME(Iter1::difference_type, std::ptrdiff_t); | |
128 | } | |
129 | ||
130 | { | |
131 | // Test computation of default when the Value is const | |
132 | typedef ptr_iterator<int const> Iter1; | |
133 | BOOST_TEST_TRAIT_SAME(Iter1::value_type, int); | |
134 | BOOST_TEST_TRAIT_SAME(Iter1::reference, const int&); | |
135 | BOOST_TEST_TRAIT_SAME(Iter1::pointer, int const*); | |
136 | } | |
137 | ||
138 | { | |
139 | // Test constant iterator idiom | |
140 | typedef ptr_iterator<int> BaseIter; | |
141 | typedef constant_iterator<BaseIter> Iter; | |
142 | ||
143 | BOOST_TEST_TRAIT_SAME(Iter::value_type, int); | |
144 | BOOST_TEST_TRAIT_SAME(Iter::reference, int const&); | |
145 | BOOST_TEST_TRAIT_SAME(Iter::pointer, int const*); | |
146 | } | |
147 | ||
148 | // Test the iterator_adaptor | |
149 | { | |
150 | ptr_iterator<dummyT> i(array); | |
151 | random_access_iterator_test(i, N, array); | |
152 | ||
153 | ptr_iterator<const dummyT> j(array); | |
154 | random_access_iterator_test(j, N, array); | |
155 | const_nonconst_iterator_test(i, ++j); | |
156 | } | |
157 | ||
158 | // check that base_type is correct | |
159 | { | |
160 | // Test constant iterator idiom | |
161 | typedef ptr_iterator<int> BaseIter; | |
162 | ||
163 | BOOST_TEST_TRAIT_SAME(BaseIter::base_type, int*); | |
164 | BOOST_TEST_TRAIT_SAME(constant_iterator<BaseIter>::base_type, BaseIter); | |
165 | } | |
166 | ||
167 | { | |
168 | int data[] = {49, 77}; | |
169 | ||
170 | mutable_it i(data); | |
171 | constant_it j(data + 1); | |
172 | BOOST_TEST(i < j); | |
173 | BOOST_TEST(j > i); | |
174 | BOOST_TEST(i <= j); | |
175 | BOOST_TEST(j >= i); | |
176 | BOOST_TEST(j - i == 1); | |
177 | BOOST_TEST(i - j == -1); | |
178 | ||
179 | constant_it k = i; | |
180 | ||
181 | BOOST_TEST(!(i < k)); | |
182 | BOOST_TEST(!(k > i)); | |
183 | BOOST_TEST(i <= k); | |
184 | BOOST_TEST(k >= i); | |
185 | BOOST_TEST(k - i == 0); | |
186 | BOOST_TEST(i - k == 0); | |
187 | } | |
188 | ||
189 | return boost::report_errors(); | |
190 | } |