Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2000-2002
|
Chris@16
|
3 // Joerg Walter, Mathias Koch
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // The authors gratefully acknowledge the support of
|
Chris@16
|
10 // GeNeSys mbH & Co. KG in producing this work.
|
Chris@16
|
11 //
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_UBLAS_STORAGE_H
|
Chris@16
|
14 #define BOOST_UBLAS_STORAGE_H
|
Chris@16
|
15
|
Chris@16
|
16 #include <algorithm>
|
Chris@16
|
17 #ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
|
Chris@16
|
18 #include <boost/shared_array.hpp>
|
Chris@16
|
19 #endif
|
Chris@16
|
20
|
Chris@16
|
21 #include <boost/serialization/array.hpp>
|
Chris@16
|
22 #include <boost/serialization/collection_size_type.hpp>
|
Chris@16
|
23 #include <boost/serialization/nvp.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 #include <boost/numeric/ublas/exception.hpp>
|
Chris@16
|
26 #include <boost/numeric/ublas/traits.hpp>
|
Chris@16
|
27 #include <boost/numeric/ublas/detail/iterator.hpp>
|
Chris@16
|
28
|
Chris@16
|
29
|
Chris@16
|
30 namespace boost { namespace numeric { namespace ublas {
|
Chris@16
|
31
|
Chris@16
|
32
|
Chris@16
|
33 // Base class for Storage Arrays - see the Barton Nackman trick
|
Chris@16
|
34 template<class E>
|
Chris@16
|
35 class storage_array:
|
Chris@16
|
36 private nonassignable {
|
Chris@16
|
37 };
|
Chris@16
|
38
|
Chris@16
|
39
|
Chris@16
|
40 // Unbounded array - with allocator
|
Chris@16
|
41 template<class T, class ALLOC>
|
Chris@16
|
42 class unbounded_array:
|
Chris@16
|
43 public storage_array<unbounded_array<T, ALLOC> > {
|
Chris@16
|
44
|
Chris@16
|
45 typedef unbounded_array<T, ALLOC> self_type;
|
Chris@16
|
46 public:
|
Chris@16
|
47 typedef ALLOC allocator_type;
|
Chris@16
|
48 typedef typename ALLOC::size_type size_type;
|
Chris@16
|
49 typedef typename ALLOC::difference_type difference_type;
|
Chris@16
|
50 typedef T value_type;
|
Chris@16
|
51 typedef const T &const_reference;
|
Chris@16
|
52 typedef T &reference;
|
Chris@16
|
53 typedef const T *const_pointer;
|
Chris@16
|
54 typedef T *pointer;
|
Chris@16
|
55 typedef const_pointer const_iterator;
|
Chris@16
|
56 typedef pointer iterator;
|
Chris@16
|
57
|
Chris@16
|
58 // Construction and destruction
|
Chris@16
|
59 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
60 unbounded_array (const ALLOC &a = ALLOC()):
|
Chris@16
|
61 alloc_ (a), size_ (0) {
|
Chris@16
|
62 data_ = 0;
|
Chris@16
|
63 }
|
Chris@16
|
64 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
65 unbounded_array (size_type size, const ALLOC &a = ALLOC()):
|
Chris@16
|
66 alloc_(a), size_ (size) {
|
Chris@16
|
67 if (size_) {
|
Chris@16
|
68 data_ = alloc_.allocate (size_);
|
Chris@16
|
69 if (! detail::has_trivial_constructor<T>::value) {
|
Chris@16
|
70 for (pointer d = data_; d != data_ + size_; ++d)
|
Chris@16
|
71 alloc_.construct(d, value_type());
|
Chris@16
|
72 }
|
Chris@16
|
73 }
|
Chris@16
|
74 else
|
Chris@16
|
75 data_ = 0;
|
Chris@16
|
76 }
|
Chris@16
|
77 // No value initialised, but still be default constructed
|
Chris@16
|
78 BOOST_UBLAS_INLINE
|
Chris@16
|
79 unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()):
|
Chris@16
|
80 alloc_ (a), size_ (size) {
|
Chris@16
|
81 if (size_) {
|
Chris@16
|
82 data_ = alloc_.allocate (size_);
|
Chris@16
|
83 std::uninitialized_fill (begin(), end(), init);
|
Chris@16
|
84 }
|
Chris@16
|
85 else
|
Chris@16
|
86 data_ = 0;
|
Chris@16
|
87 }
|
Chris@16
|
88 BOOST_UBLAS_INLINE
|
Chris@16
|
89 unbounded_array (const unbounded_array &c):
|
Chris@16
|
90 storage_array<unbounded_array<T, ALLOC> >(),
|
Chris@16
|
91 alloc_ (c.alloc_), size_ (c.size_) {
|
Chris@16
|
92 if (size_) {
|
Chris@16
|
93 data_ = alloc_.allocate (size_);
|
Chris@16
|
94 std::uninitialized_copy (c.begin(), c.end(), begin());
|
Chris@16
|
95 }
|
Chris@16
|
96 else
|
Chris@16
|
97 data_ = 0;
|
Chris@16
|
98 }
|
Chris@16
|
99 BOOST_UBLAS_INLINE
|
Chris@16
|
100 ~unbounded_array () {
|
Chris@16
|
101 if (size_) {
|
Chris@16
|
102 if (! detail::has_trivial_destructor<T>::value) {
|
Chris@16
|
103 // std::_Destroy (begin(), end(), alloc_);
|
Chris@16
|
104 const iterator i_end = end();
|
Chris@16
|
105 for (iterator i = begin (); i != i_end; ++i) {
|
Chris@16
|
106 iterator_destroy (i);
|
Chris@16
|
107 }
|
Chris@16
|
108 }
|
Chris@16
|
109 alloc_.deallocate (data_, size_);
|
Chris@16
|
110 }
|
Chris@16
|
111 }
|
Chris@16
|
112
|
Chris@16
|
113 // Resizing
|
Chris@16
|
114 private:
|
Chris@16
|
115 BOOST_UBLAS_INLINE
|
Chris@16
|
116 void resize_internal (const size_type size, const value_type init, const bool preserve) {
|
Chris@16
|
117 if (size != size_) {
|
Chris@16
|
118 pointer p_data = data_;
|
Chris@16
|
119 if (size) {
|
Chris@16
|
120 data_ = alloc_.allocate (size);
|
Chris@16
|
121 if (preserve) {
|
Chris@16
|
122 pointer si = p_data;
|
Chris@16
|
123 pointer di = data_;
|
Chris@16
|
124 if (size < size_) {
|
Chris@16
|
125 for (; di != data_ + size; ++di) {
|
Chris@16
|
126 alloc_.construct (di, *si);
|
Chris@16
|
127 ++si;
|
Chris@16
|
128 }
|
Chris@16
|
129 }
|
Chris@16
|
130 else {
|
Chris@101
|
131 for (; si != p_data + size_; ++si) {
|
Chris@16
|
132 alloc_.construct (di, *si);
|
Chris@16
|
133 ++di;
|
Chris@16
|
134 }
|
Chris@16
|
135 for (; di != data_ + size; ++di) {
|
Chris@16
|
136 alloc_.construct (di, init);
|
Chris@16
|
137 }
|
Chris@16
|
138 }
|
Chris@16
|
139 }
|
Chris@16
|
140 else {
|
Chris@16
|
141 if (! detail::has_trivial_constructor<T>::value) {
|
Chris@16
|
142 for (pointer di = data_; di != data_ + size; ++di)
|
Chris@16
|
143 alloc_.construct (di, value_type());
|
Chris@16
|
144 }
|
Chris@16
|
145 }
|
Chris@16
|
146 }
|
Chris@16
|
147
|
Chris@16
|
148 if (size_) {
|
Chris@16
|
149 if (! detail::has_trivial_destructor<T>::value) {
|
Chris@16
|
150 for (pointer si = p_data; si != p_data + size_; ++si)
|
Chris@16
|
151 alloc_.destroy (si);
|
Chris@16
|
152 }
|
Chris@16
|
153 alloc_.deallocate (p_data, size_);
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 if (!size)
|
Chris@16
|
157 data_ = 0;
|
Chris@16
|
158 size_ = size;
|
Chris@16
|
159 }
|
Chris@16
|
160 }
|
Chris@16
|
161 public:
|
Chris@16
|
162 BOOST_UBLAS_INLINE
|
Chris@16
|
163 void resize (size_type size) {
|
Chris@16
|
164 resize_internal (size, value_type (), false);
|
Chris@16
|
165 }
|
Chris@16
|
166 BOOST_UBLAS_INLINE
|
Chris@16
|
167 void resize (size_type size, value_type init) {
|
Chris@16
|
168 resize_internal (size, init, true);
|
Chris@16
|
169 }
|
Chris@16
|
170
|
Chris@16
|
171 // Random Access Container
|
Chris@16
|
172 BOOST_UBLAS_INLINE
|
Chris@16
|
173 size_type max_size () const {
|
Chris@16
|
174 return ALLOC ().max_size();
|
Chris@16
|
175 }
|
Chris@16
|
176
|
Chris@16
|
177 BOOST_UBLAS_INLINE
|
Chris@16
|
178 bool empty () const {
|
Chris@16
|
179 return size_ == 0;
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 BOOST_UBLAS_INLINE
|
Chris@16
|
183 size_type size () const {
|
Chris@16
|
184 return size_;
|
Chris@16
|
185 }
|
Chris@16
|
186
|
Chris@16
|
187 // Element access
|
Chris@16
|
188 BOOST_UBLAS_INLINE
|
Chris@16
|
189 const_reference operator [] (size_type i) const {
|
Chris@16
|
190 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
191 return data_ [i];
|
Chris@16
|
192 }
|
Chris@16
|
193 BOOST_UBLAS_INLINE
|
Chris@16
|
194 reference operator [] (size_type i) {
|
Chris@16
|
195 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
196 return data_ [i];
|
Chris@16
|
197 }
|
Chris@16
|
198
|
Chris@16
|
199 // Assignment
|
Chris@16
|
200 BOOST_UBLAS_INLINE
|
Chris@16
|
201 unbounded_array &operator = (const unbounded_array &a) {
|
Chris@16
|
202 if (this != &a) {
|
Chris@16
|
203 resize (a.size_);
|
Chris@16
|
204 std::copy (a.data_, a.data_ + a.size_, data_);
|
Chris@16
|
205 }
|
Chris@16
|
206 return *this;
|
Chris@16
|
207 }
|
Chris@16
|
208 BOOST_UBLAS_INLINE
|
Chris@16
|
209 unbounded_array &assign_temporary (unbounded_array &a) {
|
Chris@16
|
210 swap (a);
|
Chris@16
|
211 return *this;
|
Chris@16
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214 // Swapping
|
Chris@16
|
215 BOOST_UBLAS_INLINE
|
Chris@16
|
216 void swap (unbounded_array &a) {
|
Chris@16
|
217 if (this != &a) {
|
Chris@16
|
218 std::swap (size_, a.size_);
|
Chris@16
|
219 std::swap (data_, a.data_);
|
Chris@16
|
220 }
|
Chris@16
|
221 }
|
Chris@16
|
222 BOOST_UBLAS_INLINE
|
Chris@16
|
223 friend void swap (unbounded_array &a1, unbounded_array &a2) {
|
Chris@16
|
224 a1.swap (a2);
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 BOOST_UBLAS_INLINE
|
Chris@16
|
228 const_iterator begin () const {
|
Chris@16
|
229 return data_;
|
Chris@16
|
230 }
|
Chris@16
|
231 BOOST_UBLAS_INLINE
|
Chris@101
|
232 const_iterator cbegin () const {
|
Chris@101
|
233 return begin ();
|
Chris@101
|
234 }
|
Chris@101
|
235 BOOST_UBLAS_INLINE
|
Chris@16
|
236 const_iterator end () const {
|
Chris@16
|
237 return data_ + size_;
|
Chris@16
|
238 }
|
Chris@101
|
239 BOOST_UBLAS_INLINE
|
Chris@101
|
240 const_iterator cend () const {
|
Chris@101
|
241 return end ();
|
Chris@101
|
242 }
|
Chris@16
|
243
|
Chris@16
|
244 BOOST_UBLAS_INLINE
|
Chris@16
|
245 iterator begin () {
|
Chris@16
|
246 return data_;
|
Chris@16
|
247 }
|
Chris@16
|
248 BOOST_UBLAS_INLINE
|
Chris@16
|
249 iterator end () {
|
Chris@16
|
250 return data_ + size_;
|
Chris@16
|
251 }
|
Chris@16
|
252
|
Chris@16
|
253 // Reverse iterators
|
Chris@16
|
254 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
255 typedef std::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
256
|
Chris@16
|
257 BOOST_UBLAS_INLINE
|
Chris@16
|
258 const_reverse_iterator rbegin () const {
|
Chris@16
|
259 return const_reverse_iterator (end ());
|
Chris@16
|
260 }
|
Chris@16
|
261 BOOST_UBLAS_INLINE
|
Chris@101
|
262 const_reverse_iterator crbegin () const {
|
Chris@101
|
263 return rbegin ();
|
Chris@101
|
264 }
|
Chris@101
|
265 BOOST_UBLAS_INLINE
|
Chris@16
|
266 const_reverse_iterator rend () const {
|
Chris@16
|
267 return const_reverse_iterator (begin ());
|
Chris@16
|
268 }
|
Chris@16
|
269 BOOST_UBLAS_INLINE
|
Chris@101
|
270 const_reverse_iterator crend () const {
|
Chris@101
|
271 return rend ();
|
Chris@101
|
272 }
|
Chris@101
|
273 BOOST_UBLAS_INLINE
|
Chris@16
|
274 reverse_iterator rbegin () {
|
Chris@16
|
275 return reverse_iterator (end ());
|
Chris@16
|
276 }
|
Chris@16
|
277 BOOST_UBLAS_INLINE
|
Chris@16
|
278 reverse_iterator rend () {
|
Chris@16
|
279 return reverse_iterator (begin ());
|
Chris@16
|
280 }
|
Chris@16
|
281
|
Chris@16
|
282 // Allocator
|
Chris@16
|
283 allocator_type get_allocator () {
|
Chris@16
|
284 return alloc_;
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287 private:
|
Chris@16
|
288 friend class boost::serialization::access;
|
Chris@16
|
289
|
Chris@16
|
290 // Serialization
|
Chris@16
|
291 template<class Archive>
|
Chris@101
|
292 void serialize(Archive & ar, const unsigned int /*version*/)
|
Chris@16
|
293 {
|
Chris@16
|
294 serialization::collection_size_type s(size_);
|
Chris@16
|
295 ar & serialization::make_nvp("size",s);
|
Chris@16
|
296 if ( Archive::is_loading::value ) {
|
Chris@16
|
297 resize(s);
|
Chris@16
|
298 }
|
Chris@16
|
299 ar & serialization::make_array(data_, s);
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 private:
|
Chris@16
|
303 // Handle explict destroy on a (possibly indexed) iterator
|
Chris@16
|
304 BOOST_UBLAS_INLINE
|
Chris@16
|
305 static void iterator_destroy (iterator &i) {
|
Chris@16
|
306 (&(*i)) -> ~value_type ();
|
Chris@16
|
307 }
|
Chris@16
|
308 ALLOC alloc_;
|
Chris@16
|
309 size_type size_;
|
Chris@16
|
310 pointer data_;
|
Chris@16
|
311 };
|
Chris@16
|
312
|
Chris@16
|
313 // Bounded array - with allocator for size_type and difference_type
|
Chris@16
|
314 template<class T, std::size_t N, class ALLOC>
|
Chris@16
|
315 class bounded_array:
|
Chris@16
|
316 public storage_array<bounded_array<T, N, ALLOC> > {
|
Chris@16
|
317
|
Chris@16
|
318 typedef bounded_array<T, N, ALLOC> self_type;
|
Chris@16
|
319 public:
|
Chris@16
|
320 // No allocator_type as ALLOC is not used for allocation
|
Chris@16
|
321 typedef typename ALLOC::size_type size_type;
|
Chris@16
|
322 typedef typename ALLOC::difference_type difference_type;
|
Chris@16
|
323 typedef T value_type;
|
Chris@16
|
324 typedef const T &const_reference;
|
Chris@16
|
325 typedef T &reference;
|
Chris@16
|
326 typedef const T *const_pointer;
|
Chris@16
|
327 typedef T *pointer;
|
Chris@16
|
328 typedef const_pointer const_iterator;
|
Chris@16
|
329 typedef pointer iterator;
|
Chris@16
|
330
|
Chris@16
|
331 // Construction and destruction
|
Chris@16
|
332 BOOST_UBLAS_INLINE
|
Chris@16
|
333 bounded_array ():
|
Chris@16
|
334 size_ (0) /*, data_ ()*/ { // size 0 - use bounded_vector to default construct with size N
|
Chris@16
|
335 }
|
Chris@16
|
336 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
337 bounded_array (size_type size):
|
Chris@16
|
338 size_ (size) /*, data_ ()*/ {
|
Chris@16
|
339 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
|
Chris@16
|
340 // data_ (an array) elements are already default constructed
|
Chris@16
|
341 }
|
Chris@16
|
342 BOOST_UBLAS_INLINE
|
Chris@16
|
343 bounded_array (size_type size, const value_type &init):
|
Chris@16
|
344 size_ (size) /*, data_ ()*/ {
|
Chris@16
|
345 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
|
Chris@16
|
346 // ISSUE elements should be value constructed here, but we must fill instead as already default constructed
|
Chris@16
|
347 std::fill (begin(), end(), init) ;
|
Chris@16
|
348 }
|
Chris@16
|
349 BOOST_UBLAS_INLINE
|
Chris@16
|
350 bounded_array (const bounded_array &c):
|
Chris@16
|
351 size_ (c.size_) {
|
Chris@16
|
352 // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed
|
Chris@16
|
353 std::copy (c.begin(), c.end(), begin());
|
Chris@16
|
354 }
|
Chris@16
|
355
|
Chris@16
|
356 // Resizing
|
Chris@16
|
357 BOOST_UBLAS_INLINE
|
Chris@16
|
358 void resize (size_type size) {
|
Chris@16
|
359 BOOST_UBLAS_CHECK (size <= N, bad_size ());
|
Chris@16
|
360 size_ = size;
|
Chris@16
|
361 }
|
Chris@16
|
362 BOOST_UBLAS_INLINE
|
Chris@16
|
363 void resize (size_type size, value_type init) {
|
Chris@16
|
364 BOOST_UBLAS_CHECK (size <= N, bad_size ());
|
Chris@16
|
365 if (size > size_)
|
Chris@16
|
366 std::fill (data_ + size_, data_ + size, init);
|
Chris@16
|
367 size_ = size;
|
Chris@16
|
368 }
|
Chris@16
|
369
|
Chris@16
|
370 // Random Access Container
|
Chris@16
|
371 BOOST_UBLAS_INLINE
|
Chris@16
|
372 size_type max_size () const {
|
Chris@101
|
373 return N;
|
Chris@16
|
374 }
|
Chris@16
|
375
|
Chris@16
|
376 BOOST_UBLAS_INLINE
|
Chris@16
|
377 bool empty () const {
|
Chris@16
|
378 return size_ == 0;
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 BOOST_UBLAS_INLINE
|
Chris@16
|
382 size_type size () const {
|
Chris@16
|
383 return size_;
|
Chris@16
|
384 }
|
Chris@16
|
385
|
Chris@16
|
386 // Element access
|
Chris@16
|
387 BOOST_UBLAS_INLINE
|
Chris@16
|
388 const_reference operator [] (size_type i) const {
|
Chris@16
|
389 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
390 return data_ [i];
|
Chris@16
|
391 }
|
Chris@16
|
392 BOOST_UBLAS_INLINE
|
Chris@16
|
393 reference operator [] (size_type i) {
|
Chris@16
|
394 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
395 return data_ [i];
|
Chris@16
|
396 }
|
Chris@16
|
397
|
Chris@16
|
398 // Assignment
|
Chris@16
|
399 BOOST_UBLAS_INLINE
|
Chris@16
|
400 bounded_array &operator = (const bounded_array &a) {
|
Chris@16
|
401 if (this != &a) {
|
Chris@16
|
402 resize (a.size_);
|
Chris@16
|
403 std::copy (a.data_, a.data_ + a.size_, data_);
|
Chris@16
|
404 }
|
Chris@16
|
405 return *this;
|
Chris@16
|
406 }
|
Chris@16
|
407 BOOST_UBLAS_INLINE
|
Chris@16
|
408 bounded_array &assign_temporary (bounded_array &a) {
|
Chris@16
|
409 *this = a;
|
Chris@16
|
410 return *this;
|
Chris@16
|
411 }
|
Chris@16
|
412
|
Chris@16
|
413 // Swapping
|
Chris@16
|
414 BOOST_UBLAS_INLINE
|
Chris@16
|
415 void swap (bounded_array &a) {
|
Chris@16
|
416 if (this != &a) {
|
Chris@16
|
417 std::swap (size_, a.size_);
|
Chris@16
|
418 std::swap_ranges (data_, data_ + (std::max) (size_, a.size_), a.data_);
|
Chris@16
|
419 }
|
Chris@16
|
420 }
|
Chris@16
|
421 BOOST_UBLAS_INLINE
|
Chris@16
|
422 friend void swap (bounded_array &a1, bounded_array &a2) {
|
Chris@16
|
423 a1.swap (a2);
|
Chris@16
|
424 }
|
Chris@16
|
425
|
Chris@16
|
426 BOOST_UBLAS_INLINE
|
Chris@16
|
427 const_iterator begin () const {
|
Chris@16
|
428 return data_;
|
Chris@16
|
429 }
|
Chris@16
|
430 BOOST_UBLAS_INLINE
|
Chris@101
|
431 const_iterator cbegin () const {
|
Chris@101
|
432 return begin ();
|
Chris@101
|
433 }
|
Chris@101
|
434 BOOST_UBLAS_INLINE
|
Chris@16
|
435 const_iterator end () const {
|
Chris@16
|
436 return data_ + size_;
|
Chris@16
|
437 }
|
Chris@101
|
438 BOOST_UBLAS_INLINE
|
Chris@101
|
439 const_iterator cend () const {
|
Chris@101
|
440 return end ();
|
Chris@101
|
441 }
|
Chris@16
|
442
|
Chris@16
|
443 BOOST_UBLAS_INLINE
|
Chris@16
|
444 iterator begin () {
|
Chris@16
|
445 return data_;
|
Chris@16
|
446 }
|
Chris@16
|
447 BOOST_UBLAS_INLINE
|
Chris@16
|
448 iterator end () {
|
Chris@16
|
449 return data_ + size_;
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 // Reverse iterators
|
Chris@16
|
453 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
454 typedef std::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
455
|
Chris@16
|
456 BOOST_UBLAS_INLINE
|
Chris@16
|
457 const_reverse_iterator rbegin () const {
|
Chris@16
|
458 return const_reverse_iterator (end ());
|
Chris@16
|
459 }
|
Chris@16
|
460 BOOST_UBLAS_INLINE
|
Chris@101
|
461 const_reverse_iterator crbegin () const {
|
Chris@101
|
462 return rbegin ();
|
Chris@101
|
463 }
|
Chris@101
|
464 BOOST_UBLAS_INLINE
|
Chris@16
|
465 const_reverse_iterator rend () const {
|
Chris@16
|
466 return const_reverse_iterator (begin ());
|
Chris@16
|
467 }
|
Chris@16
|
468 BOOST_UBLAS_INLINE
|
Chris@101
|
469 const_reverse_iterator crend () const {
|
Chris@101
|
470 return rend ();
|
Chris@101
|
471 }
|
Chris@101
|
472 BOOST_UBLAS_INLINE
|
Chris@16
|
473 reverse_iterator rbegin () {
|
Chris@16
|
474 return reverse_iterator (end ());
|
Chris@16
|
475 }
|
Chris@16
|
476 BOOST_UBLAS_INLINE
|
Chris@16
|
477 reverse_iterator rend () {
|
Chris@16
|
478 return reverse_iterator (begin ());
|
Chris@16
|
479 }
|
Chris@16
|
480
|
Chris@16
|
481 private:
|
Chris@16
|
482 // Serialization
|
Chris@16
|
483 friend class boost::serialization::access;
|
Chris@16
|
484
|
Chris@16
|
485 template<class Archive>
|
Chris@101
|
486 void serialize(Archive & ar, const unsigned int /*version*/)
|
Chris@16
|
487 {
|
Chris@16
|
488 serialization::collection_size_type s(size_);
|
Chris@16
|
489 ar & serialization::make_nvp("size", s);
|
Chris@16
|
490 if ( Archive::is_loading::value ) {
|
Chris@16
|
491 if (s > N) bad_size("too large size in bounded_array::load()\n").raise();
|
Chris@16
|
492 resize(s);
|
Chris@16
|
493 }
|
Chris@16
|
494 ar & serialization::make_array(data_, s);
|
Chris@16
|
495 }
|
Chris@16
|
496
|
Chris@16
|
497 private:
|
Chris@16
|
498 size_type size_;
|
Chris@16
|
499 // MSVC does not like arrays of size 0 in base classes. Hence, this conditionally changes the size to 1
|
Chris@16
|
500 #ifdef _MSC_VER
|
Chris@16
|
501 BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [(N>0)?N:1];
|
Chris@16
|
502 #else
|
Chris@16
|
503 BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [N];
|
Chris@16
|
504 #endif
|
Chris@16
|
505 };
|
Chris@16
|
506
|
Chris@16
|
507
|
Chris@16
|
508 // Array adaptor with normal deep copy semantics of elements
|
Chris@16
|
509 template<class T>
|
Chris@16
|
510 class array_adaptor:
|
Chris@16
|
511 public storage_array<array_adaptor<T> > {
|
Chris@16
|
512
|
Chris@16
|
513 typedef array_adaptor<T> self_type;
|
Chris@16
|
514 public:
|
Chris@16
|
515 typedef std::size_t size_type;
|
Chris@16
|
516 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
517 typedef T value_type;
|
Chris@16
|
518 typedef const T &const_reference;
|
Chris@16
|
519 typedef T &reference;
|
Chris@16
|
520 typedef const T *const_pointer;
|
Chris@16
|
521 typedef T *pointer;
|
Chris@16
|
522
|
Chris@16
|
523 // Construction and destruction
|
Chris@16
|
524 BOOST_UBLAS_INLINE
|
Chris@16
|
525 array_adaptor ():
|
Chris@16
|
526 size_ (0), own_ (true), data_ (new value_type [0]) {
|
Chris@16
|
527 }
|
Chris@16
|
528 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
529 array_adaptor (size_type size):
|
Chris@16
|
530 size_ (size), own_ (true), data_ (new value_type [size]) {
|
Chris@16
|
531 }
|
Chris@16
|
532 BOOST_UBLAS_INLINE
|
Chris@16
|
533 array_adaptor (size_type size, const value_type &init):
|
Chris@16
|
534 size_ (size), own_ (true), data_ (new value_type [size]) {
|
Chris@16
|
535 std::fill (data_, data_ + size_, init);
|
Chris@16
|
536 }
|
Chris@16
|
537 BOOST_UBLAS_INLINE
|
Chris@16
|
538 array_adaptor (size_type size, pointer data):
|
Chris@16
|
539 size_ (size), own_ (false), data_ (data) {}
|
Chris@101
|
540
|
Chris@101
|
541 template <size_t N>
|
Chris@101
|
542 BOOST_UBLAS_INLINE array_adaptor (T (&data)[N]):
|
Chris@101
|
543 size_ (N), own_ (false), data_ (data) {}
|
Chris@16
|
544 BOOST_UBLAS_INLINE
|
Chris@16
|
545 array_adaptor (const array_adaptor &a):
|
Chris@16
|
546 storage_array<self_type> (),
|
Chris@16
|
547 size_ (a.size_), own_ (true), data_ (new value_type [a.size_]) {
|
Chris@16
|
548 *this = a;
|
Chris@16
|
549 }
|
Chris@16
|
550 BOOST_UBLAS_INLINE
|
Chris@16
|
551 ~array_adaptor () {
|
Chris@16
|
552 if (own_) {
|
Chris@16
|
553 delete [] data_;
|
Chris@16
|
554 }
|
Chris@16
|
555 }
|
Chris@16
|
556
|
Chris@16
|
557 // Resizing
|
Chris@16
|
558 private:
|
Chris@16
|
559 BOOST_UBLAS_INLINE
|
Chris@16
|
560 void resize_internal (size_type size, value_type init, bool preserve = true) {
|
Chris@16
|
561 if (size != size_) {
|
Chris@16
|
562 pointer data = new value_type [size];
|
Chris@16
|
563 if (preserve) {
|
Chris@16
|
564 std::copy (data_, data_ + (std::min) (size, size_), data);
|
Chris@16
|
565 std::fill (data + (std::min) (size, size_), data + size, init);
|
Chris@16
|
566 }
|
Chris@16
|
567 if (own_)
|
Chris@16
|
568 delete [] data_;
|
Chris@16
|
569 size_ = size;
|
Chris@16
|
570 own_ = true;
|
Chris@16
|
571 data_ = data;
|
Chris@16
|
572 }
|
Chris@16
|
573 }
|
Chris@16
|
574 BOOST_UBLAS_INLINE
|
Chris@16
|
575 void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
|
Chris@16
|
576 if (data != data_) {
|
Chris@16
|
577 if (preserve) {
|
Chris@16
|
578 std::copy (data_, data_ + (std::min) (size, size_), data);
|
Chris@16
|
579 std::fill (data + (std::min) (size, size_), data + size, init);
|
Chris@16
|
580 }
|
Chris@16
|
581 if (own_)
|
Chris@16
|
582 delete [] data_;
|
Chris@16
|
583 own_ = false;
|
Chris@16
|
584 data_ = data;
|
Chris@16
|
585 }
|
Chris@16
|
586 else {
|
Chris@16
|
587 std::fill (data + (std::min) (size, size_), data + size, init);
|
Chris@16
|
588 }
|
Chris@16
|
589 size_ = size;
|
Chris@16
|
590 }
|
Chris@16
|
591 public:
|
Chris@16
|
592 BOOST_UBLAS_INLINE
|
Chris@16
|
593 void resize (size_type size) {
|
Chris@16
|
594 resize_internal (size, value_type (), false);
|
Chris@16
|
595 }
|
Chris@16
|
596 BOOST_UBLAS_INLINE
|
Chris@16
|
597 void resize (size_type size, value_type init) {
|
Chris@16
|
598 resize_internal (size, init, true);
|
Chris@16
|
599 }
|
Chris@16
|
600 BOOST_UBLAS_INLINE
|
Chris@16
|
601 void resize (size_type size, pointer data) {
|
Chris@16
|
602 resize_internal (size, data, value_type (), false);
|
Chris@16
|
603 }
|
Chris@16
|
604 BOOST_UBLAS_INLINE
|
Chris@16
|
605 void resize (size_type size, pointer data, value_type init) {
|
Chris@16
|
606 resize_internal (size, data, init, true);
|
Chris@16
|
607 }
|
Chris@16
|
608
|
Chris@101
|
609 template <size_t N>
|
Chris@101
|
610 BOOST_UBLAS_INLINE void resize (T (&data)[N]) {
|
Chris@101
|
611 resize_internal (N, data, value_type (), false);
|
Chris@101
|
612 }
|
Chris@101
|
613
|
Chris@101
|
614 template <size_t N>
|
Chris@101
|
615 BOOST_UBLAS_INLINE void resize (T (&data)[N], value_type init) {
|
Chris@101
|
616 resize_internal (N, data, init, true);
|
Chris@101
|
617 }
|
Chris@101
|
618
|
Chris@16
|
619 BOOST_UBLAS_INLINE
|
Chris@16
|
620 size_type size () const {
|
Chris@16
|
621 return size_;
|
Chris@16
|
622 }
|
Chris@16
|
623
|
Chris@16
|
624 // Element access
|
Chris@16
|
625 BOOST_UBLAS_INLINE
|
Chris@16
|
626 const_reference operator [] (size_type i) const {
|
Chris@16
|
627 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
628 return data_ [i];
|
Chris@16
|
629 }
|
Chris@16
|
630 BOOST_UBLAS_INLINE
|
Chris@16
|
631 reference operator [] (size_type i) {
|
Chris@16
|
632 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
633 return data_ [i];
|
Chris@16
|
634 }
|
Chris@16
|
635
|
Chris@16
|
636 // Assignment
|
Chris@16
|
637 BOOST_UBLAS_INLINE
|
Chris@16
|
638 array_adaptor &operator = (const array_adaptor &a) {
|
Chris@16
|
639 if (this != &a) {
|
Chris@16
|
640 resize (a.size_);
|
Chris@16
|
641 std::copy (a.data_, a.data_ + a.size_, data_);
|
Chris@16
|
642 }
|
Chris@16
|
643 return *this;
|
Chris@16
|
644 }
|
Chris@16
|
645 BOOST_UBLAS_INLINE
|
Chris@16
|
646 array_adaptor &assign_temporary (array_adaptor &a) {
|
Chris@16
|
647 if (own_ && a.own_)
|
Chris@16
|
648 swap (a);
|
Chris@16
|
649 else
|
Chris@16
|
650 *this = a;
|
Chris@16
|
651 return *this;
|
Chris@16
|
652 }
|
Chris@16
|
653
|
Chris@16
|
654 // Swapping
|
Chris@16
|
655 BOOST_UBLAS_INLINE
|
Chris@16
|
656 void swap (array_adaptor &a) {
|
Chris@16
|
657 if (this != &a) {
|
Chris@16
|
658 std::swap (size_, a.size_);
|
Chris@16
|
659 std::swap (own_, a.own_);
|
Chris@16
|
660 std::swap (data_, a.data_);
|
Chris@16
|
661 }
|
Chris@16
|
662 }
|
Chris@16
|
663 BOOST_UBLAS_INLINE
|
Chris@16
|
664 friend void swap (array_adaptor &a1, array_adaptor &a2) {
|
Chris@16
|
665 a1.swap (a2);
|
Chris@16
|
666 }
|
Chris@16
|
667
|
Chris@16
|
668 // Iterators simply are pointers.
|
Chris@16
|
669
|
Chris@16
|
670 typedef const_pointer const_iterator;
|
Chris@16
|
671
|
Chris@16
|
672 BOOST_UBLAS_INLINE
|
Chris@16
|
673 const_iterator begin () const {
|
Chris@16
|
674 return data_;
|
Chris@16
|
675 }
|
Chris@16
|
676 BOOST_UBLAS_INLINE
|
Chris@101
|
677 const_iterator cbegin () const {
|
Chris@101
|
678 return begin ();
|
Chris@101
|
679 }
|
Chris@101
|
680 BOOST_UBLAS_INLINE
|
Chris@16
|
681 const_iterator end () const {
|
Chris@16
|
682 return data_ + size_;
|
Chris@16
|
683 }
|
Chris@101
|
684 BOOST_UBLAS_INLINE
|
Chris@101
|
685 const_iterator cend () const {
|
Chris@101
|
686 return end ();
|
Chris@101
|
687 }
|
Chris@16
|
688
|
Chris@16
|
689 typedef pointer iterator;
|
Chris@16
|
690
|
Chris@16
|
691 BOOST_UBLAS_INLINE
|
Chris@16
|
692 iterator begin () {
|
Chris@16
|
693 return data_;
|
Chris@16
|
694 }
|
Chris@16
|
695 BOOST_UBLAS_INLINE
|
Chris@16
|
696 iterator end () {
|
Chris@16
|
697 return data_ + size_;
|
Chris@16
|
698 }
|
Chris@16
|
699
|
Chris@16
|
700 // Reverse iterators
|
Chris@16
|
701 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
702 typedef std::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
703
|
Chris@16
|
704 BOOST_UBLAS_INLINE
|
Chris@16
|
705 const_reverse_iterator rbegin () const {
|
Chris@16
|
706 return const_reverse_iterator (end ());
|
Chris@16
|
707 }
|
Chris@16
|
708 BOOST_UBLAS_INLINE
|
Chris@101
|
709 const_reverse_iterator crbegin () const {
|
Chris@101
|
710 return rbegin ();
|
Chris@101
|
711 }
|
Chris@101
|
712 BOOST_UBLAS_INLINE
|
Chris@16
|
713 const_reverse_iterator rend () const {
|
Chris@16
|
714 return const_reverse_iterator (begin ());
|
Chris@16
|
715 }
|
Chris@16
|
716 BOOST_UBLAS_INLINE
|
Chris@101
|
717 const_reverse_iterator crend () const {
|
Chris@101
|
718 return rend ();
|
Chris@101
|
719 }
|
Chris@101
|
720 BOOST_UBLAS_INLINE
|
Chris@16
|
721 reverse_iterator rbegin () {
|
Chris@16
|
722 return reverse_iterator (end ());
|
Chris@16
|
723 }
|
Chris@16
|
724 BOOST_UBLAS_INLINE
|
Chris@16
|
725 reverse_iterator rend () {
|
Chris@16
|
726 return reverse_iterator (begin ());
|
Chris@16
|
727 }
|
Chris@16
|
728
|
Chris@16
|
729 private:
|
Chris@16
|
730 size_type size_;
|
Chris@16
|
731 bool own_;
|
Chris@16
|
732 pointer data_;
|
Chris@16
|
733 };
|
Chris@16
|
734
|
Chris@16
|
735 #ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
|
Chris@16
|
736 // Array adaptor with shallow (reference) copy semantics of elements.
|
Chris@16
|
737 // shared_array is used to maintain reference counts.
|
Chris@16
|
738 // This class breaks the normal copy semantics for a storage container and is very dangerous!
|
Chris@16
|
739 template<class T>
|
Chris@16
|
740 class shallow_array_adaptor:
|
Chris@16
|
741 public storage_array<shallow_array_adaptor<T> > {
|
Chris@16
|
742
|
Chris@16
|
743 typedef shallow_array_adaptor<T> self_type;
|
Chris@16
|
744
|
Chris@16
|
745 template<class TT>
|
Chris@16
|
746 struct leaker {
|
Chris@16
|
747 typedef void result_type;
|
Chris@16
|
748 typedef TT *argument_type;
|
Chris@16
|
749
|
Chris@16
|
750 BOOST_UBLAS_INLINE
|
Chris@101
|
751 result_type operator () (argument_type /* x */) {}
|
Chris@16
|
752 };
|
Chris@16
|
753
|
Chris@16
|
754 public:
|
Chris@16
|
755 typedef std::size_t size_type;
|
Chris@16
|
756 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
757 typedef T value_type;
|
Chris@16
|
758 typedef const T &const_reference;
|
Chris@16
|
759 typedef T &reference;
|
Chris@16
|
760 typedef const T *const_pointer;
|
Chris@16
|
761 typedef T *pointer;
|
Chris@16
|
762
|
Chris@16
|
763 // Construction and destruction
|
Chris@16
|
764 BOOST_UBLAS_INLINE
|
Chris@16
|
765 shallow_array_adaptor ():
|
Chris@16
|
766 size_ (0), own_ (true), data_ (new value_type [0]) {
|
Chris@16
|
767 }
|
Chris@16
|
768 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
769 shallow_array_adaptor (size_type size):
|
Chris@16
|
770 size_ (size), own_ (true), data_ (new value_type [size]) {
|
Chris@16
|
771 }
|
Chris@16
|
772 BOOST_UBLAS_INLINE
|
Chris@16
|
773 shallow_array_adaptor (size_type size, const value_type &init):
|
Chris@16
|
774 size_ (size), own_ (true), data_ (new value_type [size]) {
|
Chris@16
|
775 std::fill (data_.get (), data_.get () + size_, init);
|
Chris@16
|
776 }
|
Chris@16
|
777 BOOST_UBLAS_INLINE
|
Chris@16
|
778 shallow_array_adaptor (size_type size, pointer data):
|
Chris@16
|
779 size_ (size), own_ (false), data_ (data, leaker<value_type> ()) {}
|
Chris@101
|
780 BOOST_UBLAS_INLINE
|
Chris@101
|
781 template <size_t N>
|
Chris@101
|
782 shallow_array_adaptor (T (&data)[N]):
|
Chris@101
|
783 size_ (N), own_ (false), data_ (data, leaker<value_type> ()) {}
|
Chris@16
|
784
|
Chris@16
|
785 BOOST_UBLAS_INLINE
|
Chris@16
|
786 shallow_array_adaptor (const shallow_array_adaptor &a):
|
Chris@16
|
787 storage_array<self_type> (),
|
Chris@16
|
788 size_ (a.size_), own_ (a.own_), data_ (a.data_) {}
|
Chris@16
|
789
|
Chris@16
|
790 BOOST_UBLAS_INLINE
|
Chris@16
|
791 ~shallow_array_adaptor () {
|
Chris@16
|
792 }
|
Chris@16
|
793
|
Chris@16
|
794 // Resizing
|
Chris@16
|
795 private:
|
Chris@16
|
796 BOOST_UBLAS_INLINE
|
Chris@16
|
797 void resize_internal (size_type size, value_type init, bool preserve = true) {
|
Chris@16
|
798 if (size != size_) {
|
Chris@16
|
799 shared_array<value_type> data (new value_type [size]);
|
Chris@16
|
800 if (preserve) {
|
Chris@16
|
801 std::copy (data_.get (), data_.get () + (std::min) (size, size_), data.get ());
|
Chris@16
|
802 std::fill (data.get () + (std::min) (size, size_), data.get () + size, init);
|
Chris@16
|
803 }
|
Chris@16
|
804 size_ = size;
|
Chris@101
|
805 own_ = true;
|
Chris@16
|
806 data_ = data;
|
Chris@16
|
807 }
|
Chris@16
|
808 }
|
Chris@16
|
809 BOOST_UBLAS_INLINE
|
Chris@16
|
810 void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
|
Chris@16
|
811 if (preserve) {
|
Chris@16
|
812 std::copy (data_.get (), data_.get () + (std::min) (size, size_), data);
|
Chris@16
|
813 std::fill (data + (std::min) (size, size_), data + size, init);
|
Chris@16
|
814 }
|
Chris@16
|
815 size_ = size;
|
Chris@101
|
816 own_ = false;
|
Chris@101
|
817 data_.reset(data, leaker<value_type> ());
|
Chris@16
|
818 }
|
Chris@16
|
819 public:
|
Chris@16
|
820 BOOST_UBLAS_INLINE
|
Chris@16
|
821 void resize (size_type size) {
|
Chris@16
|
822 resize_internal (size, value_type (), false);
|
Chris@16
|
823 }
|
Chris@16
|
824 BOOST_UBLAS_INLINE
|
Chris@16
|
825 void resize (size_type size, value_type init) {
|
Chris@16
|
826 resize_internal (size, init, true);
|
Chris@16
|
827 }
|
Chris@16
|
828 BOOST_UBLAS_INLINE
|
Chris@16
|
829 void resize (size_type size, pointer data) {
|
Chris@16
|
830 resize_internal (size, data, value_type (), false);
|
Chris@16
|
831 }
|
Chris@16
|
832 BOOST_UBLAS_INLINE
|
Chris@16
|
833 void resize (size_type size, pointer data, value_type init) {
|
Chris@16
|
834 resize_internal (size, data, init, true);
|
Chris@16
|
835 }
|
Chris@101
|
836 BOOST_UBLAS_INLINE
|
Chris@101
|
837 template <size_t N>
|
Chris@101
|
838 void resize (T (&data)[N]) {
|
Chris@101
|
839 resize_internal (N, data, value_type (), false);
|
Chris@101
|
840 }
|
Chris@101
|
841 BOOST_UBLAS_INLINE
|
Chris@101
|
842 template <size_t N>
|
Chris@101
|
843 void resize (T (&data)[N], value_type init) {
|
Chris@101
|
844 resize_internal (N, data, init, true);
|
Chris@101
|
845 }
|
Chris@16
|
846
|
Chris@16
|
847 BOOST_UBLAS_INLINE
|
Chris@16
|
848 size_type size () const {
|
Chris@16
|
849 return size_;
|
Chris@16
|
850 }
|
Chris@16
|
851
|
Chris@16
|
852 // Element access
|
Chris@16
|
853 BOOST_UBLAS_INLINE
|
Chris@16
|
854 const_reference operator [] (size_type i) const {
|
Chris@16
|
855 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
856 return data_ [i];
|
Chris@16
|
857 }
|
Chris@16
|
858 BOOST_UBLAS_INLINE
|
Chris@16
|
859 reference operator [] (size_type i) {
|
Chris@16
|
860 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
861 return data_ [i];
|
Chris@16
|
862 }
|
Chris@16
|
863
|
Chris@16
|
864 // Assignment
|
Chris@16
|
865 BOOST_UBLAS_INLINE
|
Chris@16
|
866 shallow_array_adaptor &operator = (const shallow_array_adaptor &a) {
|
Chris@16
|
867 if (this != &a) {
|
Chris@16
|
868 resize (a.size_);
|
Chris@16
|
869 std::copy (a.data_.get (), a.data_.get () + a.size_, data_.get ());
|
Chris@16
|
870 }
|
Chris@16
|
871 return *this;
|
Chris@16
|
872 }
|
Chris@16
|
873 BOOST_UBLAS_INLINE
|
Chris@16
|
874 shallow_array_adaptor &assign_temporary (shallow_array_adaptor &a) {
|
Chris@16
|
875 if (own_ && a.own_)
|
Chris@16
|
876 swap (a);
|
Chris@16
|
877 else
|
Chris@16
|
878 *this = a;
|
Chris@16
|
879 return *this;
|
Chris@16
|
880 }
|
Chris@16
|
881
|
Chris@16
|
882 // Swapping
|
Chris@16
|
883 BOOST_UBLAS_INLINE
|
Chris@16
|
884 void swap (shallow_array_adaptor &a) {
|
Chris@16
|
885 if (this != &a) {
|
Chris@16
|
886 std::swap (size_, a.size_);
|
Chris@16
|
887 std::swap (own_, a.own_);
|
Chris@16
|
888 std::swap (data_, a.data_);
|
Chris@16
|
889 }
|
Chris@16
|
890 }
|
Chris@16
|
891 BOOST_UBLAS_INLINE
|
Chris@16
|
892 friend void swap (shallow_array_adaptor &a1, shallow_array_adaptor &a2) {
|
Chris@16
|
893 a1.swap (a2);
|
Chris@16
|
894 }
|
Chris@16
|
895
|
Chris@16
|
896 // Iterators simply are pointers.
|
Chris@16
|
897
|
Chris@16
|
898 typedef const_pointer const_iterator;
|
Chris@16
|
899
|
Chris@16
|
900 BOOST_UBLAS_INLINE
|
Chris@16
|
901 const_iterator begin () const {
|
Chris@16
|
902 return data_.get ();
|
Chris@16
|
903 }
|
Chris@16
|
904 BOOST_UBLAS_INLINE
|
Chris@101
|
905 const_iterator cbegin () const {
|
Chris@101
|
906 return begin ();
|
Chris@101
|
907 }
|
Chris@101
|
908 BOOST_UBLAS_INLINE
|
Chris@16
|
909 const_iterator end () const {
|
Chris@16
|
910 return data_.get () + size_;
|
Chris@16
|
911 }
|
Chris@101
|
912 BOOST_UBLAS_INLINE
|
Chris@101
|
913 const_iterator cend () const {
|
Chris@101
|
914 return end ();
|
Chris@101
|
915 }
|
Chris@16
|
916
|
Chris@16
|
917 typedef pointer iterator;
|
Chris@16
|
918
|
Chris@16
|
919 BOOST_UBLAS_INLINE
|
Chris@16
|
920 iterator begin () {
|
Chris@16
|
921 return data_.get ();
|
Chris@16
|
922 }
|
Chris@16
|
923 BOOST_UBLAS_INLINE
|
Chris@16
|
924 iterator end () {
|
Chris@16
|
925 return data_.get () + size_;
|
Chris@16
|
926 }
|
Chris@16
|
927
|
Chris@16
|
928 // Reverse iterators
|
Chris@16
|
929 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
930 typedef std::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
931
|
Chris@16
|
932 BOOST_UBLAS_INLINE
|
Chris@16
|
933 const_reverse_iterator rbegin () const {
|
Chris@16
|
934 return const_reverse_iterator (end ());
|
Chris@16
|
935 }
|
Chris@16
|
936 BOOST_UBLAS_INLINE
|
Chris@101
|
937 const_reverse_iterator crbegin () const {
|
Chris@101
|
938 return rbegin ();
|
Chris@101
|
939 }
|
Chris@101
|
940 BOOST_UBLAS_INLINE
|
Chris@16
|
941 const_reverse_iterator rend () const {
|
Chris@16
|
942 return const_reverse_iterator (begin ());
|
Chris@16
|
943 }
|
Chris@16
|
944 BOOST_UBLAS_INLINE
|
Chris@101
|
945 const_reverse_iterator crend () const {
|
Chris@101
|
946 return rend ();
|
Chris@101
|
947 }
|
Chris@101
|
948 BOOST_UBLAS_INLINE
|
Chris@16
|
949 reverse_iterator rbegin () {
|
Chris@16
|
950 return reverse_iterator (end ());
|
Chris@16
|
951 }
|
Chris@16
|
952 BOOST_UBLAS_INLINE
|
Chris@16
|
953 reverse_iterator rend () {
|
Chris@16
|
954 return reverse_iterator (begin ());
|
Chris@16
|
955 }
|
Chris@16
|
956
|
Chris@16
|
957 private:
|
Chris@16
|
958 size_type size_;
|
Chris@16
|
959 bool own_;
|
Chris@16
|
960 shared_array<value_type> data_;
|
Chris@16
|
961 };
|
Chris@16
|
962
|
Chris@16
|
963 #endif
|
Chris@16
|
964
|
Chris@16
|
965
|
Chris@16
|
966 // Range class
|
Chris@16
|
967 template <class Z, class D>
|
Chris@16
|
968 class basic_range {
|
Chris@16
|
969 typedef basic_range<Z, D> self_type;
|
Chris@16
|
970 public:
|
Chris@16
|
971 typedef Z size_type;
|
Chris@16
|
972 typedef D difference_type;
|
Chris@16
|
973 typedef size_type value_type;
|
Chris@16
|
974 typedef value_type const_reference;
|
Chris@16
|
975 typedef const_reference reference;
|
Chris@16
|
976 typedef const value_type *const_pointer;
|
Chris@16
|
977 typedef value_type *pointer;
|
Chris@16
|
978
|
Chris@16
|
979 // Construction and destruction
|
Chris@16
|
980 BOOST_UBLAS_INLINE
|
Chris@16
|
981 basic_range ():
|
Chris@16
|
982 start_ (0), size_ (0) {}
|
Chris@16
|
983 BOOST_UBLAS_INLINE
|
Chris@16
|
984 basic_range (size_type start, size_type stop):
|
Chris@16
|
985 start_ (start), size_ (stop - start) {
|
Chris@16
|
986 BOOST_UBLAS_CHECK (start_ <= stop, bad_index ());
|
Chris@16
|
987 }
|
Chris@16
|
988
|
Chris@16
|
989 BOOST_UBLAS_INLINE
|
Chris@16
|
990 size_type start () const {
|
Chris@16
|
991 return start_;
|
Chris@16
|
992 }
|
Chris@16
|
993 BOOST_UBLAS_INLINE
|
Chris@16
|
994 size_type size () const {
|
Chris@16
|
995 return size_;
|
Chris@16
|
996 }
|
Chris@16
|
997
|
Chris@16
|
998 // Random Access Container
|
Chris@16
|
999 BOOST_UBLAS_INLINE
|
Chris@16
|
1000 size_type max_size () const {
|
Chris@16
|
1001 return size_;
|
Chris@16
|
1002 }
|
Chris@16
|
1003
|
Chris@16
|
1004 BOOST_UBLAS_INLINE
|
Chris@16
|
1005 bool empty () const {
|
Chris@16
|
1006 return size_ == 0;
|
Chris@16
|
1007 }
|
Chris@16
|
1008
|
Chris@16
|
1009 // Element access
|
Chris@16
|
1010 BOOST_UBLAS_INLINE
|
Chris@16
|
1011 const_reference operator () (size_type i) const {
|
Chris@16
|
1012 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
1013 return start_ + i;
|
Chris@16
|
1014 }
|
Chris@16
|
1015
|
Chris@16
|
1016 // Composition
|
Chris@16
|
1017 BOOST_UBLAS_INLINE
|
Chris@16
|
1018 basic_range compose (const basic_range &r) const {
|
Chris@16
|
1019 return basic_range (start_ + r.start_, start_ + r.start_ + r.size_);
|
Chris@16
|
1020 }
|
Chris@16
|
1021
|
Chris@16
|
1022 // Comparison
|
Chris@16
|
1023 BOOST_UBLAS_INLINE
|
Chris@16
|
1024 bool operator == (const basic_range &r) const {
|
Chris@16
|
1025 return start_ == r.start_ && size_ == r.size_;
|
Chris@16
|
1026 }
|
Chris@16
|
1027 BOOST_UBLAS_INLINE
|
Chris@16
|
1028 bool operator != (const basic_range &r) const {
|
Chris@16
|
1029 return ! (*this == r);
|
Chris@16
|
1030 }
|
Chris@16
|
1031
|
Chris@16
|
1032 // Iterator types
|
Chris@16
|
1033 private:
|
Chris@16
|
1034 // Use and index
|
Chris@16
|
1035 typedef size_type const_subiterator_type;
|
Chris@16
|
1036
|
Chris@16
|
1037 public:
|
Chris@16
|
1038 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1039 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
|
Chris@16
|
1040 #else
|
Chris@16
|
1041 class const_iterator:
|
Chris@16
|
1042 public container_const_reference<basic_range>,
|
Chris@16
|
1043 public random_access_iterator_base<std::random_access_iterator_tag,
|
Chris@16
|
1044 const_iterator, value_type> {
|
Chris@16
|
1045 public:
|
Chris@16
|
1046 typedef typename basic_range::value_type value_type;
|
Chris@16
|
1047 typedef typename basic_range::difference_type difference_type;
|
Chris@16
|
1048 typedef typename basic_range::const_reference reference;
|
Chris@16
|
1049 typedef typename basic_range::const_pointer pointer;
|
Chris@16
|
1050
|
Chris@16
|
1051 // Construction and destruction
|
Chris@16
|
1052 BOOST_UBLAS_INLINE
|
Chris@16
|
1053 const_iterator ():
|
Chris@16
|
1054 container_const_reference<basic_range> (), it_ () {}
|
Chris@16
|
1055 BOOST_UBLAS_INLINE
|
Chris@16
|
1056 const_iterator (const basic_range &r, const const_subiterator_type &it):
|
Chris@16
|
1057 container_const_reference<basic_range> (r), it_ (it) {}
|
Chris@16
|
1058
|
Chris@16
|
1059 // Arithmetic
|
Chris@16
|
1060 BOOST_UBLAS_INLINE
|
Chris@16
|
1061 const_iterator &operator ++ () {
|
Chris@16
|
1062 ++ it_;
|
Chris@16
|
1063 return *this;
|
Chris@16
|
1064 }
|
Chris@16
|
1065 BOOST_UBLAS_INLINE
|
Chris@16
|
1066 const_iterator &operator -- () {
|
Chris@16
|
1067 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
|
Chris@16
|
1068 -- it_;
|
Chris@16
|
1069 return *this;
|
Chris@16
|
1070 }
|
Chris@16
|
1071 BOOST_UBLAS_INLINE
|
Chris@16
|
1072 const_iterator &operator += (difference_type n) {
|
Chris@16
|
1073 BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
|
Chris@16
|
1074 it_ += n;
|
Chris@16
|
1075 return *this;
|
Chris@16
|
1076 }
|
Chris@16
|
1077 BOOST_UBLAS_INLINE
|
Chris@16
|
1078 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
1079 BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
|
Chris@16
|
1080 it_ -= n;
|
Chris@16
|
1081 return *this;
|
Chris@16
|
1082 }
|
Chris@16
|
1083 BOOST_UBLAS_INLINE
|
Chris@16
|
1084 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
1085 return it_ - it.it_;
|
Chris@16
|
1086 }
|
Chris@16
|
1087
|
Chris@16
|
1088 // Dereference
|
Chris@16
|
1089 BOOST_UBLAS_INLINE
|
Chris@16
|
1090 const_reference operator * () const {
|
Chris@16
|
1091 BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
|
Chris@16
|
1092 BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
|
Chris@16
|
1093 return it_;
|
Chris@16
|
1094 }
|
Chris@16
|
1095
|
Chris@16
|
1096 BOOST_UBLAS_INLINE
|
Chris@16
|
1097 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1098 return *(*this + n);
|
Chris@16
|
1099 }
|
Chris@16
|
1100
|
Chris@16
|
1101 // Index
|
Chris@16
|
1102 BOOST_UBLAS_INLINE
|
Chris@16
|
1103 size_type index () const {
|
Chris@16
|
1104 BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
|
Chris@16
|
1105 BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
|
Chris@16
|
1106 return it_ - (*this) ().start ();
|
Chris@16
|
1107 }
|
Chris@16
|
1108
|
Chris@16
|
1109 // Assignment
|
Chris@16
|
1110 BOOST_UBLAS_INLINE
|
Chris@16
|
1111 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
1112 // Comeau recommends...
|
Chris@16
|
1113 this->assign (&it ());
|
Chris@16
|
1114 it_ = it.it_;
|
Chris@16
|
1115 return *this;
|
Chris@16
|
1116 }
|
Chris@16
|
1117
|
Chris@16
|
1118 // Comparison
|
Chris@16
|
1119 BOOST_UBLAS_INLINE
|
Chris@16
|
1120 bool operator == (const const_iterator &it) const {
|
Chris@16
|
1121 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1122 return it_ == it.it_;
|
Chris@16
|
1123 }
|
Chris@16
|
1124 BOOST_UBLAS_INLINE
|
Chris@16
|
1125 bool operator < (const const_iterator &it) const {
|
Chris@16
|
1126 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1127 return it_ < it.it_;
|
Chris@16
|
1128 }
|
Chris@16
|
1129
|
Chris@16
|
1130 private:
|
Chris@16
|
1131 const_subiterator_type it_;
|
Chris@16
|
1132 };
|
Chris@16
|
1133 #endif
|
Chris@16
|
1134
|
Chris@16
|
1135 BOOST_UBLAS_INLINE
|
Chris@16
|
1136 const_iterator begin () const {
|
Chris@16
|
1137 return const_iterator (*this, start_);
|
Chris@16
|
1138 }
|
Chris@16
|
1139 BOOST_UBLAS_INLINE
|
Chris@101
|
1140 const_iterator cbegin () const {
|
Chris@101
|
1141 return begin ();
|
Chris@101
|
1142 }
|
Chris@101
|
1143 BOOST_UBLAS_INLINE
|
Chris@16
|
1144 const_iterator end () const {
|
Chris@16
|
1145 return const_iterator (*this, start_ + size_);
|
Chris@16
|
1146 }
|
Chris@101
|
1147 BOOST_UBLAS_INLINE
|
Chris@101
|
1148 const_iterator cend () const {
|
Chris@101
|
1149 return end ();
|
Chris@101
|
1150 }
|
Chris@16
|
1151
|
Chris@16
|
1152 // Reverse iterator
|
Chris@16
|
1153 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
1154
|
Chris@16
|
1155 BOOST_UBLAS_INLINE
|
Chris@16
|
1156 const_reverse_iterator rbegin () const {
|
Chris@16
|
1157 return const_reverse_iterator (end ());
|
Chris@16
|
1158 }
|
Chris@16
|
1159 BOOST_UBLAS_INLINE
|
Chris@101
|
1160 const_reverse_iterator crbegin () const {
|
Chris@101
|
1161 return rbegin ();
|
Chris@101
|
1162 }
|
Chris@101
|
1163 BOOST_UBLAS_INLINE
|
Chris@16
|
1164 const_reverse_iterator rend () const {
|
Chris@16
|
1165 return const_reverse_iterator (begin ());
|
Chris@16
|
1166 }
|
Chris@101
|
1167 BOOST_UBLAS_INLINE
|
Chris@101
|
1168 const_reverse_iterator crend () const {
|
Chris@101
|
1169 return rend ();
|
Chris@101
|
1170 }
|
Chris@16
|
1171
|
Chris@16
|
1172 BOOST_UBLAS_INLINE
|
Chris@16
|
1173 basic_range preprocess (size_type size) const {
|
Chris@16
|
1174 if (this != &all_)
|
Chris@16
|
1175 return *this;
|
Chris@16
|
1176 return basic_range (0, size);
|
Chris@16
|
1177 }
|
Chris@16
|
1178 static
|
Chris@16
|
1179 BOOST_UBLAS_INLINE
|
Chris@16
|
1180 const basic_range &all () {
|
Chris@16
|
1181 return all_;
|
Chris@16
|
1182 }
|
Chris@16
|
1183
|
Chris@16
|
1184 private:
|
Chris@16
|
1185 size_type start_;
|
Chris@16
|
1186 size_type size_;
|
Chris@16
|
1187 static const basic_range all_;
|
Chris@16
|
1188 };
|
Chris@16
|
1189
|
Chris@16
|
1190 template <class Z, class D>
|
Chris@16
|
1191 const basic_range<Z,D> basic_range<Z,D>::all_ (0, size_type (-1));
|
Chris@16
|
1192
|
Chris@16
|
1193
|
Chris@16
|
1194 // Slice class
|
Chris@16
|
1195 template <class Z, class D>
|
Chris@16
|
1196 class basic_slice {
|
Chris@16
|
1197 typedef basic_slice<Z, D> self_type;
|
Chris@16
|
1198 public:
|
Chris@16
|
1199 typedef Z size_type;
|
Chris@16
|
1200 typedef D difference_type;
|
Chris@16
|
1201 typedef size_type value_type;
|
Chris@16
|
1202 typedef value_type const_reference;
|
Chris@16
|
1203 typedef const_reference reference;
|
Chris@16
|
1204 typedef const value_type *const_pointer;
|
Chris@16
|
1205 typedef value_type *pointer;
|
Chris@16
|
1206
|
Chris@16
|
1207 // Construction and destruction
|
Chris@16
|
1208 BOOST_UBLAS_INLINE
|
Chris@16
|
1209 basic_slice ():
|
Chris@16
|
1210 start_ (0), stride_ (0), size_ (0) {}
|
Chris@16
|
1211 BOOST_UBLAS_INLINE
|
Chris@16
|
1212 basic_slice (size_type start, difference_type stride, size_type size):
|
Chris@16
|
1213 start_ (start), stride_ (stride), size_ (size) {}
|
Chris@16
|
1214
|
Chris@16
|
1215 BOOST_UBLAS_INLINE
|
Chris@16
|
1216 size_type start () const {
|
Chris@16
|
1217 return start_;
|
Chris@16
|
1218 }
|
Chris@16
|
1219 BOOST_UBLAS_INLINE
|
Chris@16
|
1220 difference_type stride () const {
|
Chris@16
|
1221 return stride_;
|
Chris@16
|
1222 }
|
Chris@16
|
1223 BOOST_UBLAS_INLINE
|
Chris@16
|
1224 size_type size () const {
|
Chris@16
|
1225 return size_;
|
Chris@16
|
1226 }
|
Chris@16
|
1227
|
Chris@16
|
1228 // Random Access Container
|
Chris@16
|
1229 BOOST_UBLAS_INLINE
|
Chris@16
|
1230 size_type max_size () const {
|
Chris@16
|
1231 return size_;
|
Chris@16
|
1232 }
|
Chris@16
|
1233
|
Chris@16
|
1234 BOOST_UBLAS_INLINE
|
Chris@16
|
1235 bool empty () const {
|
Chris@16
|
1236 return size_ == 0;
|
Chris@16
|
1237 }
|
Chris@16
|
1238
|
Chris@16
|
1239 // Element access
|
Chris@16
|
1240 BOOST_UBLAS_INLINE
|
Chris@16
|
1241 const_reference operator () (size_type i) const {
|
Chris@16
|
1242 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
1243 BOOST_UBLAS_CHECK (stride_ >= 0 || start_ >= i * -stride_, bad_index ());
|
Chris@16
|
1244 return start_ + i * stride_;
|
Chris@16
|
1245 }
|
Chris@16
|
1246
|
Chris@16
|
1247 // Composition
|
Chris@16
|
1248 BOOST_UBLAS_INLINE
|
Chris@16
|
1249 basic_slice compose (const basic_range<size_type, difference_type> &r) const {
|
Chris@16
|
1250 BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * r.start(), bad_index ());
|
Chris@16
|
1251 return basic_slice (start_ + stride_ * r.start (), stride_, r.size ());
|
Chris@16
|
1252 }
|
Chris@16
|
1253 BOOST_UBLAS_INLINE
|
Chris@16
|
1254 basic_slice compose (const basic_slice &s) const {
|
Chris@16
|
1255 BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * s.start_, bad_index ());
|
Chris@16
|
1256 return basic_slice (start_ + stride_ * s.start_, stride_ * s.stride_, s.size_);
|
Chris@16
|
1257 }
|
Chris@16
|
1258
|
Chris@16
|
1259 // Comparison
|
Chris@16
|
1260 BOOST_UBLAS_INLINE
|
Chris@16
|
1261 bool operator == (const basic_slice &s) const {
|
Chris@16
|
1262 return start_ == s.start_ && stride_ == s.stride_ && size_ == s.size_;
|
Chris@16
|
1263 }
|
Chris@16
|
1264 BOOST_UBLAS_INLINE
|
Chris@16
|
1265 bool operator != (const basic_slice &s) const {
|
Chris@16
|
1266 return ! (*this == s);
|
Chris@16
|
1267 }
|
Chris@16
|
1268
|
Chris@16
|
1269 // Iterator types
|
Chris@16
|
1270 private:
|
Chris@16
|
1271 // Use and index
|
Chris@16
|
1272 typedef size_type const_subiterator_type;
|
Chris@16
|
1273
|
Chris@16
|
1274 public:
|
Chris@16
|
1275 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1276 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
|
Chris@16
|
1277 #else
|
Chris@16
|
1278 class const_iterator:
|
Chris@16
|
1279 public container_const_reference<basic_slice>,
|
Chris@16
|
1280 public random_access_iterator_base<std::random_access_iterator_tag,
|
Chris@16
|
1281 const_iterator, value_type> {
|
Chris@16
|
1282 public:
|
Chris@16
|
1283 typedef typename basic_slice::value_type value_type;
|
Chris@16
|
1284 typedef typename basic_slice::difference_type difference_type;
|
Chris@16
|
1285 typedef typename basic_slice::const_reference reference;
|
Chris@16
|
1286 typedef typename basic_slice::const_pointer pointer;
|
Chris@16
|
1287
|
Chris@16
|
1288 // Construction and destruction
|
Chris@16
|
1289 BOOST_UBLAS_INLINE
|
Chris@16
|
1290 const_iterator ():
|
Chris@16
|
1291 container_const_reference<basic_slice> (), it_ () {}
|
Chris@16
|
1292 BOOST_UBLAS_INLINE
|
Chris@16
|
1293 const_iterator (const basic_slice &s, const const_subiterator_type &it):
|
Chris@16
|
1294 container_const_reference<basic_slice> (s), it_ (it) {}
|
Chris@16
|
1295
|
Chris@16
|
1296 // Arithmetic
|
Chris@16
|
1297 BOOST_UBLAS_INLINE
|
Chris@16
|
1298 const_iterator &operator ++ () {
|
Chris@16
|
1299 ++it_;
|
Chris@16
|
1300 return *this;
|
Chris@16
|
1301 }
|
Chris@16
|
1302 BOOST_UBLAS_INLINE
|
Chris@16
|
1303 const_iterator &operator -- () {
|
Chris@16
|
1304 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
|
Chris@16
|
1305 --it_;
|
Chris@16
|
1306 return *this;
|
Chris@16
|
1307 }
|
Chris@16
|
1308 BOOST_UBLAS_INLINE
|
Chris@16
|
1309 const_iterator &operator += (difference_type n) {
|
Chris@16
|
1310 BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
|
Chris@16
|
1311 it_ += n;
|
Chris@16
|
1312 return *this;
|
Chris@16
|
1313 }
|
Chris@16
|
1314 BOOST_UBLAS_INLINE
|
Chris@16
|
1315 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
1316 BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
|
Chris@16
|
1317 it_ -= n;
|
Chris@16
|
1318 return *this;
|
Chris@16
|
1319 }
|
Chris@16
|
1320 BOOST_UBLAS_INLINE
|
Chris@16
|
1321 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
1322 return it_ - it.it_;
|
Chris@16
|
1323 }
|
Chris@16
|
1324
|
Chris@16
|
1325 // Dereference
|
Chris@16
|
1326 BOOST_UBLAS_INLINE
|
Chris@16
|
1327 const_reference operator * () const {
|
Chris@16
|
1328 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
|
Chris@16
|
1329 return (*this) ().start () + it_* (*this) ().stride ();
|
Chris@16
|
1330 }
|
Chris@16
|
1331
|
Chris@16
|
1332 BOOST_UBLAS_INLINE
|
Chris@16
|
1333 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1334 return *(*this + n);
|
Chris@16
|
1335 }
|
Chris@16
|
1336
|
Chris@16
|
1337 // Index
|
Chris@16
|
1338 BOOST_UBLAS_INLINE
|
Chris@16
|
1339 size_type index () const {
|
Chris@16
|
1340 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
|
Chris@16
|
1341 return it_;
|
Chris@16
|
1342 }
|
Chris@16
|
1343
|
Chris@16
|
1344 // Assignment
|
Chris@16
|
1345 BOOST_UBLAS_INLINE
|
Chris@16
|
1346 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
1347 // Comeau recommends...
|
Chris@16
|
1348 this->assign (&it ());
|
Chris@16
|
1349 it_ = it.it_;
|
Chris@16
|
1350 return *this;
|
Chris@16
|
1351 }
|
Chris@16
|
1352
|
Chris@16
|
1353 // Comparison
|
Chris@16
|
1354 BOOST_UBLAS_INLINE
|
Chris@16
|
1355 bool operator == (const const_iterator &it) const {
|
Chris@16
|
1356 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1357 return it_ == it.it_;
|
Chris@16
|
1358 }
|
Chris@16
|
1359 BOOST_UBLAS_INLINE
|
Chris@16
|
1360 bool operator < (const const_iterator &it) const {
|
Chris@16
|
1361 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1362 return it_ < it.it_;
|
Chris@16
|
1363 }
|
Chris@16
|
1364
|
Chris@16
|
1365 private:
|
Chris@16
|
1366 const_subiterator_type it_;
|
Chris@16
|
1367 };
|
Chris@16
|
1368 #endif
|
Chris@16
|
1369
|
Chris@16
|
1370 BOOST_UBLAS_INLINE
|
Chris@16
|
1371 const_iterator begin () const {
|
Chris@16
|
1372 return const_iterator (*this, 0);
|
Chris@16
|
1373 }
|
Chris@16
|
1374 BOOST_UBLAS_INLINE
|
Chris@101
|
1375 const_iterator cbegin () const {
|
Chris@101
|
1376 return begin ();
|
Chris@101
|
1377 }
|
Chris@101
|
1378 BOOST_UBLAS_INLINE
|
Chris@16
|
1379 const_iterator end () const {
|
Chris@16
|
1380 return const_iterator (*this, size_);
|
Chris@16
|
1381 }
|
Chris@101
|
1382 BOOST_UBLAS_INLINE
|
Chris@101
|
1383 const_iterator cend () const {
|
Chris@101
|
1384 return end ();
|
Chris@101
|
1385 }
|
Chris@16
|
1386
|
Chris@16
|
1387 // Reverse iterator
|
Chris@16
|
1388 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
1389
|
Chris@16
|
1390 BOOST_UBLAS_INLINE
|
Chris@16
|
1391 const_reverse_iterator rbegin () const {
|
Chris@16
|
1392 return const_reverse_iterator (end ());
|
Chris@16
|
1393 }
|
Chris@16
|
1394 BOOST_UBLAS_INLINE
|
Chris@101
|
1395 const_reverse_iterator crbegin () const {
|
Chris@101
|
1396 return rbegin ();
|
Chris@101
|
1397 }
|
Chris@101
|
1398 BOOST_UBLAS_INLINE
|
Chris@16
|
1399 const_reverse_iterator rend () const {
|
Chris@16
|
1400 return const_reverse_iterator (begin ());
|
Chris@16
|
1401 }
|
Chris@101
|
1402 BOOST_UBLAS_INLINE
|
Chris@101
|
1403 const_reverse_iterator crend () const {
|
Chris@101
|
1404 return rend ();
|
Chris@101
|
1405 }
|
Chris@16
|
1406
|
Chris@16
|
1407 BOOST_UBLAS_INLINE
|
Chris@16
|
1408 basic_slice preprocess (size_type size) const {
|
Chris@16
|
1409 if (this != &all_)
|
Chris@16
|
1410 return *this;
|
Chris@16
|
1411 return basic_slice (0, 1, size);
|
Chris@16
|
1412 }
|
Chris@16
|
1413 static
|
Chris@16
|
1414 BOOST_UBLAS_INLINE
|
Chris@16
|
1415 const basic_slice &all () {
|
Chris@16
|
1416 return all_;
|
Chris@16
|
1417 }
|
Chris@16
|
1418
|
Chris@16
|
1419 private:
|
Chris@16
|
1420 size_type start_;
|
Chris@16
|
1421 difference_type stride_;
|
Chris@16
|
1422 size_type size_;
|
Chris@16
|
1423 static const basic_slice all_;
|
Chris@16
|
1424 };
|
Chris@16
|
1425
|
Chris@16
|
1426 template <class Z, class D>
|
Chris@16
|
1427 const basic_slice<Z,D> basic_slice<Z,D>::all_ (0, 1, size_type (-1));
|
Chris@16
|
1428
|
Chris@16
|
1429
|
Chris@16
|
1430 // Indirect array class
|
Chris@16
|
1431 template<class A>
|
Chris@16
|
1432 class indirect_array {
|
Chris@16
|
1433 typedef indirect_array<A> self_type;
|
Chris@16
|
1434 public:
|
Chris@16
|
1435 typedef A array_type;
|
Chris@16
|
1436 typedef const A const_array_type;
|
Chris@16
|
1437 typedef typename A::size_type size_type;
|
Chris@16
|
1438 typedef typename A::difference_type difference_type;
|
Chris@16
|
1439 typedef typename A::value_type value_type;
|
Chris@16
|
1440 typedef typename A::const_reference const_reference;
|
Chris@16
|
1441 typedef typename A::reference reference;
|
Chris@16
|
1442 typedef typename A::const_pointer const_pointer;
|
Chris@16
|
1443 typedef typename A::pointer pointer;
|
Chris@16
|
1444
|
Chris@16
|
1445 // Construction and destruction
|
Chris@16
|
1446 BOOST_UBLAS_INLINE
|
Chris@16
|
1447 indirect_array ():
|
Chris@16
|
1448 size_ (), data_ () {}
|
Chris@16
|
1449 explicit BOOST_UBLAS_INLINE
|
Chris@16
|
1450 indirect_array (size_type size):
|
Chris@16
|
1451 size_ (size), data_ (size) {}
|
Chris@16
|
1452 BOOST_UBLAS_INLINE
|
Chris@16
|
1453 indirect_array (size_type size, const array_type &data):
|
Chris@16
|
1454 size_ (size), data_ (data) {}
|
Chris@16
|
1455 BOOST_UBLAS_INLINE
|
Chris@16
|
1456 indirect_array (pointer start, pointer stop):
|
Chris@16
|
1457 size_ (stop - start), data_ (stop - start) {
|
Chris@16
|
1458 std::copy (start, stop, data_.begin ());
|
Chris@16
|
1459 }
|
Chris@16
|
1460
|
Chris@16
|
1461 BOOST_UBLAS_INLINE
|
Chris@16
|
1462 size_type size () const {
|
Chris@16
|
1463 return size_;
|
Chris@16
|
1464 }
|
Chris@16
|
1465 BOOST_UBLAS_INLINE
|
Chris@16
|
1466 const_array_type data () const {
|
Chris@16
|
1467 return data_;
|
Chris@16
|
1468 }
|
Chris@16
|
1469 BOOST_UBLAS_INLINE
|
Chris@16
|
1470 array_type data () {
|
Chris@16
|
1471 return data_;
|
Chris@16
|
1472 }
|
Chris@16
|
1473
|
Chris@16
|
1474 // Random Access Container
|
Chris@16
|
1475 BOOST_UBLAS_INLINE
|
Chris@16
|
1476 size_type max_size () const {
|
Chris@16
|
1477 return size_;
|
Chris@16
|
1478 }
|
Chris@16
|
1479
|
Chris@16
|
1480 BOOST_UBLAS_INLINE
|
Chris@16
|
1481 bool empty () const {
|
Chris@16
|
1482 return data_.size () == 0;
|
Chris@16
|
1483 }
|
Chris@16
|
1484
|
Chris@16
|
1485 // Element access
|
Chris@16
|
1486 BOOST_UBLAS_INLINE
|
Chris@16
|
1487 const_reference operator () (size_type i) const {
|
Chris@16
|
1488 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
1489 return data_ [i];
|
Chris@16
|
1490 }
|
Chris@16
|
1491 BOOST_UBLAS_INLINE
|
Chris@16
|
1492 reference operator () (size_type i) {
|
Chris@16
|
1493 BOOST_UBLAS_CHECK (i < size_, bad_index ());
|
Chris@16
|
1494 return data_ [i];
|
Chris@16
|
1495 }
|
Chris@16
|
1496
|
Chris@16
|
1497 BOOST_UBLAS_INLINE
|
Chris@16
|
1498 const_reference operator [] (size_type i) const {
|
Chris@16
|
1499 return (*this) (i);
|
Chris@16
|
1500 }
|
Chris@16
|
1501 BOOST_UBLAS_INLINE
|
Chris@16
|
1502 reference operator [] (size_type i) {
|
Chris@16
|
1503 return (*this) (i);
|
Chris@16
|
1504 }
|
Chris@16
|
1505
|
Chris@16
|
1506 // Composition
|
Chris@16
|
1507 BOOST_UBLAS_INLINE
|
Chris@16
|
1508 indirect_array compose (const basic_range<size_type, difference_type> &r) const {
|
Chris@16
|
1509 BOOST_UBLAS_CHECK (r.start () + r.size () <= size_, bad_size ());
|
Chris@16
|
1510 array_type data (r.size ());
|
Chris@16
|
1511 for (size_type i = 0; i < r.size (); ++ i)
|
Chris@16
|
1512 data [i] = data_ [r.start () + i];
|
Chris@16
|
1513 return indirect_array (r.size (), data);
|
Chris@16
|
1514 }
|
Chris@16
|
1515 BOOST_UBLAS_INLINE
|
Chris@16
|
1516 indirect_array compose (const basic_slice<size_type, difference_type> &s) const {
|
Chris@16
|
1517 BOOST_UBLAS_CHECK (s.start () + s.stride () * (s.size () - (s.size () > 0)) <= size (), bad_size ());
|
Chris@16
|
1518 array_type data (s.size ());
|
Chris@16
|
1519 for (size_type i = 0; i < s.size (); ++ i)
|
Chris@16
|
1520 data [i] = data_ [s.start () + s.stride () * i];
|
Chris@16
|
1521 return indirect_array (s.size (), data);
|
Chris@16
|
1522 }
|
Chris@16
|
1523 BOOST_UBLAS_INLINE
|
Chris@16
|
1524 indirect_array compose (const indirect_array &ia) const {
|
Chris@16
|
1525 array_type data (ia.size_);
|
Chris@16
|
1526 for (size_type i = 0; i < ia.size_; ++ i) {
|
Chris@16
|
1527 BOOST_UBLAS_CHECK (ia.data_ [i] <= size_, bad_size ());
|
Chris@16
|
1528 data [i] = data_ [ia.data_ [i]];
|
Chris@16
|
1529 }
|
Chris@16
|
1530 return indirect_array (ia.size_, data);
|
Chris@16
|
1531 }
|
Chris@16
|
1532
|
Chris@16
|
1533 // Comparison
|
Chris@16
|
1534 template<class OA>
|
Chris@16
|
1535 BOOST_UBLAS_INLINE
|
Chris@16
|
1536 bool operator == (const indirect_array<OA> &ia) const {
|
Chris@16
|
1537 if (size_ != ia.size_)
|
Chris@16
|
1538 return false;
|
Chris@16
|
1539 for (size_type i = 0; i < BOOST_UBLAS_SAME (size_, ia.size_); ++ i)
|
Chris@16
|
1540 if (data_ [i] != ia.data_ [i])
|
Chris@16
|
1541 return false;
|
Chris@16
|
1542 return true;
|
Chris@16
|
1543 }
|
Chris@16
|
1544 template<class OA>
|
Chris@16
|
1545 BOOST_UBLAS_INLINE
|
Chris@16
|
1546 bool operator != (const indirect_array<OA> &ia) const {
|
Chris@16
|
1547 return ! (*this == ia);
|
Chris@16
|
1548 }
|
Chris@16
|
1549
|
Chris@16
|
1550 // Iterator types
|
Chris@16
|
1551 private:
|
Chris@16
|
1552 // Use a index difference
|
Chris@16
|
1553 typedef difference_type const_subiterator_type;
|
Chris@16
|
1554
|
Chris@16
|
1555 public:
|
Chris@16
|
1556 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
Chris@16
|
1557 typedef indexed_const_iterator<indirect_array, std::random_access_iterator_tag> const_iterator;
|
Chris@16
|
1558 #else
|
Chris@16
|
1559 class const_iterator:
|
Chris@16
|
1560 public container_const_reference<indirect_array>,
|
Chris@16
|
1561 public random_access_iterator_base<std::random_access_iterator_tag,
|
Chris@16
|
1562 const_iterator, value_type> {
|
Chris@16
|
1563 public:
|
Chris@16
|
1564 typedef typename indirect_array::value_type value_type;
|
Chris@16
|
1565 typedef typename indirect_array::difference_type difference_type;
|
Chris@16
|
1566 typedef typename indirect_array::const_reference reference;
|
Chris@16
|
1567 typedef typename indirect_array::const_pointer pointer;
|
Chris@16
|
1568
|
Chris@16
|
1569 // Construction and destruction
|
Chris@16
|
1570 BOOST_UBLAS_INLINE
|
Chris@16
|
1571 const_iterator ():
|
Chris@16
|
1572 container_const_reference<indirect_array> (), it_ () {}
|
Chris@16
|
1573 BOOST_UBLAS_INLINE
|
Chris@16
|
1574 const_iterator (const indirect_array &ia, const const_subiterator_type &it):
|
Chris@16
|
1575 container_const_reference<indirect_array> (ia), it_ (it) {}
|
Chris@16
|
1576
|
Chris@16
|
1577 // Arithmetic
|
Chris@16
|
1578 BOOST_UBLAS_INLINE
|
Chris@16
|
1579 const_iterator &operator ++ () {
|
Chris@16
|
1580 ++ it_;
|
Chris@16
|
1581 return *this;
|
Chris@16
|
1582 }
|
Chris@16
|
1583 BOOST_UBLAS_INLINE
|
Chris@16
|
1584 const_iterator &operator -- () {
|
Chris@16
|
1585 -- it_;
|
Chris@16
|
1586 return *this;
|
Chris@16
|
1587 }
|
Chris@16
|
1588 BOOST_UBLAS_INLINE
|
Chris@16
|
1589 const_iterator &operator += (difference_type n) {
|
Chris@16
|
1590 it_ += n;
|
Chris@16
|
1591 return *this;
|
Chris@16
|
1592 }
|
Chris@16
|
1593 BOOST_UBLAS_INLINE
|
Chris@16
|
1594 const_iterator &operator -= (difference_type n) {
|
Chris@16
|
1595 it_ -= n;
|
Chris@16
|
1596 return *this;
|
Chris@16
|
1597 }
|
Chris@16
|
1598 BOOST_UBLAS_INLINE
|
Chris@16
|
1599 difference_type operator - (const const_iterator &it) const {
|
Chris@16
|
1600 return it_ - it.it_;
|
Chris@16
|
1601 }
|
Chris@16
|
1602
|
Chris@16
|
1603 // Dereference
|
Chris@16
|
1604 BOOST_UBLAS_INLINE
|
Chris@16
|
1605 const_reference operator * () const {
|
Chris@16
|
1606 return (*this) () (it_);
|
Chris@16
|
1607 }
|
Chris@16
|
1608
|
Chris@16
|
1609 BOOST_UBLAS_INLINE
|
Chris@16
|
1610 const_reference operator [] (difference_type n) const {
|
Chris@16
|
1611 return *(*this + n);
|
Chris@16
|
1612 }
|
Chris@16
|
1613
|
Chris@16
|
1614 // Index
|
Chris@16
|
1615 BOOST_UBLAS_INLINE
|
Chris@16
|
1616 size_type index () const {
|
Chris@16
|
1617 return it_;
|
Chris@16
|
1618 }
|
Chris@16
|
1619
|
Chris@16
|
1620 // Assignment
|
Chris@16
|
1621 BOOST_UBLAS_INLINE
|
Chris@16
|
1622 const_iterator &operator = (const const_iterator &it) {
|
Chris@16
|
1623 // Comeau recommends...
|
Chris@16
|
1624 this->assign (&it ());
|
Chris@16
|
1625 it_ = it.it_;
|
Chris@16
|
1626 return *this;
|
Chris@16
|
1627 }
|
Chris@16
|
1628
|
Chris@16
|
1629 // Comparison
|
Chris@16
|
1630 BOOST_UBLAS_INLINE
|
Chris@16
|
1631 bool operator == (const const_iterator &it) const {
|
Chris@16
|
1632 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1633 return it_ == it.it_;
|
Chris@16
|
1634 }
|
Chris@16
|
1635 BOOST_UBLAS_INLINE
|
Chris@16
|
1636 bool operator < (const const_iterator &it) const {
|
Chris@16
|
1637 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
|
Chris@16
|
1638 return it_ < it.it_;
|
Chris@16
|
1639 }
|
Chris@16
|
1640
|
Chris@16
|
1641 private:
|
Chris@16
|
1642 const_subiterator_type it_;
|
Chris@16
|
1643 };
|
Chris@16
|
1644 #endif
|
Chris@16
|
1645
|
Chris@16
|
1646 BOOST_UBLAS_INLINE
|
Chris@16
|
1647 const_iterator begin () const {
|
Chris@16
|
1648 return const_iterator (*this, 0);
|
Chris@16
|
1649 }
|
Chris@16
|
1650 BOOST_UBLAS_INLINE
|
Chris@101
|
1651 const_iterator cbegin () const {
|
Chris@101
|
1652 return begin ();
|
Chris@101
|
1653 }
|
Chris@101
|
1654 BOOST_UBLAS_INLINE
|
Chris@16
|
1655 const_iterator end () const {
|
Chris@16
|
1656 return const_iterator (*this, size_);
|
Chris@16
|
1657 }
|
Chris@101
|
1658 BOOST_UBLAS_INLINE
|
Chris@101
|
1659 const_iterator cend () const {
|
Chris@101
|
1660 return end ();
|
Chris@101
|
1661 }
|
Chris@16
|
1662
|
Chris@16
|
1663 // Reverse iterator
|
Chris@16
|
1664 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
1665
|
Chris@16
|
1666 BOOST_UBLAS_INLINE
|
Chris@16
|
1667 const_reverse_iterator rbegin () const {
|
Chris@16
|
1668 return const_reverse_iterator (end ());
|
Chris@16
|
1669 }
|
Chris@16
|
1670 BOOST_UBLAS_INLINE
|
Chris@101
|
1671 const_reverse_iterator crbegin () const {
|
Chris@101
|
1672 return rbegin ();
|
Chris@101
|
1673 }
|
Chris@101
|
1674 BOOST_UBLAS_INLINE
|
Chris@16
|
1675 const_reverse_iterator rend () const {
|
Chris@16
|
1676 return const_reverse_iterator (begin ());
|
Chris@16
|
1677 }
|
Chris@101
|
1678 BOOST_UBLAS_INLINE
|
Chris@101
|
1679 const_reverse_iterator crend () const {
|
Chris@101
|
1680 return rend ();
|
Chris@101
|
1681 }
|
Chris@16
|
1682
|
Chris@16
|
1683 BOOST_UBLAS_INLINE
|
Chris@16
|
1684 indirect_array preprocess (size_type size) const {
|
Chris@16
|
1685 if (this != &all_)
|
Chris@16
|
1686 return *this;
|
Chris@16
|
1687 indirect_array ia (size);
|
Chris@16
|
1688 for (size_type i = 0; i < size; ++ i)
|
Chris@16
|
1689 ia (i) = i;
|
Chris@16
|
1690 return ia;
|
Chris@16
|
1691 }
|
Chris@16
|
1692 static
|
Chris@16
|
1693 BOOST_UBLAS_INLINE
|
Chris@16
|
1694 const indirect_array &all () {
|
Chris@16
|
1695 return all_;
|
Chris@16
|
1696 }
|
Chris@16
|
1697
|
Chris@16
|
1698 private:
|
Chris@16
|
1699 size_type size_;
|
Chris@16
|
1700 array_type data_;
|
Chris@16
|
1701 static const indirect_array all_;
|
Chris@16
|
1702 };
|
Chris@16
|
1703
|
Chris@16
|
1704 template<class A>
|
Chris@16
|
1705 const indirect_array<A> indirect_array<A>::all_;
|
Chris@16
|
1706
|
Chris@16
|
1707
|
Chris@16
|
1708
|
Chris@16
|
1709 // Gunter Winkler contributed the classes index_pair, index_pair_array,
|
Chris@16
|
1710 // index_triple and index_triple_array to enable inplace sort of parallel arrays.
|
Chris@16
|
1711
|
Chris@16
|
1712 template <class V>
|
Chris@16
|
1713 class index_pair :
|
Chris@16
|
1714 public container_reference<V> {
|
Chris@16
|
1715
|
Chris@16
|
1716 typedef index_pair<V> self_type;
|
Chris@16
|
1717 public:
|
Chris@16
|
1718 typedef typename V::size_type size_type;
|
Chris@16
|
1719
|
Chris@16
|
1720 BOOST_UBLAS_INLINE
|
Chris@16
|
1721 index_pair(V& v, size_type i) :
|
Chris@16
|
1722 container_reference<V>(v), i_(i),
|
Chris@16
|
1723 v1_(v.data1_[i]), v2_(v.data2_[i]),
|
Chris@16
|
1724 dirty_(false), is_copy_(false) {}
|
Chris@16
|
1725 BOOST_UBLAS_INLINE
|
Chris@16
|
1726 index_pair(const self_type& rhs) :
|
Chris@16
|
1727 container_reference<V>(rhs()), i_(0),
|
Chris@16
|
1728 v1_(rhs.v1_), v2_(rhs.v2_),
|
Chris@16
|
1729 dirty_(false), is_copy_(true) {}
|
Chris@16
|
1730 BOOST_UBLAS_INLINE
|
Chris@16
|
1731 ~index_pair() {
|
Chris@16
|
1732 if (dirty_ && (!is_copy_) ) {
|
Chris@16
|
1733 (*this)().data1_[i_] = v1_;
|
Chris@16
|
1734 (*this)().data2_[i_] = v2_;
|
Chris@16
|
1735 }
|
Chris@16
|
1736 }
|
Chris@16
|
1737
|
Chris@16
|
1738 BOOST_UBLAS_INLINE
|
Chris@16
|
1739 self_type& operator=(const self_type& rhs) {
|
Chris@16
|
1740 v1_ = rhs.v1_;
|
Chris@16
|
1741 v2_ = rhs.v2_;
|
Chris@16
|
1742 dirty_ = true;
|
Chris@16
|
1743 return *this;
|
Chris@16
|
1744 }
|
Chris@16
|
1745
|
Chris@16
|
1746 BOOST_UBLAS_INLINE
|
Chris@16
|
1747 void swap(self_type& rhs) {
|
Chris@16
|
1748 self_type tmp(rhs);
|
Chris@16
|
1749 rhs = *this;
|
Chris@16
|
1750 *this = tmp;
|
Chris@16
|
1751 }
|
Chris@101
|
1752
|
Chris@16
|
1753 BOOST_UBLAS_INLINE
|
Chris@16
|
1754 friend void swap(self_type& lhs, self_type& rhs) {
|
Chris@16
|
1755 lhs.swap(rhs);
|
Chris@16
|
1756 }
|
Chris@16
|
1757
|
Chris@101
|
1758 friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
|
Chris@101
|
1759 lhs.swap(rhs);
|
Chris@101
|
1760 }
|
Chris@101
|
1761
|
Chris@101
|
1762
|
Chris@16
|
1763 BOOST_UBLAS_INLINE
|
Chris@16
|
1764 bool equal(const self_type& rhs) const {
|
Chris@16
|
1765 return (v1_ == rhs.v1_);
|
Chris@16
|
1766 }
|
Chris@16
|
1767 BOOST_UBLAS_INLINE
|
Chris@16
|
1768 bool less(const self_type& rhs) const {
|
Chris@16
|
1769 return (v1_ < rhs.v1_);
|
Chris@16
|
1770 }
|
Chris@16
|
1771 BOOST_UBLAS_INLINE
|
Chris@16
|
1772 friend bool operator == (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1773 return lhs.equal(rhs);
|
Chris@16
|
1774 }
|
Chris@16
|
1775 BOOST_UBLAS_INLINE
|
Chris@16
|
1776 friend bool operator != (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1777 return !lhs.equal(rhs);
|
Chris@16
|
1778 }
|
Chris@16
|
1779 BOOST_UBLAS_INLINE
|
Chris@16
|
1780 friend bool operator < (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1781 return lhs.less(rhs);
|
Chris@16
|
1782 }
|
Chris@16
|
1783 BOOST_UBLAS_INLINE
|
Chris@16
|
1784 friend bool operator >= (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1785 return !lhs.less(rhs);
|
Chris@16
|
1786 }
|
Chris@16
|
1787 BOOST_UBLAS_INLINE
|
Chris@16
|
1788 friend bool operator > (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1789 return rhs.less(lhs);
|
Chris@16
|
1790 }
|
Chris@16
|
1791 BOOST_UBLAS_INLINE
|
Chris@16
|
1792 friend bool operator <= (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1793 return !rhs.less(lhs);
|
Chris@16
|
1794 }
|
Chris@16
|
1795
|
Chris@16
|
1796 private:
|
Chris@16
|
1797 size_type i_;
|
Chris@16
|
1798 typename V::value1_type v1_;
|
Chris@16
|
1799 typename V::value2_type v2_;
|
Chris@16
|
1800 bool dirty_;
|
Chris@16
|
1801 bool is_copy_;
|
Chris@16
|
1802 };
|
Chris@16
|
1803
|
Chris@16
|
1804 template <class V1, class V2>
|
Chris@16
|
1805 class index_pair_array:
|
Chris@16
|
1806 private boost::noncopyable {
|
Chris@16
|
1807
|
Chris@16
|
1808 typedef index_pair_array<V1, V2> self_type;
|
Chris@16
|
1809 public:
|
Chris@16
|
1810 typedef typename V1::value_type value1_type;
|
Chris@16
|
1811 typedef typename V2::value_type value2_type;
|
Chris@16
|
1812
|
Chris@16
|
1813 typedef typename V1::size_type size_type;
|
Chris@16
|
1814 typedef typename V1::difference_type difference_type;
|
Chris@16
|
1815 typedef index_pair<self_type> value_type;
|
Chris@16
|
1816 // There is nothing that can be referenced directly. Always return a copy of the index_pair
|
Chris@16
|
1817 typedef value_type reference;
|
Chris@16
|
1818 typedef const value_type const_reference;
|
Chris@16
|
1819
|
Chris@16
|
1820 BOOST_UBLAS_INLINE
|
Chris@16
|
1821 index_pair_array(size_type size, V1& data1, V2& data2) :
|
Chris@16
|
1822 size_(size),data1_(data1),data2_(data2) {}
|
Chris@16
|
1823
|
Chris@16
|
1824 BOOST_UBLAS_INLINE
|
Chris@16
|
1825 size_type size() const {
|
Chris@16
|
1826 return size_;
|
Chris@16
|
1827 }
|
Chris@16
|
1828
|
Chris@16
|
1829 BOOST_UBLAS_INLINE
|
Chris@16
|
1830 const_reference operator () (size_type i) const {
|
Chris@16
|
1831 return value_type((*this), i);
|
Chris@16
|
1832 }
|
Chris@16
|
1833 BOOST_UBLAS_INLINE
|
Chris@16
|
1834 reference operator () (size_type i) {
|
Chris@16
|
1835 return value_type((*this), i);
|
Chris@16
|
1836 }
|
Chris@16
|
1837
|
Chris@16
|
1838 typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
|
Chris@16
|
1839 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
|
Chris@16
|
1840
|
Chris@16
|
1841 BOOST_UBLAS_INLINE
|
Chris@16
|
1842 iterator begin() {
|
Chris@16
|
1843 return iterator( (*this), 0);
|
Chris@16
|
1844 }
|
Chris@16
|
1845 BOOST_UBLAS_INLINE
|
Chris@16
|
1846 iterator end() {
|
Chris@16
|
1847 return iterator( (*this), size());
|
Chris@16
|
1848 }
|
Chris@16
|
1849
|
Chris@16
|
1850 BOOST_UBLAS_INLINE
|
Chris@16
|
1851 const_iterator begin() const {
|
Chris@16
|
1852 return const_iterator( (*this), 0);
|
Chris@16
|
1853 }
|
Chris@16
|
1854 BOOST_UBLAS_INLINE
|
Chris@101
|
1855 const_iterator cbegin () const {
|
Chris@101
|
1856 return begin ();
|
Chris@101
|
1857 }
|
Chris@101
|
1858 BOOST_UBLAS_INLINE
|
Chris@16
|
1859 const_iterator end() const {
|
Chris@16
|
1860 return const_iterator( (*this), size());
|
Chris@16
|
1861 }
|
Chris@101
|
1862 BOOST_UBLAS_INLINE
|
Chris@101
|
1863 const_iterator cend () const {
|
Chris@101
|
1864 return end ();
|
Chris@101
|
1865 }
|
Chris@16
|
1866
|
Chris@16
|
1867 // unnecessary function:
|
Chris@16
|
1868 BOOST_UBLAS_INLINE
|
Chris@16
|
1869 bool equal(size_type i1, size_type i2) const {
|
Chris@16
|
1870 return data1_[i1] == data1_[i2];
|
Chris@16
|
1871 }
|
Chris@16
|
1872 BOOST_UBLAS_INLINE
|
Chris@16
|
1873 bool less(size_type i1, size_type i2) const {
|
Chris@16
|
1874 return data1_[i1] < data1_[i2];
|
Chris@16
|
1875 }
|
Chris@16
|
1876
|
Chris@16
|
1877 // gives a large speedup
|
Chris@16
|
1878 BOOST_UBLAS_INLINE
|
Chris@16
|
1879 friend void iter_swap(const iterator& lhs, const iterator& rhs) {
|
Chris@16
|
1880 const size_type i1 = lhs.index();
|
Chris@16
|
1881 const size_type i2 = rhs.index();
|
Chris@16
|
1882 std::swap(lhs().data1_[i1], rhs().data1_[i2]);
|
Chris@16
|
1883 std::swap(lhs().data2_[i1], rhs().data2_[i2]);
|
Chris@16
|
1884 }
|
Chris@16
|
1885
|
Chris@16
|
1886 private:
|
Chris@16
|
1887 size_type size_;
|
Chris@16
|
1888 V1& data1_;
|
Chris@16
|
1889 V2& data2_;
|
Chris@16
|
1890
|
Chris@16
|
1891 // friend class value_type;
|
Chris@16
|
1892 friend class index_pair<self_type>;
|
Chris@16
|
1893 };
|
Chris@16
|
1894
|
Chris@16
|
1895 template <class M>
|
Chris@16
|
1896 class index_triple :
|
Chris@16
|
1897 public container_reference<M> {
|
Chris@16
|
1898
|
Chris@16
|
1899 typedef index_triple<M> self_type;
|
Chris@16
|
1900 public:
|
Chris@16
|
1901 typedef typename M::size_type size_type;
|
Chris@16
|
1902
|
Chris@16
|
1903 BOOST_UBLAS_INLINE
|
Chris@16
|
1904 index_triple(M& m, size_type i) :
|
Chris@16
|
1905 container_reference<M>(m), i_(i),
|
Chris@16
|
1906 v1_(m.data1_[i]), v2_(m.data2_[i]), v3_(m.data3_[i]),
|
Chris@16
|
1907 dirty_(false), is_copy_(false) {}
|
Chris@16
|
1908 BOOST_UBLAS_INLINE
|
Chris@16
|
1909 index_triple(const self_type& rhs) :
|
Chris@16
|
1910 container_reference<M>(rhs()), i_(0),
|
Chris@16
|
1911 v1_(rhs.v1_), v2_(rhs.v2_), v3_(rhs.v3_),
|
Chris@16
|
1912 dirty_(false), is_copy_(true) {}
|
Chris@16
|
1913 BOOST_UBLAS_INLINE
|
Chris@16
|
1914 ~index_triple() {
|
Chris@16
|
1915 if (dirty_ && (!is_copy_) ) {
|
Chris@16
|
1916 (*this)().data1_[i_] = v1_;
|
Chris@16
|
1917 (*this)().data2_[i_] = v2_;
|
Chris@16
|
1918 (*this)().data3_[i_] = v3_;
|
Chris@16
|
1919 }
|
Chris@16
|
1920 }
|
Chris@16
|
1921
|
Chris@16
|
1922 BOOST_UBLAS_INLINE
|
Chris@16
|
1923 self_type& operator=(const self_type& rhs) {
|
Chris@16
|
1924 v1_ = rhs.v1_;
|
Chris@16
|
1925 v2_ = rhs.v2_;
|
Chris@16
|
1926 v3_ = rhs.v3_;
|
Chris@16
|
1927 dirty_ = true;
|
Chris@16
|
1928 return *this;
|
Chris@16
|
1929 }
|
Chris@16
|
1930
|
Chris@16
|
1931 BOOST_UBLAS_INLINE
|
Chris@16
|
1932 void swap(self_type& rhs) {
|
Chris@16
|
1933 self_type tmp(rhs);
|
Chris@16
|
1934 rhs = *this;
|
Chris@16
|
1935 *this = tmp;
|
Chris@16
|
1936 }
|
Chris@101
|
1937
|
Chris@16
|
1938 BOOST_UBLAS_INLINE
|
Chris@16
|
1939 friend void swap(self_type& lhs, self_type& rhs) {
|
Chris@16
|
1940 lhs.swap(rhs);
|
Chris@16
|
1941 }
|
Chris@16
|
1942
|
Chris@101
|
1943 friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
|
Chris@101
|
1944 lhs.swap(rhs);
|
Chris@101
|
1945 }
|
Chris@101
|
1946
|
Chris@16
|
1947 BOOST_UBLAS_INLINE
|
Chris@16
|
1948 bool equal(const self_type& rhs) const {
|
Chris@16
|
1949 return ((v1_ == rhs.v1_) && (v2_ == rhs.v2_));
|
Chris@16
|
1950 }
|
Chris@16
|
1951 BOOST_UBLAS_INLINE
|
Chris@16
|
1952 bool less(const self_type& rhs) const {
|
Chris@16
|
1953 return ((v1_ < rhs.v1_) ||
|
Chris@16
|
1954 (v1_ == rhs.v1_ && v2_ < rhs.v2_));
|
Chris@16
|
1955 }
|
Chris@16
|
1956 BOOST_UBLAS_INLINE
|
Chris@16
|
1957 friend bool operator == (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1958 return lhs.equal(rhs);
|
Chris@16
|
1959 }
|
Chris@16
|
1960 BOOST_UBLAS_INLINE
|
Chris@16
|
1961 friend bool operator != (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1962 return !lhs.equal(rhs);
|
Chris@16
|
1963 }
|
Chris@16
|
1964 BOOST_UBLAS_INLINE
|
Chris@16
|
1965 friend bool operator < (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1966 return lhs.less(rhs);
|
Chris@16
|
1967 }
|
Chris@16
|
1968 BOOST_UBLAS_INLINE
|
Chris@16
|
1969 friend bool operator >= (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1970 return !lhs.less(rhs);
|
Chris@16
|
1971 }
|
Chris@16
|
1972 BOOST_UBLAS_INLINE
|
Chris@16
|
1973 friend bool operator > (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1974 return rhs.less(lhs);
|
Chris@16
|
1975 }
|
Chris@16
|
1976 BOOST_UBLAS_INLINE
|
Chris@16
|
1977 friend bool operator <= (const self_type& lhs, const self_type& rhs) {
|
Chris@16
|
1978 return !rhs.less(lhs);
|
Chris@16
|
1979 }
|
Chris@16
|
1980
|
Chris@16
|
1981 private:
|
Chris@16
|
1982 size_type i_;
|
Chris@16
|
1983 typename M::value1_type v1_;
|
Chris@16
|
1984 typename M::value2_type v2_;
|
Chris@16
|
1985 typename M::value3_type v3_;
|
Chris@16
|
1986 bool dirty_;
|
Chris@16
|
1987 bool is_copy_;
|
Chris@16
|
1988 };
|
Chris@16
|
1989
|
Chris@16
|
1990 template <class V1, class V2, class V3>
|
Chris@16
|
1991 class index_triple_array:
|
Chris@16
|
1992 private boost::noncopyable {
|
Chris@16
|
1993
|
Chris@16
|
1994 typedef index_triple_array<V1, V2, V3> self_type;
|
Chris@16
|
1995 public:
|
Chris@16
|
1996 typedef typename V1::value_type value1_type;
|
Chris@16
|
1997 typedef typename V2::value_type value2_type;
|
Chris@16
|
1998 typedef typename V3::value_type value3_type;
|
Chris@16
|
1999
|
Chris@16
|
2000 typedef typename V1::size_type size_type;
|
Chris@16
|
2001 typedef typename V1::difference_type difference_type;
|
Chris@16
|
2002 typedef index_triple<self_type> value_type;
|
Chris@16
|
2003 // There is nothing that can be referenced directly. Always return a copy of the index_triple
|
Chris@16
|
2004 typedef value_type reference;
|
Chris@16
|
2005 typedef const value_type const_reference;
|
Chris@16
|
2006
|
Chris@16
|
2007 BOOST_UBLAS_INLINE
|
Chris@16
|
2008 index_triple_array(size_type size, V1& data1, V2& data2, V3& data3) :
|
Chris@16
|
2009 size_(size),data1_(data1),data2_(data2),data3_(data3) {}
|
Chris@16
|
2010
|
Chris@16
|
2011 BOOST_UBLAS_INLINE
|
Chris@16
|
2012 size_type size() const {
|
Chris@16
|
2013 return size_;
|
Chris@16
|
2014 }
|
Chris@16
|
2015
|
Chris@16
|
2016 BOOST_UBLAS_INLINE
|
Chris@16
|
2017 const_reference operator () (size_type i) const {
|
Chris@16
|
2018 return value_type((*this), i);
|
Chris@16
|
2019 }
|
Chris@16
|
2020 BOOST_UBLAS_INLINE
|
Chris@16
|
2021 reference operator () (size_type i) {
|
Chris@16
|
2022 return value_type((*this), i);
|
Chris@16
|
2023 }
|
Chris@16
|
2024
|
Chris@16
|
2025 typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
|
Chris@16
|
2026 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
|
Chris@16
|
2027
|
Chris@16
|
2028 BOOST_UBLAS_INLINE
|
Chris@16
|
2029 iterator begin() {
|
Chris@16
|
2030 return iterator( (*this), 0);
|
Chris@16
|
2031 }
|
Chris@16
|
2032 BOOST_UBLAS_INLINE
|
Chris@16
|
2033 iterator end() {
|
Chris@16
|
2034 return iterator( (*this), size());
|
Chris@16
|
2035 }
|
Chris@16
|
2036
|
Chris@16
|
2037 BOOST_UBLAS_INLINE
|
Chris@16
|
2038 const_iterator begin() const {
|
Chris@16
|
2039 return const_iterator( (*this), 0);
|
Chris@16
|
2040 }
|
Chris@16
|
2041 BOOST_UBLAS_INLINE
|
Chris@101
|
2042 const_iterator cbegin () const {
|
Chris@101
|
2043 return begin ();
|
Chris@101
|
2044 }
|
Chris@101
|
2045 BOOST_UBLAS_INLINE
|
Chris@16
|
2046 const_iterator end() const {
|
Chris@16
|
2047 return const_iterator( (*this), size());
|
Chris@16
|
2048 }
|
Chris@101
|
2049 BOOST_UBLAS_INLINE
|
Chris@101
|
2050 const_iterator cend () const {
|
Chris@101
|
2051 return end ();
|
Chris@101
|
2052 }
|
Chris@16
|
2053
|
Chris@16
|
2054 // unnecessary function:
|
Chris@16
|
2055 BOOST_UBLAS_INLINE
|
Chris@16
|
2056 bool equal(size_type i1, size_type i2) const {
|
Chris@16
|
2057 return ((data1_[i1] == data1_[i2]) && (data2_[i1] == data2_[i2]));
|
Chris@16
|
2058 }
|
Chris@16
|
2059 BOOST_UBLAS_INLINE
|
Chris@16
|
2060 bool less(size_type i1, size_type i2) const {
|
Chris@16
|
2061 return ((data1_[i1] < data1_[i2]) ||
|
Chris@16
|
2062 (data1_[i1] == data1_[i2] && data2_[i1] < data2_[i2]));
|
Chris@16
|
2063 }
|
Chris@16
|
2064
|
Chris@16
|
2065 // gives a large speedup
|
Chris@16
|
2066 BOOST_UBLAS_INLINE
|
Chris@16
|
2067 friend void iter_swap(const iterator& lhs, const iterator& rhs) {
|
Chris@16
|
2068 const size_type i1 = lhs.index();
|
Chris@16
|
2069 const size_type i2 = rhs.index();
|
Chris@16
|
2070 std::swap(lhs().data1_[i1], rhs().data1_[i2]);
|
Chris@16
|
2071 std::swap(lhs().data2_[i1], rhs().data2_[i2]);
|
Chris@16
|
2072 std::swap(lhs().data3_[i1], rhs().data3_[i2]);
|
Chris@16
|
2073 }
|
Chris@16
|
2074
|
Chris@16
|
2075 private:
|
Chris@16
|
2076 size_type size_;
|
Chris@16
|
2077 V1& data1_;
|
Chris@16
|
2078 V2& data2_;
|
Chris@16
|
2079 V3& data3_;
|
Chris@16
|
2080
|
Chris@16
|
2081 // friend class value_type;
|
Chris@16
|
2082 friend class index_triple<self_type>;
|
Chris@16
|
2083 };
|
Chris@16
|
2084
|
Chris@16
|
2085 }}}
|
Chris@16
|
2086
|
Chris@16
|
2087 #endif
|