$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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: