]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/multi_array/multi_array_ref.hpp
* src/MenuBackend.[Ch]: the specialMenu is now a real menu, not a
[lyx.git] / boost / boost / multi_array / multi_array_ref.hpp
index 43418df2321cba5d374958d3bf26e3c2b8c36e74..41b962a8ebe0b87fb7f81821f10b2664fb9aa7ab 100644 (file)
@@ -1,3 +1,15 @@
+// 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 BOOST_MULTI_ARRAY_REF_RG071801_HPP
 #define BOOST_MULTI_ARRAY_REF_RG071801_HPP
 
@@ -13,6 +25,7 @@
 #include "boost/multi_array/subarray.hpp"
 #include "boost/multi_array/view.hpp"
 #include "boost/multi_array/algorithm.hpp"
+#include "boost/type_traits/is_integral.hpp"
 #include "boost/array.hpp"
 #include "boost/concept_check.hpp"
 #include "boost/functional.hpp"
@@ -36,14 +49,13 @@ public:
   typedef typename super_type::value_type value_type;
   typedef typename super_type::const_reference const_reference;
   typedef typename super_type::const_iterator const_iterator;
-  typedef typename super_type::const_iter_base const_iter_base;
   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
   typedef typename super_type::element element;
   typedef typename super_type::size_type size_type;
   typedef typename super_type::difference_type difference_type;
   typedef typename super_type::index index;
   typedef typename super_type::extent_range extent_range;
-
+  typedef general_storage_order<NumDims> storage_order_type;
 
   // template typedefs
   template <std::size_t NDims>
@@ -62,9 +74,10 @@ public:
   friend class const_multi_array_ref;
 #endif
 
+  // This ensures that const_multi_array_ref types with different TPtr 
+  // types can convert to each other
   template <typename OPtr>
-  const_multi_array_ref(const const_multi_array_ref<T,NumDims,
-                       OPtr>& other)
+  const_multi_array_ref(const const_multi_array_ref<T,NumDims,OPtr>& other)
     : base_(other.base_), storage_(other.storage_),
       extent_list_(other.extent_list_),
       stride_list_(other.stride_list_),
@@ -85,7 +98,7 @@ public:
   
   template <typename ExtentList>
   explicit const_multi_array_ref(TPtr base, const ExtentList& extents,
-                      const general_storage_order<NumDims>& so) : 
+                       const general_storage_order<NumDims>& so) : 
     base_(base), storage_(so) {
     boost::function_requires<
       detail::multi_array::CollectionConcept<ExtentList> >();
@@ -95,17 +108,17 @@ public:
   }
   
   explicit const_multi_array_ref(TPtr base,
-                        const detail::multi_array::
-                        extent_gen<NumDims>& ranges) :
+                         const detail::multi_array::
+                         extent_gen<NumDims>& ranges) :
     base_(base), storage_(c_storage_order()) {
 
     init_from_extent_gen(ranges);
   }
   
   explicit const_multi_array_ref(TPtr base,
-                          const detail::multi_array::
-                          extent_gen<NumDims>& ranges,
-                          const general_storage_order<NumDims>& so) :
+                           const detail::multi_array::
+                           extent_gen<NumDims>& ranges,
+                           const general_storage_order<NumDims>& so) :
     base_(base), storage_(so) {
 
     init_from_extent_gen(ranges);
@@ -125,20 +138,27 @@ public:
   }
 
   template <class BaseList>
-  void reindex(const BaseList& values) {
+#ifdef BOOST_NO_SFINAE
+  void
+#else
+  typename
+  disable_if<typename boost::is_integral<BaseList>::type,void >::type
+#endif // BOOST_NO_SFINAE
+  reindex(const BaseList& values) {
     boost::function_requires<
       detail::multi_array::CollectionConcept<BaseList> >();
-    boost::copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
+    boost::detail::multi_array::
+      copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
     origin_offset_ =
-      calculate_origin_offset(stride_list_,extent_list_,
-                             storage_,index_base_list_);
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
   }
 
   void reindex(index value) {
     index_base_list_.assign(value);
     origin_offset_ =
-      calculate_origin_offset(stride_list_,extent_list_,
-                             storage_,index_base_list_);
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
   }
 
   template <typename SizeList>
@@ -146,15 +166,15 @@ public:
     boost::function_requires<
       detail::multi_array::CollectionConcept<SizeList> >();
     assert(num_elements_ ==
-          std::accumulate(extents.begin(),extents.end(),
-                           size_type(1),std::multiplies<size_type>()));
+           std::accumulate(extents.begin(),extents.end(),
+                            size_type(1),std::multiplies<size_type>()));
 
     std::copy(extents.begin(),extents.end(),extent_list_.begin());
-    compute_strides(stride_list_,extent_list_,storage_);
+    this->compute_strides(stride_list_,extent_list_,storage_);
 
     origin_offset_ =
-      calculate_origin_offset(stride_list_,extent_list_,
-                             storage_,index_base_list_);
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
   }
 
   size_type num_dimensions() const { return NumDims; }
@@ -183,50 +203,55 @@ public:
     return index_base_list_.data();
   }
 
+
+  const storage_order_type& storage_order() const {
+    return storage_;
+  }
+
   template <typename IndexList>
   const element& operator()(IndexList indices) const {
     boost::function_requires<
       detail::multi_array::CollectionConcept<IndexList> >();
     return super_type::access_element(boost::type<const element&>(),
-                                     origin(),
-                                     indices,strides());
+                                      indices,origin(),
+                                      shape(),strides(),index_bases());
   }
 
   // Only allow const element access
   const_reference operator[](index idx) const {
     return super_type::access(boost::type<const_reference>(),
-                             idx,origin(),
-                             shape(),strides(),index_bases());
+                              idx,origin(),
+                              shape(),strides(),index_bases());
   }
 
   // see generate_array_view in base.hpp
-#ifndef BOOST_MSVC
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
   template <int NDims>
 #else
   template <int NumDims, int NDims> // else ICE
 #endif // BOOST_MSVC
   typename const_array_view<NDims>::type 
   operator[](const detail::multi_array::
-            index_gen<NumDims,NDims>& indices)
+             index_gen<NumDims,NDims>& indices)
     const {
-    typedef const_array_view<NDims>::type return_type;
+    typedef typename const_array_view<NDims>::type return_type;
     return
       super_type::generate_array_view(boost::type<return_type>(),
-                                     indices,
-                                     shape(),
-                                     strides(),
-                                     index_bases(),
-                                     origin());
+                                      indices,
+                                      shape(),
+                                      strides(),
+                                      index_bases(),
+                                      origin());
   }
   
   const_iterator begin() const {
-    return const_iterator(const_iter_base(*index_bases(),origin(),
-                                  shape(),strides(),index_bases()));
+    return const_iterator(*index_bases(),origin(),
+                          shape(),strides(),index_bases());
   }
 
   const_iterator end() const {
-    return const_iterator(const_iter_base(*index_bases()+*shape(),origin(),
-                                  shape(),strides(),index_bases()));
+    return const_iterator(*index_bases()+(index)*shape(),origin(),
+                          shape(),strides(),index_bases());
   }
 
   const_reverse_iterator rbegin() const {
@@ -240,79 +265,93 @@ public:
 
   template <typename OPtr>
   bool operator==(const
-                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                  const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     if(std::equal(extent_list_.begin(),
-                 extent_list_.end(),
-                 rhs.extent_list_.begin()))
+                  extent_list_.end(),
+                  rhs.extent_list_.begin()))
       return std::equal(begin(),end(),rhs.begin());
     else return false;
   }
 
   template <typename OPtr>
   bool operator<(const
-                const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
   }
 
   template <typename OPtr>
   bool operator!=(const
-                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                  const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     return !(*this == rhs);
   }
 
   template <typename OPtr>
   bool operator>(const
-                const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     return rhs < *this;
   }
 
   template <typename OPtr>
   bool operator<=(const
-                const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     return !(*this > rhs);
   }
 
   template <typename OPtr>
   bool operator>=(const
-                const_multi_array_ref<T,NumDims,OPtr>& rhs)
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
     const {
     return !(*this < rhs);
   }
 
-// This ensures that const_multi_array_ref types with different TPtr 
-// types can convert to each other
+
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 protected:
 #else
 public:
 #endif
+
+  typedef boost::array<size_type,NumDims> size_list;
+  typedef boost::array<index,NumDims> index_list;
+
   // This is used by multi_array, which is a subclass of this
   void set_base_ptr(TPtr new_base) { base_ = new_base; }
 
-  template <typename OPtr>
-  const_multi_array_ref(const detail::multi_array::
-                 const_sub_array<T,NumDims,OPtr>& rhs)
-    : base_(rhs.origin()),
-      storage_(c_storage_order()),
-      origin_offset_(0), directional_offset_(0),
-      num_elements_(rhs.num_elements())
-  {
-    using boost::copy_n;
-    copy_n(rhs.shape(),rhs.num_dimensions(),extent_list_.begin());
-    copy_n(rhs.strides(),rhs.num_dimensions(),stride_list_.begin());
-    copy_n(rhs.index_bases(),rhs.num_dimensions(),index_base_list_.begin());
-  }
 
-  typedef boost::array<size_type,NumDims> size_list;
-  typedef boost::array<index,NumDims> index_list;
+  // This constructor supports multi_array's default constructor
+  // and constructors from multi_array_ref, subarray, and array_view
+  explicit
+  const_multi_array_ref(TPtr base,
+                        const storage_order_type& so,
+                        const index * index_bases,
+                        const size_type* extents) :
+    base_(base), storage_(so), origin_offset_(0), directional_offset_(0)
+ {
+   // If index_bases or extents is null, then initialize the corresponding
+   // private data to zeroed lists.
+   if(index_bases) {
+     boost::detail::multi_array::
+       copy_n(index_bases,NumDims,index_base_list_.begin());
+   } else {
+     std::fill_n(index_base_list_.begin(),NumDims,0);
+   }
+   if(extents) {
+     init_multi_array_ref(extents);
+   } else {
+     boost::array<index,NumDims> extent_list;
+     extent_list.assign(0);
+     init_multi_array_ref(extent_list.begin());
+   }
+ }
+
 
   TPtr base_;
-  general_storage_order<NumDims> storage_;
+  storage_order_type storage_;
   size_list extent_list_;
   index_list stride_list_;
   index_list index_base_list_;
@@ -325,49 +364,54 @@ private:
   const_multi_array_ref& operator=(const const_multi_array_ref& other);
 
   void init_from_extent_gen(const
-                       detail::multi_array::
-                       extent_gen<NumDims>& ranges) { 
+                        detail::multi_array::
+                        extent_gen<NumDims>& ranges) { 
     
     typedef boost::array<index,NumDims> extent_list;
 
     // get the index_base values
     std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
-             index_base_list_.begin(),
-             boost::mem_fun_ref(&extent_range::start));
+              index_base_list_.begin(),
+              boost::mem_fun_ref(&extent_range::start));
 
     // calculate the extents
     extent_list extents;
     std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
-             extents.begin(),
-             boost::mem_fun_ref(&extent_range::size));
+              extents.begin(),
+              boost::mem_fun_ref(&extent_range::size));
 
     init_multi_array_ref(extents.begin());
   }
 
 
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+#else
+public:
+#endif
+  // RG - move me!
   template <class InputIterator>
   void init_multi_array_ref(InputIterator extents_iter) {
     boost::function_requires<InputIteratorConcept<InputIterator> >();
 
-    boost::copy_n(extents_iter,num_dimensions(),extent_list_.begin());
+    boost::detail::multi_array::
+      copy_n(extents_iter,num_dimensions(),extent_list_.begin());
 
     // Calculate the array size
     num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
-                           1,std::multiplies<index>());
-    assert(num_elements_ != 0);
+                            size_type(1),std::multiplies<size_type>());
 
-    compute_strides(stride_list_,extent_list_,storage_);
+    this->compute_strides(stride_list_,extent_list_,storage_);
 
     origin_offset_ =
-      calculate_origin_offset(stride_list_,extent_list_,
-                             storage_,index_base_list_);
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
     directional_offset_ =
-      calculate_descending_dimension_offset(stride_list_,extent_list_,
-                                           storage_);
+      this->calculate_descending_dimension_offset(stride_list_,extent_list_,
+                                            storage_);
   }
 };
 
-
 template <typename T, std::size_t NumDims>
 class multi_array_ref :
   public const_multi_array_ref<T,NumDims,T*>
@@ -377,11 +421,9 @@ public:
   typedef typename super_type::value_type value_type;
   typedef typename super_type::reference reference;
   typedef typename super_type::iterator iterator;
-  typedef typename super_type::iter_base iter_base;
   typedef typename super_type::reverse_iterator reverse_iterator;
   typedef typename super_type::const_reference const_reference;
   typedef typename super_type::const_iterator const_iterator;
-  typedef typename super_type::const_iter_base const_iter_base;
   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
   typedef typename super_type::element element;
   typedef typename super_type::size_type size_type;
@@ -389,7 +431,9 @@ public:
   typedef typename super_type::index index;
   typedef typename super_type::extent_range extent_range;
 
-
+  typedef typename super_type::storage_order_type storage_order_type;
+  typedef typename super_type::index_list index_list;
+  typedef typename super_type::size_list size_list;
 
   template <std::size_t NDims>
   struct const_array_view {
@@ -410,7 +454,7 @@ public:
 
   template <class ExtentList>
   explicit multi_array_ref(T* base, const ExtentList& extents,
-                          const general_storage_order<NumDims>& so) :
+                           const general_storage_order<NumDims>& so) :
     super_type(base,extents,so) {
     boost::function_requires<
       detail::multi_array::CollectionConcept<ExtentList> >();
@@ -418,22 +462,18 @@ public:
 
 
   explicit multi_array_ref(T* base,
-                          const detail::multi_array::
-                          extent_gen<NumDims>& ranges) :
+                           const detail::multi_array::
+                           extent_gen<NumDims>& ranges) :
     super_type(base,ranges) { }
 
 
   explicit multi_array_ref(T* base,
-                          const detail::multi_array::
-                          extent_gen<NumDims>&
-                            ranges,
-                          const general_storage_order<NumDims>& so) :
+                           const detail::multi_array::
+                           extent_gen<NumDims>&
+                             ranges,
+                           const general_storage_order<NumDims>& so) :
     super_type(base,ranges,so) { }
 
-  template <typename OPtr>
-  multi_array_ref(const detail::multi_array::
-                 const_sub_array<T,NumDims,OPtr>& rhs)
-    : super_type(rhs) {} 
 
   // Assignment from other ConstMultiArray types.
   template <typename ConstMultiArray>
@@ -443,11 +483,11 @@ public:
       ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
 
     // make sure the dimensions agree
-    assert(other.num_dimensions() == num_dimensions());
-    assert(std::equal(other.shape(),other.shape()+num_dimensions(),
-                     shape()));
+    assert(other.num_dimensions() == this->num_dimensions());
+    assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+                      this->shape()));
     // iterator-based copy
-    std::copy(other.begin(),other.end(),begin());
+    std::copy(other.begin(),other.end(),this->begin());
     return *this;
   }
 
@@ -455,68 +495,70 @@ public:
     if (&other != this) {
       // make sure the dimensions agree
       
-      assert(other.num_dimensions() == num_dimensions());
-      assert(std::equal(other.shape(),other.shape()+num_dimensions(),
-                       shape()));
+      assert(other.num_dimensions() == this->num_dimensions());
+      assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+                        this->shape()));
       // iterator-based copy
-      std::copy(other.begin(),other.end(),begin());
+      std::copy(other.begin(),other.end(),this->begin());
     }
     return *this;
   }
 
-  element* origin() { return base_+origin_offset_; }
+  element* origin() { return super_type::base_+super_type::origin_offset_; }
 
-  element* data() { return base_; }
+  element* data() { return super_type::base_; }
 
   template <class IndexList>
   element& operator()(const IndexList& indices) {
-  boost::function_requires<
-    detail::multi_array::CollectionConcept<IndexList> >();
-  return super_type::access_element(boost::type<element&>(),
-                                     origin(),
-                                     indices,strides());
+    boost::function_requires<
+      detail::multi_array::CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<element&>(),
+                                      indices,origin(),
+                                      this->shape(),this->strides(),
+                                      this->index_bases());
   }
 
 
   reference operator[](index idx) {
     return super_type::access(boost::type<reference>(),
-                             idx,origin(),
-                             shape(),strides(),
-                             index_bases());
+                              idx,origin(),
+                              this->shape(),this->strides(),
+                              this->index_bases());
   }
 
 
   // See note attached to generate_array_view in base.hpp
-#ifndef BOOST_MSVC
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
   template <int NDims>
 #else
   template <int NumDims, int NDims> // else ICE
 #endif // BOOST_MSVC
   typename array_view<NDims>::type 
   operator[](const detail::multi_array::
-            index_gen<NumDims,NDims>& indices) {
-    typedef array_view<NDims>::type return_type;
+             index_gen<NumDims,NDims>& indices) {
+    typedef typename array_view<NDims>::type return_type;
     return
       super_type::generate_array_view(boost::type<return_type>(),
-                                     indices,
-                                     shape(),
-                                     strides(),
-                                     index_bases(),
-                                     origin());
+                                      indices,
+                                      this->shape(),
+                                      this->strides(),
+                                      this->index_bases(),
+                                      origin());
   }
   
   
   iterator begin() {
-    return iterator(iter_base(*index_bases(),origin(),shape(),
-                             strides(),index_bases()));
+    return iterator(*this->index_bases(),origin(),this->shape(),
+                    this->strides(),this->index_bases());
   }
 
   iterator end() {
-    return iterator(iter_base(*index_bases()+*shape(),origin(),
-                             shape(),strides(),index_bases()));
+    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+                    this->shape(),this->strides(),
+                    this->index_bases());
   }
 
-  // RG - rbegin() and rend() written naively to thwart MSVC ICE.
+  // rbegin() and rend() written naively to thwart MSVC ICE.
   reverse_iterator rbegin() {
     reverse_iterator ri(end());
     return ri;
@@ -542,19 +584,20 @@ public:
 
   const_reference operator[](index idx) const {
     return super_type::access(boost::type<const_reference>(),
-                             idx,origin(),
-                             shape(),strides(),index_bases());
+                              idx,origin(),
+                              this->shape(),this->strides(),
+                              this->index_bases());
   }
 
   // See note attached to generate_array_view in base.hpp
-#ifndef BOOST_MSVC
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
   template <int NDims>
 #else
   template <int NumDims, int NDims> // else ICE
 #endif // BOOST_MSVC
   typename const_array_view<NDims>::type 
   operator[](const detail::multi_array::
-            index_gen<NumDims,NDims>& indices)
+             index_gen<NumDims,NDims>& indices)
     const {
     return super_type::operator[](indices);
   }
@@ -574,6 +617,15 @@ public:
   const_reverse_iterator rend() const {
     return super_type::rend();
   }
+
+protected:
+  // This is only supplied to support multi_array's default constructor
+  explicit multi_array_ref(T* base,
+                           const storage_order_type& so,
+                           const index* index_bases,
+                           const size_type* extents) :
+    super_type(base,so,index_bases,extents) { }
+
 };
 
 } // namespace boost