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