Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71519 - in sandbox/variadic_templates/sandbox: array_dyn bind
From: cppljevans_at_[hidden]
Date: 2011-04-26 12:35:19


Author: cppljevans
Date: 2011-04-26 12:35:18 EDT (Tue, 26 Apr 2011)
New Revision: 71519
URL: http://svn.boost.org/trac/boost/changeset/71519

Log:
Add array_dyn as help to A.M.Wink and as compare to recent index_list proposal

Added:
   sandbox/variadic_templates/sandbox/array_dyn/
   sandbox/variadic_templates/sandbox/array_dyn/array_dyn.cpp (contents, props changed)
   sandbox/variadic_templates/sandbox/array_dyn/array_dyn.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/array_dyn/box_domain.hpp (contents, props changed)
Text files modified:
   sandbox/variadic_templates/sandbox/bind/Makefile | 1 -
   1 files changed, 0 insertions(+), 1 deletions(-)

Added: sandbox/variadic_templates/sandbox/array_dyn/array_dyn.cpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/array_dyn/array_dyn.cpp 2011-04-26 12:35:18 EDT (Tue, 26 Apr 2011)
@@ -0,0 +1,52 @@
+//Purpose:
+// Demo array whose dimensions and sizes are defined at runtime.
+//
+#include "array_dyn.hpp"
+
+int main(void)
+{
+ for(unsigned dir_op=dir_fwd; dir_op<unsigned(dir_rev+1); ++dir_op)
+ {
+ std::cout<<"*************************\n";
+ std::cout<<"dir_op="<<dir_op<<"\n";
+ array_dyn<int> ai(dirs(dir_op),2,3,4);
+ unsigned const size=ai.my_data.size();
+ std::cout<<"my_data.size()="<<size<<"\n";
+ unsigned const value0=1000;
+ for( unsigned i=0; i<size; ++i)
+ {
+ ai.my_data[i]=value0+i;
+ }
+ unsigned const rank=ai.rank();
+ std::cout<<"rank="<<rank<<"\n";
+ std::cout<<"size()="<<ai.size()<<"\n";
+ for(unsigned i=0;i<rank;++i)
+ {
+ std::cout<<"stride("<<i<<")="<<ai.stride(i)<<"\n";
+ std::cout<<" size("<<i<<")="<<ai.size(i)<<"\n";
+ }
+ std::cout<<"ai.offset_at_indices(1,0,0)="<<ai.offset_at_indices(1,0,0)<<"\n";
+ std::cout<<"ai(1,0,0)="<<ai(1,0,0)<<"\n";
+ std::cout<<"ai.offset_at_indices(0,1,0)="<<ai.offset_at_indices(0,1,0)<<"\n";
+ std::cout<<"ai(0,1,0)="<<ai(0,1,0)<<"\n";
+ std::cout<<"ai.offset_at_indices(0,0,1)="<<ai.offset_at_indices(0,0,1)<<"\n";
+ std::cout<<"ai(0,0,1)="<<ai(0,0,1)<<"\n";
+ std::cout<<"ai.ok_indices(1,2,3)="<<ai.ok_indices(1,2,3)<<"\n";
+ std::cout<<"ai.ok_indices(1,2,4)="<<ai.ok_indices(1,2,4)<<"\n";
+ std::cout<<"ai.ok_indices(1,2,3,0)="<<ai.ok_indices(1,2,3,0)<<"\n";
+ unsigned offset=ai.offset_at_indices(1,2,3);
+ std::cout<<"ai.offset_at_indices(1,2,3)="<<offset<<"\n";
+ std::vector<unsigned> indices(ai.indices_at_offset(offset));
+ std::cout<<"indices_at_offset("<<offset<<")=\n";
+ for(unsigned i=0; i< indices.size(); ++i)
+ {
+ std::cout<<indices[i]<<" ";
+ }
+ std::cout<<"\n";
+ #if 1
+ std::cout<<"ai=\n";
+ std::cout<<ai<<".\n";
+ #endif
+ }
+ return 0;
+}

Added: sandbox/variadic_templates/sandbox/array_dyn/array_dyn.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/array_dyn/array_dyn.hpp 2011-04-26 12:35:18 EDT (Tue, 26 Apr 2011)
@@ -0,0 +1,234 @@
+#ifndef ARRAY_DYN_HPP_INCLUDED
+#define ARRAY_DYN_HPP_INCLUDED
+#include <iostream>
+#include <iomanip>
+
+#include "box_domain.hpp"
+
+ template
+ < typename T
+ >
+ struct
+array_dyn
+/**@brief
+ * Multidimensional array whose
+ * 'shape' is defined at runtime.
+ * 'Shape' means upper bounds on indices
+ * for each dimension (or axis in apl terminology).
+ */
+: box_domain<>
+{
+ typedef
+ box_domain<>
+ super_t
+ ;
+ typedef typename
+ super_t::index_t
+ index_t
+ ;
+ std::vector<T>
+ my_data
+ /**@brief
+ * data in the array.
+ */
+ ;
+ template
+ < typename... Size
+ >
+ array_dyn( dirs a_dir, Size... a_size)
+ : super_t( a_dir, a_size...)
+ , my_data( super_t::size())
+ {
+ }
+
+ template
+ < typename... Size
+ >
+ void
+ reshape( Size... a_size)
+ {
+ my_data.resize(super_t::reshape(a_size...));
+ }
+
+ template
+ < typename... Index
+ >
+ T&
+ operator()( Index... a_index)
+ {
+ return my_data[offset_at_indices(a_index...)];
+ }
+
+ template
+ < typename... Index
+ >
+ T const&
+ operator()( Index... a_index)const
+ {
+ return my_data[offset_at_indices(a_index...)];
+ }
+
+};
+
+ template
+ < typename Array
+ >
+ struct
+array_host
+{
+ Array&
+ my_array
+ ;
+ typedef typename
+ Array::index_t
+ index_t
+ ;
+ int const
+ my_axis_dir
+ /**@brief
+ * +1 or -1: the direction in which axis changes.
+ */
+ ;
+ index_t const
+ my_axis_beg
+ ;
+ index_t const
+ my_axis_end
+ ;
+ array_host
+ ( Array& a_array
+ , dirs a_dir=dir_fwd
+ )
+ : my_array(a_array)
+ , my_axis_dir
+ ( (a_dir==dir_fwd)
+ ? +1
+ : -1
+ )
+ , my_axis_beg
+ ( (a_dir==dir_fwd)
+ ? 0
+ : my_array.rank()-1
+ )
+ , my_axis_end
+ ( (a_dir==dir_fwd)
+ ? my_array.rank()-1
+ : 0
+ )
+ {
+ }
+
+ template
+ < typename Visitor
+ >
+ void
+ accept
+ ( Visitor& a_viz
+ )
+ {
+ accept_off_ax
+ ( a_viz
+ , 0
+ , my_axis_beg
+ );
+ }
+ private:
+ template
+ < typename Visitor
+ >
+ void
+ accept_off_ax
+ ( Visitor& a_viz
+ , index_t offset
+ , index_t axis_now
+ )
+ {
+ index_t const axis_size=my_array.size(axis_now);
+ bool const is_leaf=axis_now==my_axis_end;
+ index_t const axis_stride=my_array.stride(axis_now);
+ for(index_t i=0; i<axis_size; ++i)
+ {
+ a_viz.visit_pre(is_leaf, axis_now, i);
+ if(is_leaf)
+ {
+ a_viz.visit_node(my_array.my_data[offset]);
+ }
+ else
+ {
+ this->accept_off_ax
+ ( a_viz
+ , offset
+ , axis_now+my_axis_dir
+ );
+ }
+ offset+=axis_stride;
+ }
+ a_viz.visit_post(is_leaf, axis_now);
+ }
+};
+
+ template
+ < typename T
+ >
+ struct
+print_array
+{
+ std::ostream&
+ my_sout
+ ;
+ typedef typename
+ array_dyn<T>::index_t
+ index_t
+ ;
+ print_array(std::ostream& a_sout)
+ : my_sout(a_sout)
+ {}
+
+ void visit_pre( bool is_leaf, index_t axis, index_t index)
+ {
+ if(index==0)
+ {
+ my_sout<<"{ ";
+ }
+ else
+ {
+ if(!is_leaf)
+ {
+ my_sout<<std::setw(2*axis)<<"";
+ }
+ my_sout<<", ";
+ }
+ }
+
+ void visit_node(T const& a_t)
+ {
+ my_sout<<a_t;
+ }
+
+ void visit_post( bool is_leaf, index_t axis)
+ {
+ if(!is_leaf)
+ {
+ my_sout<<std::setw(2*axis)<<"";
+ }
+ my_sout<<"}\n";
+ }
+
+};
+
+ template
+ < typename T
+ >
+ std::ostream&
+operator<<
+( std::ostream& sout
+, array_dyn<T>const& a_arr
+)
+{
+ print_array<T> a_viz(sout);
+ array_host<array_dyn<T> const> host_arr(a_arr);
+ host_arr.accept(a_viz);
+ return sout;
+}
+
+#endif

Added: sandbox/variadic_templates/sandbox/array_dyn/box_domain.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/array_dyn/box_domain.hpp 2011-04-26 12:35:18 EDT (Tue, 26 Apr 2011)
@@ -0,0 +1,283 @@
+#ifndef BOX_DOMAIN_HPP_INCLUDED
+#define BOX_DOMAIN_HPP_INCLUDED
+#include <vector>
+#include <numeric>
+#include <algorithm>
+
+enum dirs //directions(used to flag order of processing an ordered sequence).
+{ dir_fwd //forward direction.
+, dir_rev //reverse direction.
+};
+
+ template
+ < typename Index_Type = unsigned
+ >
+ struct
+box_domain
+ /**@brief
+ * Domain for indices contained within an (hyper)box.
+ * and used to index into (or as the domain of)
+ * a multidimensional array.
+ **@Acknowledgements
+ * Basic idea (and the name) from boost/index_list/domain.hpp
+ * at:
+ * http://svn.boost.org/svn/boost/sandbox/index_list/boost/index_list/domain.hpp
+ * on: 2011-04-23.
+ *
+ * I'm *guessing* that what's missing from this box_domain
+ * but present in the index_list box_domain are(for I in
+ * 0..num_dimensions_-1):
+ * ordering_[I] //Not sure what this is.
+ * ascending_[I] //Not sure what this is.
+ * index_bases_[I] //lower bound for index for I-th axis?
+ * index_tops_[I] //upper bound for index for I-th axis?
+ * I'm also *guessing* that the my_dirs member variable here
+ * is somehow related to one of:
+ * ordering_
+ * ascending_
+ */
+{
+ typedef
+ Index_Type
+ index_t
+ ;
+ typedef
+ std::vector<index_t>
+ strides_t
+ ;
+ strides_t
+ my_strides
+ /**@brief
+ * The strides for each axis in a multidimensional array.
+ */
+ ;
+ int const
+ my_dir
+ /**@brief
+ * Either 0 or 1.
+ * If 1, then my_strides[i]/my_strides[i+1] > 0
+ * Otherwise, my_strides[i+1]/my_strides[i] > 0
+ */
+ ;
+ template
+ < typename InpIter
+ , typename OutIter
+ >
+ OutIter
+ init_iter_strides
+ ( InpIter sizes_beg
+ , InpIter sizes_end
+ , OutIter strides
+ )
+ /**@brief
+ * Helper function for init_strides( Sizes...)
+ */
+ {
+ *strides=1;
+ return
+ std::partial_sum
+ ( sizes_beg
+ , sizes_end
+ , ++strides
+ , std::multiplies<typename InpIter::value_type>()
+ );
+ }
+ template
+ < typename... Sizes
+ >
+ index_t
+ init_strides
+ ( Sizes... a_size
+ )
+ /**@brief
+ * Calculates strides of the array with shape, a_size...
+ * If(my_dir==dir_fwd) then strides increase with index;
+ * otherwise, they decrease with index.
+ * Returns the size of the whole array, IOW, the
+ * product of a_size...
+ */
+ {
+ strides_t const sizes({a_size...});
+ index_t result;
+ if(my_dir==dir_fwd)
+ {
+ auto
+ it_v=init_iter_strides
+ ( sizes.begin()
+ , sizes.end()
+ , my_strides.begin()
+ );
+ result=*(--it_v);
+ }
+ else
+ {
+ auto
+ it_v=init_iter_strides
+ ( sizes.rbegin()
+ , sizes.rend()
+ , my_strides.rbegin()
+ );
+ result=*(--it_v);
+ }
+ return result;
+ }
+
+ template
+ < typename... Size
+ >
+ box_domain( dirs a_dir, Size... a_size)
+ : my_strides( sizeof...(Size)+1)
+ , my_dir(a_dir)
+ {
+ init_strides( a_size...);
+ }
+
+ index_t
+ rank()const
+ {
+ return my_strides.size()-1;
+ }
+
+ index_t
+ stride(index_t Index)const
+ /**@brief
+ * size of Index-th axis.
+ */
+ {
+ return my_strides[Index+my_dir];
+ }
+
+ index_t
+ size(index_t Index)const
+ {
+ index_t const greater=(my_dir+1)%2;
+ return my_strides[Index+greater]/my_strides[Index+my_dir];
+ }
+
+ index_t
+ size()const
+ /**@brief
+ * size of complete array.
+ */
+ {
+ return
+ (my_dir==dir_fwd)
+ ? my_strides[my_strides.size()-1]
+ : my_strides[0]
+ ;
+ }
+
+ template
+ < typename... Index
+ >
+ index_t
+ offset_at_indices
+ ( Index... a_index
+ )const
+ /**@brief
+ * The offset of element in an array
+ * corresponding to indices, a_index...
+ */
+ {
+ strides_t const indices({a_index...});
+ index_t const offset
+ = std::inner_product
+ ( indices.begin()
+ , indices.end()
+ , my_strides.begin()+my_dir
+ , index_t(0)
+ );
+ return offset;
+ }
+
+ template
+ < typename InpIter
+ , typename OutIter
+ >
+ void
+ indices_at_offset
+ ( index_t a_offset
+ , InpIter strides_beg
+ , InpIter strides_end
+ , OutIter indices
+ )const
+ /**@brief
+ * Helper function for unary indices_at_offset(see below).
+ */
+ {
+ std::transform
+ ( strides_beg
+ , strides_end
+ , indices
+ , [&a_offset](index_t stride)
+ {
+ index_t index=a_offset/stride;
+ a_offset-=index*stride;
+ return index;
+ }
+ );
+ }
+
+ std::vector<index_t>
+ indices_at_offset
+ ( index_t offset
+ )const
+ /**@brief
+ * Inverse of offset_at_indices
+ */
+ {
+ std::vector<index_t> indices(rank());
+ if(my_dir==dir_fwd)
+ {
+ indices_at_offset
+ ( offset
+ , my_strides.rbegin()+1
+ , my_strides.rend()
+ , indices.rbegin()
+ );
+ }
+ else
+ {
+ indices_at_offset
+ ( offset
+ , my_strides.begin()+1
+ , my_strides.end()
+ , indices.begin()
+ );
+ }
+ return indices;
+ }
+
+ template
+ < typename... Size
+ >
+ index_t
+ reshape( Size... a_size)
+ {
+ index_t const rankp1=sizeof...(a_size)+1;
+ my_strides.resize(rankp1);
+ return init_strides( a_size...);
+ }
+
+ template
+ < typename... Index
+ >
+ bool
+ ok_indices( Index... a_index)
+ /**@brief
+ * Is a_index... a valid argument to
+ * offset_at_indices?
+ */
+ {
+ std::vector<index_t> const indices({a_index...});
+ unsigned n=indices.size();
+ bool result= n<=rank();
+ for( unsigned i=0; i<n && result; ++i)
+ {
+ result = 0<=indices[i] && indices[i]<size(i);
+ }
+ return result;
+ }
+};
+
+#endif

Modified: sandbox/variadic_templates/sandbox/bind/Makefile
==============================================================================
--- sandbox/variadic_templates/sandbox/bind/Makefile (original)
+++ sandbox/variadic_templates/sandbox/bind/Makefile 2011-04-26 12:35:18 EDT (Tue, 26 Apr 2011)
@@ -1,5 +1,4 @@
 MAIN=bindo
-#MAIN=gcc_bug.nullary_variadic_functor
 YES_NOT=yes
 #Purpose:
 # compile/run $(MAIN).cpp with one_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