epoc32/include/stdapis/boost/multi_array/iterator.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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