sl@0
|
1 |
//
|
sl@0
|
2 |
// Copyright (c) 2000-2002
|
sl@0
|
3 |
// Joerg Walter, Mathias Koch
|
sl@0
|
4 |
//
|
sl@0
|
5 |
// Permission to use, copy, modify, distribute and sell this software
|
sl@0
|
6 |
// and its documentation for any purpose is hereby granted without fee,
|
sl@0
|
7 |
// provided that the above copyright notice appear in all copies and
|
sl@0
|
8 |
// that both that copyright notice and this permission notice appear
|
sl@0
|
9 |
// in supporting documentation. The authors make no representations
|
sl@0
|
10 |
// about the suitability of this software for any purpose.
|
sl@0
|
11 |
// It is provided "as is" without express or implied warranty.
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// The authors gratefully acknowledge the support of
|
sl@0
|
14 |
// GeNeSys mbH & Co. KG in producing this work.
|
sl@0
|
15 |
//
|
sl@0
|
16 |
|
sl@0
|
17 |
#ifndef _BOOST_UBLAS_TRAITS_
|
sl@0
|
18 |
#define _BOOST_UBLAS_TRAITS_
|
sl@0
|
19 |
|
sl@0
|
20 |
#include <iterator>
|
sl@0
|
21 |
#include <complex>
|
sl@0
|
22 |
#include <cmath>
|
sl@0
|
23 |
|
sl@0
|
24 |
#include <boost/numeric/ublas/detail/config.hpp>
|
sl@0
|
25 |
#include <boost/numeric/ublas/detail/iterator.hpp>
|
sl@0
|
26 |
#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
|
sl@0
|
27 |
|
sl@0
|
28 |
|
sl@0
|
29 |
namespace boost { namespace numeric { namespace ublas {
|
sl@0
|
30 |
|
sl@0
|
31 |
// Use Joel de Guzman's return type deduction
|
sl@0
|
32 |
// uBLAS assumes a common return type for all binary arithmetic operators
|
sl@0
|
33 |
template<class X, class Y>
|
sl@0
|
34 |
struct promote_traits {
|
sl@0
|
35 |
typedef type_deduction_detail::base_result_of<X, Y> base_type;
|
sl@0
|
36 |
static typename base_type::x_type x;
|
sl@0
|
37 |
static typename base_type::y_type y;
|
sl@0
|
38 |
static const std::size_t size = sizeof (
|
sl@0
|
39 |
type_deduction_detail::test<
|
sl@0
|
40 |
typename base_type::x_type
|
sl@0
|
41 |
, typename base_type::y_type
|
sl@0
|
42 |
>(x + y) // Use x+y to stand of all the arithmetic actions
|
sl@0
|
43 |
);
|
sl@0
|
44 |
|
sl@0
|
45 |
static const std::size_t index = (size / sizeof (char)) - 1;
|
sl@0
|
46 |
typedef typename mpl::at_c<
|
sl@0
|
47 |
typename base_type::types, index>::type id;
|
sl@0
|
48 |
typedef typename id::type promote_type;
|
sl@0
|
49 |
};
|
sl@0
|
50 |
|
sl@0
|
51 |
|
sl@0
|
52 |
// Type traits - generic numeric properties and functions
|
sl@0
|
53 |
template<class T>
|
sl@0
|
54 |
struct type_traits;
|
sl@0
|
55 |
|
sl@0
|
56 |
// Define properties for a generic scalar type
|
sl@0
|
57 |
template<class T>
|
sl@0
|
58 |
struct scalar_traits {
|
sl@0
|
59 |
typedef scalar_traits<T> self_type;
|
sl@0
|
60 |
typedef T value_type;
|
sl@0
|
61 |
typedef const T &const_reference;
|
sl@0
|
62 |
typedef T &reference;
|
sl@0
|
63 |
|
sl@0
|
64 |
typedef T real_type;
|
sl@0
|
65 |
typedef real_type precision_type; // we do not know what type has more precision then the real_type
|
sl@0
|
66 |
|
sl@0
|
67 |
static const unsigned plus_complexity = 1;
|
sl@0
|
68 |
static const unsigned multiplies_complexity = 1;
|
sl@0
|
69 |
|
sl@0
|
70 |
static
|
sl@0
|
71 |
BOOST_UBLAS_INLINE
|
sl@0
|
72 |
real_type real (const_reference t) {
|
sl@0
|
73 |
return t;
|
sl@0
|
74 |
}
|
sl@0
|
75 |
static
|
sl@0
|
76 |
BOOST_UBLAS_INLINE
|
sl@0
|
77 |
real_type imag (const_reference /*t*/) {
|
sl@0
|
78 |
return 0;
|
sl@0
|
79 |
}
|
sl@0
|
80 |
static
|
sl@0
|
81 |
BOOST_UBLAS_INLINE
|
sl@0
|
82 |
value_type conj (const_reference t) {
|
sl@0
|
83 |
return t;
|
sl@0
|
84 |
}
|
sl@0
|
85 |
|
sl@0
|
86 |
static
|
sl@0
|
87 |
BOOST_UBLAS_INLINE
|
sl@0
|
88 |
real_type type_abs (const_reference t) {
|
sl@0
|
89 |
return std::abs (t); // must use explict std:: as bultin types are not in std namespace
|
sl@0
|
90 |
}
|
sl@0
|
91 |
static
|
sl@0
|
92 |
BOOST_UBLAS_INLINE
|
sl@0
|
93 |
value_type type_sqrt (const_reference t) {
|
sl@0
|
94 |
// force a type conversion back to value_type for intgral types
|
sl@0
|
95 |
return value_type (std::sqrt (t)); // must use explict std:: as bultin types are not in std namespace
|
sl@0
|
96 |
}
|
sl@0
|
97 |
|
sl@0
|
98 |
static
|
sl@0
|
99 |
BOOST_UBLAS_INLINE
|
sl@0
|
100 |
real_type norm_1 (const_reference t) {
|
sl@0
|
101 |
return self_type::type_abs (t);
|
sl@0
|
102 |
}
|
sl@0
|
103 |
static
|
sl@0
|
104 |
BOOST_UBLAS_INLINE
|
sl@0
|
105 |
real_type norm_2 (const_reference t) {
|
sl@0
|
106 |
return self_type::type_abs (t);
|
sl@0
|
107 |
}
|
sl@0
|
108 |
static
|
sl@0
|
109 |
BOOST_UBLAS_INLINE
|
sl@0
|
110 |
real_type norm_inf (const_reference t) {
|
sl@0
|
111 |
return self_type::type_abs (t);
|
sl@0
|
112 |
}
|
sl@0
|
113 |
|
sl@0
|
114 |
static
|
sl@0
|
115 |
BOOST_UBLAS_INLINE
|
sl@0
|
116 |
bool equals (const_reference t1, const_reference t2) {
|
sl@0
|
117 |
return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
sl@0
|
118 |
(std::max) ((std::max) (self_type::norm_inf (t1),
|
sl@0
|
119 |
self_type::norm_inf (t2)),
|
sl@0
|
120 |
BOOST_UBLAS_TYPE_CHECK_MIN);
|
sl@0
|
121 |
}
|
sl@0
|
122 |
};
|
sl@0
|
123 |
|
sl@0
|
124 |
// Define default type traits, assume T is a scalar type
|
sl@0
|
125 |
template<class T>
|
sl@0
|
126 |
struct type_traits : scalar_traits <T> {
|
sl@0
|
127 |
typedef type_traits<T> self_type;
|
sl@0
|
128 |
typedef T value_type;
|
sl@0
|
129 |
typedef const T &const_reference;
|
sl@0
|
130 |
typedef T &reference;
|
sl@0
|
131 |
|
sl@0
|
132 |
typedef T real_type;
|
sl@0
|
133 |
typedef real_type precision_type;
|
sl@0
|
134 |
static const unsigned multiplies_complexity = 1;
|
sl@0
|
135 |
|
sl@0
|
136 |
};
|
sl@0
|
137 |
|
sl@0
|
138 |
// Define real type traits
|
sl@0
|
139 |
template<>
|
sl@0
|
140 |
struct type_traits<float> : scalar_traits<float> {
|
sl@0
|
141 |
typedef type_traits<float> self_type;
|
sl@0
|
142 |
typedef float value_type;
|
sl@0
|
143 |
typedef const value_type &const_reference;
|
sl@0
|
144 |
typedef value_type &reference;
|
sl@0
|
145 |
typedef value_type real_type;
|
sl@0
|
146 |
typedef double precision_type;
|
sl@0
|
147 |
};
|
sl@0
|
148 |
template<>
|
sl@0
|
149 |
struct type_traits<double> : scalar_traits<double> {
|
sl@0
|
150 |
typedef type_traits<double> self_type;
|
sl@0
|
151 |
typedef double value_type;
|
sl@0
|
152 |
typedef const value_type &const_reference;
|
sl@0
|
153 |
typedef value_type &reference;
|
sl@0
|
154 |
typedef value_type real_type;
|
sl@0
|
155 |
typedef long double precision_type;
|
sl@0
|
156 |
};
|
sl@0
|
157 |
template<>
|
sl@0
|
158 |
struct type_traits<long double> : scalar_traits<long double> {
|
sl@0
|
159 |
typedef type_traits<long double> self_type;
|
sl@0
|
160 |
typedef long double value_type;
|
sl@0
|
161 |
typedef const value_type &const_reference;
|
sl@0
|
162 |
typedef value_type &reference;
|
sl@0
|
163 |
typedef value_type real_type;
|
sl@0
|
164 |
typedef value_type precision_type;
|
sl@0
|
165 |
};
|
sl@0
|
166 |
|
sl@0
|
167 |
// Define properties for a generic complex type
|
sl@0
|
168 |
template<class T>
|
sl@0
|
169 |
struct complex_traits {
|
sl@0
|
170 |
typedef complex_traits<T> self_type;
|
sl@0
|
171 |
typedef T value_type;
|
sl@0
|
172 |
typedef const T &const_reference;
|
sl@0
|
173 |
typedef T &reference;
|
sl@0
|
174 |
|
sl@0
|
175 |
typedef typename T::value_type real_type;
|
sl@0
|
176 |
typedef real_type precision_type; // we do not know what type has more precision then the real_type
|
sl@0
|
177 |
|
sl@0
|
178 |
static const unsigned plus_complexity = 2;
|
sl@0
|
179 |
static const unsigned multiplies_complexity = 6;
|
sl@0
|
180 |
|
sl@0
|
181 |
static
|
sl@0
|
182 |
BOOST_UBLAS_INLINE
|
sl@0
|
183 |
real_type real (const_reference t) {
|
sl@0
|
184 |
return std::real (t);
|
sl@0
|
185 |
}
|
sl@0
|
186 |
static
|
sl@0
|
187 |
BOOST_UBLAS_INLINE
|
sl@0
|
188 |
real_type imag (const_reference t) {
|
sl@0
|
189 |
return std::imag (t);
|
sl@0
|
190 |
}
|
sl@0
|
191 |
static
|
sl@0
|
192 |
BOOST_UBLAS_INLINE
|
sl@0
|
193 |
value_type conj (const_reference t) {
|
sl@0
|
194 |
return std::conj (t);
|
sl@0
|
195 |
}
|
sl@0
|
196 |
|
sl@0
|
197 |
static
|
sl@0
|
198 |
BOOST_UBLAS_INLINE
|
sl@0
|
199 |
real_type type_abs (const_reference t) {
|
sl@0
|
200 |
return abs (t);
|
sl@0
|
201 |
}
|
sl@0
|
202 |
static
|
sl@0
|
203 |
BOOST_UBLAS_INLINE
|
sl@0
|
204 |
value_type type_sqrt (const_reference t) {
|
sl@0
|
205 |
return sqrt (t);
|
sl@0
|
206 |
}
|
sl@0
|
207 |
|
sl@0
|
208 |
static
|
sl@0
|
209 |
BOOST_UBLAS_INLINE
|
sl@0
|
210 |
real_type norm_1 (const_reference t) {
|
sl@0
|
211 |
return type_traits<real_type>::type_abs (self_type::real (t)) +
|
sl@0
|
212 |
type_traits<real_type>::type_abs (self_type::imag (t));
|
sl@0
|
213 |
}
|
sl@0
|
214 |
static
|
sl@0
|
215 |
BOOST_UBLAS_INLINE
|
sl@0
|
216 |
real_type norm_2 (const_reference t) {
|
sl@0
|
217 |
return self_type::type_abs (t);
|
sl@0
|
218 |
}
|
sl@0
|
219 |
static
|
sl@0
|
220 |
BOOST_UBLAS_INLINE
|
sl@0
|
221 |
real_type norm_inf (const_reference t) {
|
sl@0
|
222 |
return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
|
sl@0
|
223 |
type_traits<real_type>::type_abs (self_type::imag (t)));
|
sl@0
|
224 |
}
|
sl@0
|
225 |
|
sl@0
|
226 |
static
|
sl@0
|
227 |
BOOST_UBLAS_INLINE
|
sl@0
|
228 |
bool equals (const_reference t1, const_reference t2) {
|
sl@0
|
229 |
return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
sl@0
|
230 |
(std::max) ((std::max) (self_type::norm_inf (t1),
|
sl@0
|
231 |
self_type::norm_inf (t2)),
|
sl@0
|
232 |
BOOST_UBLAS_TYPE_CHECK_MIN);
|
sl@0
|
233 |
}
|
sl@0
|
234 |
};
|
sl@0
|
235 |
|
sl@0
|
236 |
// Define complex type traits
|
sl@0
|
237 |
template<>
|
sl@0
|
238 |
struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
|
sl@0
|
239 |
typedef type_traits<std::complex<float> > self_type;
|
sl@0
|
240 |
typedef std::complex<float> value_type;
|
sl@0
|
241 |
typedef const value_type &const_reference;
|
sl@0
|
242 |
typedef value_type &reference;
|
sl@0
|
243 |
typedef float real_type;
|
sl@0
|
244 |
typedef std::complex<double> precision_type;
|
sl@0
|
245 |
|
sl@0
|
246 |
};
|
sl@0
|
247 |
template<>
|
sl@0
|
248 |
struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
|
sl@0
|
249 |
typedef type_traits<std::complex<double> > self_type;
|
sl@0
|
250 |
typedef std::complex<double> value_type;
|
sl@0
|
251 |
typedef const value_type &const_reference;
|
sl@0
|
252 |
typedef value_type &reference;
|
sl@0
|
253 |
typedef double real_type;
|
sl@0
|
254 |
typedef std::complex<long double> precision_type;
|
sl@0
|
255 |
};
|
sl@0
|
256 |
template<>
|
sl@0
|
257 |
struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
|
sl@0
|
258 |
typedef type_traits<std::complex<long double> > self_type;
|
sl@0
|
259 |
typedef std::complex<long double> value_type;
|
sl@0
|
260 |
typedef const value_type &const_reference;
|
sl@0
|
261 |
typedef value_type &reference;
|
sl@0
|
262 |
typedef long double real_type;
|
sl@0
|
263 |
typedef value_type precision_type;
|
sl@0
|
264 |
};
|
sl@0
|
265 |
|
sl@0
|
266 |
#ifdef BOOST_UBLAS_USE_INTERVAL
|
sl@0
|
267 |
// Define properties for a generic scalar interval type
|
sl@0
|
268 |
template<class T>
|
sl@0
|
269 |
struct scalar_interval_type_traits : scalar_type_traits<T> {
|
sl@0
|
270 |
typedef scalar_interval_type_traits<T> self_type;
|
sl@0
|
271 |
typedef boost::numeric::interval<float> value_type;
|
sl@0
|
272 |
typedef const value_type &const_reference;
|
sl@0
|
273 |
typedef value_type &reference;
|
sl@0
|
274 |
typedef value_type real_type;
|
sl@0
|
275 |
typedef real_type precision_type; // we do not know what type has more precision then the real_type
|
sl@0
|
276 |
|
sl@0
|
277 |
static const unsigned plus_complexity = 1;
|
sl@0
|
278 |
static const unsigned multiplies_complexity = 1;
|
sl@0
|
279 |
|
sl@0
|
280 |
static
|
sl@0
|
281 |
BOOST_UBLAS_INLINE
|
sl@0
|
282 |
real_type type_abs (const_reference t) {
|
sl@0
|
283 |
return abs (t);
|
sl@0
|
284 |
}
|
sl@0
|
285 |
static
|
sl@0
|
286 |
BOOST_UBLAS_INLINE
|
sl@0
|
287 |
value_type type_sqrt (const_reference t) {
|
sl@0
|
288 |
return sqrt (t);
|
sl@0
|
289 |
}
|
sl@0
|
290 |
|
sl@0
|
291 |
static
|
sl@0
|
292 |
BOOST_UBLAS_INLINE
|
sl@0
|
293 |
real_type norm_1 (const_reference t) {
|
sl@0
|
294 |
return self_type::type_abs (t);
|
sl@0
|
295 |
}
|
sl@0
|
296 |
static
|
sl@0
|
297 |
BOOST_UBLAS_INLINE
|
sl@0
|
298 |
real_type norm_2 (const_reference t) {
|
sl@0
|
299 |
return self_type::type_abs (t);
|
sl@0
|
300 |
}
|
sl@0
|
301 |
static
|
sl@0
|
302 |
BOOST_UBLAS_INLINE
|
sl@0
|
303 |
real_type norm_inf (const_reference t) {
|
sl@0
|
304 |
return self_type::type_abs (t);
|
sl@0
|
305 |
}
|
sl@0
|
306 |
|
sl@0
|
307 |
static
|
sl@0
|
308 |
BOOST_UBLAS_INLINE
|
sl@0
|
309 |
bool equals (const_reference t1, const_reference t2) {
|
sl@0
|
310 |
return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
sl@0
|
311 |
(std::max) ((std::max) (self_type::norm_inf (t1),
|
sl@0
|
312 |
self_type::norm_inf (t2)),
|
sl@0
|
313 |
BOOST_UBLAS_TYPE_CHECK_MIN);
|
sl@0
|
314 |
}
|
sl@0
|
315 |
};
|
sl@0
|
316 |
|
sl@0
|
317 |
// Define scalar interval type traits
|
sl@0
|
318 |
template<>
|
sl@0
|
319 |
struct type_traits<boost::numeric::interval<float> > : scalar_interval_type_traits<boost::numeric::interval<float> > {
|
sl@0
|
320 |
typedef type_traits<boost::numeric::interval<float> > self_type;
|
sl@0
|
321 |
typedef boost::numeric::interval<float> value_type;
|
sl@0
|
322 |
typedef const value_type &const_reference;
|
sl@0
|
323 |
typedef value_type &reference;
|
sl@0
|
324 |
typedef value_type real_type;
|
sl@0
|
325 |
typedef boost::numeric::interval<double> precision_type;
|
sl@0
|
326 |
|
sl@0
|
327 |
};
|
sl@0
|
328 |
template<>
|
sl@0
|
329 |
struct type_traits<boost::numeric::interval<double> > : scalar_interval_type_traits<boost::numeric::interval<double> > {
|
sl@0
|
330 |
typedef type_traits<boost::numeric::interval<double> > self_type;
|
sl@0
|
331 |
typedef boost::numeric::interval<double> value_type;
|
sl@0
|
332 |
typedef const value_type &const_reference;
|
sl@0
|
333 |
typedef value_type &reference;
|
sl@0
|
334 |
typedef value_type real_type;
|
sl@0
|
335 |
typedef boost::numeric::interval<long double> precision_type;
|
sl@0
|
336 |
};
|
sl@0
|
337 |
template<>
|
sl@0
|
338 |
struct type_traits<boost::numeric::interval<long double> > : scalar_interval_type_traits<boost::numeric::interval<long double> > {
|
sl@0
|
339 |
typedef type_traits<boost::numeric::interval<long double> > self_type;
|
sl@0
|
340 |
typedef boost::numeric::interval<long double> value_type;
|
sl@0
|
341 |
typedef const value_type &const_reference;
|
sl@0
|
342 |
typedef value_type &reference;
|
sl@0
|
343 |
typedef value_type real_type;
|
sl@0
|
344 |
typedef value_type precision_type;
|
sl@0
|
345 |
};
|
sl@0
|
346 |
|
sl@0
|
347 |
#endif
|
sl@0
|
348 |
|
sl@0
|
349 |
|
sl@0
|
350 |
// Storage tags -- hierarchical definition of storage characteristics
|
sl@0
|
351 |
|
sl@0
|
352 |
struct unknown_storage_tag {};
|
sl@0
|
353 |
struct sparse_proxy_tag: public unknown_storage_tag {};
|
sl@0
|
354 |
struct sparse_tag: public sparse_proxy_tag {};
|
sl@0
|
355 |
struct packed_proxy_tag: public sparse_proxy_tag {};
|
sl@0
|
356 |
struct packed_tag: public packed_proxy_tag {};
|
sl@0
|
357 |
struct dense_proxy_tag: public packed_proxy_tag {};
|
sl@0
|
358 |
struct dense_tag: public dense_proxy_tag {};
|
sl@0
|
359 |
|
sl@0
|
360 |
template<class S1, class S2>
|
sl@0
|
361 |
struct storage_restrict_traits {
|
sl@0
|
362 |
typedef S1 storage_category;
|
sl@0
|
363 |
};
|
sl@0
|
364 |
|
sl@0
|
365 |
template<>
|
sl@0
|
366 |
struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
|
sl@0
|
367 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
368 |
};
|
sl@0
|
369 |
template<>
|
sl@0
|
370 |
struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
|
sl@0
|
371 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
372 |
};
|
sl@0
|
373 |
template<>
|
sl@0
|
374 |
struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
|
sl@0
|
375 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
376 |
};
|
sl@0
|
377 |
|
sl@0
|
378 |
template<>
|
sl@0
|
379 |
struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
|
sl@0
|
380 |
typedef packed_proxy_tag storage_category;
|
sl@0
|
381 |
};
|
sl@0
|
382 |
template<>
|
sl@0
|
383 |
struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
|
sl@0
|
384 |
typedef packed_proxy_tag storage_category;
|
sl@0
|
385 |
};
|
sl@0
|
386 |
template<>
|
sl@0
|
387 |
struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
|
sl@0
|
388 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
389 |
};
|
sl@0
|
390 |
|
sl@0
|
391 |
template<>
|
sl@0
|
392 |
struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
|
sl@0
|
393 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
394 |
};
|
sl@0
|
395 |
|
sl@0
|
396 |
template<>
|
sl@0
|
397 |
struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
|
sl@0
|
398 |
typedef dense_proxy_tag storage_category;
|
sl@0
|
399 |
};
|
sl@0
|
400 |
template<>
|
sl@0
|
401 |
struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
|
sl@0
|
402 |
typedef packed_proxy_tag storage_category;
|
sl@0
|
403 |
};
|
sl@0
|
404 |
template<>
|
sl@0
|
405 |
struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
|
sl@0
|
406 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
407 |
};
|
sl@0
|
408 |
|
sl@0
|
409 |
template<>
|
sl@0
|
410 |
struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
|
sl@0
|
411 |
typedef packed_proxy_tag storage_category;
|
sl@0
|
412 |
};
|
sl@0
|
413 |
template<>
|
sl@0
|
414 |
struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
|
sl@0
|
415 |
typedef sparse_proxy_tag storage_category;
|
sl@0
|
416 |
};
|
sl@0
|
417 |
|
sl@0
|
418 |
|
sl@0
|
419 |
// Iterator tags -- hierarchical definition of storage characteristics
|
sl@0
|
420 |
|
sl@0
|
421 |
struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
|
sl@0
|
422 |
struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
|
sl@0
|
423 |
struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
|
sl@0
|
424 |
|
sl@0
|
425 |
// Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
|
sl@0
|
426 |
template<class IC>
|
sl@0
|
427 |
struct iterator_base_traits {};
|
sl@0
|
428 |
|
sl@0
|
429 |
template<>
|
sl@0
|
430 |
struct iterator_base_traits<std::forward_iterator_tag> {
|
sl@0
|
431 |
template<class I, class T>
|
sl@0
|
432 |
struct iterator_base {
|
sl@0
|
433 |
typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
|
sl@0
|
434 |
};
|
sl@0
|
435 |
};
|
sl@0
|
436 |
|
sl@0
|
437 |
template<>
|
sl@0
|
438 |
struct iterator_base_traits<std::bidirectional_iterator_tag> {
|
sl@0
|
439 |
template<class I, class T>
|
sl@0
|
440 |
struct iterator_base {
|
sl@0
|
441 |
typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
|
sl@0
|
442 |
};
|
sl@0
|
443 |
};
|
sl@0
|
444 |
template<>
|
sl@0
|
445 |
struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
|
sl@0
|
446 |
template<class I, class T>
|
sl@0
|
447 |
struct iterator_base {
|
sl@0
|
448 |
typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
|
sl@0
|
449 |
};
|
sl@0
|
450 |
};
|
sl@0
|
451 |
|
sl@0
|
452 |
template<>
|
sl@0
|
453 |
struct iterator_base_traits<std::random_access_iterator_tag> {
|
sl@0
|
454 |
template<class I, class T>
|
sl@0
|
455 |
struct iterator_base {
|
sl@0
|
456 |
typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
|
sl@0
|
457 |
};
|
sl@0
|
458 |
};
|
sl@0
|
459 |
template<>
|
sl@0
|
460 |
struct iterator_base_traits<packed_random_access_iterator_tag> {
|
sl@0
|
461 |
template<class I, class T>
|
sl@0
|
462 |
struct iterator_base {
|
sl@0
|
463 |
typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
|
sl@0
|
464 |
};
|
sl@0
|
465 |
};
|
sl@0
|
466 |
template<>
|
sl@0
|
467 |
struct iterator_base_traits<dense_random_access_iterator_tag> {
|
sl@0
|
468 |
template<class I, class T>
|
sl@0
|
469 |
struct iterator_base {
|
sl@0
|
470 |
typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
|
sl@0
|
471 |
};
|
sl@0
|
472 |
};
|
sl@0
|
473 |
|
sl@0
|
474 |
template<class I1, class I2>
|
sl@0
|
475 |
struct iterator_restrict_traits {
|
sl@0
|
476 |
typedef I1 iterator_category;
|
sl@0
|
477 |
};
|
sl@0
|
478 |
|
sl@0
|
479 |
template<>
|
sl@0
|
480 |
struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
|
sl@0
|
481 |
typedef sparse_bidirectional_iterator_tag iterator_category;
|
sl@0
|
482 |
};
|
sl@0
|
483 |
template<>
|
sl@0
|
484 |
struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
|
sl@0
|
485 |
typedef sparse_bidirectional_iterator_tag iterator_category;
|
sl@0
|
486 |
};
|
sl@0
|
487 |
|
sl@0
|
488 |
template<>
|
sl@0
|
489 |
struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
|
sl@0
|
490 |
typedef sparse_bidirectional_iterator_tag iterator_category;
|
sl@0
|
491 |
};
|
sl@0
|
492 |
template<>
|
sl@0
|
493 |
struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
|
sl@0
|
494 |
typedef sparse_bidirectional_iterator_tag iterator_category;
|
sl@0
|
495 |
};
|
sl@0
|
496 |
|
sl@0
|
497 |
template<>
|
sl@0
|
498 |
struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
|
sl@0
|
499 |
typedef packed_random_access_iterator_tag iterator_category;
|
sl@0
|
500 |
};
|
sl@0
|
501 |
template<>
|
sl@0
|
502 |
struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
|
sl@0
|
503 |
typedef packed_random_access_iterator_tag iterator_category;
|
sl@0
|
504 |
};
|
sl@0
|
505 |
|
sl@0
|
506 |
template<class I>
|
sl@0
|
507 |
BOOST_UBLAS_INLINE
|
sl@0
|
508 |
void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
|
sl@0
|
509 |
it += (std::min) (compare, it_end - it);
|
sl@0
|
510 |
}
|
sl@0
|
511 |
template<class I>
|
sl@0
|
512 |
BOOST_UBLAS_INLINE
|
sl@0
|
513 |
void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
|
sl@0
|
514 |
++ it;
|
sl@0
|
515 |
}
|
sl@0
|
516 |
template<class I>
|
sl@0
|
517 |
BOOST_UBLAS_INLINE
|
sl@0
|
518 |
void increment (I &it, const I &it_end, typename I::difference_type compare) {
|
sl@0
|
519 |
increment (it, it_end, compare, typename I::iterator_category ());
|
sl@0
|
520 |
}
|
sl@0
|
521 |
|
sl@0
|
522 |
template<class I>
|
sl@0
|
523 |
BOOST_UBLAS_INLINE
|
sl@0
|
524 |
void increment (I &it, const I &it_end) {
|
sl@0
|
525 |
#if BOOST_UBLAS_TYPE_CHECK
|
sl@0
|
526 |
I cit (it);
|
sl@0
|
527 |
while (cit != it_end) {
|
sl@0
|
528 |
BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
|
sl@0
|
529 |
++ cit;
|
sl@0
|
530 |
}
|
sl@0
|
531 |
#endif
|
sl@0
|
532 |
it = it_end;
|
sl@0
|
533 |
}
|
sl@0
|
534 |
|
sl@0
|
535 |
}}}
|
sl@0
|
536 |
|
sl@0
|
537 |
#endif
|