1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
// Copyright 2002 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Boost.MultiArray Library
// Authors: Ronald Garcia
// Jeremy Siek
// Andrew Lumsdaine
// See http://www.boost.org/libs/multi_array for documentation.
//
// iterators.cpp - checking out iterator stuffs.
// The tests assume that the array has shape 2x3x4
//
#define MULTIARRAY_TEST_ASSIGN
#include "generative_tests.hpp"
#include <boost/concept_check.hpp> // for ignore_unused_variable_warning
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
// iterator-test-specific code
template <typename Array>
void assign_if_not_const(Array& A, const mutable_array_tag&) {
typedef typename Array::iterator iterator3;
typedef typename Array::template subarray<2>::type::iterator iterator2;
typedef typename Array::template subarray<1>::type::iterator iterator1;
int num = 0;
for (iterator3 i = A.begin(); i != A.end(); ++i)
for(iterator2 ii = (*i).begin(); ii != (*i).end(); ++ii)
for(iterator1 iii = (*ii).begin(); iii != (*ii).end(); ++iii)
*iii = num++;
}
template <typename Array>
struct ittraits_const {
typedef typename Array::const_iterator iterator3;
typedef typename boost::subarray_gen<Array,2>::type::const_iterator
iterator2;
typedef typename boost::subarray_gen<Array,1>::type::const_iterator
iterator1;
typedef typename Array::const_reverse_iterator riterator3;
typedef typename boost::subarray_gen<Array,2>::type::const_reverse_iterator
riterator2;
typedef typename boost::subarray_gen<Array,1>::type::const_reverse_iterator
riterator1;
};
template <typename Array>
struct ittraits_mutable {
typedef typename Array::iterator iterator3;
typedef typename boost::subarray_gen<Array,2>::type::iterator iterator2;
typedef typename boost::subarray_gen<Array,1>::type::iterator iterator1;
typedef typename Array::reverse_iterator riterator3;
typedef typename boost::subarray_gen<Array,2>::type::reverse_iterator
riterator2;
typedef typename boost::subarray_gen<Array,1>::type::reverse_iterator
riterator1;
};
// Meta-program chooses ittraits implementation.
template <typename Array, typename ConstTag>
struct ittraits_generator :
boost::mpl::if_< boost::is_same<ConstTag,const_array_tag>,
ittraits_const<Array>,
ittraits_mutable<Array> >
{};
template <typename Array>
void construct_iterators(Array&) {
// Default constructed iterators and
// const iterators constructed from iterators.
{
typename Array::iterator i1;
typename Array::const_iterator ci1;
typename Array::reverse_iterator r1;
typename Array::const_reverse_iterator cr1;
#if 0 // RG - MSVC fails to compile these
typename Array::const_iterator ci2 =
typename Array::iterator();
typename Array::const_reverse_iterator cr2 =
typename Array::reverse_iterator();
#endif
typename Array::const_iterator ci2 = i1;
typename Array::const_reverse_iterator cr2 = cr1;
boost::ignore_unused_variable_warning(cr2);
}
}
template <typename Array, typename IterTraits>
void test_iterators(Array& A, const IterTraits&) {
// Iterator comparison and arithmetic
{
typedef typename IterTraits::iterator3 iterator;
iterator i1 = A.begin();
iterator i2 = A.end();
BOOST_TEST(i1 < i2);
BOOST_TEST((i2 - i1) == typename iterator::difference_type(2));
}
// Standard Array Iteration
{
typedef typename IterTraits::iterator3 iterator3;
typedef typename IterTraits::iterator2 iterator2;
typedef typename IterTraits::iterator1 iterator1;
int vals = 0;
for (iterator3 i = A.begin(); i != A.end(); ++i)
for(iterator2 ii = (*i).begin(); ii != (*i).end(); ++ii)
for(iterator1 iii = (*ii).begin(); iii != (*ii).end(); ++iii)
BOOST_TEST(*iii == vals++);
}
// Using operator->() on iterators
{
typedef typename IterTraits::iterator3 iterator3;
typedef typename IterTraits::iterator2 iterator2;
typedef typename IterTraits::iterator1 iterator1;
int vals = 0;
for (iterator3 i = A.begin(); i != A.end(); ++i)
for(iterator2 ii = i->begin(); ii != i->end(); ++ii)
for(iterator1 iii = ii->begin(); iii != ii->end(); ++iii)
BOOST_TEST(*iii == vals++);
}
// Reverse Iterator Hierarchy Test
{
typedef typename IterTraits::riterator3 riterator3;
typedef typename IterTraits::riterator2 riterator2;
typedef typename IterTraits::riterator1 riterator1;
int check_iter_val = A.num_elements()-1;
for (riterator3 i = A.rbegin(); i != (riterator3)A.rend(); ++i)
for(riterator2 ii = (*i).rbegin(); ii != (riterator2)(*i).rend(); ++ii)
for(riterator1 iii = (*ii).rbegin(); iii != (riterator1)(*ii).rend();
++iii)
BOOST_TEST(*iii == check_iter_val--);
}
++tests_run;
}
template <typename Array>
void access(Array& A, const mutable_array_tag&) {
assign(A);
construct_iterators(A);
typedef typename ittraits_generator<Array,mutable_array_tag>::type
m_iter_traits;
typedef typename ittraits_generator<Array,const_array_tag>::type
c_iter_traits;
test_iterators(A,m_iter_traits());
test_iterators(A,c_iter_traits());
const Array& CA = A;
test_iterators(CA,c_iter_traits());
}
template <typename Array>
void access(Array& A, const const_array_tag&) {
construct_iterators(A);
typedef typename ittraits_generator<Array,const_array_tag>::type
c_iter_traits;
test_iterators(A,c_iter_traits());
}
int
main()
{
return run_generative_tests();
}
|