1 // Copyright 2002 The Trustees of Indiana University.
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)
7 // Boost.MultiArray Library
8 // Authors: Ronald Garcia
11 // See http://www.boost.org/libs/multi_array for documentation.
13 #ifndef ITERATOR_RG071801_HPP
14 #define ITERATOR_RG071801_HPP
17 // iterator.hpp - implementation of iterators for the
18 // multi-dimensional array class
21 #include "boost/multi_array/base.hpp"
22 #include "boost/iterator/iterator_facade.hpp"
23 #include "boost/mpl/aux_/msvc_eti_base.hpp"
30 namespace multi_array
{
32 /////////////////////////////////////////////////////////////////////////
33 // iterator components
34 /////////////////////////////////////////////////////////////////////////
37 struct operator_arrow_proxy
39 operator_arrow_proxy(T
const& px
) : value_(px
) {}
40 T
* operator->() const { return &value_
; }
41 // This function is needed for MWCW and BCC, which won't call operator->
42 // again automatically per 13.3.1.2 para 8
43 operator T
*() const { return &value_
; }
47 template <typename T
, typename TPtr
, typename NumDims
, typename Reference
>
50 template <typename T
, typename TPtr
, typename NumDims
, typename Reference
>
54 array_iterator
<T
,TPtr
,NumDims
,Reference
>
55 , typename associated_types
<T
,NumDims
>::value_type
56 , boost::random_access_traversal_tag
60 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
61 mpl::aux::msvc_eti_base
<typename
63 value_accessor_generator
<T
,NumDims
>::type
64 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
68 friend class iterator_core_access
;
69 typedef detail::multi_array::associated_types
<T
,NumDims
> access_t
;
71 typedef iterator_facade
<
72 array_iterator
<T
,TPtr
,NumDims
,Reference
>
73 , typename
detail::multi_array::associated_types
<T
,NumDims
>::value_type
74 , boost::random_access_traversal_tag
78 typedef typename
access_t::index index
;
79 typedef typename
access_t::size_type size_type
;
81 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
82 template <typename
, typename
, typename
, typename
>
83 friend class array_iterator
;
90 const size_type
* extents_
;
91 const index
* strides_
;
92 const index
* index_base_
;
95 // Typedefs to circumvent ambiguities between parent classes
96 typedef typename
facade_type::reference reference
;
97 typedef typename
facade_type::value_type value_type
;
98 typedef typename
facade_type::difference_type difference_type
;
102 array_iterator(index idx
, TPtr base
, const size_type
* extents
,
103 const index
* strides
,
104 const index
* index_base
) :
105 idx_(idx
), base_(base
), extents_(extents
),
106 strides_(strides
), index_base_(index_base
) { }
108 template <typename OPtr
, typename ORef
>
110 const array_iterator
<T
,OPtr
,NumDims
,ORef
>& rhs
111 , typename
boost::enable_if_convertible
<OPtr
,TPtr
>::type
* = 0
113 : idx_(rhs
.idx_
), base_(rhs
.base_
), extents_(rhs
.extents_
),
114 strides_(rhs
.strides_
), index_base_(rhs
.index_base_
) { }
117 // RG - we make our own operator->
118 operator_arrow_proxy
<reference
>
121 return operator_arrow_proxy
<reference
>(this->dereference());
125 reference
dereference() const
127 typedef typename value_accessor_generator
<T
,NumDims
>::type accessor
;
128 return accessor::access(boost::type
<reference
>(),
136 void increment() { ++idx_
; }
137 void decrement() { --idx_
; }
139 template <class IteratorAdaptor
>
140 bool equal(IteratorAdaptor
& rhs
) const {
141 const std::size_t N
= NumDims::value
;
142 return (idx_
== rhs
.idx_
) &&
143 (base_
== rhs
.base_
) &&
144 ( (extents_
== rhs
.extents_
) ||
145 std::equal(extents_
,extents_
+N
,rhs
.extents_
) ) &&
146 ( (strides_
== rhs
.strides_
) ||
147 std::equal(strides_
,strides_
+N
,rhs
.strides_
) ) &&
148 ( (index_base_
== rhs
.index_base_
) ||
149 std::equal(index_base_
,index_base_
+N
,rhs
.index_base_
) );
152 template <class DifferenceType
>
153 void advance(DifferenceType n
) {
157 template <class IteratorAdaptor
>
158 typename
facade_type::difference_type
159 distance_to(IteratorAdaptor
& rhs
) const {
160 return rhs
.idx_
- idx_
;
166 } // namespace multi_array
167 } // namespace detail
170 #endif // ITERATOR_RG071801_HPP