File indexing completed on 2025-01-18 09:42:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_MULTI_ARRAY_ITERATOR_HPP
0014 #define BOOST_MULTI_ARRAY_ITERATOR_HPP
0015
0016
0017
0018
0019
0020
0021 #include "boost/multi_array/base.hpp"
0022 #include "boost/iterator/iterator_facade.hpp"
0023 #include <algorithm>
0024 #include <cstddef>
0025 #include <iterator>
0026
0027 namespace boost {
0028 namespace detail {
0029 namespace multi_array {
0030
0031
0032
0033
0034
0035 template <class T>
0036 struct operator_arrow_proxy
0037 {
0038 operator_arrow_proxy(T const& px) : value_(px) {}
0039 T* operator->() const { return &value_; }
0040
0041
0042 operator T*() const { return &value_; }
0043 mutable T value_;
0044 };
0045
0046 template <typename T, typename TPtr, typename NumDims, typename Reference,
0047 typename IteratorCategory>
0048 class array_iterator;
0049
0050 template <typename T, typename TPtr, typename NumDims, typename Reference,
0051 typename IteratorCategory>
0052 class array_iterator
0053 : public
0054 iterator_facade<
0055 array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
0056 , typename associated_types<T,NumDims>::value_type
0057 , IteratorCategory
0058 , Reference
0059 >
0060 , private
0061 value_accessor_generator<T,NumDims>::type
0062 {
0063 friend class ::boost::iterator_core_access;
0064 typedef detail::multi_array::associated_types<T,NumDims> access_t;
0065
0066 typedef iterator_facade<
0067 array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
0068 , typename detail::multi_array::associated_types<T,NumDims>::value_type
0069 , boost::random_access_traversal_tag
0070 , Reference
0071 > facade_type;
0072
0073 typedef typename access_t::index index;
0074 typedef typename access_t::size_type size_type;
0075
0076 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0077 template <typename, typename, typename, typename, typename>
0078 friend class array_iterator;
0079 #else
0080 public:
0081 #endif
0082
0083 index idx_;
0084 TPtr base_;
0085 const size_type* extents_;
0086 const index* strides_;
0087 const index* index_base_;
0088
0089 public:
0090
0091 typedef typename facade_type::reference reference;
0092 typedef typename facade_type::value_type value_type;
0093 typedef typename facade_type::difference_type difference_type;
0094
0095 array_iterator() {}
0096
0097 array_iterator(index idx, TPtr base, const size_type* extents,
0098 const index* strides,
0099 const index* index_base) :
0100 idx_(idx), base_(base), extents_(extents),
0101 strides_(strides), index_base_(index_base) { }
0102
0103 template <typename OPtr, typename ORef, typename Cat>
0104 array_iterator(
0105 const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
0106 , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
0107 )
0108 : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
0109 strides_(rhs.strides_), index_base_(rhs.index_base_) { }
0110
0111
0112
0113 operator_arrow_proxy<reference>
0114 operator->() const
0115 {
0116 return operator_arrow_proxy<reference>(this->dereference());
0117 }
0118
0119
0120 reference dereference() const
0121 {
0122 typedef typename value_accessor_generator<T,NumDims>::type accessor;
0123 return accessor::access(boost::type<reference>(),
0124 idx_,
0125 base_,
0126 extents_,
0127 strides_,
0128 index_base_);
0129 }
0130
0131 void increment() { ++idx_; }
0132 void decrement() { --idx_; }
0133
0134 template <class IteratorAdaptor>
0135 bool equal(IteratorAdaptor& rhs) const {
0136 const std::size_t N = NumDims::value;
0137 return (idx_ == rhs.idx_) &&
0138 (base_ == rhs.base_) &&
0139 ( (extents_ == rhs.extents_) ||
0140 std::equal(extents_,extents_+N,rhs.extents_) ) &&
0141 ( (strides_ == rhs.strides_) ||
0142 std::equal(strides_,strides_+N,rhs.strides_) ) &&
0143 ( (index_base_ == rhs.index_base_) ||
0144 std::equal(index_base_,index_base_+N,rhs.index_base_) );
0145 }
0146
0147 template <class DifferenceType>
0148 void advance(DifferenceType n) {
0149 idx_ += n;
0150 }
0151
0152 template <class IteratorAdaptor>
0153 typename facade_type::difference_type
0154 distance_to(IteratorAdaptor& rhs) const {
0155 return rhs.idx_ - idx_;
0156 }
0157
0158
0159 };
0160
0161 }
0162 }
0163 }
0164
0165 #endif