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();
}
|