summaryrefslogtreecommitdiff
path: root/boost/multi_array/iterator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/multi_array/iterator.hpp')
-rw-r--r--boost/multi_array/iterator.hpp170
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