]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | /* Copyright 2016-2018 Joaquin M Lopez Munoz. |
b32b8144 FG |
2 | * Distributed under the Boost Software License, Version 1.0. |
3 | * (See accompanying file LICENSE_1_0.txt or copy at | |
4 | * http://www.boost.org/LICENSE_1_0.txt) | |
5 | * | |
6 | * See http://www.boost.org/libs/poly_collection for library home page. | |
7 | */ | |
8 | ||
9 | #include "test_iterators.hpp" | |
10 | ||
11 | #include <boost/core/lightweight_test.hpp> | |
12 | #include <iterator> | |
13 | #include <type_traits> | |
14 | #include "any_types.hpp" | |
15 | #include "base_types.hpp" | |
16 | #include "function_types.hpp" | |
17 | #include "test_utilities.hpp" | |
18 | ||
19 | using namespace test_utilities; | |
20 | ||
21 | template<typename Iterator> | |
22 | using is_input=std::is_base_of< | |
23 | std::input_iterator_tag, | |
24 | typename std::iterator_traits<Iterator>::iterator_category | |
25 | >; | |
26 | template<typename Iterator> | |
27 | using is_forward=std::is_base_of< | |
28 | std::forward_iterator_tag, | |
29 | typename std::iterator_traits<Iterator>::iterator_category | |
30 | >; | |
31 | template<typename Iterator> | |
32 | using is_random_access=std::is_base_of< | |
33 | std::random_access_iterator_tag, | |
34 | typename std::iterator_traits<Iterator>::iterator_category | |
35 | >; | |
36 | ||
37 | template<typename Type,typename PolyCollection> | |
38 | void test_iterators(PolyCollection& p) | |
39 | { | |
40 | using local_base_iterator=typename PolyCollection::local_base_iterator; | |
41 | using const_local_base_iterator= | |
42 | typename PolyCollection::const_local_base_iterator; | |
43 | using local_iterator=typename PolyCollection::template local_iterator<Type>; | |
44 | using const_local_iterator= | |
45 | typename PolyCollection::template const_local_iterator<Type>; | |
46 | using base_segment_info=typename PolyCollection::base_segment_info; | |
47 | using const_base_segment_info= | |
48 | typename PolyCollection::const_base_segment_info; | |
49 | using const_segment_info= | |
50 | typename PolyCollection::template const_segment_info<Type>; | |
51 | using segment_info=typename PolyCollection::template segment_info<Type>; | |
52 | ||
53 | static_assert(is_random_access<local_iterator>::value, | |
54 | "local_iterator must be random access"); | |
55 | static_assert(is_random_access<const_local_iterator>::value, | |
56 | "const_local_iterator must be random access"); | |
57 | static_assert(std::is_base_of<const_segment_info,segment_info>::value, | |
58 | "segment_info must derive from const_segment_info"); | |
59 | ||
60 | { | |
92f5a8d4 | 61 | local_iterator lit,lit2; |
b32b8144 FG |
62 | const_local_iterator clit,clit2(lit); /* sorry about the names */ |
63 | ||
92f5a8d4 | 64 | lit=lit2; |
b32b8144 FG |
65 | clit=clit2; |
66 | clit=lit; | |
67 | } | |
68 | ||
69 | const PolyCollection& cp=p; | |
70 | std::size_t n=0; | |
71 | local_base_iterator lbfirst=p.begin(typeid(Type)), | |
72 | lblast=p.end(typeid(Type)); | |
73 | const_local_base_iterator clbfirst=cp.begin(typeid(Type)), | |
74 | clblast=cp.end(typeid(Type)); | |
75 | local_iterator lfirst=p.template begin<Type>(), | |
76 | llast=p.template end<Type>(); | |
77 | const_local_iterator clfirst=cp.template begin<Type>(), | |
78 | cllast=cp.template end<Type>(); | |
79 | base_segment_info bi=p.segment(typeid(Type)); | |
80 | const_base_segment_info cbi=cp.segment(typeid(Type)); | |
81 | segment_info i=p.template segment<Type>(); | |
82 | const_segment_info ci=cp.template segment<Type>(); | |
83 | ||
84 | BOOST_TEST(clbfirst==cp.cbegin(typeid(Type))); | |
85 | BOOST_TEST(clblast==cp.cend(typeid(Type))); | |
86 | BOOST_TEST(clfirst==cp.template cbegin<Type>()); | |
87 | BOOST_TEST(cllast==cp.template cend<Type>()); | |
88 | ||
89 | BOOST_TEST(lbfirst==bi.begin()); | |
90 | BOOST_TEST(lblast==bi.end()); | |
91 | BOOST_TEST(clbfirst==bi.cbegin()); | |
92 | BOOST_TEST(clbfirst==cbi.begin()); | |
93 | BOOST_TEST(clblast==bi.cend()); | |
94 | BOOST_TEST(clblast==cbi.end()); | |
95 | ||
96 | BOOST_TEST(lfirst==i.begin()); | |
97 | BOOST_TEST(llast==i.end()); | |
98 | BOOST_TEST(clfirst==i.cbegin()); | |
99 | BOOST_TEST(clfirst==ci.begin()); | |
100 | BOOST_TEST(cllast==i.cend()); | |
101 | BOOST_TEST(cllast==ci.end()); | |
102 | ||
103 | for(;lbfirst!=lblast;++lbfirst,++clbfirst,++lfirst,++clfirst){ | |
104 | BOOST_TEST(lfirst==static_cast<local_iterator>(lbfirst)); | |
105 | BOOST_TEST(static_cast<local_base_iterator>(lfirst)==lbfirst); | |
106 | BOOST_TEST(clfirst==static_cast<const_local_iterator>(clbfirst)); | |
107 | BOOST_TEST(static_cast<const_local_base_iterator>(clfirst)==clbfirst); | |
108 | BOOST_TEST(clfirst==lfirst); | |
109 | BOOST_TEST(&*lfirst==&*static_cast<local_iterator>(lbfirst)); | |
110 | BOOST_TEST(&*clfirst==&*static_cast<const_local_iterator>(clbfirst)); | |
111 | BOOST_TEST(&*clfirst==&*lfirst); | |
112 | ||
113 | Type& r=p.template begin<Type>()[n]; | |
114 | const Type& cr=cp.template begin<Type>()[n]; | |
115 | ||
116 | BOOST_TEST(&*lfirst==&r); | |
117 | BOOST_TEST(&*clfirst==&cr); | |
118 | ||
119 | ++n; | |
120 | } | |
121 | BOOST_TEST(clbfirst==clblast); | |
122 | BOOST_TEST(lfirst==llast); | |
123 | BOOST_TEST(clfirst==cllast); | |
124 | BOOST_TEST(lfirst==static_cast<local_iterator>(llast)); | |
125 | BOOST_TEST(clfirst==static_cast<const_local_iterator>(cllast)); | |
126 | BOOST_TEST(clfirst==llast); | |
127 | BOOST_TEST((std::ptrdiff_t)n==p.end(typeid(Type))-p.begin(typeid(Type))); | |
128 | BOOST_TEST( | |
129 | (std::ptrdiff_t)n==p.template end<Type>()-p.template begin<Type>()); | |
130 | ||
131 | for(auto s:p.segment_traversal()){ | |
132 | if(s.type_info()==typeid(Type)){ | |
133 | const auto& cs=s; | |
134 | ||
135 | BOOST_TEST( | |
136 | s.template begin<Type>()== | |
137 | static_cast<local_iterator>(s.begin())); | |
138 | BOOST_TEST( | |
139 | s.template end<Type>()== | |
140 | static_cast<local_iterator>(s.end())); | |
141 | BOOST_TEST( | |
142 | cs.template begin<Type>()== | |
143 | static_cast<const_local_iterator>(cs.begin())); | |
144 | BOOST_TEST( | |
145 | cs.template end<Type>()== | |
146 | static_cast<const_local_iterator>(cs.end())); | |
147 | BOOST_TEST( | |
148 | cs.template cbegin<Type>()== | |
149 | static_cast<const_local_iterator>(cs.cbegin())); | |
150 | BOOST_TEST( | |
151 | cs.template cend<Type>()== | |
152 | static_cast<const_local_iterator>(cs.cend())); | |
153 | } | |
154 | } | |
155 | } | |
156 | ||
157 | template<typename PolyCollection,typename ValueFactory,typename... Types> | |
158 | void test_iterators() | |
159 | { | |
160 | using value_type=typename PolyCollection::value_type; | |
161 | using iterator=typename PolyCollection::iterator; | |
162 | using const_iterator=typename PolyCollection::const_iterator; | |
163 | using local_base_iterator=typename PolyCollection::local_base_iterator; | |
164 | using const_local_base_iterator= | |
165 | typename PolyCollection::const_local_base_iterator; | |
166 | using const_base_segment_info= | |
167 | typename PolyCollection::const_base_segment_info; | |
168 | using base_segment_info=typename PolyCollection::base_segment_info; | |
169 | using base_segment_info_iterator= | |
170 | typename PolyCollection::base_segment_info_iterator; | |
171 | using const_base_segment_info_iterator= | |
172 | typename PolyCollection::const_base_segment_info_iterator; | |
173 | using const_segment_traversal_info= | |
174 | typename PolyCollection::const_segment_traversal_info; | |
175 | using segment_traversal_info= | |
176 | typename PolyCollection::segment_traversal_info; | |
177 | ||
178 | static_assert(is_forward<iterator>::value, | |
179 | "iterator must be forward"); | |
180 | static_assert(is_forward<const_iterator>::value, | |
181 | "const_iterator must be forward"); | |
182 | static_assert(is_random_access<local_base_iterator>::value, | |
183 | "local_base_iterator must be random access"); | |
184 | static_assert(is_random_access<const_local_base_iterator>::value, | |
185 | "const_local_base_iterator must be random access"); | |
186 | static_assert(std::is_base_of< | |
187 | const_base_segment_info,base_segment_info>::value, | |
188 | "base_segment_info must derive from const_base_segment_info"); | |
189 | static_assert(is_input<base_segment_info_iterator>::value, | |
190 | "base_segment_info_iterator must be input"); | |
191 | static_assert(is_input<const_base_segment_info_iterator>::value, | |
192 | "const_base_segment_info_iterator must be input"); | |
193 | static_assert(std::is_base_of< | |
194 | const_segment_traversal_info,segment_traversal_info>::value, | |
195 | "const_segment_traversal_info must derive "\ | |
196 | "from segment_traversal_info"); | |
197 | ||
198 | { | |
92f5a8d4 | 199 | iterator it,it2; |
b32b8144 | 200 | const_iterator cit,cit2(it); |
92f5a8d4 | 201 | local_base_iterator lbit,lbit2; |
b32b8144 | 202 | const_local_base_iterator clbit,clbit2(lbit); |
92f5a8d4 | 203 | base_segment_info_iterator sit,sit2; |
b32b8144 FG |
204 | const_base_segment_info_iterator csit,csit2(csit); |
205 | ||
92f5a8d4 | 206 | it=it2; |
b32b8144 FG |
207 | cit=cit2; |
208 | cit=it; | |
92f5a8d4 | 209 | lbit=lbit2; |
b32b8144 FG |
210 | clbit=clbit2; |
211 | clbit=lbit; | |
92f5a8d4 | 212 | sit=sit2; |
b32b8144 FG |
213 | csit=csit2; |
214 | csit=sit; | |
215 | } | |
216 | ||
217 | PolyCollection p; | |
218 | const PolyCollection& cp=p; | |
219 | ValueFactory v; | |
220 | ||
221 | fill<constraints<>,Types...>(p,v,2); | |
222 | ||
223 | { | |
224 | std::size_t n=0; | |
225 | iterator first=p.begin(),last=p.end(); | |
226 | const_iterator cfirst=cp.begin(),clast=cp.end(); | |
227 | ||
228 | BOOST_TEST(cfirst==cp.cbegin()); | |
229 | BOOST_TEST(clast==cp.cend()); | |
230 | ||
231 | for(;first!=last;++first,++cfirst){ | |
232 | BOOST_TEST(first==cfirst); | |
233 | BOOST_TEST(&*first==&*cfirst); | |
234 | ||
235 | ++n; | |
236 | } | |
237 | BOOST_TEST(cfirst==clast); | |
238 | BOOST_TEST(last==clast); | |
239 | BOOST_TEST(n==p.size()); | |
240 | } | |
241 | ||
242 | { | |
243 | std::size_t n=0; | |
244 | base_segment_info_iterator first=p.segment_traversal().begin(), | |
245 | last=p.segment_traversal().end(); | |
246 | const_base_segment_info_iterator cfirst=cp.segment_traversal().begin(), | |
247 | clast=cp.segment_traversal().end(); | |
248 | ||
249 | BOOST_TEST(cfirst==cp.segment_traversal().cbegin()); | |
250 | BOOST_TEST(clast==cp.segment_traversal().cend()); | |
251 | ||
252 | for(;first!=last;++first,++cfirst){ | |
253 | BOOST_TEST(first==cfirst); | |
254 | ||
255 | std::size_t m=0; | |
256 | local_base_iterator lbfirst=first->begin(),lblast=first->end(); | |
257 | const_local_base_iterator clbfirst=cfirst->begin(),clblast=cfirst->end(); | |
258 | ||
259 | BOOST_TEST(clbfirst==cfirst->cbegin()); | |
260 | BOOST_TEST(clblast==cfirst->cend()); | |
261 | BOOST_TEST(lbfirst==p.begin(first->type_info())); | |
262 | BOOST_TEST(lblast==p.end(first->type_info())); | |
263 | BOOST_TEST(clbfirst==cp.begin(first->type_info())); | |
264 | BOOST_TEST(clblast==cp.end(first->type_info())); | |
265 | BOOST_TEST(clbfirst==cp.cbegin(first->type_info())); | |
266 | BOOST_TEST(clblast==cp.cend(first->type_info())); | |
267 | ||
268 | for(;lbfirst!=lblast;++lbfirst,++clbfirst){ | |
269 | BOOST_TEST(lbfirst==clbfirst); | |
270 | BOOST_TEST(&*lbfirst==&*clbfirst); | |
271 | ||
272 | value_type& r=first->begin()[m]; | |
273 | const value_type& cr=cfirst->begin()[m]; | |
274 | ||
275 | BOOST_TEST(&*lbfirst==&r); | |
276 | BOOST_TEST(&*clbfirst==&cr); | |
277 | ||
278 | ++m; | |
279 | } | |
280 | BOOST_TEST(clbfirst==clblast); | |
281 | BOOST_TEST(lblast==clblast); | |
282 | BOOST_TEST((std::ptrdiff_t)m==first->end()-first->begin()); | |
283 | BOOST_TEST((std::ptrdiff_t)m==cfirst->end()-cfirst->begin()); | |
284 | BOOST_TEST((std::ptrdiff_t)m==cfirst->cend()-cfirst->cbegin()); | |
285 | ||
286 | n+=m; | |
287 | } | |
288 | BOOST_TEST(cfirst==clast); | |
289 | BOOST_TEST(last==clast); | |
290 | BOOST_TEST(n==p.size()); | |
291 | } | |
292 | ||
293 | do_((test_iterators<Types>(p),0)...); | |
294 | } | |
295 | ||
296 | void test_iterators() | |
297 | { | |
298 | test_iterators< | |
299 | any_types::collection,auto_increment, | |
300 | any_types::t1,any_types::t2,any_types::t3, | |
301 | any_types::t4,any_types::t5>(); | |
302 | test_iterators< | |
303 | base_types::collection,auto_increment, | |
304 | base_types::t1,base_types::t2,base_types::t3, | |
305 | base_types::t4,base_types::t5>(); | |
306 | test_iterators< | |
307 | function_types::collection,auto_increment, | |
308 | function_types::t1,function_types::t2,function_types::t3, | |
309 | function_types::t4,function_types::t5>(); | |
310 | } |