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
|
Index: branches/release/boost/multi_array/base.hpp
===================================================================
--- a/branches/release/boost/multi_array/base.hpp
+++ b/branches/release/boost/multi_array/base.hpp
@@ -18,6 +18,7 @@
// functionality is acquired
//
+#include "boost/multi_array/collection_concept.hpp"
#include "boost/multi_array/extent_range.hpp"
#include "boost/multi_array/extent_gen.hpp"
#include "boost/multi_array/index_range.hpp"
@@ -82,5 +82,6 @@
class const_sub_array;
-template <typename T, typename TPtr, typename NumDims, typename Reference>
+ template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
class array_iterator;
@@ -252,5 +253,17 @@
/////////////////////////////////////////////////////////////////////////
-
+// Due to some imprecision in the C++ Standard,
+// MSVC 2010 is broken in debug mode: it requires
+// that an Output Iterator have output_iterator_tag in its iterator_category if
+// that iterator is not bidirectional_iterator or random_access_iterator.
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+struct mutable_iterator_tag
+ : boost::random_access_traversal_tag, std::input_iterator_tag
+{
+ operator std::output_iterator_tag() const {
+ return std::output_iterator_tag();
+ }
+};
+#endif
////////////////////////////////////////////////////////////////////////
@@ -302,6 +315,14 @@
// iterator support
//
- typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference> iterator;
- typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference> const_iterator;
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+ // Deal with VC 2010 output_iterator_tag requirement
+ typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+ mutable_iterator_tag> iterator;
+#else
+ typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+ boost::random_access_traversal_tag> iterator;
+#endif
+ typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference,
+ boost::random_access_traversal_tag> const_iterator;
typedef ::boost::reverse_iterator<iterator> reverse_iterator;
@@ -322,5 +343,6 @@
const index* strides,
const index* index_bases) const {
-
+ boost::function_requires<
+ detail::multi_array::CollectionConcept<IndexList> >();
ignore_unused_variable_warning(index_bases);
ignore_unused_variable_warning(extents);
@@ -333,7 +355,13 @@
index offset = 0;
- for (size_type n = 0; n != NumDims; ++n)
- offset += indices[n] * strides[n];
-
+ {
+ typename IndexList::const_iterator i = indices.begin();
+ size_type n = 0;
+ while (n != NumDims) {
+ offset += (*i) * strides[n];
+ ++n;
+ ++i;
+ }
+ }
return base[offset];
}
Index: branches/release/boost/multi_array/concept_checks.hpp
===================================================================
--- a/branches/release/boost/multi_array/concept_checks.hpp
+++ b/branches/release/boost/multi_array/concept_checks.hpp
@@ -132,4 +132,5 @@
function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
+ function_requires< boost::OutputIterator<iterator,value_type> >();
// RG - a( CollectionArchetype) when available...
Index: branches/release/boost/multi_array/iterator.hpp
===================================================================
--- a/branches/release/boost/multi_array/iterator.hpp
+++ b/branches/release/boost/multi_array/iterator.hpp
@@ -45,14 +45,16 @@
};
-template <typename T, typename TPtr, typename NumDims, typename Reference>
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
class array_iterator;
-template <typename T, typename TPtr, typename NumDims, typename Reference>
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
class array_iterator
: public
iterator_facade<
- array_iterator<T,TPtr,NumDims,Reference>
+ array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename associated_types<T,NumDims>::value_type
- , boost::random_access_traversal_tag
+ , IteratorCategory
, Reference
>
@@ -70,5 +72,5 @@
typedef iterator_facade<
- array_iterator<T,TPtr,NumDims,Reference>
+ array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename detail::multi_array::associated_types<T,NumDims>::value_type
, boost::random_access_traversal_tag
@@ -80,5 +82,5 @@
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
- template <typename, typename, typename, typename>
+ template <typename, typename, typename, typename, typename>
friend class array_iterator;
#else
@@ -106,7 +108,7 @@
strides_(strides), index_base_(index_base) { }
- template <typename OPtr, typename ORef>
+ template <typename OPtr, typename ORef, typename Cat>
array_iterator(
- const array_iterator<T,OPtr,NumDims,ORef>& rhs
+ const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
, typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
)
|