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