1 /* Copyright 2016-2018 Joaquin M Lopez Munoz.
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)
6 * See http://www.boost.org/libs/poly_collection for library home page.
9 #include "test_iterators.hpp"
11 #include <boost/core/lightweight_test.hpp>
13 #include <type_traits>
14 #include "any_types.hpp"
15 #include "base_types.hpp"
16 #include "function_types.hpp"
17 #include "test_utilities.hpp"
19 using namespace test_utilities
;
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
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
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
37 template<typename Type
,typename PolyCollection
>
38 void test_iterators(PolyCollection
& p
)
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
>;
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");
61 local_iterator lit
,lit2
;
62 const_local_iterator clit
,clit2(lit
); /* sorry about the names */
69 const PolyCollection
& cp
=p
;
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
>();
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
>());
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());
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());
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
);
113 Type
& r
=p
.template begin
<Type
>()[n
];
114 const Type
& cr
=cp
.template begin
<Type
>()[n
];
116 BOOST_TEST(&*lfirst
==&r
);
117 BOOST_TEST(&*clfirst
==&cr
);
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
)));
129 (std::ptrdiff_t)n
==p
.template end
<Type
>()-p
.template begin
<Type
>());
131 for(auto s
:p
.segment_traversal()){
132 if(s
.type_info()==typeid(Type
)){
136 s
.template begin
<Type
>()==
137 static_cast<local_iterator
>(s
.begin()));
139 s
.template end
<Type
>()==
140 static_cast<local_iterator
>(s
.end()));
142 cs
.template begin
<Type
>()==
143 static_cast<const_local_iterator
>(cs
.begin()));
145 cs
.template end
<Type
>()==
146 static_cast<const_local_iterator
>(cs
.end()));
148 cs
.template cbegin
<Type
>()==
149 static_cast<const_local_iterator
>(cs
.cbegin()));
151 cs
.template cend
<Type
>()==
152 static_cast<const_local_iterator
>(cs
.cend()));
157 template<typename PolyCollection
,typename ValueFactory
,typename
... Types
>
158 void test_iterators()
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
;
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");
200 const_iterator cit
,cit2(it
);
201 local_base_iterator lbit
,lbit2
;
202 const_local_base_iterator clbit
,clbit2(lbit
);
203 base_segment_info_iterator sit
,sit2
;
204 const_base_segment_info_iterator csit
,csit2(csit
);
218 const PolyCollection
& cp
=p
;
221 fill
<constraints
<>,Types
...>(p
,v
,2);
225 iterator first
=p
.begin(),last
=p
.end();
226 const_iterator cfirst
=cp
.begin(),clast
=cp
.end();
228 BOOST_TEST(cfirst
==cp
.cbegin());
229 BOOST_TEST(clast
==cp
.cend());
231 for(;first
!=last
;++first
,++cfirst
){
232 BOOST_TEST(first
==cfirst
);
233 BOOST_TEST(&*first
==&*cfirst
);
237 BOOST_TEST(cfirst
==clast
);
238 BOOST_TEST(last
==clast
);
239 BOOST_TEST(n
==p
.size());
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();
249 BOOST_TEST(cfirst
==cp
.segment_traversal().cbegin());
250 BOOST_TEST(clast
==cp
.segment_traversal().cend());
252 for(;first
!=last
;++first
,++cfirst
){
253 BOOST_TEST(first
==cfirst
);
256 local_base_iterator lbfirst
=first
->begin(),lblast
=first
->end();
257 const_local_base_iterator clbfirst
=cfirst
->begin(),clblast
=cfirst
->end();
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()));
268 for(;lbfirst
!=lblast
;++lbfirst
,++clbfirst
){
269 BOOST_TEST(lbfirst
==clbfirst
);
270 BOOST_TEST(&*lbfirst
==&*clbfirst
);
272 value_type
& r
=first
->begin()[m
];
273 const value_type
& cr
=cfirst
->begin()[m
];
275 BOOST_TEST(&*lbfirst
==&r
);
276 BOOST_TEST(&*clbfirst
==&cr
);
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());
288 BOOST_TEST(cfirst
==clast
);
289 BOOST_TEST(last
==clast
);
290 BOOST_TEST(n
==p
.size());
293 do_((test_iterators
<Types
>(p
),0)...);
296 void 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
>();
303 base_types::collection
,auto_increment
,
304 base_types::t1
,base_types::t2
,base_types::t3
,
305 base_types::t4
,base_types::t5
>();
307 function_types::collection
,auto_increment
,
308 function_types::t1
,function_types::t2
,function_types::t3
,
309 function_types::t4
,function_types::t5
>();