Boost logo

Boost-Commit :

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 {


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk