iterator.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2002 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Boost.MultiArray Library
  6. // Authors: Ronald Garcia
  7. // Jeremy Siek
  8. // Andrew Lumsdaine
  9. // See http://www.boost.org/libs/multi_array for documentation.
  10. #ifndef ITERATOR_RG071801_HPP
  11. #define ITERATOR_RG071801_HPP
  12. //
  13. // iterator.hpp - implementation of iterators for the
  14. // multi-dimensional array class
  15. //
  16. #include "boost/multi_array/base.hpp"
  17. #include "boost/iterator/iterator_facade.hpp"
  18. #include <algorithm>
  19. #include <cstddef>
  20. #include <iterator>
  21. namespace boost {
  22. namespace detail {
  23. namespace multi_array {
  24. /////////////////////////////////////////////////////////////////////////
  25. // iterator components
  26. /////////////////////////////////////////////////////////////////////////
  27. template <class T>
  28. struct operator_arrow_proxy
  29. {
  30. operator_arrow_proxy(T const& px) : value_(px) {}
  31. T* operator->() const { return &value_; }
  32. // This function is needed for MWCW and BCC, which won't call operator->
  33. // again automatically per 13.3.1.2 para 8
  34. operator T*() const { return &value_; }
  35. mutable T value_;
  36. };
  37. template <typename T, typename TPtr, typename NumDims, typename Reference,
  38. typename IteratorCategory>
  39. class array_iterator;
  40. template <typename T, typename TPtr, typename NumDims, typename Reference,
  41. typename IteratorCategory>
  42. class array_iterator
  43. : public
  44. iterator_facade<
  45. array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
  46. , typename associated_types<T,NumDims>::value_type
  47. , IteratorCategory
  48. , Reference
  49. >
  50. , private
  51. value_accessor_generator<T,NumDims>::type
  52. {
  53. friend class ::boost::iterator_core_access;
  54. typedef detail::multi_array::associated_types<T,NumDims> access_t;
  55. typedef iterator_facade<
  56. array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
  57. , typename detail::multi_array::associated_types<T,NumDims>::value_type
  58. , boost::random_access_traversal_tag
  59. , Reference
  60. > facade_type;
  61. typedef typename access_t::index index;
  62. typedef typename access_t::size_type size_type;
  63. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  64. template <typename, typename, typename, typename, typename>
  65. friend class array_iterator;
  66. #else
  67. public:
  68. #endif
  69. index idx_;
  70. TPtr base_;
  71. const size_type* extents_;
  72. const index* strides_;
  73. const index* index_base_;
  74. public:
  75. // Typedefs to circumvent ambiguities between parent classes
  76. typedef typename facade_type::reference reference;
  77. typedef typename facade_type::value_type value_type;
  78. typedef typename facade_type::difference_type difference_type;
  79. array_iterator() {}
  80. array_iterator(index idx, TPtr base, const size_type* extents,
  81. const index* strides,
  82. const index* index_base) :
  83. idx_(idx), base_(base), extents_(extents),
  84. strides_(strides), index_base_(index_base) { }
  85. template <typename OPtr, typename ORef, typename Cat>
  86. array_iterator(
  87. const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
  88. , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
  89. )
  90. : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
  91. strides_(rhs.strides_), index_base_(rhs.index_base_) { }
  92. // RG - we make our own operator->
  93. operator_arrow_proxy<reference>
  94. operator->() const
  95. {
  96. return operator_arrow_proxy<reference>(this->dereference());
  97. }
  98. reference dereference() const
  99. {
  100. typedef typename value_accessor_generator<T,NumDims>::type accessor;
  101. return accessor::access(boost::type<reference>(),
  102. idx_,
  103. base_,
  104. extents_,
  105. strides_,
  106. index_base_);
  107. }
  108. void increment() { ++idx_; }
  109. void decrement() { --idx_; }
  110. template <class IteratorAdaptor>
  111. bool equal(IteratorAdaptor& rhs) const {
  112. const std::size_t N = NumDims::value;
  113. return (idx_ == rhs.idx_) &&
  114. (base_ == rhs.base_) &&
  115. ( (extents_ == rhs.extents_) ||
  116. std::equal(extents_,extents_+N,rhs.extents_) ) &&
  117. ( (strides_ == rhs.strides_) ||
  118. std::equal(strides_,strides_+N,rhs.strides_) ) &&
  119. ( (index_base_ == rhs.index_base_) ||
  120. std::equal(index_base_,index_base_+N,rhs.index_base_) );
  121. }
  122. template <class DifferenceType>
  123. void advance(DifferenceType n) {
  124. idx_ += n;
  125. }
  126. template <class IteratorAdaptor>
  127. typename facade_type::difference_type
  128. distance_to(IteratorAdaptor& rhs) const {
  129. return rhs.idx_ - idx_;
  130. }
  131. };
  132. } // namespace multi_array
  133. } // namespace detail
  134. } // namespace boost
  135. #endif // ITERATOR_RG071801_HPP