]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/multi_array/iterator.hpp
* src/MenuBackend.[Ch]: the specialMenu is now a real menu, not a
[lyx.git] / boost / boost / multi_array / iterator.hpp
index 529d19e3e512fae9215e94fc1cbfbc4f5a5226dd..59e7724f55048d9af26fea77fd9aa572c6ba6f53 100644 (file)
@@ -1,14 +1,14 @@
-// Copyright (C) 2002 Ronald Garcia
-//
-// Permission to copy, use, sell and distribute this software is granted
-// provided this copyright notice appears in all copies. 
-// Permission to modify the code and to distribute modified code is granted
-// provided this copyright notice appears in all copies, and a notice 
-// that the code was modified is included with the copyright notice.
-//
-// This software is provided "as is" without express or implied warranty, 
-// and with no claim as to its suitability for any purpose.
-//
+// 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
@@ -19,8 +19,9 @@
 //
 
 #include "boost/multi_array/base.hpp"
-#include "boost/multi_array/iterator_adaptors.hpp"
-#include "boost/iterator_adaptors.hpp"
+#include "boost/iterator/iterator_facade.hpp"
+#include "boost/mpl/aux_/msvc_eti_base.hpp"
+#include <algorithm>
 #include <cstddef>
 #include <iterator>
 
@@ -32,136 +33,134 @@ namespace multi_array {
 // iterator components
 /////////////////////////////////////////////////////////////////////////
 
-template <typename T, typename TPtr>
-struct iterator_base : private multi_array_base {
-  typedef multi_array_base super_type;
-  typedef super_type::index index;
-  typedef super_type::size_type size_type;
+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() {}
 
-  iterator_base(int idx, TPtr base, const size_type* extents,
+  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) {
+    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());
   }
+  
 
-  template <typename OPtr>
-  iterator_base(const iterator_base<T,OPtr>& rhs) :
-    idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
-    strides_(rhs.strides_), index_base_(rhs.index_base_) {
-  }
-
-  // default constructor required
-  iterator_base() {}
-};
-
-template<typename T, std::size_t NumDims>
-struct iterator_policies :
-  public boost::detail::multi_array::default_iterator_policies,
-  private value_accessor_generator<T,NumDims>::type {
-private:
-  typedef typename value_accessor_generator<T,NumDims>::type super_type;
-public:
-  template <class IteratorAdaptor>
-  typename IteratorAdaptor::reference
-  dereference(const IteratorAdaptor& iter) const {
-    typedef typename IteratorAdaptor::reference reference;
-    return super_type::access(boost::type<reference>(),
-                              iter.base().idx_,
-                              iter.base().base_,
-                              iter.base().extents_,
-                              iter.base().strides_,
-                              iter.base().index_base_);
+  reference dereference() const
+  {
+    typedef typename value_accessor_generator<T,NumDims>::type accessor;
+    return accessor::access(boost::type<reference>(),
+                            idx_,
+                            base_,
+                            extents_,
+                            strides_,
+                            index_base_);
   }
   
-  template <class IteratorAdaptor>
-  static void increment(IteratorAdaptor& x) { ++x.base().idx_; }
+  void increment() { ++idx_; }
+  void decrement() { --idx_; }
 
   template <class IteratorAdaptor>
-  static void decrement(IteratorAdaptor& x) { --x.base().idx_; }
-
-  template <class IteratorAdaptor1, class IteratorAdaptor2>
-  bool equal(IteratorAdaptor1& lhs, IteratorAdaptor2& rhs) const {
-    return (lhs.base().idx_ == rhs.base().idx_) &&
-      (lhs.base().base_ == rhs.base().base_) &&
-      (lhs.base().extents_ == rhs.base().extents_) &&
-      (lhs.base().strides_ == rhs.base().strides_) &&
-      (lhs.base().index_base_ == rhs.base().index_base_);
+  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 IteratorAdaptor, class DifferenceType>
-  static void advance(IteratorAdaptor& x, DifferenceType n) {
-    x.idx_ += n;
+  template <class DifferenceType>
+  void advance(DifferenceType n) {
+    idx_ += n;
   }
 
-  template <class IteratorAdaptor1, class IteratorAdaptor2>
-  typename IteratorAdaptor1::difference_type
-  distance(IteratorAdaptor1& lhs, IteratorAdaptor2& rhs) const {
-    return rhs.base().idx_ - lhs.base().idx_;
+  template <class IteratorAdaptor>
+  typename facade_type::difference_type
+  distance_to(IteratorAdaptor& rhs) const {
+    return rhs.idx_ - idx_;
   }
-};
-
-
-template <typename T, typename base_type,
-  std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct iterator_gen_helper {
-private:
-  typedef iterator_policies<T,NumDims> policies;
-  typedef value_type* pointer_type;
-  typedef tag category;
-public:
-  typedef boost::detail::multi_array::iterator_adaptor<base_type,policies,value_type,
-    reference_type,pointer_type,category,difference_type> type;
-};
-
-
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct iterator_generator {
-private:
-  typedef iterator_base<T,T*> base_type;
-public:
-  typedef typename iterator_gen_helper<T,base_type,NumDims,value_type,
-    reference_type,tag,difference_type>::type type;
-};
-
-template <typename T,  std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct const_iterator_generator {
-private:
-  typedef iterator_base<T,const T*> base_type;
-public:
-  typedef typename iterator_gen_helper<T,base_type,NumDims,value_type,
-    reference_type,tag,difference_type>::type type;
-};
 
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct reverse_iterator_generator {
-private:
-  typedef iterator_base<T,T*> base_type;
-  typedef typename iterator_gen_helper<T,base_type,NumDims,value_type,
-    reference_type,tag,difference_type>::type it_type;
-public:
-  typedef typename boost::reverse_iterator_generator<it_type>::type type;
-};
 
-template <typename T,  std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct const_reverse_iterator_generator {
-private:
-  typedef iterator_base<T,const T*> base_type;
-  typedef typename iterator_gen_helper<T,base_type,NumDims,value_type,
-    reference_type,tag,difference_type>::type it_type;
-public:
-  typedef typename boost::reverse_iterator_generator<it_type>::type type;
 };
 
 } // namespace multi_array