Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r74539 - sandbox/variadic_templates/sandbox/stepper/boost/array_stepper
From: cppljevans_at_[hidden]
Date: 2011-09-23 14:43:26


Author: cppljevans
Date: 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
New Revision: 74539
URL: http://svn.boost.org/trac/boost/changeset/74539

Log:
index_stack*.hpp avoids need to manually code
nested for loops.
Other updates and mods are minor

Added:
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_host.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_store_print.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/index_stack_length_stride_crtp.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride_compose.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_strides_offset.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/scan_first_iter.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/vector_print.hpp (contents, props changed)
Text files modified:
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/mk_iota.hpp | 17 +++++
   sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/stepper_offset.hpp | 120 +++++++++++++++++++++++++++++++--------
   2 files changed, 111 insertions(+), 26 deletions(-)

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_host.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_host.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,131 @@
+#ifndef BOOST_ARRAY_STEPPER_ARRAY_HOST_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_ARRAY_HOST_HPP_INCLUDED
+namespace boost
+{
+namespace array_stepper
+{
+ template
+ < typename Array
+ >
+ struct
+array_host
+{
+ Array&
+ my_array
+ ;
+ typedef typename
+ Array::domain_t
+ domain_t
+ ;
+ typedef typename
+ domain_t::index_t
+ index_t
+ ;
+ typedef typename
+ domain_t::offset_t
+ offset_t
+ ;
+ typedef typename
+ domain_t::length_stride_t
+ length_stride_t
+ ;
+ typedef typename
+ domain_t::length_strides_t::const_iterator
+ axis_iter_t
+ ;
+ axis_iter_t
+ my_axis_beg
+ ;
+ axis_iter_t const
+ my_axis_end
+ ;
+ array_host
+ ( Array& a_array
+ )
+ : my_array(a_array)
+ , my_axis_beg
+ ( my_array.length_strides().begin()
+ )
+ , my_axis_end
+ ( my_array.length_strides().end()
+ )
+ {
+ }
+
+ template
+ < typename Visitor
+ >
+ void
+ accept
+ ( Visitor& a_viz
+ )
+ {
+ if(my_array.rank() == 0)
+ {
+ a_viz.null_array();
+ }
+ else
+ {
+ accept_off_ax
+ ( a_viz
+ , my_array.offset()
+ , my_axis_beg
+ );
+ }
+ }
+ private:
+ template
+ < typename Visitor
+ >
+ void
+ accept_off_ax
+ ( Visitor& a_viz
+ , index_t offset
+ , axis_iter_t axis_now
+ )
+ {
+ if(axis_now==my_axis_end)
+ {
+ a_viz.visit_child(my_array.data()[offset]);
+ }
+ else
+ {
+ axis_iter_t axis_nxt=axis_now+1;
+ length_stride_t const axis_length_stride=*axis_now;
+ typedef typename length_stride_t::stride_t stride_t;
+ typedef typename length_stride_t::length_t length_t;
+ stride_t const axis_stride=axis_length_stride.stride();
+ length_t const axis_length=axis_length_stride.length();
+ #if 0
+ std::cout
+ <<":axis="<<axis_now-my_axis_beg
+ <<":offset="<<offset
+ <<":length="<<axis_length
+ <<":stride="<<axis_stride
+ <<"\n";
+ #endif
+ a_viz.pre_children();
+ for(length_t i=0; i<axis_length; ++i)
+ {
+ #if 0
+ std::cout
+ <<":i="<<i
+ <<"\n";
+ #endif
+ a_viz.pre_child( i);
+ this->accept_off_ax
+ ( a_viz
+ , offset
+ , axis_nxt
+ );
+ a_viz.post_child();
+ offset+=axis_stride;
+ }
+ a_viz.post_children();
+ }
+ }
+};
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_store_print.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/array_store_print.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,183 @@
+#ifndef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_HPP_INCLUDED
+
+#include <boost/array_stepper/array_store.hpp>
+#if 1
+#include <boost/array_stepper/array_host.hpp>
+#include <boost/iostreams/utility/indent_scoped_ostreambuf.hpp>
+#else
+#include <boost/array_stepper/length_stride_offset_iter_stack.hpp>
+#include <iostream>
+#include <iomanip>
+//#define BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+#ifdef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+#include <boost/assert.hpp>
+#endif
+#endif
+
+#ifndef BOOST_ARRAY_STEPPER_LENGTH_STRIDE_OFFSET_ITER_STACK_HPP_INCLUDED
+namespace boost
+{
+namespace array_stepper
+{
+ template
+ < typename T
+ >
+ struct
+array_store_print
+{
+ std::ostream&
+ my_sout
+ ;
+ typedef typename
+ array_store<T>::index_t
+ index_t
+ ;
+ array_store_print
+ ( std::ostream& a_sout
+ )
+ : my_sout(a_sout)
+ {}
+
+ void null_array( )const
+ {
+ my_sout<<"(null_array)";
+ }
+
+ void pre_children()
+ {
+ my_sout<<"{ ";
+ }
+
+ void pre_child( index_t index)
+ {
+ if(0<index) my_sout<<", ";
+ my_sout<<indent_buf_in;
+ }
+
+ void visit_child( T const& a_t)
+ {
+ #if 0
+ ::operator<<( my_sout, a_t);
+ //MAINTENANCE_NOTE:2011-06-29 with gcc4.6:
+ // For some strange reason, have to use above with
+ // gcc instead of what's in #else part because
+ // otherwise compiler gives error saying:
+ // no match for 'operator<<'
+ // when T is std::vector<unsigned> even though
+ // there is a:
+ // std::ostream&
+ // operator<<
+ // ( std::ostream&
+ // , std::vector<unsigned>const&
+ // );
+ // defined.
+ #else
+ my_sout<<a_t;
+ #endif
+ }
+
+ void post_child( )
+ {
+ my_sout<<indent_buf_out;
+ }
+
+ void post_children()
+ {
+ my_sout<<"}\n";
+ }
+
+};
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif
+
+ template
+ < typename T
+ >
+ std::ostream&
+operator<<
+( std::ostream& sout
+, boost::array_stepper::array_store<T>const& a_arr
+)
+{
+ #ifdef BOOST_ARRAY_STEPPER_LENGTH_STRIDE_OFFSET_ITER_STACK_HPP_INCLUDED
+ typedef typename boost::array_stepper::array_store<T> arr_t;
+ typedef typename arr_t::domain_t domain_t;
+ typedef boost::array_stepper::length_stride_offset_iter_stack<> lsos_t;
+ lsos_t
+ lsos_v
+ ( a_arr.length_strides().begin()
+ , a_arr.length_strides().end()
+ );
+ typedef typename arr_t::data_t data_t;
+ data_t const& data_v=a_arr.data();
+ int const n=data_v.size();
+ typename lsos_t::indices_t const& indices_v=lsos_v.indices();
+ int const axis_max=indices_v.size()-1;
+ int axis_now= axis_max;
+ int axis_pre=-1;
+ for(int l=axis_pre; l<axis_now; ++l)
+ { //open 1st element for all axes.
+ sout<<"{ ";
+ }
+ for(int i=0; i<n; ++i,axis_pre=axis_now,axis_now=++lsos_v)
+ {
+ if(axis_now<axis_pre)
+ { //exiting one element and starting next.
+ for(int l=axis_pre; axis_now<l; --l)
+ { //close axis_pre to axis_now elements.
+ if(l!=axis_pre)
+ sout<<std::setw(l*2)<<"";
+ sout<<"}\n";
+ }
+ sout<<std::setw(axis_now*2)<<""<<", ";//put delimiter between elements
+ for(int l=axis_pre; axis_now<l; --l)
+ { //open axis_now to axis_pre elements.
+ sout<<"{ ";
+ }
+ #ifdef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+ sout<<"(axis_now<axis_pre)";
+ BOOST_ASSERT(axis_pre == axis_max);
+ #endif
+ }
+ else if(-1<axis_pre)
+ { sout<<", ";//put delimiter between elements
+ #ifdef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+ sout<<"(-1<axis_pre)";
+ BOOST_ASSERT( axis_now==axis_max && 0<indices_v[axis_now]);
+ #endif
+ }
+ #ifdef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+ sout
+ <<":i="<<std::setw(2)<<i
+ <<":axis_pre="<<axis_pre
+ <<":axis_now="<<axis_now
+ <<":v="
+ ;
+ #endif
+ sout<<data_v[lsos_v.offset()];
+ }
+ for(int l=axis_pre; axis_now<l; --l)
+ {//close axis_pre to axis_now elements.
+ if(l!=axis_pre)
+ sout<<std::setw(l*2)<<"";
+ sout<<"}\n";
+ }
+ #ifdef BOOST_ARRAY_STEPPER_ARRAY_STORE_PRINT_TRACE
+ sout
+ <<":axis_pre="<<axis_pre
+ <<":axis_now="<<axis_now
+ <<"\n"
+ ;
+ #endif
+ #else
+ boost::array_stepper::array_store_print<T> a_viz(sout);
+ boost::array_stepper::array_host<boost::array_stepper::array_store<T> const> host_arr(a_arr);
+ host_arr.accept(a_viz);
+ #endif
+ return sout;
+}
+
+#endif

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/index_stack_length_stride_crtp.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/index_stack_length_stride_crtp.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,718 @@
+//stack of loop indices and length_strides_for an array.
+#ifndef BOOST_ARRAY_STEPPER_INDEX_STACK_LENGTH_STRIDE_CRTP_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_INDEX_STACK_LENGTH_STRIDE_CRTP_HPP_INCLUDED
+// (C) Copyright Larry Evans 2011.
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//====================================================================
+#include <boost/array_stepper/length_strides_offset.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/assert.hpp>
+namespace boost
+{
+namespace array_stepper
+{
+
+enum index_bounds_value_enum
+{ index_bound_lower
+, index_bound_upper
+, index_value
+};
+enum
+{ index_bounds_value_size=index_value+1
+};
+enum mutable_enum
+{ mutable_not
+, mutable_yes
+};
+
+ template
+ < typename Stride=int
+ >
+ struct
+index_stack_length_stride_crtp_types
+{
+ typedef
+ Stride
+ stride_t
+ ;
+ typedef
+ length_strides_offset
+ < stride_t
+ >
+ length_strides_offset_t
+ ;
+ typedef
+ typename length_strides_offset_t::length_stride_t
+ length_stride_t
+ ;
+ typedef
+ typename length_strides_offset_t::length_strides_t
+ length_strides_t
+ ;
+ typedef
+ typename length_strides_t::const_iterator
+ length_stride_iter_t
+ ;
+ typedef
+ typename length_strides_offset_t::index_t
+ index_t
+ ;
+ typedef
+ typename length_strides_offset_t::axis_t
+ axis_t
+ ;
+ typedef
+ std::vector<index_t>
+ indices_t
+ ;
+ struct
+ offset_space
+ /**@brief
+ * offset from beginning or the array's storage.
+ */
+ {
+ offset_space()
+ : my_offset(0)
+ {}
+ stride_t
+ offset_space_val()const
+ {
+ return my_offset;
+ }
+ stride_t&
+ offset_space_ref()
+ {
+ return my_offset;
+ }
+ private:
+ stride_t
+ my_offset
+ ;
+ };
+
+ struct
+ offset_index_bounds
+ /**@brief
+ * Offset from front and back of
+ * an index range and current index.
+ */
+ : private array
+ < index_t
+ , std::size_t(index_bounds_value_size)
+ >
+ {
+ typedef
+ array
+ < index_t
+ , std::size_t(index_bounds_value_size)
+ >
+ super_t
+ ;
+ offset_index_bounds
+ (
+ )
+ : super_t
+ ({{ 0
+ , 0
+ , 0
+ }
+ }
+ )
+ {}
+ template
+ < index_bounds_value_enum IBV
+ >
+ index_t
+ val
+ (
+ )const
+ {
+ super_t const&me=*this;
+ return me[IBV];
+ }
+ template
+ < index_bounds_value_enum IBV
+ >
+ index_t&
+ ref
+ (
+ )
+ {
+ super_t&me=*this;
+ return me[IBV];
+ }
+ template
+ < index_bounds_value_enum IBV
+ >
+ index_t
+ get
+ (
+ )const
+ {
+ return val<IBV>();
+ }
+ template
+ < index_bounds_value_enum IBV
+ >
+ index_t&
+ get
+ (
+ )
+ {
+ return ref<IBV>();
+ }
+ };
+
+ template
+ < mutable_enum MutEnum
+ >
+ struct index_bound_stride
+ {
+ typedef
+ typename ::boost::mpl::if_c
+ < MutEnum==mutable_yes
+ , offset_index_bounds
+ , offset_index_bounds const
+ >::type
+ offset_index_bounds_t
+ ;
+ private:
+ offset_index_bounds_t&
+ my_oib
+ ;
+ length_stride_t const&
+ my_ls
+ ;
+ public:
+ index_bound_stride
+ ( offset_index_bounds_t& a_oib
+ , length_stride_t const& a_ls
+ )
+ : my_oib(a_oib)
+ , my_ls(a_ls)
+ {}
+ template
+ < index_bounds_value_enum IBV
+ >
+ index_t
+ get
+ (
+ )const
+ {
+ return my_oib.template get<IBV>();
+ }
+ template
+ < index_bounds_value_enum IBV
+ >
+ typename ::boost::mpl::if_c
+ < MutEnum==mutable_yes
+ , index_t&
+ , index_t
+ >::type
+ get
+ (
+ )
+ {
+ return my_oib.template get<IBV>();
+ }
+
+ template
+ < index_bounds_value_enum IBV
+ >
+ typename ::boost::enable_if_c
+ < IBV!=index_value
+ , index_t
+ >::type
+ bound()const
+ {
+ index_t offset=my_oib.template val<IBV>();
+ if(IBV==index_bound_lower) return offset;
+ return my_ls.length()-1-offset;
+ }
+ stride_t
+ stride_val()const
+ {
+ my_ls.stride();
+ }
+ stride_t
+ length_val()const
+ {
+ index_t index_upper=bound<index_bound_upper>();
+ index_t index_lower=bound<index_bound_lower>();
+ return index_upper-index_lower+1;
+ }
+ };
+
+ struct indices_bounds_strides
+ {
+ private:
+ typedef
+ std::vector
+ < offset_index_bounds
+ >
+ offset_indices_bounds_t
+ ;
+ offset_indices_bounds_t
+ my_oib
+ ;
+ length_stride_iter_t
+ my_lsi
+ ;
+ public:
+ indices_bounds_strides
+ ( axis_t a_rank
+ , length_stride_iter_t const& a_lsi
+ )
+ : my_oib
+ ( a_rank
+ )
+ , my_lsi
+ ( a_lsi
+ )
+ {}
+
+ axis_t
+ rank()const
+ {
+ return my_oib.size();
+ }
+
+ index_bound_stride<mutable_yes>
+ operator[](axis_t a_axis)
+ {
+ offset_index_bounds&oib=my_oib[a_axis];
+ length_stride_t const&ls=my_lsi[a_axis];
+ return index_bound_stride<mutable_yes>( oib, ls);
+ }
+ index_bound_stride<mutable_not>
+ operator[](axis_t a_axis)const
+ {
+ offset_index_bounds const&oib=my_oib[a_axis];
+ length_stride_t const&ls=my_lsi[a_axis];
+ return index_bound_stride<mutable_not>( oib, ls);
+ }
+ };
+};
+
+enum inc_dec_enum
+{ inc_ator
+, dec_ator
+};
+
+ template
+ < inc_dec_enum ID
+ >
+ struct
+inc_dec_concrete
+ /**@brief
+ * Specializations provide operations & values
+ * used by:
+ * index_stack_length_stride_crtp_abstract::
+ * inc_dec_ator<ID>
+ * templated member function.
+ */
+;
+ template
+ <
+ >
+ struct
+inc_dec_concrete
+ < inc_ator
+ >
+{
+ static
+ index_bounds_value_enum const
+ bound_limit=index_bound_upper
+ ;
+ static
+ index_bounds_value_enum const
+ bound_reset=index_bound_lower
+ ;
+ template
+ < typename Index
+ , typename Offset
+ , typename Stride
+ >
+ static
+ void
+ change
+ ( Index& index
+ , Offset& offset
+ , Stride stride
+ )
+ {
+ ++index;
+ offset+=stride;
+ }
+};
+
+ template
+ <
+ >
+ struct
+inc_dec_concrete
+ < dec_ator
+ >
+{
+ static
+ index_bounds_value_enum const
+ bound_limit=index_bound_lower
+ ;
+ static
+ index_bounds_value_enum const
+ bound_reset=index_bound_upper
+ ;
+ template
+ < typename Index
+ , typename Offset
+ , typename Stride
+ >
+ static
+ void
+ change
+ ( Index& index
+ , Offset& offset
+ , Stride stride
+ )
+ {
+ --index;
+ offset-=stride;
+ }
+};
+
+ template
+ < typename IndexStackConcrete
+ >
+ struct
+index_stack_length_stride_crtp_abstract
+ /**@brief
+ * An "abstract stack" of indices like those
+ * for a N nested for loops, where N is the
+ * value from rank() function of derived().
+ * This class is abstract because the concrete
+ * values are supplied by derived().
+ */
+{
+ typedef
+ IndexStackConcrete
+ index_stack_concrete_t
+ ;
+ index_stack_concrete_t&
+ derived()
+ {
+ *static_cast<index_stack_concrete_t*>(this);
+ }
+ index_stack_concrete_t const&
+ derived()const
+ {
+ *static_cast<index_stack_concrete_t const*>(this);
+ }
+ template
+ < inc_dec_enum ID
+ >
+ int
+ inc_dec_ator()
+ /**@brief
+ * increment (if ID==inc_ator) or decrement(if ID==dec_ator) the indices
+ * 1 at a time, from rightmost to leftmost.
+ * IOW, the rightmost index increments fastest, and
+ * the leftmost index increments slowest.
+ */
+ {
+ index_stack_concrete_t&der=derived();
+ typedef inc_dec_concrete<ID> conc_t;
+ auto& offset_space=der.offset_space_ref();
+ int const n=der.rank();
+ int axis=n-1;//increment 1st rightmost index.
+ //#define TRACE_INC_DEC_ATOR
+ while( 0<=axis)
+ {
+ auto ibs=der[axis];
+ auto& index_axis=ibs.template get<index_value>();
+ auto bound_limit_axis=ibs.template bound<conc_t::bound_limit>();
+ auto stride_axis=ibs.stride_val();
+ #ifdef TRACE_INC_DEC_ATOR
+ std::cout
+ <<"inc_dec_ator::before:axis="<<axis
+ <<":index_axis="<<index_axis
+ <<":bound_limit_axis="<<bound_limit_axis
+ <<"\n";
+ #endif
+ if( index_axis == bound_limit_axis)//if axis-th index at triggeer bound, then
+ {
+ { //reset index_axis to bound opposite to bound_limit_axis:
+ auto bound_reset_axis=ibs.template bound<conc_t::bound_reset>();
+ //First, change offset_space to reflect future
+ //change in index_axis to bounds_reset_axis.
+ offset_space-=(index_axis-bound_reset_axis)*stride_axis;
+ //Next, change index_axis.
+ index_axis=bound_reset_axis;
+ }
+ //then proceed to increment/decrement next (in left direction) index in loop.
+ --axis;
+ }
+ else
+ { //just cnahge index_axis, offset_space, and exit loop.
+ conc_t::change( index_axis, offset_space, stride_axis);
+ break;
+ }
+ #ifdef TRACE_INC_DEC_ATOR
+ std::cout
+ <<"inc_dec_ator::after:axis="<<axis
+ <<":index_axis="<<index_axis
+ <<"\n";
+ #endif
+ }
+ return axis;
+ }
+ int
+ operator++()
+ {
+ return inc_dec_ator<inc_ator>();
+ }
+ int
+ operator--()
+ {
+ return inc_dec_ator<dec_ator>();
+ }
+
+};
+
+ template
+ < typename IndexStackConcrete
+ >
+ struct
+indices_space
+;
+ template
+ < typename Stride
+ , template< typename>class Tmpl
+ >
+ struct
+indices_space
+ < Tmpl<Stride>
+ >
+{
+ typedef
+ Tmpl<Stride>
+ derived_t
+ ;
+ typedef
+ Stride
+ stride_t
+ ;
+ typedef
+ index_stack_length_stride_crtp_types<stride_t>
+ types_t
+ ;
+ typedef
+ typename types_t::axis_t
+ axis_t
+ ;
+ typedef
+ typename types_t::index_t
+ index_t
+ ;
+ indices_space()
+ : my_space(this->ctor_space())
+ {
+ }
+ stride_t
+ space()const
+ {
+ return my_space;
+ }
+
+ void
+ axis_index_put
+ ( axis_t a_axis
+ , index_t a_index
+ )
+ {
+ derived_t&der=derived();
+ auto ibs=der[a_axis];
+ auto&index_ref=ibs.get<index_value>();
+ auto&offset_space=der.offset_space_ref();
+ int index_diff=a_index-index_ref;
+ auto stride=ibs.stride_val();
+ int offset_diff=index_diff*stride;
+ offset_space+=offset_diff;
+ index_ref=a_index;
+ }
+
+ void
+ axis_offset_put
+ ( axis_t a_axis
+ , index_t a_offset_lower
+ , index_t a_offset_upper
+ )
+ {
+ derived_t&der=derived();
+ auto ibs=der[a_axis];
+ auto l_old=ibs.length_val();
+ ibs.get<index_bound_lower>()=a_offset_lower;
+ ibs.get<index_bound_upper>()=a_offset_upper;
+ auto l_new=ibs.length_val();
+ auto index_lower=ibs.template bound<index_bound_lower>();
+ axis_index_put(a_axis,index_lower);
+ if(l_old==l_new)return;
+ my_space/=l_old;
+ my_space*=l_new;
+ }
+
+ derived_t&
+ derived()
+ {
+ return *static_cast<derived_t*>(this);
+ }
+ private:
+ stride_t
+ ctor_space()
+ /**@brief
+ * 1) returns number of elements =
+ * (bounds_upper[ 0]+1-bounds_lower[ 0])
+ * *(bounds_upper[ 1]+1-bounds_lower[ 1])
+ * ...
+ * *(bounds_upper[rank-1]+1-bounds_lower[rank-1])
+ * 2) sets indices[*] to bounds_lower[*].
+ * 3) sets offset_space =
+ * bounds_lower[ 0]*strides[ 0]
+ * +bounds_lower[ 1]*strides[ 1]
+ * ...
+ * +bounds_lower[rank-1]*strides[rank-1]
+ *
+ * where:
+ * rank = number of axes.
+ * indices [a_axis] is index of axis, a_axis.
+ * bounds_lower[a_axis] is lower bound of index of axis, a_axis.
+ * bounds_upper[a_axis] is upper bound of index of axis, a_axis.
+ * strides [a_axis] is stride of axis, a_axis.
+ */
+ {
+ typedef
+ typename derived_t::axis_t
+ axis_t;
+ derived_t&der=derived();
+ auto&offset_space=der.offset_space_ref();
+ stride_t s=1;
+ axis_t const rank=der.rank();
+ for
+ ( axis_t axis=0
+ ; axis<rank
+ ; ++axis
+ )
+ {
+ auto ibs=der[axis];
+ offset_space+=ibs.template get<index_value>()*std::abs(ibs.stride_val());
+ int l=ibs.length_val();
+ if(l<0)l=0;
+ s*=l;
+ }
+ return s;
+ }
+ stride_t
+ my_space
+ ;
+};
+
+ template
+ < typename Stride=int
+ >
+ struct
+index_stack_length_stride_crtp_indices
+: index_stack_length_stride_crtp_types<Stride>::indices_bounds_strides
+, index_stack_length_stride_crtp_types<Stride>::offset_space
+, index_stack_length_stride_crtp_abstract
+ < index_stack_length_stride_crtp_indices
+ < Stride
+ >
+ >
+, indices_space
+ < index_stack_length_stride_crtp_indices
+ < Stride
+ >
+ >
+{
+
+ typedef
+ index_stack_length_stride_crtp_types
+ < Stride
+ >
+ types_t
+ ;
+ typedef
+ typename types_t::stride_t
+ stride_t
+ ;
+ typedef
+ typename types_t::index_t
+ index_t
+ ;
+ typedef
+ typename types_t::axis_t
+ axis_t
+ ;
+ typedef
+ typename types_t::indices_bounds_strides
+ indices_bounds_strides_t
+ ;
+ typedef
+ indices_space
+ < index_stack_length_stride_crtp_indices
+ < Stride
+ >
+ >
+ indices_space_t
+ ;
+ typedef
+ typename types_t::length_stride_iter_t
+ length_stride_iter_t
+ ;
+ index_stack_length_stride_crtp_indices
+ ( length_stride_iter_t ls_iter_beg
+ , length_stride_iter_t ls_iter_end
+ )
+ : index_stack_length_stride_crtp_types<Stride>::indices_bounds_strides
+ ( axis_t(ls_iter_end-ls_iter_beg)
+ , ls_iter_beg
+ )
+ {
+ }
+};
+
+}//exit array_stepper namespace
+}//exit boost namespace
+
+#include <iostream>
+#include <iomanip>
+
+ template< typename Stride>
+ std::ostream&
+operator<<
+ ( std::ostream& sout
+ , boost::array_stepper::index_stack_length_stride_crtp_indices<Stride>const& lsos_v
+ )
+ {
+ sout<<"{ offset="<<std::setw(2)<<lsos_v.offset_space_val();
+ sout<<", indices=";
+ sout<<"{ ";
+ for(unsigned axis=0; axis<lsos_v.rank(); ++axis)
+ {
+ if(0<axis)sout<<", ";
+ auto ibs=lsos_v[axis];
+ auto index=ibs.template get<boost::array_stepper::index_value>();
+ sout<<std::setw(2)<<index;
+ }
+ sout<<"} ";
+ sout<<"}";
+ return sout;
+ }
+
+#endif

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,132 @@
+#ifndef BOOST_ARRAY_STEPPER_LENGTH_STRIDE_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_LENGTH_STRIDE_HPP_INCLUDED
+#include <limits>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+namespace boost
+{
+namespace array_stepper
+{
+ template
+ < typename StrideDir = int
+ >
+ struct
+length_stride
+ /**@brief
+ * Length and Stride of an array axis.
+ **@reference:
+ * _An APL Compiler_
+ * Timothy Budd
+ * Springer-Verlag, 1988
+ */
+{
+ typedef
+ StrideDir
+ stride_t
+ /**@brief
+ * Stride of an axis.
+ */
+ ;
+ private:
+ BOOST_STATIC_ASSERT(std::numeric_limits<stride_t>::is_signed)
+ /**@brief
+ * stride_t is be signed to allow for reverse ordering
+ * of indices. IOW, allow the (i+1)-th value
+ * to be located *before* the i-th value.
+ */
+ ;
+ public:
+ typedef
+ typename make_unsigned<stride_t>::type
+ length_t
+ ;
+ private:
+ length_t
+ my_length
+ /**@brief
+ * Length of the axis.
+ * Corresponds to the s_i in equation (5.1)
+ * of section:
+ * 5.1 Expansion Vectors
+ * of @reference.
+ */
+ ;
+ stride_t
+ my_stride
+ /**@brief
+ * Stride of the axis, i.e.
+ * the distance between adjacent
+ * elements on the axis.
+ * If < 0, this indicates the
+ * axis is reversed, IOW for
+ * indices i,j such that i<j:
+ * address of i-th element
+ * > address of j-th element.
+ * See comments in:
+ * length_stride_compose<>::operator()(...)
+ * in length_stride_compose.hpp.
+ *
+ * This corresponds to the e_i in equation (5.1)
+ * of section:
+ * 5.1 Expansion Vectors
+ * of @reference, *except* it may be negative
+ * to account for axis reveral, as explained above.
+ */
+ ;
+ public:
+ length_t
+ length()const
+ {
+ return my_length;
+ }
+ stride_t
+ stride()const
+ {
+ return my_stride;
+ }
+ length_t
+ space()const
+ {
+ return length()*abs(stride());
+ }
+ length_stride()
+ : my_length(1)
+ , my_stride(1)
+ {}
+ length_stride(length_t a_length)
+ : my_length(a_length)
+ , my_stride(1)
+ {}
+ length_stride(length_t a_length, stride_t a_stride)
+ : my_length(a_length)
+ , my_stride(a_stride)
+ {}
+
+};
+
+ template
+ < typename LengthStride
+ >
+ typename LengthStride::space_t
+length
+ ( LengthStride const& ls
+ )
+ {
+ return ls.length();
+ }
+
+ template
+ < typename LengthStride
+ >
+ typename LengthStride::stride_t
+stride
+ ( LengthStride const& ls
+ )
+ {
+ return ls.stride();
+ }
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride_compose.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_stride_compose.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,152 @@
+#ifndef BOOST_ARRAY_STEPPER_LENGTH_STRIDE_COMPOSE_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_LENGTH_STRIDE_COMPOSE_HPP_INCLUDED
+#include <boost/array_stepper/length_stride.hpp>
+#include <cstddef>
+#include <numeric>
+namespace boost
+{
+namespace array_stepper
+{
+ enum
+sign_val
+{ less0=-1
+, is0
+, more0
+};
+
+ template
+ < typename LengthStride //instance of length_stride.
+ , typename Offset=std::size_t
+ >
+ struct
+length_stride_compose
+ /**@brief
+ * Used as 1st arg to scan_first_iter to
+ * create LengthStride's from
+ * sequence of LengthStride::length_t's.
+ */
+{
+ typedef
+ LengthStride
+ length_stride_t
+ ;
+ typedef
+ typename length_stride_t::length_t
+ length_t
+ ;
+ typedef
+ typename length_stride_t::stride_t
+ stride_t
+ ;
+ typedef
+ stride_t
+ length_dir_t
+ /**@brief
+ * axis length which is signed in order
+ * to indicate forward (>0) or reverse(<0)
+ * order of indices.
+ */
+ ;
+ typedef
+ Offset
+ offset_t
+ ;
+ private:
+ offset_t
+ my_offset
+ /**@brief
+ * Modified by negative length_t arguments.
+ * A negative length_t indicates that the
+ * elements are stored in reverse order.
+ * In other words, the element stored
+ * at index, i, is stored after the
+ * element stored at index, (i+1).
+ * Here, index means the index argument
+ * to the subscript operator.
+ *
+ **@reference:
+ * _An APL Compiler_
+ * Timothy Budd
+ * Springer-Verlag, 1988
+ */
+ ;
+ public:
+ length_stride_compose()
+ : my_offset(0)
+ {}
+ offset_t
+ offset()const
+ {
+ return my_offset;
+ }
+
+ static
+ sign_val
+ isign( length_dir_t a_length)
+ /**@brief
+ * Returns one of {less0,is0,more0}
+ * depending on sign of a_length.
+ */
+ {
+ sign_val r=(a_length<0)?less0:((a_length==0)?is0:more0);
+ return r;
+ }
+
+ length_stride_t
+ operator()
+ ( length_dir_t a_length //The first length in the length sequence.
+ )
+ {
+ sign_val sv=isign(a_length);
+ length_t ex=abs(a_length);
+ /**
+ * The comment preceding the similar statment
+ * in binary operator() applies here also.
+ */
+ length_t sp=1;
+ if(sv==less0) my_offset =(ex-1)*sp;
+ stride_t st=sv*sp;
+ length_stride_t result( ex, st);
+ return result;
+ }
+
+ length_stride_t
+ operator()
+ ( length_stride_t a_length_stride //previous length stride
+ , length_dir_t a_length //current length (not first)
+ )
+ /**@brief
+ * Returns current length_stride_t.
+ */
+ {
+ sign_val sv=isign(a_length);
+ length_t ex=abs(a_length);
+ /**
+ * The following 3 statements, when applied to all
+ * the axes, do, essentially, what's done by the:
+ * equations:
+ * t_i' = s_i - t_i - 1
+ * d_i' = -d_i
+ * in section:
+ * 6.1.4 Reversal
+ * and the alpha equation:
+ * alpha = t_1*e_1 + ... t_n*e_n
+ * in section:
+ * 6.2 The Accessor
+ * of @reference (see comments to my_offset declaration).
+ *
+ * In summary, alpha in the above section 6.2 equation
+ * of @reference is my_offset here.
+ */
+ length_t sp=a_length_stride.space();
+ if(sv==less0) my_offset+=(ex-1)*sp;
+ stride_t st=sv*sp;
+ length_stride_t result( ex, st);
+ return result;
+ }
+
+};
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_strides_offset.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/length_strides_offset.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,522 @@
+#ifndef BOOST_ARRAY_STEPPER_LENGTH_STRIDES_OFFSET_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_LENGTH_STRIDES_OFFSET_HPP_INCLUDED
+#if 0
+#include <boost/array_stepper/length_strides_axis_offset.hpp>
+#include <boost/array_stepper/length_strides_val.hpp>
+#endif
+#include <boost/array_stepper/length_stride_compose.hpp>
+#include <boost/array_stepper/scan_first_iter.hpp>
+#include <boost/array_stepper/permutation.hpp>
+#include <boost/array.hpp>
+#include <boost/iterator/permutation_iterator.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/assert.hpp>
+#include <algorithm>
+
+namespace boost
+{
+namespace array_stepper
+{
+
+enum storage_order_predefined
+{ store_reverse //strides decrease as axis increases(as with c arrays).
+, store_forward //strides increase as axis increases(as with fortran arrays).
+};
+enum
+{ storage_order_predef_num=store_forward+1
+};
+enum struct_op_enum
+/**@brief
+ * enumeration of the structural operations
+ */
+{ op_ax_permute //permute axes
+, op_ax_rotate //rotate axes(a specialized & faster permute)
+};
+ template
+ < struct_op_enum StrOp
+ >
+struct struct_op_tag
+{};
+
+ template
+ < typename StrideDir=int
+ >
+ struct
+length_strides_offset
+ /**@brief
+ * For each axis (or dimension) in a multi-dimentional array,
+ * this structure stores a length_stride. In addition,
+ * to account for a negative stride for any of the axes, this
+ * class stores an offset.
+ **@reference:
+ * _An APL Compiler_
+ * Timothy Budd
+ * Springer-Verlag, 1988
+ */
+{
+ typedef
+ length_stride
+ < StrideDir
+ >
+ length_stride_t
+ ;
+ typedef
+ typename length_stride_t::stride_t
+ stride_t
+ ;
+ typedef
+ unsigned
+ axis_t
+ ;
+ typedef
+ int
+ rot_t
+ /**@brief
+ * axis rotation amount.
+ */
+ ;
+ typedef
+ std::vector
+ < length_stride_t
+ >
+ length_strides_t
+ ;
+ typedef
+ length_stride_compose<length_stride_t>
+ comp_t
+ ;
+ typedef
+ typename comp_t::length_dir_t
+ length_dir_t
+ ;
+ typedef
+ typename comp_t::offset_t
+ offset_t
+ ;
+ typedef
+ offset_t
+ index_t
+ ;
+ typedef
+ std::vector<index_t>
+ indexs_t
+ ;
+ typedef
+ std::vector<unsigned>
+ permute_t
+ /**@brief
+ * Type of a permutaion of indices, 0...Rank-1
+ * for some unsigned Rank.
+ */
+ ;
+ typedef typename
+ permute_t::value_type
+ permute_val_t
+ ;
+ public:
+ typedef
+ permute_t
+ (*permute_0to_t) //function returning a permutation of [0,a_last)
+ ( permute_val_t //a_last
+ )
+ ;
+ static
+ permute_t
+ identity_permutation
+ ( permute_val_t a_last
+ )
+ {
+ return mk_iota( permute_val_t(0), a_last);
+ }
+
+ static
+ permute_t
+ reverse_permutation
+ ( permute_val_t a_last
+ )
+ {
+ return mk_iota( a_last, permute_val_t(0));
+ }
+
+ static
+ storage_order_predefined const
+ storage_order_default
+ =store_reverse
+ ;
+ permute_0to_t
+ permute_select
+ ( storage_order_predefined a_so=storage_order_default
+ )
+ {
+ static permute_0to_t mk[storage_order_predef_num]=
+ { reverse_permutation
+ , identity_permutation
+ };
+ return mk[a_so];
+ }
+
+ private:
+ offset_t
+ my_offset
+ /**@brief
+ * Offset from start of array where all 0 index
+ * is located. my_offset != 0 iff one or more
+ * of the lengths passed to CTOR are < 0.
+ */
+ ;
+ length_strides_t
+ my_length_strides
+ /**@brief
+ * The length & strides for each axis in a multidimensional array.
+ */
+ ;
+ template
+ < typename InpIter
+ , typename OutIter
+ >
+ OutIter
+ init_iter_strides
+ ( InpIter lengths_beg
+ , InpIter lengths_end
+ , OutIter strides_beg
+ )
+ /**@brief
+ * 1) Helper function for init_strides( Lengths...)
+ * 2) Initializes my_offset.
+ */
+ {
+ comp_t comp_v;
+ OutIter strides_end=
+ scan_first_iter
+ ( comp_v
+ , lengths_beg
+ , lengths_end
+ , strides_beg
+ );
+ my_offset=comp_v.offset();
+ return strides_end;
+ }
+
+ protected:
+
+ template
+ < typename Lengths
+ >
+ stride_t
+ init_strides
+ ( Lengths const& a_lengths
+ , permute_t const& a_permute
+ )
+ /**@brief
+ * 1) Calculates strides of the array with shape, a_lengths,
+ * permuted by a_permute.
+ * 2) Initializes my_offset.
+ * 3) returns number of elements in a multi-dimenstional
+ * array with these Lengths (which is the
+ * product of the absolute value of all a_length
+ * elements).
+ */
+ {
+ BOOST_ASSERT
+ ( ( a_lengths.size() == my_length_strides.size())
+ && ( a_permute.size() == my_length_strides.size())
+ && permutation::is_permutation( a_permute)
+ );
+ typedef
+ permutation_iterator
+ < typename Lengths::const_iterator
+ , permute_t::const_iterator
+ >
+ plenit_t;
+ plenit_t len_beg( a_lengths.begin(), a_permute.begin());
+ plenit_t len_end( a_lengths.begin(), a_permute.end());
+ typedef
+ permutation_iterator
+ < typename length_strides_t::iterator
+ , permute_t::const_iterator
+ >
+ plss_t;
+ plss_t lss_beg( my_length_strides.begin(), a_permute.begin());
+ plss_t lss_end=
+ init_iter_strides
+ ( len_beg
+ , len_end
+ , lss_beg
+ );
+ return lss_end->space();
+ }
+
+ template
+ < typename Lengths
+ >
+ stride_t
+ init_strides
+ ( Lengths const& a_lengths
+ , storage_order_predefined a_so=storage_order_default
+ )
+ {
+ return
+ init_strides
+ ( a_lengths
+ , permute_select
+ ( a_so
+ )
+ ( a_lengths.size()
+ )
+ );
+ }
+
+ length_strides_offset
+ ( std::size_t a_size
+ )
+ /**@brief
+ * To be used by subclasses which should
+ * call this->init_strides( a_lengths, ...)
+ * where a_lengths.size() == a_size
+ */
+ : my_length_strides( a_size)
+ {
+ }
+ public:
+
+ template< typename Lengths>
+ length_strides_offset
+ ( Lengths const& a_lengths
+ , storage_order_predefined a_so=storage_order_default
+ )
+ : my_length_strides( a_lengths.size())
+ {
+ init_strides( a_lengths, a_so);
+ }
+
+ template< typename Lengths>
+ length_strides_offset
+ ( Lengths const& a_lengths
+ , permute_t const& a_permute
+ )
+ : my_length_strides( a_lengths.size())
+ {
+ init_strides( a_lengths, a_permute);
+ }
+
+ length_strides_offset
+ ( length_strides_offset const& a_iso
+ , index_t a_index
+ )
+ /**@brief
+ * Let an array, A, be described by a_iso.
+ * This CTOR produces a description of
+ * A[a_index].
+ */
+ : my_offset
+ ( a_iso.offset()
+ + a_iso.length_strides().front().stride()
+ * a_index
+ )
+ , my_length_strides
+ ( a_iso.begin()+1
+ , a_iso.end()
+ )
+ {
+ }
+
+ length_strides_offset
+ ( struct_op_tag<op_ax_rotate>
+ , length_strides_offset const& a_iso
+ , axis_t a_axis
+ )
+ /**@brief
+ * Let an array, A, be described by a_iso.
+ * This CTOR produces a description of an
+ * array, B, with axes, a_axis..A.rank()
+ * rotated by 1.
+ */
+ : my_offset
+ ( a_iso.offset()
+ )
+ , my_length_strides
+ ( a_iso.rank()
+ )
+ {
+ std::copy //copy 1st part of a_iso
+ ( a_iso.begin()
+ , a_iso.begin()+a_axis-1
+ , my_length_strides.begin()
+ );
+ std::rotate_copy //copy 2nd part of a_iso rotated by 1.
+ ( a_iso.begin()+a_axis
+ , a_iso.begin()+a_axis+1
+ , a_iso.end()
+ , my_length_strides.begin()+a_axis
+ );
+ }
+
+ axis_t
+ rank()const
+ {
+ return my_length_strides.size();
+ }
+ length_strides_t const&
+ length_strides()const
+ {
+ return my_length_strides;
+ }
+ typename length_strides_t::const_iterator
+ begin()const
+ {
+ return length_strides().begin();
+ }
+ offset_t
+ offset()const
+ {
+ return my_offset;
+ }
+ axis_t
+ normalize_rotation
+ ( int rotation
+ , axis_t a_axis
+ )
+ {
+ axis_t const rnk=rank()-a_axis;
+ int nrot=rotation%rnk;//-rnk < nrot && nrot < rnk
+ axis_t mrot=(nrot+rnk)%rnk;//0<=mrot && mrot < rnk
+ return mrot;
+ }
+ axis_t
+ normalize_axis
+ ( axis_t a_axis
+ )
+ {
+ return a_axis%rank();
+ }
+ void
+ axis_rot
+ ( int a_rot=1
+ , axis_t a_axis=0
+ )
+ {
+ a_axis=normalize_axis(a_axis);
+ unsigned const n_rot=normalize_rotation( a_rot, a_axis);
+ typedef typename length_strides_t::iterator iter_t;
+ iter_t beg=my_length_strides.begin()+a_axis;
+ iter_t mid=beg+n_rot;
+ iter_t end=my_length_strides.end();
+ std::rotate( beg, mid, end);
+ }
+ static
+ offset_t
+ offset_at_indexs_seq
+ ( indexs_t const& a_indexs_seq
+ , typename length_strides_t::const_iterator beg_ls
+ , offset_t a_offset
+ )
+ /**@brief
+ * The offset of element in an array
+ * corresponding to indices in index sequence, a_indices.
+ *
+ * This corresponds to equation (5.2) of the @reference.
+ */
+ {
+ typename indexs_t::const_iterator beg_i=a_indexs_seq.begin();
+ typename indexs_t::const_iterator end_i=a_indexs_seq.end();
+ typedef stride_t(*get_stride_t)(length_stride_t const&);
+ transform_iterator
+ < get_stride_t
+ , typename length_strides_t::const_iterator
+ >
+ beg_s
+ ( beg_ls
+ , stride< length_stride_t>
+ );
+ offset_t const r_offset
+ = std::inner_product
+ ( beg_i
+ , end_i
+ , beg_s
+ , a_offset
+ );
+ return r_offset;
+ }
+ offset_t
+ offset_at_indexs_seq
+ ( indexs_t const& a_indexs_seq
+ )const
+ /**@brief
+ * The offset of element in an array
+ * corresponding to indices in index sequence, a_indices.
+ *
+ * This corresponds to equation (5.2) of the @reference.
+ */
+ {
+ typename length_strides_t::const_iterator beg_ls=my_length_strides.begin();
+ return offset_at_indexs_seq( a_indexs_seq, beg_ls, my_offset);
+ }
+
+ struct index_at_offset
+ /**@brief
+ * Functor used by indexs_at_offset.
+ */
+ {
+ offset_t
+ my_offset
+ /**@brief
+ * offset in multitimensional array.
+ * from beginning of array.
+ */
+ ;
+ index_at_offset( offset_t a_offset)
+ : my_offset(a_offset)
+ {}
+ typedef
+ index_t
+ result_type
+ /**@brief
+ * required by make_transform_iterator
+ * used in indexs_at_offset.
+ */
+ ;
+ index_t
+ operator()( length_stride_t const& ls)const
+ /**@brief
+ * this is equation (5.7) in @reference
+ * for an axis described by ls.
+ */
+ {
+ index_t div_v=my_offset/ls.stride();
+ index_t index_v=div_v%ls.length();
+ return index_v;
+ }
+ };
+ indexs_t
+ indexs_at_offset
+ ( offset_t a_offset
+ )const
+ /**@brief
+ * The inverse of offset_at_indexs_seq.
+ *
+ * This corresponds to equation (5.7) in @reference
+ * for each axis.
+ */
+ {
+ typedef typename length_strides_t::const_iterator citer;
+ citer beg_ls=my_length_strides.begin();
+ citer end_ls=my_length_strides.end();
+ index_at_offset iao(a_offset);
+ typedef transform_iterator<index_at_offset,citer> xiter;
+ xiter beg_index( beg_ls, iao);
+ xiter end_index( end_ls, iao);
+ indexs_t a_indexs_seq(rank());
+ typename indexs_t::iterator beg_is=a_indexs_seq.begin();
+ std::copy
+ ( beg_index
+ , end_index
+ , beg_is
+ );
+ return a_indexs_seq;
+ }
+
+};
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif

Modified: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/mk_iota.hpp
==============================================================================
--- sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/mk_iota.hpp (original)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/mk_iota.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -1,7 +1,12 @@
 #ifndef BOOST_ARRAY_STEPPER_MK_IOTA_HPP_INCLUDED
 #define BOOST_ARRAY_STEPPER_MK_IOTA_HPP_INCLUDED
-#include <numeric>
+#include <cstdlib>
 #include <vector>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <numeric>
+#else
+#include <boost/iterator/counting_iterator.hpp>
+#endif
 namespace boost
 {
 namespace array_stepper
@@ -19,11 +24,21 @@
       std::vector<Value> result(abs(size));
       if(size>0)
       {
+ #ifdef __GXX_EXPERIMENTAL_CXX0X__
           std::iota( result.begin(), result.end(), first);
+ #else
+ unsigned const n=size;
+ for(unsigned i=0; i<n; ++i) result[i]=first+i;
+ #endif
       }
       else
       {
+ #ifdef __GXX_EXPERIMENTAL_CXX0X__
           std::iota( result.rbegin(), result.rend(), last);
+ #else
+ unsigned const n=-size;
+ for(unsigned i=0; i<n; ++i) result[n-1-i]=last+i;
+ #endif
       }
       return result;
   }

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/scan_first_iter.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/scan_first_iter.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,41 @@
+#ifndef BOOST_ARRAY_STEPPER_SCAN_FIRST_ITER_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_SCAN_FIRST_ITER_HPP_INCLUDED
+namespace boost
+{
+namespace array_stepper
+{
+
+ template
+ < typename InputIter
+ , typename OutputIter
+ , typename Operations
+ >
+ OutputIter
+scan_first_iter
+ ( Operations& ops
+ , InputIter first
+ , InputIter last
+ , OutputIter result
+ )
+{
+ if(first!=last)
+ {
+ typedef typename OutputIter::value_type value_t;
+ *result=ops(*first);
+ for
+ ( ++first
+ ; first!=last
+ ; ++first
+ )
+ {
+ value_t next=ops(*result,*first);
+ ++result;
+ *result=next;
+ }
+ }
+ return result;
+}
+
+}//exit array_stepper namespace
+}//exit boost namespace
+#endif

Modified: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/stepper_offset.hpp
==============================================================================
--- sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/stepper_offset.hpp (original)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/stepper_offset.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -4,8 +4,9 @@
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/make_signed.hpp>
 #include <boost/type_traits/make_unsigned.hpp>
-#include <limits>
 #include <boost/array_stepper/permutation0_last.hpp>
+#include <limits>
+
 namespace boost
 {
 namespace array_stepper
@@ -27,6 +28,7 @@
 enum
 { stepr_size=stepr_axis+1
 };
+
   template
   < typename Value=int
     //Value must include negative values(i.e. be signed)
@@ -203,22 +205,47 @@
     {
         return my_offset;
     }
+ offset_t
+ offset(index_t a_index)const
+ {
+ axis_t const a_axis= my_stepper_ones[0][stepr_axis];
+ return offset()+my_stepper_ones[a_axis].offset(a_index);
+ }
       const_iterator
     begin()const
     {
         return my_stepper_ones.begin();
     }
       void
- permute( axes_permutation_t a_permut)
+ permute_axes
+ ( axes_permutation_t a_permut
+ , axis_t a_from=0
+ )
     {
- stepper_ones_t so_v(stepper_ones());
- unsigned r=rank();
- for( unsigned i=0; i<r; ++i)
+ unsigned r=rank()-a_from;
+ std::vector<value_t> axes(r);
+ for( unsigned i=a_from; i<r; ++i)
+ {
+ axes[i]=my_stepper_ones[i][stepr_axis];
+ }
+ for( unsigned i=a_from; i<r; ++i)
         {
             unsigned p=a_permut[i];
- my_stepper_ones[i]=so_v[p];
- //my_stepper_ones[i][stepr_axis]=a_permut[so_v[i][stepr_axis]];
+ my_stepper_ones[i][stepr_axis]=axes[p];
+ }
+ }
+ void
+ rotate_axes
+ ( axis_t a_from=0
+ )
+ {
+ unsigned r=rank();
+ axis_t a_axis=my_stepper_ones[a_from][stepr_axis];
+ for( unsigned i=a_from; i<r-1; ++i)
+ {
+ my_stepper_ones[i][stepr_axis]=my_stepper_ones[i+1][stepr_axis];
         }
+ my_stepper_ones[r-1][stepr_axis]=a_axis;
     }
  protected:
       offset_t
@@ -230,26 +257,69 @@
         unsigned size=a_lengths.size();
         if(0<size)
         {
- unsigned i=0;
- unsigned now_index =a_permut[i];
- value_t now_length=a_lengths[now_index];
- int now_sign =isign(now_length);
- my_stepper_ones[now_index][stepr_length]=abs(now_length);
- my_stepper_ones[now_index][stepr_stride]=now_sign;
- my_stepper_ones[now_index][stepr_axis ]=size-1-i;
- my_offset+=my_stepper_ones[now_index].offset();
- for(++i; i<size; ++i)
+ #if 0
+ unsigned leng_indx=0;
+ unsigned perm_indx=a_permut[leng_indx];
+ value_t leng_valu=a_lengths[perm_indx];
+ int leng_sign=isign(leng_valu);
+ my_stepper_ones[perm_indx][stepr_length]=abs(leng_valu);
+ my_stepper_ones[perm_indx][stepr_stride]=leng_sign;
+ my_stepper_ones[perm_indx][stepr_axis ]=size-1-leng_indx;
+ my_offset+=my_stepper_ones[perm_indx].offset();
+ for(++leng_indx; leng_indx<size; ++leng_indx)
+ {
+ value_t pre_space=my_stepper_ones[perm_indx].space();
+ perm_indx=a_permut[leng_indx];
+ leng_valu=a_lengths[perm_indx];
+ leng_sign=isign(leng_valu);
+ my_stepper_ones[perm_indx][stepr_length]=abs(leng_valu);
+ my_stepper_ones[perm_indx][stepr_stride]=leng_sign*pre_space;
+ my_stepper_ones[perm_indx][stepr_axis ]=size-1-leng_indx;
+ my_offset+=my_stepper_ones[perm_indx].offset();
+ }
+ return my_stepper_ones[perm_indx].space();
+ #elif 0
+ unsigned leng_indx=0;
+ unsigned perm_indx=a_permut[leng_indx];
+ value_t leng_valu=a_lengths[perm_indx];
+ int leng_sign=isign(leng_valu);
+ my_stepper_ones[perm_indx][stepr_length]=abs(leng_valu);
+ my_stepper_ones[perm_indx][stepr_stride]=leng_sign;
+ my_stepper_ones[perm_indx][stepr_axis ]=leng_indx;
+ my_offset+=my_stepper_ones[perm_indx].offset();
+ for(++leng_indx; leng_indx<size; ++leng_indx)
+ {
+ value_t pre_space=my_stepper_ones[perm_indx].space();
+ perm_indx=a_permut[leng_indx];
+ leng_valu=a_lengths[perm_indx];
+ leng_sign=isign(leng_valu);
+ my_stepper_ones[perm_indx][stepr_length]=abs(leng_valu);
+ my_stepper_ones[perm_indx][stepr_stride]=leng_sign*pre_space;
+ my_stepper_ones[perm_indx][stepr_axis ]=leng_indx;
+ my_offset+=my_stepper_ones[perm_indx].offset();
+ }
+ return my_stepper_ones[perm_indx].space();
+ #else
+ unsigned maxm_indx=size-1;//MAXiMum index
+ for( unsigned leng_indx=0; leng_indx<size; ++leng_indx)
+ {
+ unsigned perm_indx=maxm_indx-a_permut[leng_indx];
+ value_t leng_valu=a_lengths[leng_indx];
+ int leng_sign=isign(leng_valu);
+ my_stepper_ones[perm_indx][stepr_length]=abs(leng_valu);
+ my_stepper_ones[perm_indx][stepr_stride]=leng_sign;
+ my_stepper_ones[leng_indx][stepr_axis ]=perm_indx;
+ }
             {
- value_t pre_space=my_stepper_ones[now_index].space();
- now_index =a_permut[i];
- now_length=a_lengths[now_index];
- now_sign =isign(now_length);
- my_stepper_ones[now_index][stepr_length]=abs(now_length);
- my_stepper_ones[now_index][stepr_stride]=now_sign*pre_space;
- my_stepper_ones[now_index][stepr_axis ]=size-1-i;
- my_offset+=my_stepper_ones[now_index].offset();
+ my_offset=my_stepper_ones[maxm_indx].offset();
+ for( int axis_indx=maxm_indx-1; 0<=axis_indx; --axis_indx)
+ {
+ my_stepper_ones[axis_indx][stepr_stride]*=my_stepper_ones[axis_indx+1].space();
+ my_offset+=my_stepper_ones[axis_indx].offset();
+ }
             }
- return my_stepper_ones[now_index].space();
+ return my_stepper_ones[maxm_indx].space();
+ #endif
         }
         else
         {

Added: sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/vector_print.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/stepper/boost/array_stepper/vector_print.hpp 2011-09-23 14:43:24 EDT (Fri, 23 Sep 2011)
@@ -0,0 +1,24 @@
+#ifndef BOOST_ARRAY_STEPPER_VECTOR_PRINT_HPP_INCLUDED
+#define BOOST_ARRAY_STEPPER_VECTOR_PRINT_HPP_INCLUDED
+#include <vector>
+#include <iostream>
+ template
+ < typename T
+ >
+ std::ostream&
+operator<<
+ ( std::ostream& sout
+ , std::vector<T> const& a_container
+ )
+{
+ sout<<"{ ";
+ unsigned const size=a_container.size();
+ for(unsigned i=0; i<size; ++i)
+ {
+ if(0<i) sout<<", ";
+ sout<<a_container[i];
+ }
+ sout<<"} ";
+ return sout;
+}
+#endif


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