source: NonGTP/Boost/boost/multi_array/iterator.hpp @ 857

Revision 857, 4.7 KB checked in by igarcia, 18 years ago (diff)
Line 
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#ifndef ITERATOR_RG071801_HPP
14#define ITERATOR_RG071801_HPP
15
16//
17// iterator.hpp - implementation of iterators for the
18// multi-dimensional array class
19//
20
21#include "boost/multi_array/base.hpp"
22#include "boost/iterator/iterator_facade.hpp"
23#include "boost/mpl/aux_/msvc_eti_base.hpp"
24#include <cstddef>
25#include <iterator>
26
27namespace boost {
28namespace detail {
29namespace multi_array {
30
31/////////////////////////////////////////////////////////////////////////
32// iterator components
33/////////////////////////////////////////////////////////////////////////
34
35template <class T>
36struct operator_arrow_proxy
37{
38  operator_arrow_proxy(T const& px) : value_(px) {}
39  T* operator->() const { return &value_; }
40  // This function is needed for MWCW and BCC, which won't call operator->
41  // again automatically per 13.3.1.2 para 8
42  operator T*() const { return &value_; }
43  mutable T value_;
44};
45
46template <typename T, typename TPtr, typename NumDims, typename Reference>
47class array_iterator;
48
49template <typename T, typename TPtr, typename NumDims, typename Reference>
50class array_iterator
51  : public
52    iterator_facade<
53        array_iterator<T,TPtr,NumDims,Reference>
54      , typename associated_types<T,NumDims>::value_type
55      , boost::random_access_traversal_tag
56      , Reference
57    >
58    , private
59#if BOOST_WORKAROUND(BOOST_MSVC,==1200)
60      mpl::aux::msvc_eti_base<typename
61#endif
62          value_accessor_generator<T,NumDims>::type
63#if BOOST_WORKAROUND(BOOST_MSVC,==1200)
64      >::type
65#endif
66{
67  friend class iterator_core_access;
68  typedef detail::multi_array::associated_types<T,NumDims> access_t;
69
70  typedef iterator_facade<
71        array_iterator<T,TPtr,NumDims,Reference>
72      , typename detail::multi_array::associated_types<T,NumDims>::value_type
73      , boost::random_access_traversal_tag
74      , Reference
75    > facade_type;
76
77  typedef typename access_t::index index;
78  typedef typename access_t::size_type size_type;
79
80#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
81  template <typename, typename, typename, typename>
82    friend class array_iterator;
83#else
84 public:
85#endif
86
87  index idx_;
88  TPtr base_;
89  const size_type* extents_;
90  const index* strides_;
91  const index* index_base_;
92 
93public:
94  // Typedefs to circumvent ambiguities between parent classes
95  typedef typename facade_type::reference reference;
96  typedef typename facade_type::value_type value_type;
97  typedef typename facade_type::difference_type difference_type;
98
99  array_iterator() {}
100
101  array_iterator(index idx, TPtr base, const size_type* extents,
102                const index* strides,
103                const index* index_base) :
104    idx_(idx), base_(base), extents_(extents),
105    strides_(strides), index_base_(index_base) { }
106
107  template <typename OPtr, typename ORef>
108  array_iterator(
109      const array_iterator<T,OPtr,NumDims,ORef>& rhs
110    , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
111  )
112    : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
113    strides_(rhs.strides_), index_base_(rhs.index_base_) { }
114
115
116  // RG - we make our own operator->
117  operator_arrow_proxy<reference>
118  operator->() const
119  {
120    return operator_arrow_proxy<reference>(this->dereference());
121  }
122 
123
124  reference dereference() const
125  {
126    typedef typename value_accessor_generator<T,NumDims>::type accessor;
127    return accessor::access(boost::type<reference>(),
128                            idx_,
129                            base_,
130                            extents_,
131                            strides_,
132                            index_base_);
133  }
134 
135  void increment() { ++idx_; }
136  void decrement() { --idx_; }
137
138  template <class IteratorAdaptor>
139  bool equal(IteratorAdaptor& rhs) const {
140    return (idx_ == rhs.idx_) &&
141      (base_ == rhs.base_) &&
142      (extents_ == rhs.extents_) &&
143      (strides_ == rhs.strides_) &&
144      (index_base_ == rhs.index_base_);
145  }
146
147  template <class DifferenceType>
148  void advance(DifferenceType n) {
149    idx_ += n;
150  }
151
152  template <class IteratorAdaptor>
153  typename facade_type::difference_type
154  distance_to(IteratorAdaptor& rhs) const {
155    return rhs.idx_ - idx_;
156  }
157
158
159};
160
161} // namespace multi_array
162} // namespace detail
163} // namespace boost
164
165#endif // ITERATOR_RG071801_HPP
Note: See TracBrowser for help on using the repository browser.