Chris@16: // Copyright 2002 The Trustees of Indiana University. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // Boost.MultiArray Library Chris@16: // Authors: Ronald Garcia Chris@16: // Jeremy Siek Chris@16: // Andrew Lumsdaine Chris@16: // See http://www.boost.org/libs/multi_array for documentation. Chris@16: Chris@16: #ifndef ITERATOR_RG071801_HPP Chris@16: #define ITERATOR_RG071801_HPP Chris@16: Chris@16: // Chris@16: // iterator.hpp - implementation of iterators for the Chris@16: // multi-dimensional array class Chris@16: // Chris@16: Chris@16: #include "boost/multi_array/base.hpp" Chris@16: #include "boost/iterator/iterator_facade.hpp" Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace detail { Chris@16: namespace multi_array { Chris@16: Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: // iterator components Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: struct operator_arrow_proxy Chris@16: { Chris@16: operator_arrow_proxy(T const& px) : value_(px) {} Chris@16: T* operator->() const { return &value_; } Chris@16: // This function is needed for MWCW and BCC, which won't call operator-> Chris@16: // again automatically per 13.3.1.2 para 8 Chris@16: operator T*() const { return &value_; } Chris@16: mutable T value_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class array_iterator; Chris@16: Chris@16: template Chris@16: class array_iterator Chris@16: : public Chris@16: iterator_facade< Chris@16: array_iterator Chris@16: , typename associated_types::value_type Chris@16: , IteratorCategory Chris@16: , Reference Chris@16: > Chris@16: , private Chris@16: value_accessor_generator::type Chris@16: { Chris@16: friend class iterator_core_access; Chris@16: typedef detail::multi_array::associated_types access_t; Chris@16: Chris@16: typedef iterator_facade< Chris@16: array_iterator Chris@16: , typename detail::multi_array::associated_types::value_type Chris@16: , boost::random_access_traversal_tag Chris@16: , Reference Chris@16: > facade_type; Chris@16: Chris@16: typedef typename access_t::index index; Chris@16: typedef typename access_t::size_type size_type; Chris@16: Chris@16: #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS Chris@16: template Chris@16: friend class array_iterator; Chris@16: #else Chris@16: public: Chris@16: #endif Chris@16: Chris@16: index idx_; Chris@16: TPtr base_; Chris@16: const size_type* extents_; Chris@16: const index* strides_; Chris@16: const index* index_base_; Chris@16: Chris@16: public: Chris@16: // Typedefs to circumvent ambiguities between parent classes Chris@16: typedef typename facade_type::reference reference; Chris@16: typedef typename facade_type::value_type value_type; Chris@16: typedef typename facade_type::difference_type difference_type; Chris@16: Chris@16: array_iterator() {} Chris@16: Chris@16: array_iterator(index idx, TPtr base, const size_type* extents, Chris@16: const index* strides, Chris@16: const index* index_base) : Chris@16: idx_(idx), base_(base), extents_(extents), Chris@16: strides_(strides), index_base_(index_base) { } Chris@16: Chris@16: template Chris@16: array_iterator( Chris@16: const array_iterator& rhs Chris@16: , typename boost::enable_if_convertible::type* = 0 Chris@16: ) Chris@16: : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_), Chris@16: strides_(rhs.strides_), index_base_(rhs.index_base_) { } Chris@16: Chris@16: Chris@16: // RG - we make our own operator-> Chris@16: operator_arrow_proxy Chris@16: operator->() const Chris@16: { Chris@16: return operator_arrow_proxy(this->dereference()); Chris@16: } Chris@16: Chris@16: Chris@16: reference dereference() const Chris@16: { Chris@16: typedef typename value_accessor_generator::type accessor; Chris@16: return accessor::access(boost::type(), Chris@16: idx_, Chris@16: base_, Chris@16: extents_, Chris@16: strides_, Chris@16: index_base_); Chris@16: } Chris@16: Chris@16: void increment() { ++idx_; } Chris@16: void decrement() { --idx_; } Chris@16: Chris@16: template Chris@16: bool equal(IteratorAdaptor& rhs) const { Chris@16: const std::size_t N = NumDims::value; Chris@16: return (idx_ == rhs.idx_) && Chris@16: (base_ == rhs.base_) && Chris@16: ( (extents_ == rhs.extents_) || Chris@16: std::equal(extents_,extents_+N,rhs.extents_) ) && Chris@16: ( (strides_ == rhs.strides_) || Chris@16: std::equal(strides_,strides_+N,rhs.strides_) ) && Chris@16: ( (index_base_ == rhs.index_base_) || Chris@16: std::equal(index_base_,index_base_+N,rhs.index_base_) ); Chris@16: } Chris@16: Chris@16: template Chris@16: void advance(DifferenceType n) { Chris@16: idx_ += n; Chris@16: } Chris@16: Chris@16: template Chris@16: typename facade_type::difference_type Chris@16: distance_to(IteratorAdaptor& rhs) const { Chris@16: return rhs.idx_ - idx_; Chris@16: } Chris@16: Chris@16: Chris@16: }; Chris@16: Chris@16: } // namespace multi_array Chris@16: } // namespace detail Chris@16: } // namespace boost Chris@16: Chris@16: #endif // ITERATOR_RG071801_HPP