]> 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 cdefb6c04ebfc7efa1d8dd178f45323503584334..41b962a8ebe0b87fb7f81821f10b2664fb9aa7ab 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 BOOST_MULTI_ARRAY_REF_RG071801_HPP
 #define BOOST_MULTI_ARRAY_REF_RG071801_HPP
@@ -25,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"
@@ -48,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>
@@ -74,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_),
@@ -137,19 +138,26 @@ 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_,
+      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_,
+      this->calculate_origin_offset(stride_list_,extent_list_,
                               storage_,index_base_list_);
   }
 
@@ -162,10 +170,10 @@ public:
                             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_,
+      this->calculate_origin_offset(stride_list_,extent_list_,
                               storage_,index_base_list_);
   }
 
@@ -195,13 +203,18 @@ 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
@@ -232,13 +245,13 @@ public:
   }
   
   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 {
@@ -296,35 +309,49 @@ public:
     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_;
@@ -357,29 +384,34 @@ private:
   }
 
 
+#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_,
+      this->calculate_origin_offset(stride_list_,extent_list_,
                               storage_,index_base_list_);
     directional_offset_ =
-      calculate_descending_dimension_offset(stride_list_,extent_list_,
+      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*>
@@ -389,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;
@@ -401,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 {
@@ -442,10 +474,6 @@ public:
                            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>
@@ -455,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;
   }
 
@@ -467,34 +495,35 @@ 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());
+                              this->shape(),this->strides(),
+                              this->index_bases());
   }
 
 
@@ -511,24 +540,25 @@ public:
     return
       super_type::generate_array_view(boost::type<return_type>(),
                                       indices,
-                                      shape(),
-                                      strides(),
-                                      index_bases(),
+                                      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;
@@ -555,7 +585,8 @@ public:
   const_reference operator[](index idx) const {
     return super_type::access(boost::type<const_reference>(),
                               idx,origin(),
-                              shape(),strides(),index_bases());
+                              this->shape(),this->strides(),
+                              this->index_bases());
   }
 
   // See note attached to generate_array_view in base.hpp
@@ -586,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