]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/multi_array/base.hpp
* src/MenuBackend.[Ch]: the specialMenu is now a real menu, not a
[lyx.git] / boost / boost / multi_array / base.hpp
index 67807d2db593c3303298fc11ca7ae30604446cf4..5341be5824c1aa56308a03d0a02879192489786b 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 BASE_RG071801_HPP
 #define BASE_RG071801_HPP
 
 #include "boost/multi_array/storage_order.hpp"
 #include "boost/multi_array/types.hpp"
 #include "boost/config.hpp"
-#include "boost/multi_array/iterator_adaptors.hpp"
+#include "boost/multi_array/concept_checks.hpp" //for ignore_unused_...
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/size_t.hpp"
+#include "boost/mpl/aux_/msvc_eti_base.hpp"
+#include "boost/iterator/reverse_iterator.hpp"
 #include "boost/static_assert.hpp"
 #include "boost/type.hpp"
-#include <cassert>
+#include "boost/assert.hpp"
 #include <cstddef>
 #include <memory>
 
@@ -64,27 +81,8 @@ class sub_array;
 template <typename T, std::size_t NumDims, typename TPtr = const T*>
 class const_sub_array;
 
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct iterator_generator;
-
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct const_iterator_generator;
-
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct reverse_iterator_generator;
-
-template <typename T, std::size_t NumDims, typename value_type,
-  typename reference_type, typename tag, typename difference_type>
-struct const_reverse_iterator_generator;
-
-template <typename T,typename TPtr>
-struct iterator_base;
-
-template <typename T, std::size_t NumDims>
-struct iterator_policies;
+template <typename T, typename TPtr, typename NumDims, typename Reference>
+class array_iterator;
 
 template <typename T, std::size_t NumDims, typename TPtr = const T*>
 class const_multi_array_view;
@@ -130,13 +128,15 @@ protected:
   // used by array operator[] and iterators to get reference types.
   template <typename Reference, typename TPtr>
   Reference access(boost::type<Reference>,index idx,TPtr base,
-                  const size_type* extents,
-                  const index* strides,
-                  const index* index_base) const {
+                   const size_type* extents,
+                   const index* strides,
+                   const index* index_bases) const {
 
+    BOOST_ASSERT(idx - index_bases[0] >= 0);
+    BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
     // return a sub_array<T,NDims-1> proxy object
     TPtr newbase = base + idx * strides[0];
-    return Reference(newbase,extents+1,strides+1,index_base+1);
+    return Reference(newbase,extents+1,strides+1,index_bases+1);
 
   }
 
@@ -168,9 +168,14 @@ protected:
   // used by array operator[] and iterators to get reference types.
   template <typename Reference, typename TPtr>
   Reference access(boost::type<Reference>,index idx,TPtr base,
-                  const size_type*,
-                  const index* strides,
-                  const index*) const {
+                   const size_type* extents,
+                   const index* strides,
+                   const index* index_bases) const {
+
+    ignore_unused_variable_warning(index_bases);
+    ignore_unused_variable_warning(extents);
+    BOOST_ASSERT(idx - index_bases[0] >= 0);
+    BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
     return *(base + idx * strides[0]);
   }
 
@@ -183,73 +188,94 @@ protected:
 // choose value accessor begins
 //
 
+template <typename T, std::size_t NumDims>
 struct choose_value_accessor_n {
-  template <typename T, std::size_t NumDims>
-  struct bind {
-    typedef value_accessor_n<T,NumDims> type;
-  };
+  typedef value_accessor_n<T,NumDims> type;
 };
 
+template <typename T>
 struct choose_value_accessor_one {
-  template <typename T, std::size_t NumDims>
-  struct bind {
-    typedef value_accessor_one<T> type;
-  };
+  typedef value_accessor_one<T> type;
 };
 
-
-template <std::size_t NumDims>
-struct value_accessor_gen_helper {
-  typedef choose_value_accessor_n choice;
+template <typename T, typename NumDims>
+struct value_accessor_generator {
+    BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
+    
+  typedef typename
+  mpl::eval_if_c<(dimensionality == 1),
+                  choose_value_accessor_one<T>,
+                  choose_value_accessor_n<T,dimensionality>
+  >::type type;
 };
 
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+
+struct eti_value_accessor
+{
+  typedef int index;
+  typedef int size_type;
+  typedef int element;
+  typedef int index_range;
+  typedef int value_type;
+  typedef int reference;
+  typedef int const_reference;
+};
+    
 template <>
-struct value_accessor_gen_helper<1> {
-  typedef choose_value_accessor_one choice;
+struct value_accessor_generator<int,int>
+{
+  typedef eti_value_accessor type;
 };
 
-template <typename T, std::size_t NumDims>
-struct value_accessor_generator {
-private:
-  typedef typename value_accessor_gen_helper<NumDims>::choice Choice;
-public:
-  typedef typename Choice::template bind<T,NumDims>::type type;
-};
+template <class T, class NumDims>
+struct associated_types
+  : mpl::aux::msvc_eti_base<
+        typename value_accessor_generator<T,NumDims>::type
+    >::type
+{};
 
-//
-// choose value accessor ends
-/////////////////////////////////////////////////////////////////////////
+template <>
+struct associated_types<int,int> : eti_value_accessor {};
 
+#else
 
+template <class T, class NumDims>
+struct associated_types
+  : value_accessor_generator<T,NumDims>::type
+{};
+
+#endif
+
+//
+// choose value accessor ends
 /////////////////////////////////////////////////////////////////////////
-// multi_array/sub_array base stuffs
-/////////////////////////////////////////////////////////////////////////
-template <std::size_t NumDims>
-struct iterator_tag_selector {
-  typedef std::input_iterator_tag type;
-};
 
-template <>
-struct iterator_tag_selector<1> {
-  typedef std::random_access_iterator_tag type;
-};
 
 
 ////////////////////////////////////////////////////////////////////////
 // multi_array_base
 ////////////////////////////////////////////////////////////////////////
 template <typename T, std::size_t NumDims>
-class multi_array_impl_base :
-  public value_accessor_generator<T,NumDims>::type {
-  typedef typename value_accessor_generator<T,NumDims>::type super_type;
+class multi_array_impl_base
+  :
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+      public mpl::aux::msvc_eti_base<
+          typename value_accessor_generator<T,mpl::size_t<NumDims> >::type
+       >::type
+#else
+      public value_accessor_generator<T,mpl::size_t<NumDims> >::type
+#endif 
+{
+  typedef associated_types<T,mpl::size_t<NumDims> > types;
 public:
-  typedef typename super_type::index index;
-  typedef typename super_type::size_type size_type;
-  typedef typename super_type::element element;
-  typedef typename super_type::index_range index_range;
-  typedef typename super_type::value_type value_type;
-  typedef typename super_type::reference reference;
-  typedef typename super_type::const_reference const_reference;
+  typedef typename types::index index;
+  typedef typename types::size_type size_type;
+  typedef typename types::element element;
+  typedef typename types::index_range index_range;
+  typedef typename types::value_type value_type;
+  typedef typename types::reference reference;
+  typedef typename types::const_reference const_reference;
 
   template <std::size_t NDims>
   struct subarray {
@@ -275,37 +301,36 @@ public:
   //
   // iterator support
   //
+  typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference> iterator;
+  typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference> const_iterator;
 
-  typedef typename iterator_tag_selector<NumDims>::type iterator_tag;
-
-  typedef typename
-    iterator_generator<T,NumDims,value_type,
-    reference,iterator_tag,index>::type iterator;
-
-  typedef typename
-    const_iterator_generator<T,NumDims,value_type,
-    const_reference,iterator_tag,index>::type const_iterator;
-
-  typedef typename
-    reverse_iterator_generator<T,NumDims,value_type,
-    reference,iterator_tag,index>::type reverse_iterator;
-
-  typedef typename
-    const_reverse_iterator_generator<T,NumDims,value_type,
-    const_reference,iterator_tag,index>::type const_reverse_iterator;
+  typedef ::boost::reverse_iterator<iterator> reverse_iterator;
+  typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
 
+  BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
 protected:
-  typedef iterator_base<T,T*> iter_base;
-  typedef iterator_base<T,const T*> const_iter_base;
 
   multi_array_impl_base() { }
   ~multi_array_impl_base() { }
 
   // Used by operator() in our array classes
   template <typename Reference, typename IndexList, typename TPtr>
-  Reference access_element(boost::type<Reference>, TPtr base,
-                          const IndexList& indices,
-                          const index* strides) const {
+  Reference access_element(boost::type<Reference>,
+                           const IndexList& indices,
+                           TPtr base,
+                           const size_type* extents,
+                           const index* strides,
+                           const index* index_bases) const {
+
+    ignore_unused_variable_warning(index_bases);
+    ignore_unused_variable_warning(extents);
+#if !defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
+    for (size_type i = 0; i != NumDims; ++i) {
+      BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
+      BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
+    }
+#endif
+
     index offset = 0;
     for (size_type n = 0; n != NumDims; ++n) 
       offset += indices[n] * strides[n];
@@ -315,7 +340,7 @@ protected:
 
   template <typename StrideList, typename ExtentList>
   void compute_strides(StrideList& stride_list, ExtentList& extent_list,
-                      const general_storage_order<NumDims>& storage)
+                       const general_storage_order<NumDims>& storage)
   {
     // invariant: stride = the stride for dimension n
     index stride = 1;
@@ -323,7 +348,7 @@ protected:
       index stride_sign = +1;
       
       if (!storage.ascending(storage.ordering(n)))
-       stride_sign = -1;
+        stride_sign = -1;
       
       // The stride for this dimension is the product of the
       // lengths of the ranks minor to it.
@@ -339,13 +364,13 @@ protected:
   template <typename StrideList, typename ExtentList, typename BaseList>
   index
   calculate_origin_offset(const StrideList& stride_list,
-                         const ExtentList& extent_list,
-                         const general_storage_order<NumDims>& storage,
-                         const BaseList& index_base_list)
+                          const ExtentList& extent_list,
+                          const general_storage_order<NumDims>& storage,
+                          const BaseList& index_base_list)
   {
     return
       calculate_descending_dimension_offset(stride_list,extent_list,
-                                           storage) +
+                                            storage) +
       calculate_indexing_offset(stride_list,index_base_list);
   }
 
@@ -354,14 +379,14 @@ protected:
   template <typename StrideList, typename ExtentList>
   index
   calculate_descending_dimension_offset(const StrideList& stride_list,
-                               const ExtentList& extent_list,
-                               const general_storage_order<NumDims>& storage)
+                                const ExtentList& extent_list,
+                                const general_storage_order<NumDims>& storage)
   {
     index offset = 0;
     if (!storage.all_dims_ascending()) 
       for (size_type n = 0; n != NumDims; ++n)
-       if (!storage.ascending(n))
-         offset -= (extent_list[n] - 1) * stride_list[n];
+        if (!storage.ascending(n))
+          offset -= (extent_list[n] - 1) * stride_list[n];
 
     return offset;
   }
@@ -373,11 +398,11 @@ protected:
   template <typename StrideList, typename BaseList>
   index
   calculate_indexing_offset(const StrideList& stride_list,
-                         const BaseList& index_base_list)
+                          const BaseList& index_base_list)
   {
     index offset = 0;
     for (size_type n = 0; n != NumDims; ++n)
-       offset -= stride_list[n] * index_base_list[n];
+        offset -= stride_list[n] * index_base_list[n];
     return offset;
   }
 
@@ -393,12 +418,12 @@ protected:
   template <typename ArrayRef, int NDims, typename TPtr>
   ArrayRef
   generate_array_view(boost::type<ArrayRef>,
-                     const boost::detail::multi_array::
-                     index_gen<NumDims,NDims>& indices,
-                     const size_type* extents,
-                     const index* strides,
-                     const index* index_bases,
-                     TPtr base) const {
+                      const boost::detail::multi_array::
+                      index_gen<NumDims,NDims>& indices,
+                      const size_type* extents,
+                      const index* strides,
+                      const index* index_bases,
+                      TPtr base) const {
 
     boost::array<index,NDims> new_strides;
     boost::array<index,NDims> new_extents;
@@ -412,7 +437,13 @@ protected:
       index start = current_range.get_start(default_start);
       index finish = current_range.get_finish(default_finish);
       index index_factor = current_range.stride();
-      index len = (finish - start) / index_factor;
+      index len = (finish - start + (index_factor - 1)) / index_factor;
+
+      BOOST_ASSERT(index_bases[n] <= start &&
+                   start <= index_bases[n]+index(extents[n]));
+      BOOST_ASSERT(index_bases[n] <= finish &&
+                   finish <= index_bases[n]+index(extents[n]));
+      BOOST_ASSERT(index_factor > 0);
 
       // the array data pointer is modified to account for non-zero
       // bases during slicing (see [Garcia] for the math involved)
@@ -420,23 +451,23 @@ protected:
 
       if (!current_range.is_degenerate()) {
 
-       // The index_factor for each dimension is included into the
-       // strides for the array_view (see [Garcia] for the math involved).
-       new_strides[dim] = index_factor * strides[n];
-       
-       // calculate new extents
-       new_extents[dim] = len;
-       ++dim;
+        // The index_factor for each dimension is included into the
+        // strides for the array_view (see [Garcia] for the math involved).
+        new_strides[dim] = index_factor * strides[n];
+        
+        // calculate new extents
+        new_extents[dim] = len;
+        ++dim;
       }
     }
-    assert (dim == NDims);
+    BOOST_ASSERT(dim == NDims);
 
     return
       ArrayRef(base+offset,
-              new_extents,
-              new_strides);
+               new_extents,
+               new_strides);
   }
-                    
+                     
 
 };