annotate DEPENDENCIES/generic/include/boost/numeric/ublas/storage.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
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