]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/iterator.hpp
* src/MenuBackend.[Ch]: the specialMenu is now a real menu, not a
[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 <algorithm>
25 #include <cstddef>
26 #include <iterator>
27
28 namespace boost {
29 namespace detail {
30 namespace multi_array {
31
32 /////////////////////////////////////////////////////////////////////////
33 // iterator components
34 /////////////////////////////////////////////////////////////////////////
35
36 template <class T>
37 struct operator_arrow_proxy
38 {
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_; }
44   mutable T value_;
45 };
46
47 template <typename T, typename TPtr, typename NumDims, typename Reference>
48 class array_iterator;
49
50 template <typename T, typename TPtr, typename NumDims, typename Reference>
51 class array_iterator
52   : public
53     iterator_facade<
54         array_iterator<T,TPtr,NumDims,Reference>
55       , typename associated_types<T,NumDims>::value_type
56       , boost::random_access_traversal_tag
57       , Reference
58     >
59     , private
60 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
61       mpl::aux::msvc_eti_base<typename 
62 #endif 
63           value_accessor_generator<T,NumDims>::type
64 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
65       >::type
66 #endif 
67 {
68   friend class iterator_core_access;
69   typedef detail::multi_array::associated_types<T,NumDims> access_t;
70
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
75       , Reference
76     > facade_type;
77
78   typedef typename access_t::index index;
79   typedef typename access_t::size_type size_type;
80
81 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
82   template <typename, typename, typename, typename>
83     friend class array_iterator;
84 #else
85  public:
86 #endif 
87
88   index idx_;
89   TPtr base_;
90   const size_type* extents_;
91   const index* strides_;
92   const index* index_base_;
93  
94 public:
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;
99
100   array_iterator() {}
101
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) { }
107
108   template <typename OPtr, typename ORef>
109   array_iterator(
110       const array_iterator<T,OPtr,NumDims,ORef>& rhs
111     , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
112   )
113     : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
114     strides_(rhs.strides_), index_base_(rhs.index_base_) { }
115
116
117   // RG - we make our own operator->
118   operator_arrow_proxy<reference>
119   operator->() const
120   {
121     return operator_arrow_proxy<reference>(this->dereference());
122   }
123   
124
125   reference dereference() const
126   {
127     typedef typename value_accessor_generator<T,NumDims>::type accessor;
128     return accessor::access(boost::type<reference>(),
129                             idx_,
130                             base_,
131                             extents_,
132                             strides_,
133                             index_base_);
134   }
135   
136   void increment() { ++idx_; }
137   void decrement() { --idx_; }
138
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_) );
150   }
151
152   template <class DifferenceType>
153   void advance(DifferenceType n) {
154     idx_ += n;
155   }
156
157   template <class IteratorAdaptor>
158   typename facade_type::difference_type
159   distance_to(IteratorAdaptor& rhs) const {
160     return rhs.idx_ - idx_;
161   }
162
163
164 };
165
166 } // namespace multi_array
167 } // namespace detail
168 } // namespace boost
169
170 #endif // ITERATOR_RG071801_HPP