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