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
26template <typename Array>
27void 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
41template <typename Array>
42struct 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
56template <typename Array>
57struct 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.
71template <typename Array, typename ConstTag>
72struct ittraits_generator :
73 boost::mpl::if_< boost::is_same<ConstTag,const_array_tag>,
74 ittraits_const<Array>,
75 ittraits_mutable<Array> >
76{};
77
78
79template <typename Array>
80void 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
102template <typename Array, typename IterTraits>
103void 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
157template <typename Array>
158void 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
175template <typename Array>
176void 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
184int
185main()
186{
187 return run_generative_tests();
188}
189

source code of boost/libs/multi_array/test/iterators.cpp