Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:06

0001 // Copyright 2002 The Trustees of Indiana University.
0002 
0003 // Use, modification and distribution is subject to the Boost Software 
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  Boost.MultiArray Library
0008 //  Authors: Ronald Garcia
0009 //           Jeremy Siek
0010 //           Andrew Lumsdaine
0011 //  See http://www.boost.org/libs/multi_array for documentation.
0012 
0013 #ifndef BOOST_MULTI_ARRAY_ITERATOR_HPP
0014 #define BOOST_MULTI_ARRAY_ITERATOR_HPP
0015 
0016 //
0017 // iterator.hpp - implementation of iterators for the
0018 // multi-dimensional array class
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 // iterator components
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   // This function is needed for MWCW and BCC, which won't call operator->
0041   // again automatically per 13.3.1.2 para 8
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   // Typedefs to circumvent ambiguities between parent classes
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   // RG - we make our own operator->
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 } // namespace multi_array
0162 } // namespace detail
0163 } // namespace boost
0164 
0165 #endif