stdcpp/tsrc/Boost_test/multi_array/src/dimtest.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright 2002 The Trustees of Indiana University.
       
     2 
       
     3 // Use, modification and distribution is subject to the Boost Software 
       
     4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       
     5 // http://www.boost.org/LICENSE_1_0.txt)
       
     6 
       
     7 //  Boost.MultiArray Library
       
     8 //  Authors: Ronald Garcia
       
     9 //           Jeremy Siek
       
    10 //           Andrew Lumsdaine
       
    11 //  See http://www.boost.org/libs/multi_array for documentation.
       
    12 /*
       
    13  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
       
    14 */
       
    15 
       
    16 //
       
    17 // Trying to diagnose problems under visual
       
    18 
       
    19 #include "boost/config.hpp"
       
    20 #include "boost/array.hpp"
       
    21 #include "boost/limits.hpp"
       
    22 #include <algorithm>
       
    23 #include <utility>
       
    24 #include <iostream>
       
    25 
       
    26 #ifdef __SYMBIAN32__
       
    27 #include "std_log_result.h"
       
    28 #define LOG_FILENAME_LINE __FILE__, __LINE__
       
    29 #endif
       
    30 namespace dimtest
       
    31 {
       
    32   typedef int index;		
       
    33 }
       
    34 
       
    35 typedef std::size_t size_type;
       
    36 
       
    37   template <typename Index,typename SizeType>
       
    38   class index_range {
       
    39   public:
       
    40 
       
    41     index_range()
       
    42     {
       
    43       start_ = from_start();
       
    44       finish_ = to_end();
       
    45       stride_ = 1;
       
    46       degenerate_ = false;
       
    47     }
       
    48 
       
    49     explicit index_range(Index pos)
       
    50     {
       
    51       start_ = pos;
       
    52       finish_ = pos;
       
    53       stride_ = 1;
       
    54       degenerate_ = true;
       
    55     }
       
    56 
       
    57     explicit index_range(Index start, Index finish, Index stride=1)
       
    58       : start_(start), finish_(finish), stride_(stride),
       
    59         degenerate_(start_ == finish_)
       
    60     { }
       
    61 
       
    62 
       
    63     // These are for chaining assignments to an index_range
       
    64     index_range& start(Index s) {
       
    65       start_ = s;
       
    66       degenerate_ = (start_ == finish_);
       
    67       return *this;
       
    68     }
       
    69 
       
    70     index_range& finish(Index f) {
       
    71       finish_ = f;
       
    72       degenerate_ = (start_ == finish_);
       
    73       return *this;
       
    74     }
       
    75 
       
    76     index_range& stride(Index s) { stride_ = s; return *this; }
       
    77 
       
    78     Index start() const
       
    79     { 
       
    80       return start_; 
       
    81     }
       
    82 
       
    83     Index get_start(Index low_index_range = 0) const
       
    84     { 
       
    85       if (start_ == from_start())
       
    86         return low_index_range;
       
    87       return start_; 
       
    88     }
       
    89 
       
    90     Index finish() const
       
    91     {
       
    92       return finish_;
       
    93     }
       
    94 
       
    95     Index get_finish(Index high_index_range = 0) const
       
    96     {
       
    97       if (finish_ == to_end())
       
    98         return high_index_range;
       
    99       return finish_;
       
   100     }
       
   101 
       
   102     unsigned int size(Index recommended_length = 0) const
       
   103     {
       
   104       if ((start_ == from_start()) || (finish_ == to_end()))
       
   105         return recommended_length;
       
   106       else 
       
   107         return (finish_ - start_) / stride_;
       
   108     }
       
   109 
       
   110     Index stride() const { return stride_; }
       
   111 
       
   112     bool is_ascending_contiguous() const
       
   113     {
       
   114       return (start_ < finish_) && is_unit_stride();
       
   115     }
       
   116 
       
   117     void set_index_range(Index start, Index finish, Index stride=1)
       
   118     {
       
   119       start_ = start;
       
   120       finish_ = finish;
       
   121       stride_ = stride;
       
   122     }
       
   123 
       
   124     static index_range all() 
       
   125     { return index_range(from_start(), to_end(), 1); }
       
   126 
       
   127     bool is_unit_stride() const
       
   128     { return stride_ == 1; }
       
   129 
       
   130     bool is_degenerate() const { return degenerate_; }
       
   131 
       
   132     index_range operator-(Index shift) const
       
   133     { 
       
   134       return index_range(start_ - shift, finish_ - shift, stride_); 
       
   135     }
       
   136 
       
   137     index_range operator+(Index shift) const
       
   138     { 
       
   139       return index_range(start_ + shift, finish_ + shift, stride_); 
       
   140     }
       
   141 
       
   142     Index operator[](unsigned i) const
       
   143     {
       
   144       return start_ + i * stride_;
       
   145     }
       
   146 
       
   147     Index operator()(unsigned i) const
       
   148     {
       
   149       return start_ + i * stride_;
       
   150     }
       
   151 
       
   152     // add conversion to std::slice?
       
   153 
       
   154   private:
       
   155     static Index from_start()
       
   156       { return (std::numeric_limits<Index>::min)(); }
       
   157 
       
   158     static Index to_end()
       
   159       { return (std::numeric_limits<Index>::max)(); }
       
   160   public:
       
   161     Index start_, finish_, stride_;
       
   162     bool degenerate_;
       
   163   };
       
   164 
       
   165   // Express open and closed interval end-points using the comparison
       
   166   // operators.
       
   167 
       
   168   // left closed
       
   169   template <typename Index, typename SizeType>
       
   170   inline index_range<Index,SizeType>
       
   171   operator<=(Index s, const index_range<Index,SizeType>& r)
       
   172   {
       
   173     return index_range<Index,SizeType>(s, r.finish(), r.stride());
       
   174   }
       
   175 
       
   176   // left open
       
   177   template <typename Index, typename SizeType>
       
   178   inline index_range<Index,SizeType>
       
   179   operator<(Index s, const index_range<Index,SizeType>& r)
       
   180   {
       
   181     return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
       
   182   }
       
   183 
       
   184   // right open
       
   185   template <typename Index, typename SizeType>
       
   186   inline index_range<Index,SizeType>
       
   187   operator<(const index_range<Index,SizeType>& r, Index f)
       
   188   {
       
   189     return index_range<Index,SizeType>(r.start(), f, r.stride());
       
   190   }
       
   191 
       
   192   // right closed
       
   193   template <typename Index, typename SizeType>
       
   194   inline index_range<Index,SizeType>
       
   195   operator<=(const index_range<Index,SizeType>& r, Index f)
       
   196   {
       
   197     return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
       
   198   }
       
   199 
       
   200 //
       
   201 // range_list.hpp - helper to build boost::arrays for *_set types
       
   202 //
       
   203 
       
   204 /////////////////////////////////////////////////////////////////////////
       
   205 // choose range list begins
       
   206 //
       
   207 
       
   208 struct choose_range_list_n {
       
   209   template <typename T, std::size_t NumRanges>
       
   210   struct bind {
       
   211     typedef boost::array<T,NumRanges> type;
       
   212   };
       
   213 };
       
   214 
       
   215 struct choose_range_list_zero {
       
   216   template <typename T, std::size_t NumRanges>
       
   217   struct bind {
       
   218     typedef boost::array<T,1> type;
       
   219   };
       
   220 };
       
   221 
       
   222 
       
   223 template <std::size_t NumRanges>
       
   224 struct range_list_gen_helper {
       
   225   typedef choose_range_list_n choice;
       
   226 };
       
   227 
       
   228 template <>
       
   229 struct range_list_gen_helper<0> {
       
   230   typedef choose_range_list_zero choice;
       
   231 };
       
   232 
       
   233 template <typename T, std::size_t NumRanges>
       
   234 struct range_list_generator {
       
   235 private:
       
   236   typedef typename range_list_gen_helper<NumRanges>::choice Choice;
       
   237 public:
       
   238   typedef typename Choice::template bind<T,NumRanges>::type type;
       
   239 };
       
   240 
       
   241 //
       
   242 // choose range list ends
       
   243 /////////////////////////////////////////////////////////////////////////
       
   244 
       
   245 //
       
   246 // Index_gen.hpp stuff
       
   247 //
       
   248 
       
   249 template <int NumRanges, int NumDims>
       
   250 struct index_gen {
       
   251 private:
       
   252   typedef dimtest::index Index;
       
   253   typedef size_type SizeType;
       
   254   typedef index_range<Index,SizeType> range;
       
   255 public:
       
   256   typedef typename range_list_generator<range,NumRanges>::type range_list;
       
   257   range_list ranges_;
       
   258 
       
   259   index_gen() { }
       
   260 
       
   261   template <int ND>
       
   262   explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
       
   263             const index_range<Index,SizeType>& range)
       
   264   {
       
   265     std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
       
   266     *ranges_.rbegin() = range;
       
   267   }
       
   268 
       
   269   index_gen<NumRanges+1,NumDims+1>
       
   270   operator[](const index_range<Index,SizeType>& range) const
       
   271   {
       
   272     index_gen<NumRanges+1,NumDims+1> tmp;
       
   273     std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
       
   274     *tmp.ranges_.rbegin() = range;
       
   275     return tmp;
       
   276   }
       
   277 
       
   278   index_gen<NumRanges+1,NumDims>
       
   279   operator[](Index idx) const
       
   280   {
       
   281     index_gen<NumRanges+1,NumDims> tmp;
       
   282     std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
       
   283     *tmp.ranges_.rbegin() = index_range<Index,SizeType>(idx);
       
   284     return tmp;
       
   285   }    
       
   286 };
       
   287 
       
   288 
       
   289 template <int NDims, int NRanges>
       
   290 void accept_gen(index_gen<NRanges,NDims>& indices) {
       
   291   // do nothing
       
   292 }
       
   293 
       
   294 template <typename X, typename Y, int A, int B>
       
   295 class foo { };
       
   296 
       
   297 class boo {
       
   298 
       
   299 public:
       
   300   template <int NDims, int NRanges>
       
   301   void operator[](index_gen<NRanges,NDims>& indices) {
       
   302 
       
   303   }
       
   304 };
       
   305 
       
   306 
       
   307 template <typename X, typename Y, int A1, int A2>
       
   308 void take_foo(foo<X,Y,A1,A2>& f) { }
       
   309 
       
   310 using namespace std;
       
   311 int main() {
       
   312 
       
   313   index_gen<0,0> indices;
       
   314   typedef index_range<dimtest::index,size_type> range;
       
   315 
       
   316   foo<int,std::size_t,1,2> f;
       
   317   take_foo(f);
       
   318 
       
   319   indices[range()][range()][range()];  
       
   320   accept_gen(indices);
       
   321   index_gen<0,0> index_g;
       
   322   accept_gen(index_g);
       
   323   index_gen<3,3> indices_3;
       
   324   accept_gen(indices_3);
       
   325   
       
   326   boo b;
       
   327   b[indices_3];
       
   328   
       
   329   #ifdef __SYMBIAN32__
       
   330    	testResultXml("dimtest");
       
   331 	close_log_file();
       
   332 #endif
       
   333   return 0;
       
   334 }