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 |
}
|