]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/iterator.hpp
update to boost 1.32.0
[lyx.git] / boost / boost / multi_array / iterator.hpp
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
27 namespace boost {
28 namespace detail {
29 namespace multi_array {
30
31 /////////////////////////////////////////////////////////////////////////
32 // iterator components
33 /////////////////////////////////////////////////////////////////////////
34
35 template <class T>
36 struct 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
46 template <typename T, typename TPtr, typename NumDims, typename Reference>
47 class array_iterator;
48
49 template <typename T, typename TPtr, typename NumDims, typename Reference>
50 class 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  
93 public:
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(int 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