Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/multi_array/test/dimtest.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 7.1 KB
Line 
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//
14// Trying to diagnose problems under visual
15
16#include "boost/config.hpp"
17#include "boost/array.hpp"
18#include "boost/limits.hpp"
19#include <algorithm>
20#include <utility>
21
22typedef int index;
23typedef std::size_t size_type;
24
25  template <typename Index,typename SizeType>
26  class index_range {
27  public:
28
29    index_range()
30    {
31      start_ = from_start();
32      finish_ = to_end();
33      stride_ = 1;
34      degenerate_ = false;
35    }
36
37    explicit index_range(Index pos)
38    {
39      start_ = pos;
40      finish_ = pos;
41      stride_ = 1;
42      degenerate_ = true;
43    }
44
45    explicit index_range(Index start, Index finish, Index stride=1)
46      : start_(start), finish_(finish), stride_(stride),
47        degenerate_(start_ == finish_)
48    { }
49
50
51    // These are for chaining assignments to an index_range
52    index_range& start(Index s) {
53      start_ = s;
54      degenerate_ = (start_ == finish_);
55      return *this;
56    }
57
58    index_range& finish(Index f) {
59      finish_ = f;
60      degenerate_ = (start_ == finish_);
61      return *this;
62    }
63
64    index_range& stride(Index s) { stride_ = s; return *this; }
65
66    Index start() const
67    { 
68      return start_; 
69    }
70
71    Index get_start(Index low_index_range = 0) const
72    { 
73      if (start_ == from_start())
74        return low_index_range;
75      return start_; 
76    }
77
78    Index finish() const
79    {
80      return finish_;
81    }
82
83    Index get_finish(Index high_index_range = 0) const
84    {
85      if (finish_ == to_end())
86        return high_index_range;
87      return finish_;
88    }
89
90    unsigned int size(Index recommended_length = 0) const
91    {
92      if ((start_ == from_start()) || (finish_ == to_end()))
93        return recommended_length;
94      else 
95        return (finish_ - start_) / stride_;
96    }
97
98    Index stride() const { return stride_; }
99
100    bool is_ascending_contiguous() const
101    {
102      return (start_ < finish_) && is_unit_stride();
103    }
104
105    void set_index_range(Index start, Index finish, Index stride=1)
106    {
107      start_ = start;
108      finish_ = finish;
109      stride_ = stride;
110    }
111
112    static index_range all() 
113    { return index_range(from_start(), to_end(), 1); }
114
115    bool is_unit_stride() const
116    { return stride_ == 1; }
117
118    bool is_degenerate() const { return degenerate_; }
119
120    index_range operator-(Index shift) const
121    { 
122      return index_range(start_ - shift, finish_ - shift, stride_); 
123    }
124
125    index_range operator+(Index shift) const
126    { 
127      return index_range(start_ + shift, finish_ + shift, stride_); 
128    }
129
130    Index operator[](unsigned i) const
131    {
132      return start_ + i * stride_;
133    }
134
135    Index operator()(unsigned i) const
136    {
137      return start_ + i * stride_;
138    }
139
140    // add conversion to std::slice?
141
142  private:
143    static Index from_start()
144      { return (std::numeric_limits<Index>::min)(); }
145
146    static Index to_end()
147      { return (std::numeric_limits<Index>::max)(); }
148  public:
149    Index start_, finish_, stride_;
150    bool degenerate_;
151  };
152
153  // Express open and closed interval end-points using the comparison
154  // operators.
155
156  // left closed
157  template <typename Index, typename SizeType>
158  inline index_range<Index,SizeType>
159  operator<=(Index s, const index_range<Index,SizeType>& r)
160  {
161    return index_range<Index,SizeType>(s, r.finish(), r.stride());
162  }
163
164  // left open
165  template <typename Index, typename SizeType>
166  inline index_range<Index,SizeType>
167  operator<(Index s, const index_range<Index,SizeType>& r)
168  {
169    return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
170  }
171
172  // right open
173  template <typename Index, typename SizeType>
174  inline index_range<Index,SizeType>
175  operator<(const index_range<Index,SizeType>& r, Index f)
176  {
177    return index_range<Index,SizeType>(r.start(), f, r.stride());
178  }
179
180  // right closed
181  template <typename Index, typename SizeType>
182  inline index_range<Index,SizeType>
183  operator<=(const index_range<Index,SizeType>& r, Index f)
184  {
185    return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
186  }
187
188//
189// range_list.hpp - helper to build boost::arrays for *_set types
190//
191
192/////////////////////////////////////////////////////////////////////////
193// choose range list begins
194//
195
196struct choose_range_list_n {
197  template <typename T, std::size_t NumRanges>
198  struct bind {
199    typedef boost::array<T,NumRanges> type;
200  };
201};
202
203struct choose_range_list_zero {
204  template <typename T, std::size_t NumRanges>
205  struct bind {
206    typedef boost::array<T,1> type;
207  };
208};
209
210
211template <std::size_t NumRanges>
212struct range_list_gen_helper {
213  typedef choose_range_list_n choice;
214};
215
216template <>
217struct range_list_gen_helper<0> {
218  typedef choose_range_list_zero choice;
219};
220
221template <typename T, std::size_t NumRanges>
222struct range_list_generator {
223private:
224  typedef typename range_list_gen_helper<NumRanges>::choice Choice;
225public:
226  typedef typename Choice::template bind<T,NumRanges>::type type;
227};
228
229//
230// choose range list ends
231/////////////////////////////////////////////////////////////////////////
232
233//
234// Index_gen.hpp stuff
235//
236
237template <int NumRanges, int NumDims>
238struct index_gen {
239private:
240  typedef index Index;
241  typedef size_type SizeType;
242  typedef index_range<Index,SizeType> range;
243public:
244  typedef typename range_list_generator<range,NumRanges>::type range_list;
245  range_list ranges_;
246
247  index_gen() { }
248
249  template <int ND>
250  explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
251            const index_range<Index,SizeType>& range)
252  {
253    std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
254    *ranges_.rbegin() = range;
255  }
256
257  index_gen<NumRanges+1,NumDims+1>
258  operator[](const index_range<Index,SizeType>& range) const
259  {
260    index_gen<NumRanges+1,NumDims+1> tmp;
261    std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
262    *tmp.ranges_.rbegin() = range;
263    return tmp;
264  }
265
266  index_gen<NumRanges+1,NumDims>
267  operator[](Index idx) const
268  {
269    index_gen<NumRanges+1,NumDims> tmp;
270    std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
271    *tmp.ranges_.rbegin() = index_range<Index,SizeType>(idx);
272    return tmp;
273  }   
274};
275
276
277template <int NDims, int NRanges>
278void accept_gen(index_gen<NRanges,NDims>& indices) {
279  // do nothing
280}
281
282template <typename X, typename Y, int A, int B>
283class foo { };
284
285class boo {
286
287  template <int NDims, int NRanges>
288  void operator[](index_gen<NRanges,NDims>& indices) {
289
290  }
291};
292
293template <typename X, typename Y, int A1, int A2>
294void take_foo(foo<X,Y,A1,A2>& f) { }
295
296int main() {
297
298  index_gen<0,0> indices;
299  typedef index_range<index,size_type> range;
300
301  take_foo(foo<int,std::size_t,1,2>());
302
303  indices[range()][range()][range()];
304  accept_gen(indices);
305  accept_gen(index_gen<0,0>());
306  accept_gen(indices[range()][range()][range()]);
307 
308  boo b;
309  b[indices[range()][range()][range()]];
310
311  return 0;
312}
Note: See TracBrowser for help on using the repository browser.