• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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