$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r58673 - in sandbox/numeric_bindings/boost/numeric/bindings: . detail
From: rutger_at_[hidden]
Date: 2010-01-04 09:02:31
Author: rutger
Date: 2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
New Revision: 58673
URL: http://svn.boost.org/trac/boost/changeset/58673
Log:
Updates to stride computations
Text files modified: 
   sandbox/numeric_bindings/boost/numeric/bindings/detail/pod.hpp      |     2                                         
   sandbox/numeric_bindings/boost/numeric/bindings/index_major.hpp     |    11 ++-                                     
   sandbox/numeric_bindings/boost/numeric/bindings/index_minor.hpp     |     3                                         
   sandbox/numeric_bindings/boost/numeric/bindings/is_column_major.hpp |     7 ++                                      
   sandbox/numeric_bindings/boost/numeric/bindings/stride.hpp          |   119 ++++++++++++++++++++++++++++++++++++--- 
   5 files changed, 124 insertions(+), 18 deletions(-)
Modified: sandbox/numeric_bindings/boost/numeric/bindings/detail/pod.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/detail/pod.hpp	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/detail/pod.hpp	2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
@@ -25,7 +25,7 @@
         mpl::pair< tag::value_type, value_type >,
         mpl::pair< tag::entity, tag::scalar >,
         mpl::pair< tag::size_type<1>, mpl::int_<1> >,
-        mpl::pair< tag::stride_type<1>, mpl::int_<0> >
+        mpl::pair< tag::data_structure, tag::linear_array >
     > property_map;
 
     static value_type* begin_value( Id& t ) {
Modified: sandbox/numeric_bindings/boost/numeric/bindings/index_major.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/index_major.hpp	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/index_major.hpp	2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
@@ -10,8 +10,9 @@
 #define BOOST_NUMERIC_BINDINGS_INDEX_MAJOR_HPP
 
 #include <boost/mpl/if.hpp>
+#include <boost/mpl/max.hpp>
 #include <boost/numeric/bindings/rank.hpp>
-#include <boost/numeric/bindings/is_row_major.hpp>
+#include <boost/numeric/bindings/is_column_major.hpp>
 
 namespace boost {
 namespace numeric {
@@ -20,11 +21,11 @@
 template< typename T >
 struct index_major:
     mpl::if_<
-        is_row_major< T >,
-        tag::index<1>,
+        is_column_major< T >,
         tag::index<
-            rank< T >::value
-        >
+            mpl::max< tag::matrix, rank< T > >::type::value
+        >,
+        tag::index<1>
     >::type {};
 
 } // namespace bindings
Modified: sandbox/numeric_bindings/boost/numeric/bindings/index_minor.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/index_minor.hpp	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/index_minor.hpp	2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
@@ -10,6 +10,7 @@
 #define BOOST_NUMERIC_BINDINGS_INDEX_MINOR_HPP
 
 #include <boost/mpl/if.hpp>
+#include <boost/mpl/max.hpp>
 #include <boost/numeric/bindings/rank.hpp>
 #include <boost/numeric/bindings/is_column_major.hpp>
 
@@ -23,7 +24,7 @@
         is_column_major< T >,
         tag::index<1>,
         tag::index<
-            rank< T >::value
+            mpl::max< tag::matrix, rank< T > >::type::value
         >
     >::type {};
 
Modified: sandbox/numeric_bindings/boost/numeric/bindings/is_column_major.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/is_column_major.hpp	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/is_column_major.hpp	2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
@@ -9,6 +9,7 @@
 #ifndef BOOST_NUMERIC_BINDINGS_IS_COLUMN_MAJOR_HPP
 #define BOOST_NUMERIC_BINDINGS_IS_COLUMN_MAJOR_HPP
 
+#include <boost/mpl/if.hpp>
 #include <boost/numeric/bindings/detail/property_map.hpp>
 #include <boost/numeric/bindings/tag.hpp>
 
@@ -18,7 +19,11 @@
 
 template< typename T >
 struct is_column_major:
-        detail::is_same_at< T, tag::data_order, tag::column_major > {};
+        mpl::if_<
+            detail::property_has_key< T, tag::data_order >,
+            detail::is_same_at< T, tag::data_order, tag::column_major >,
+            mpl::true_
+        >::type {};
 
 } // namespace bindings
 } // namespace numeric
Modified: sandbox/numeric_bindings/boost/numeric/bindings/stride.hpp
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/stride.hpp	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/stride.hpp	2010-01-04 09:02:29 EST (Mon, 04 Jan 2010)
@@ -9,16 +9,16 @@
 #ifndef BOOST_NUMERIC_BINDINGS_STRIDE_HPP
 #define BOOST_NUMERIC_BINDINGS_STRIDE_HPP
 
-#include <boost/numeric/bindings/detail/generate_functions.hpp>
-#include <boost/numeric/bindings/detail/adaptor.hpp>
-#include <boost/numeric/bindings/detail/get.hpp>
-#include <boost/numeric/bindings/index_major.hpp>
-#include <boost/numeric/bindings/index_minor.hpp>
-#include <boost/numeric/bindings/rank.hpp>
+#include <boost/numeric/bindings/size.hpp>
 #include <boost/mpl/min.hpp>
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/less_equal.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/times.hpp>
 #include <boost/mpl/greater.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/type_traits/is_same.hpp>
 #include <boost/static_assert.hpp>
 
 namespace boost {
@@ -39,16 +39,25 @@
 };
 
 //
-// Strides for ranks outside the scope of the object are fixed at 0
-// E.g., a vector has rank 1, its stride for index<2> will be 0.
+// Strides for ranks outside the scope of the object are fixed at
+// the dot product of its existing sizes and strides.
+// 
+// Object    rank    result
+// scalar    0       1
+// vector    1       size1 * stride1
+// matrix    2       size1 * stride1 + size2 * stride2
+// tensor    N       sum_i( size_i, stride_i )  (dot( size, stride))
+//
+// Iff size_i and stride_i are integral constants, results will be known at
+// compile time. Otherwise, the result_type will be std::ptrdiff_t.
 //
 template< typename T, typename Index >
 struct stride_impl< T, Index,
         typename boost::enable_if<
-            mpl::greater< Index, rank<T> >
+            mpl::equal_to< rank<T>, tag::scalar >
         >::type > {
 
-    typedef typename mpl::int_<0> result_type;
+    typedef typename mpl::int_<1> result_type;
 
     static result_type invoke( const T& t ) {
         return result_type();
@@ -56,6 +65,96 @@
 
 };
 
+
+template< typename T, typename State, typename Index >
+struct fold_stride_size {
+
+    typedef tag::index< Index::value > index_type;
+    typedef typename result_of::size< T, index_type >::type size_type;
+    typedef typename stride_impl< T, index_type >::result_type stride_type;
+
+    typedef typename mpl::if_<
+        mpl::or_<
+            is_same< State, std::ptrdiff_t >,
+            is_same< size_type, std::ptrdiff_t >,
+            is_same< stride_type, std::ptrdiff_t >
+        >,
+        std::ptrdiff_t,
+        mpl::plus<
+            State, 
+            mpl::times< 
+                size_type,
+                stride_type
+            >
+        >
+    >::type type;
+
+};
+
+//
+// If Result isn't a ptrdiff_t, just invoke the integral constant
+// and return that. Otherwise, runtime stuff is involved, so we'll
+// have to evaluate sum_i( size_i, stride_i ).
+//
+template< typename T, typename Result, int Index >
+struct apply_fold {
+    static Result invoke( const T& t ) {
+        return Result();
+    }
+};
+
+template< typename T, int Index >
+struct apply_fold< T, std::ptrdiff_t, Index > {
+
+    static std::ptrdiff_t invoke( const T& t ) {
+        return size( t, tag::index< Index >() ) * 
+            stride_impl< T, tag::index< Index > >::invoke( t ) +
+            apply_fold< T, std::ptrdiff_t, Index-1 >::invoke( t );
+    }
+
+};
+
+template< typename T >
+struct apply_fold< T, std::ptrdiff_t, 0 > {
+
+    static std::ptrdiff_t invoke( const T& t ) {
+        return 0;
+    }
+
+};
+
+
+// Could be made generic for dimensions > 2,
+//  but not enough time right now
+
+
+template< typename T, typename Index >
+struct stride_impl< T, Index,
+        typename boost::enable_if<
+            mpl::and_<
+                 mpl::greater< rank<T>, tag::scalar >,
+                 mpl::greater< Index, rank<T> >
+           >
+        >::type > {
+
+    typedef mpl::range_c< int, 1, rank<T>::value+1 > index_range;
+    typedef typename mpl::fold<
+        index_range,
+        mpl::int_< 0 >,
+        fold_stride_size<
+            T,
+            mpl::_1,
+            mpl::_2
+        >
+    >::type result_type;
+
+    static result_type invoke( const T& t ) {
+        return apply_fold< T, result_type, rank<T>::value >::invoke( t );
+    }
+
+
+};
+
 } // namespace detail
 
 namespace result_of {