00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef BOOST_UBLAS_STORAGE_H
00018 #define BOOST_UBLAS_STORAGE_H
00019
00020 #include <algorithm>
00021 #ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
00022 #include <boost/shared_array.hpp>
00023 #endif
00024
00025 #include <boost/serialization/binary_object.hpp>
00026 #include <boost/serialization/nvp.hpp>
00027 #include <boost/serialization/split_member.hpp>
00028
00029 #include <boost/numeric/ublas/exception.hpp>
00030 #include <boost/numeric/ublas/detail/iterator.hpp>
00031
00032
00033 namespace boost { namespace numeric { namespace ublas {
00034
00035
00036
00037 template<class E>
00038 class storage_array:
00039 private nonassignable {
00040 };
00041
00042
00043
00044 template<class T, class ALLOC>
00045 class unbounded_array:
00046 public storage_array<unbounded_array<T, ALLOC> > {
00047
00048 typedef unbounded_array<T, ALLOC> self_type;
00049 public:
00050 typedef ALLOC allocator_type;
00051 typedef typename ALLOC::size_type size_type;
00052 typedef typename ALLOC::difference_type difference_type;
00053 typedef T value_type;
00054 typedef const T &const_reference;
00055 typedef T &reference;
00056 typedef const T *const_pointer;
00057 typedef T *pointer;
00058 typedef const_pointer const_iterator;
00059 typedef pointer iterator;
00060
00061
00062 explicit BOOST_UBLAS_INLINE
00063 unbounded_array (const ALLOC &a = ALLOC()):
00064 alloc_ (a), size_ (0), data_ (0) {
00065 }
00066 explicit BOOST_UBLAS_INLINE
00067 unbounded_array (size_type size, const ALLOC &a = ALLOC()):
00068 alloc_(a), size_ (size) {
00069 if (size_) {
00070 data_ = alloc_.allocate (size_);
00071
00072 #ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
00073
00074 new (data_) value_type[size_];
00075 #else
00076 for (pointer d = data_; d != data_ + size_; ++d)
00077 new (d) value_type;
00078 #endif
00079 }
00080 }
00081
00082 BOOST_UBLAS_INLINE
00083 unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()):
00084 alloc_ (a), size_ (size) {
00085 if (size_) {
00086 data_ = alloc_.allocate (size_);
00087 std::uninitialized_fill (begin(), end(), init);
00088 }
00089 }
00090 BOOST_UBLAS_INLINE
00091 unbounded_array (const unbounded_array &c):
00092 storage_array<self_type> (),
00093 alloc_ (c.alloc_), size_ (c.size_) {
00094 if (size_) {
00095 data_ = alloc_.allocate (size_);
00096 std::uninitialized_copy (c.begin(), c.end(), begin());
00097 }
00098 else
00099 data_ = 0;
00100 }
00101 BOOST_UBLAS_INLINE
00102 ~unbounded_array () {
00103 if (size_) {
00104 const iterator i_end = end();
00105 for (iterator i = begin (); i != i_end; ++i) {
00106 iterator_destroy (i);
00107 }
00108 alloc_.deallocate (data_, size_);
00109 }
00110 }
00111
00112
00113 private:
00114 friend class boost::serialization::access;
00115 template<class Archive>
00116 void save(Archive & ar, const unsigned int version) const
00117 {
00118 ar & BOOST_SERIALIZATION_NVP(size_);
00119 ar & boost::serialization::make_nvp("data", boost::serialization::make_binary_object(data_, size_*sizeof(value_type)));
00120 }
00121 template<class Archive>
00122 void load(Archive & ar, const unsigned int version)
00123 {
00124 size_type new_size;
00125 ar & BOOST_SERIALIZATION_NVP(new_size);
00126 resize_internal(new_size, value_type(), false);
00127 ar & boost::serialization::make_nvp("data", boost::serialization::make_binary_object(data_, size_*sizeof(value_type)));
00128 }
00129 BOOST_SERIALIZATION_SPLIT_MEMBER()
00130
00131
00132 private:
00133 BOOST_UBLAS_INLINE
00134 void resize_internal (size_type size, value_type init, bool preserve) {
00135 if (size != size_) {
00136 pointer data;
00137 if (size) {
00138 data = alloc_.allocate (size);
00139 if (preserve) {
00140 const_iterator si = begin ();
00141 pointer di = data;
00142 if (size < size_) {
00143 for (; di != data + size; ++di) {
00144 alloc_.construct (di, *si);
00145 ++si;
00146 }
00147 }
00148 else {
00149 for (const_iterator si_end = end (); si != si_end; ++si) {
00150 alloc_.construct (di, *si);
00151 ++di;
00152 }
00153 for (; di != data + size; ++di) {
00154 alloc_.construct (di, init);
00155 }
00156 }
00157 }
00158 else {
00159
00160 #ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
00161
00162 new (data) value_type[size];
00163 #else
00164 for (pointer d = data; d != data + size; ++d)
00165 new (d) value_type;
00166 #endif
00167 }
00168 }
00169 else
00170 data = 0;
00171 if (size_) {
00172 const iterator i_end = end();
00173 for (iterator i = begin(); i != i_end; ++i) {
00174 iterator_destroy (i);
00175 }
00176 alloc_.deallocate (data_, size_);
00177 }
00178 size_ = size;
00179 data_ = data;
00180 }
00181 }
00182 public:
00183 BOOST_UBLAS_INLINE
00184 void resize (size_type size) {
00185 resize_internal (size, value_type (), false);
00186 }
00187 BOOST_UBLAS_INLINE
00188 void resize (size_type size, value_type init) {
00189 resize_internal (size, init, true);
00190 }
00191
00192 BOOST_UBLAS_INLINE
00193 size_type size () const {
00194 return size_;
00195 }
00196
00197
00198 BOOST_UBLAS_INLINE
00199 const_reference operator [] (size_type i) const {
00200 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00201 return data_ [i];
00202 }
00203 BOOST_UBLAS_INLINE
00204 reference operator [] (size_type i) {
00205 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00206 return data_ [i];
00207 }
00208
00209
00210 BOOST_UBLAS_INLINE
00211 unbounded_array &operator = (const unbounded_array &a) {
00212 if (this != &a) {
00213 resize (a.size_);
00214 std::copy (a.data_, a.data_ + a.size_, data_);
00215 }
00216 return *this;
00217 }
00218 BOOST_UBLAS_INLINE
00219 unbounded_array &assign_temporary (unbounded_array &a) {
00220 swap (a);
00221 return *this;
00222 }
00223
00224
00225 BOOST_UBLAS_INLINE
00226 void swap (unbounded_array &a) {
00227 if (this != &a) {
00228 std::swap (size_, a.size_);
00229 std::swap (data_, a.data_);
00230 }
00231 }
00232 BOOST_UBLAS_INLINE
00233 friend void swap (unbounded_array &a1, unbounded_array &a2) {
00234 a1.swap (a2);
00235 }
00236
00237 BOOST_UBLAS_INLINE
00238 const_iterator begin () const {
00239 return data_;
00240 }
00241 BOOST_UBLAS_INLINE
00242 const_iterator end () const {
00243 return data_ + size_;
00244 }
00245
00246 BOOST_UBLAS_INLINE
00247 iterator begin () {
00248 return data_;
00249 }
00250 BOOST_UBLAS_INLINE
00251 iterator end () {
00252 return data_ + size_;
00253 }
00254
00255
00256 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00257 typedef std::reverse_iterator<iterator> reverse_iterator;
00258
00259 BOOST_UBLAS_INLINE
00260 const_reverse_iterator rbegin () const {
00261 return const_reverse_iterator (end ());
00262 }
00263 BOOST_UBLAS_INLINE
00264 const_reverse_iterator rend () const {
00265 return const_reverse_iterator (begin ());
00266 }
00267 BOOST_UBLAS_INLINE
00268 reverse_iterator rbegin () {
00269 return reverse_iterator (end ());
00270 }
00271 BOOST_UBLAS_INLINE
00272 reverse_iterator rend () {
00273 return reverse_iterator (begin ());
00274 }
00275
00276
00277 allocator_type get_allocator () {
00278 return alloc_;
00279 }
00280
00281 private:
00282
00283 BOOST_UBLAS_INLINE
00284 static void iterator_destroy (iterator &i) {
00285 (&(*i)) -> ~value_type ();
00286 }
00287 ALLOC alloc_;
00288 size_type size_;
00289 pointer data_;
00290 };
00291
00292
00293 template<class T, std::size_t N, class ALLOC>
00294 class bounded_array:
00295 public storage_array<bounded_array<T, N, ALLOC> > {
00296
00297 typedef bounded_array<T, N, ALLOC> self_type;
00298 public:
00299
00300 typedef typename ALLOC::size_type size_type;
00301 typedef typename ALLOC::difference_type difference_type;
00302 typedef T value_type;
00303 typedef const T &const_reference;
00304 typedef T &reference;
00305 typedef const T *const_pointer;
00306 typedef T *pointer;
00307 typedef const_pointer const_iterator;
00308 typedef pointer iterator;
00309
00310
00311 BOOST_UBLAS_INLINE
00312 bounded_array ():
00313 size_ (0), data_ () {
00314 }
00315 explicit BOOST_UBLAS_INLINE
00316 bounded_array (size_type size):
00317 size_ (size) {
00318 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
00319
00320 }
00321 BOOST_UBLAS_INLINE
00322 bounded_array (size_type size, const value_type &init):
00323 size_ (size) {
00324 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
00325
00326 std::fill (begin(), end(), init) ;
00327 }
00328 BOOST_UBLAS_INLINE
00329 bounded_array (const bounded_array &c):
00330 storage_array<self_type> (),
00331 size_ (c.size_) {
00332
00333 std::copy (c.data_, c.data_ + c.size_, data_);
00334 }
00335
00336
00337 BOOST_UBLAS_INLINE
00338 void resize (size_type size) {
00339 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
00340 size_ = size;
00341 }
00342 BOOST_UBLAS_INLINE
00343 void resize (size_type size, value_type init) {
00344 BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
00345 if (size > size_)
00346 std::fill (data_ + size_, data_ + size, init);
00347 size_ = size;
00348 }
00349
00350 BOOST_UBLAS_INLINE
00351 size_type size () const {
00352 return size_;
00353 }
00354
00355
00356 BOOST_UBLAS_INLINE
00357 const_reference operator [] (size_type i) const {
00358 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00359 return data_ [i];
00360 }
00361 BOOST_UBLAS_INLINE
00362 reference operator [] (size_type i) {
00363 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00364 return data_ [i];
00365 }
00366
00367
00368 BOOST_UBLAS_INLINE
00369 bounded_array &operator = (const bounded_array &a) {
00370 if (this != &a) {
00371 resize (a.size_);
00372 std::copy (a.data_, a.data_ + a.size_, data_);
00373 }
00374 return *this;
00375 }
00376 BOOST_UBLAS_INLINE
00377 bounded_array &assign_temporary (bounded_array &a) {
00378 *this = a;
00379 return *this;
00380 }
00381
00382
00383 BOOST_UBLAS_INLINE
00384 void swap (bounded_array &a) {
00385 if (this != &a) {
00386 std::swap (size_, a.size_);
00387 std::swap_ranges (data_, data_ + (std::max) (size_, a.size_), a.data_);
00388 }
00389 }
00390 BOOST_UBLAS_INLINE
00391 friend void swap (bounded_array &a1, bounded_array &a2) {
00392 a1.swap (a2);
00393 }
00394
00395 BOOST_UBLAS_INLINE
00396 const_iterator begin () const {
00397 return data_;
00398 }
00399 BOOST_UBLAS_INLINE
00400 const_iterator end () const {
00401 return data_ + size_;
00402 }
00403
00404 BOOST_UBLAS_INLINE
00405 iterator begin () {
00406 return data_;
00407 }
00408 BOOST_UBLAS_INLINE
00409 iterator end () {
00410 return data_ + size_;
00411 }
00412
00413
00414 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00415 typedef std::reverse_iterator<iterator> reverse_iterator;
00416
00417 BOOST_UBLAS_INLINE
00418 const_reverse_iterator rbegin () const {
00419 return const_reverse_iterator (end ());
00420 }
00421 BOOST_UBLAS_INLINE
00422 const_reverse_iterator rend () const {
00423 return const_reverse_iterator (begin ());
00424 }
00425 BOOST_UBLAS_INLINE
00426 reverse_iterator rbegin () {
00427 return reverse_iterator (end ());
00428 }
00429 BOOST_UBLAS_INLINE
00430 reverse_iterator rend () {
00431 return reverse_iterator (begin ());
00432 }
00433
00434 private:
00435
00436 friend class boost::serialization::access;
00437 template<class Archive>
00438 void save(Archive & ar, const unsigned int version) const
00439 {
00440 ar & BOOST_SERIALIZATION_NVP(size_);
00441 ar & boost::serialization::make_nvp("data", boost::serialization::make_binary_object(data_, size_*sizeof(value_type)));
00442 }
00443 template<class Archive>
00444 void load(Archive & ar, const unsigned int version)
00445 {
00446 size_type new_size;
00447 ar & BOOST_SERIALIZATION_NVP(new_size);
00448 if (new_size > N) bad_size("too large size in bounded_array::load()\n").raise();
00449 resize(new_size);
00450 ar & boost::serialization::make_nvp("data", boost::serialization::make_binary_object(data_, size_*sizeof(value_type)));
00451 }
00452 BOOST_SERIALIZATION_SPLIT_MEMBER()
00453
00454 private:
00455 size_type size_;
00456 BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [N];
00457 };
00458
00459
00460
00461 template<class T>
00462 class array_adaptor:
00463 public storage_array<array_adaptor<T> > {
00464
00465 typedef array_adaptor<T> self_type;
00466 public:
00467 typedef std::size_t size_type;
00468 typedef std::ptrdiff_t difference_type;
00469 typedef T value_type;
00470 typedef const T &const_reference;
00471 typedef T &reference;
00472 typedef const T *const_pointer;
00473 typedef T *pointer;
00474
00475
00476 BOOST_UBLAS_INLINE
00477 array_adaptor ():
00478 size_ (0), own_ (true), data_ (new value_type [0]) {
00479 }
00480 explicit BOOST_UBLAS_INLINE
00481 array_adaptor (size_type size):
00482 size_ (size), own_ (true), data_ (new value_type [size]) {
00483 }
00484 BOOST_UBLAS_INLINE
00485 array_adaptor (size_type size, const value_type &init):
00486 size_ (size), own_ (true), data_ (new value_type [size]) {
00487 std::fill (data_, data_ + size_, init);
00488 }
00489 BOOST_UBLAS_INLINE
00490 array_adaptor (size_type size, pointer data):
00491 size_ (size), own_ (false), data_ (data) {}
00492 BOOST_UBLAS_INLINE
00493 array_adaptor (const array_adaptor &a):
00494 storage_array<self_type> (),
00495 size_ (a.size_), own_ (true), data_ (new value_type [a.size_]) {
00496 *this = a;
00497 }
00498 BOOST_UBLAS_INLINE
00499 ~array_adaptor () {
00500 if (own_) {
00501 delete [] data_;
00502 }
00503 }
00504
00505
00506 private:
00507 BOOST_UBLAS_INLINE
00508 void resize_internal (size_type size, value_type init, bool preserve = true) {
00509 if (size != size_) {
00510 pointer data = new value_type [size];
00511 if (preserve) {
00512 std::copy (data_, data_ + (std::min) (size, size_), data);
00513 std::fill (data + (std::min) (size, size_), data + size, init);
00514 }
00515 if (own_)
00516 delete [] data_;
00517 size_ = size;
00518 own_ = true;
00519 data_ = data;
00520 }
00521 }
00522 BOOST_UBLAS_INLINE
00523 void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
00524 if (data != data_) {
00525 if (preserve) {
00526 std::copy (data_, data_ + (std::min) (size, size_), data);
00527 std::fill (data + (std::min) (size, size_), data + size, init);
00528 }
00529 if (own_)
00530 delete [] data_;
00531 own_ = false;
00532 data_ = data;
00533 }
00534 else {
00535 std::fill (data + (std::min) (size, size_), data + size, init);
00536 }
00537 size_ = size;
00538 }
00539 public:
00540 BOOST_UBLAS_INLINE
00541 void resize (size_type size) {
00542 resize_internal (size, value_type (), false);
00543 }
00544 BOOST_UBLAS_INLINE
00545 void resize (size_type size, value_type init) {
00546 resize_internal (size, init, true);
00547 }
00548 BOOST_UBLAS_INLINE
00549 void resize (size_type size, pointer data) {
00550 resize_internal (size, data, value_type (), false);
00551 }
00552 BOOST_UBLAS_INLINE
00553 void resize (size_type size, pointer data, value_type init) {
00554 resize_internal (size, data, init, true);
00555 }
00556
00557 BOOST_UBLAS_INLINE
00558 size_type size () const {
00559 return size_;
00560 }
00561
00562
00563 BOOST_UBLAS_INLINE
00564 const_reference operator [] (size_type i) const {
00565 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00566 return data_ [i];
00567 }
00568 BOOST_UBLAS_INLINE
00569 reference operator [] (size_type i) {
00570 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00571 return data_ [i];
00572 }
00573
00574
00575 BOOST_UBLAS_INLINE
00576 array_adaptor &operator = (const array_adaptor &a) {
00577 if (this != &a) {
00578 resize (a.size_);
00579 std::copy (a.data_, a.data_ + a.size_, data_);
00580 }
00581 return *this;
00582 }
00583 BOOST_UBLAS_INLINE
00584 array_adaptor &assign_temporary (array_adaptor &a) {
00585 if (own_ && a.own_)
00586 swap (a);
00587 else
00588 *this = a;
00589 return *this;
00590 }
00591
00592
00593 BOOST_UBLAS_INLINE
00594 void swap (array_adaptor &a) {
00595 if (this != &a) {
00596 std::swap (size_, a.size_);
00597 std::swap (own_, a.own_);
00598 std::swap (data_, a.data_);
00599 }
00600 }
00601 BOOST_UBLAS_INLINE
00602 friend void swap (array_adaptor &a1, array_adaptor &a2) {
00603 a1.swap (a2);
00604 }
00605
00606
00607
00608 typedef const_pointer const_iterator;
00609
00610 BOOST_UBLAS_INLINE
00611 const_iterator begin () const {
00612 return data_;
00613 }
00614 BOOST_UBLAS_INLINE
00615 const_iterator end () const {
00616 return data_ + size_;
00617 }
00618
00619 typedef pointer iterator;
00620
00621 BOOST_UBLAS_INLINE
00622 iterator begin () {
00623 return data_;
00624 }
00625 BOOST_UBLAS_INLINE
00626 iterator end () {
00627 return data_ + size_;
00628 }
00629
00630
00631 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00632 typedef std::reverse_iterator<iterator> reverse_iterator;
00633
00634 BOOST_UBLAS_INLINE
00635 const_reverse_iterator rbegin () const {
00636 return const_reverse_iterator (end ());
00637 }
00638 BOOST_UBLAS_INLINE
00639 const_reverse_iterator rend () const {
00640 return const_reverse_iterator (begin ());
00641 }
00642 BOOST_UBLAS_INLINE
00643 reverse_iterator rbegin () {
00644 return reverse_iterator (end ());
00645 }
00646 BOOST_UBLAS_INLINE
00647 reverse_iterator rend () {
00648 return reverse_iterator (begin ());
00649 }
00650
00651 private:
00652 size_type size_;
00653 bool own_;
00654 pointer data_;
00655 };
00656
00657 #ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
00658
00659
00660
00661 template<class T>
00662 class shallow_array_adaptor:
00663 public storage_array<shallow_array_adaptor<T> > {
00664
00665 typedef shallow_array_adaptor<T> self_type;
00666
00667 template<class TT>
00668 struct leaker {
00669 typedef void result_type;
00670 typedef TT *argument_type;
00671
00672 BOOST_UBLAS_INLINE
00673 result_type operator () (argument_type x) {}
00674 };
00675
00676 public:
00677 typedef std::size_t size_type;
00678 typedef std::ptrdiff_t difference_type;
00679 typedef T value_type;
00680 typedef const T &const_reference;
00681 typedef T &reference;
00682 typedef const T *const_pointer;
00683 typedef T *pointer;
00684
00685
00686 BOOST_UBLAS_INLINE
00687 shallow_array_adaptor ():
00688 size_ (0), own_ (true), data_ (new value_type [0]) {
00689 }
00690 explicit BOOST_UBLAS_INLINE
00691 shallow_array_adaptor (size_type size):
00692 size_ (size), own_ (true), data_ (new value_type [size]) {
00693 }
00694 BOOST_UBLAS_INLINE
00695 shallow_array_adaptor (size_type size, const value_type &init):
00696 size_ (size), own_ (true), data_ (new value_type [size]) {
00697 std::fill (data_.get (), data_.get () + size_, init);
00698 }
00699 BOOST_UBLAS_INLINE
00700 shallow_array_adaptor (size_type size, pointer data):
00701 size_ (size), own_ (false), data_ (data, leaker<value_type> ()) {}
00702
00703 BOOST_UBLAS_INLINE
00704 shallow_array_adaptor (const shallow_array_adaptor &a):
00705 storage_array<self_type> (),
00706 size_ (a.size_), own_ (a.own_), data_ (a.data_) {}
00707
00708 BOOST_UBLAS_INLINE
00709 ~shallow_array_adaptor () {
00710 }
00711
00712
00713 private:
00714 BOOST_UBLAS_INLINE
00715 void resize_internal (size_type size, value_type init, bool preserve = true) {
00716 if (size != size_) {
00717 shared_array<value_type> data (new value_type [size]);
00718 if (preserve) {
00719 std::copy (data_.get (), data_.get () + (std::min) (size, size_), data.get ());
00720 std::fill (data.get () + (std::min) (size, size_), data.get () + size, init);
00721 }
00722 size_ = size;
00723 data_ = data;
00724 }
00725 }
00726 BOOST_UBLAS_INLINE
00727 void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
00728 if (preserve) {
00729 std::copy (data_.get (), data_.get () + (std::min) (size, size_), data);
00730 std::fill (data + (std::min) (size, size_), data + size, init);
00731 }
00732 size_ = size;
00733 data_ = data;
00734 }
00735 public:
00736 BOOST_UBLAS_INLINE
00737 void resize (size_type size) {
00738 resize_internal (size, value_type (), false);
00739 }
00740 BOOST_UBLAS_INLINE
00741 void resize (size_type size, value_type init) {
00742 resize_internal (size, init, true);
00743 }
00744 BOOST_UBLAS_INLINE
00745 void resize (size_type size, pointer data) {
00746 resize_internal (size, data, value_type (), false);
00747 }
00748 BOOST_UBLAS_INLINE
00749 void resize (size_type size, pointer data, value_type init) {
00750 resize_internal (size, data, init, true);
00751 }
00752
00753 BOOST_UBLAS_INLINE
00754 size_type size () const {
00755 return size_;
00756 }
00757
00758
00759 BOOST_UBLAS_INLINE
00760 const_reference operator [] (size_type i) const {
00761 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00762 return data_ [i];
00763 }
00764 BOOST_UBLAS_INLINE
00765 reference operator [] (size_type i) {
00766 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00767 return data_ [i];
00768 }
00769
00770
00771 BOOST_UBLAS_INLINE
00772 shallow_array_adaptor &operator = (const shallow_array_adaptor &a) {
00773 if (this != &a) {
00774 resize (a.size_);
00775 std::copy (a.data_.get (), a.data_.get () + a.size_, data_.get ());
00776 }
00777 return *this;
00778 }
00779 BOOST_UBLAS_INLINE
00780 shallow_array_adaptor &assign_temporary (shallow_array_adaptor &a) {
00781 if (own_ && a.own_)
00782 swap (a);
00783 else
00784 *this = a;
00785 return *this;
00786 }
00787
00788
00789 BOOST_UBLAS_INLINE
00790 void swap (shallow_array_adaptor &a) {
00791 if (this != &a) {
00792 std::swap (size_, a.size_);
00793 std::swap (own_, a.own_);
00794 std::swap (data_, a.data_);
00795 }
00796 }
00797 BOOST_UBLAS_INLINE
00798 friend void swap (shallow_array_adaptor &a1, shallow_array_adaptor &a2) {
00799 a1.swap (a2);
00800 }
00801
00802
00803
00804 typedef const_pointer const_iterator;
00805
00806 BOOST_UBLAS_INLINE
00807 const_iterator begin () const {
00808 return data_.get ();
00809 }
00810 BOOST_UBLAS_INLINE
00811 const_iterator end () const {
00812 return data_.get () + size_;
00813 }
00814
00815 typedef pointer iterator;
00816
00817 BOOST_UBLAS_INLINE
00818 iterator begin () {
00819 return data_.get ();
00820 }
00821 BOOST_UBLAS_INLINE
00822 iterator end () {
00823 return data_.get () + size_;
00824 }
00825
00826
00827 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00828 typedef std::reverse_iterator<iterator> reverse_iterator;
00829
00830 BOOST_UBLAS_INLINE
00831 const_reverse_iterator rbegin () const {
00832 return const_reverse_iterator (end ());
00833 }
00834 BOOST_UBLAS_INLINE
00835 const_reverse_iterator rend () const {
00836 return const_reverse_iterator (begin ());
00837 }
00838 BOOST_UBLAS_INLINE
00839 reverse_iterator rbegin () {
00840 return reverse_iterator (end ());
00841 }
00842 BOOST_UBLAS_INLINE
00843 reverse_iterator rend () {
00844 return reverse_iterator (begin ());
00845 }
00846
00847 private:
00848 size_type size_;
00849 bool own_;
00850 shared_array<value_type> data_;
00851 };
00852
00853 #endif
00854
00855
00856 template <class Z, class D>
00857 class basic_range {
00858 typedef basic_range<Z, D> self_type;
00859 public:
00860 typedef Z size_type;
00861 typedef D difference_type;
00862 typedef size_type value_type;
00863 typedef value_type const_reference;
00864 typedef const_reference reference;
00865 typedef const value_type *const_pointer;
00866 typedef value_type *pointer;
00867
00868
00869 BOOST_UBLAS_INLINE
00870 basic_range ():
00871 start_ (0), size_ (0) {}
00872 BOOST_UBLAS_INLINE
00873 basic_range (size_type start, size_type stop):
00874 start_ (start), size_ (stop - start) {
00875 BOOST_UBLAS_CHECK (start_ <= stop, bad_index ());
00876 }
00877
00878 BOOST_UBLAS_INLINE
00879 size_type start () const {
00880 return start_;
00881 }
00882 BOOST_UBLAS_INLINE
00883 size_type size () const {
00884 return size_;
00885 }
00886
00887
00888 basic_range operator=( basic_range const& r ) {
00889 start_ = r.start_ ;
00890 size_ = r.size_ ;
00891 return *this ;
00892 }
00893
00894
00895 BOOST_UBLAS_INLINE
00896 const_reference operator () (size_type i) const {
00897 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00898 return start_ + i;
00899 }
00900
00901
00902 BOOST_UBLAS_INLINE
00903 basic_range compose (const basic_range &r) const {
00904 return basic_range (start_ + r.start_, start_ + r.start_ + r.size_);
00905 }
00906
00907
00908 BOOST_UBLAS_INLINE
00909 bool operator == (const basic_range &r) const {
00910 return start_ == r.start_ && size_ == r.size_;
00911 }
00912 BOOST_UBLAS_INLINE
00913 bool operator != (const basic_range &r) const {
00914 return ! (*this == r);
00915 }
00916
00917
00918 private:
00919
00920 typedef size_type const_subiterator_type;
00921
00922 public:
00923 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00924 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
00925 #else
00926 class const_iterator:
00927 public container_const_reference<basic_range>,
00928 public random_access_iterator_base<std::random_access_iterator_tag,
00929 const_iterator, value_type> {
00930 public:
00931 typedef typename basic_range::value_type value_type;
00932 typedef typename basic_range::difference_type difference_type;
00933 typedef typename basic_range::const_reference reference;
00934 typedef typename basic_range::const_pointer pointer;
00935
00936
00937 BOOST_UBLAS_INLINE
00938 const_iterator ():
00939 container_const_reference<basic_range> (), it_ () {}
00940 BOOST_UBLAS_INLINE
00941 const_iterator (const basic_range &r, const const_subiterator_type &it):
00942 container_const_reference<basic_range> (r), it_ (it) {}
00943
00944
00945 BOOST_UBLAS_INLINE
00946 const_iterator &operator ++ () {
00947 ++ it_;
00948 return *this;
00949 }
00950 BOOST_UBLAS_INLINE
00951 const_iterator &operator -- () {
00952 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
00953 -- it_;
00954 return *this;
00955 }
00956 BOOST_UBLAS_INLINE
00957 const_iterator &operator += (difference_type n) {
00958 BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
00959 it_ += n;
00960 return *this;
00961 }
00962 BOOST_UBLAS_INLINE
00963 const_iterator &operator -= (difference_type n) {
00964 BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
00965 it_ -= n;
00966 return *this;
00967 }
00968 BOOST_UBLAS_INLINE
00969 difference_type operator - (const const_iterator &it) const {
00970 return it_ - it.it_;
00971 }
00972
00973
00974 BOOST_UBLAS_INLINE
00975 const_reference operator * () const {
00976 BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
00977 BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
00978 return it_;
00979 }
00980
00981
00982 BOOST_UBLAS_INLINE
00983 size_type index () const {
00984 BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
00985 BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
00986 return it_ - (*this) ().start ();
00987 }
00988
00989
00990 BOOST_UBLAS_INLINE
00991 const_iterator &operator = (const const_iterator &it) {
00992
00993 this->assign (&it ());
00994 it_ = it.it_;
00995 return *this;
00996 }
00997
00998
00999 BOOST_UBLAS_INLINE
01000 bool operator == (const const_iterator &it) const {
01001 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01002 return it_ == it.it_;
01003 }
01004 BOOST_UBLAS_INLINE
01005 bool operator < (const const_iterator &it) const {
01006 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01007 return it_ < it.it_;
01008 }
01009
01010 private:
01011 const_subiterator_type it_;
01012 };
01013 #endif
01014
01015 BOOST_UBLAS_INLINE
01016 const_iterator begin () const {
01017 return const_iterator (*this, start_);
01018 }
01019 BOOST_UBLAS_INLINE
01020 const_iterator end () const {
01021 return const_iterator (*this, start_ + size_);
01022 }
01023
01024
01025 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
01026
01027 BOOST_UBLAS_INLINE
01028 const_reverse_iterator rbegin () const {
01029 return const_reverse_iterator (end ());
01030 }
01031 BOOST_UBLAS_INLINE
01032 const_reverse_iterator rend () const {
01033 return const_reverse_iterator (begin ());
01034 }
01035
01036 BOOST_UBLAS_INLINE
01037 basic_range preprocess (size_type size) const {
01038 if (this != &all_)
01039 return *this;
01040 return basic_range (0, size);
01041 }
01042 static
01043 BOOST_UBLAS_INLINE
01044 const basic_range &all () {
01045 return all_;
01046 }
01047
01048 private:
01049 size_type start_;
01050 size_type size_;
01051 static const basic_range all_;
01052 };
01053
01054 template <class Z, class D>
01055 const basic_range<Z,D> basic_range<Z,D>::all_ (0, size_type (-1));
01056
01057
01058
01059 template <class Z, class D>
01060 class basic_slice {
01061 typedef basic_slice<Z, D> self_type;
01062 public:
01063 typedef Z size_type;
01064 typedef D difference_type;
01065 typedef size_type value_type;
01066 typedef value_type const_reference;
01067 typedef const_reference reference;
01068 typedef const value_type *const_pointer;
01069 typedef value_type *pointer;
01070
01071
01072 BOOST_UBLAS_INLINE
01073 basic_slice ():
01074 start_ (0), stride_ (0), size_ (0) {}
01075 BOOST_UBLAS_INLINE
01076 basic_slice (size_type start, difference_type stride, size_type size):
01077 start_ (start), stride_ (stride), size_ (size) {}
01078
01079 BOOST_UBLAS_INLINE
01080 size_type start () const {
01081 return start_;
01082 }
01083 BOOST_UBLAS_INLINE
01084 difference_type stride () const {
01085 return stride_;
01086 }
01087 BOOST_UBLAS_INLINE
01088 size_type size () const {
01089 return size_;
01090 }
01091
01092
01093 BOOST_UBLAS_INLINE
01094 const_reference operator () (size_type i) const {
01095 BOOST_UBLAS_CHECK (i < size_, bad_index ());
01096 BOOST_UBLAS_CHECK (stride_ >= 0 || start_ >= i * -stride_, bad_index ());
01097 return start_ + i * stride_;
01098 }
01099
01100
01101 BOOST_UBLAS_INLINE
01102 basic_slice compose (const basic_range<size_type, difference_type> &r) const {
01103 BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * r.start(), bad_index ());
01104 return basic_slice (start_ + stride_ * r.start (), stride_, r.size ());
01105 }
01106 BOOST_UBLAS_INLINE
01107 basic_slice compose (const basic_slice &s) const {
01108 BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * s.start_, bad_index ());
01109 return basic_slice (start_ + stride_ * s.start_, stride_ * s.stride_, s.size_);
01110 }
01111
01112
01113 BOOST_UBLAS_INLINE
01114 bool operator == (const basic_slice &s) const {
01115 return start_ == s.start_ && stride_ == s.stride_ && size_ == s.size_;
01116 }
01117 BOOST_UBLAS_INLINE
01118 bool operator != (const basic_slice &s) const {
01119 return ! (*this == s);
01120 }
01121
01122
01123 private:
01124
01125 typedef size_type const_subiterator_type;
01126
01127 public:
01128 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01129 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
01130 #else
01131 class const_iterator:
01132 public container_const_reference<basic_slice>,
01133 public random_access_iterator_base<std::random_access_iterator_tag,
01134 const_iterator, value_type> {
01135 public:
01136 typedef typename basic_slice::value_type value_type;
01137 typedef typename basic_slice::difference_type difference_type;
01138 typedef typename basic_slice::const_reference reference;
01139 typedef typename basic_slice::const_pointer pointer;
01140
01141
01142 BOOST_UBLAS_INLINE
01143 const_iterator ():
01144 container_const_reference<basic_slice> (), it_ () {}
01145 BOOST_UBLAS_INLINE
01146 const_iterator (const basic_slice &s, const const_subiterator_type &it):
01147 container_const_reference<basic_slice> (s), it_ (it) {}
01148
01149
01150 BOOST_UBLAS_INLINE
01151 const_iterator &operator ++ () {
01152 ++it_;
01153 return *this;
01154 }
01155 BOOST_UBLAS_INLINE
01156 const_iterator &operator -- () {
01157 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
01158 --it_;
01159 return *this;
01160 }
01161 BOOST_UBLAS_INLINE
01162 const_iterator &operator += (difference_type n) {
01163 BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
01164 it_ += n;
01165 return *this;
01166 }
01167 BOOST_UBLAS_INLINE
01168 const_iterator &operator -= (difference_type n) {
01169 BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
01170 it_ -= n;
01171 return *this;
01172 }
01173 BOOST_UBLAS_INLINE
01174 difference_type operator - (const const_iterator &it) const {
01175 return it_ - it.it_;
01176 }
01177
01178
01179 BOOST_UBLAS_INLINE
01180 const_reference operator * () const {
01181 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
01182 return (*this) ().start () + it_* (*this) ().stride ();
01183 }
01184
01185
01186 BOOST_UBLAS_INLINE
01187 size_type index () const {
01188 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
01189 return it_;
01190 }
01191
01192
01193 BOOST_UBLAS_INLINE
01194 const_iterator &operator = (const const_iterator &it) {
01195
01196 this->assign (&it ());
01197 it_ = it.it_;
01198 return *this;
01199 }
01200
01201
01202 BOOST_UBLAS_INLINE
01203 bool operator == (const const_iterator &it) const {
01204 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01205 return it_ == it.it_;
01206 }
01207 BOOST_UBLAS_INLINE
01208 bool operator < (const const_iterator &it) const {
01209 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01210 return it_ < it.it_;
01211 }
01212
01213 private:
01214 const_subiterator_type it_;
01215 };
01216 #endif
01217
01218 BOOST_UBLAS_INLINE
01219 const_iterator begin () const {
01220 return const_iterator (*this, 0);
01221 }
01222 BOOST_UBLAS_INLINE
01223 const_iterator end () const {
01224 return const_iterator (*this, size_);
01225 }
01226
01227
01228 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
01229
01230 BOOST_UBLAS_INLINE
01231 const_reverse_iterator rbegin () const {
01232 return const_reverse_iterator (end ());
01233 }
01234 BOOST_UBLAS_INLINE
01235 const_reverse_iterator rend () const {
01236 return const_reverse_iterator (begin ());
01237 }
01238
01239 BOOST_UBLAS_INLINE
01240 basic_slice preprocess (size_type size) const {
01241 if (this != &all_)
01242 return *this;
01243 return basic_slice (0, 1, size);
01244 }
01245 static
01246 BOOST_UBLAS_INLINE
01247 const basic_slice &all () {
01248 return all_;
01249 }
01250
01251 private:
01252 size_type start_;
01253 difference_type stride_;
01254 size_type size_;
01255 static const basic_slice all_;
01256 };
01257
01258 template <class Z, class D>
01259 const basic_slice<Z,D> basic_slice<Z,D>::all_ (0, 1, size_type (-1));
01260
01261
01262
01263 template<class A>
01264 class indirect_array {
01265 typedef indirect_array<A> self_type;
01266 public:
01267 typedef A array_type;
01268 typedef const A const_array_type;
01269 typedef typename A::size_type size_type;
01270 typedef typename A::difference_type difference_type;
01271 typedef typename A::value_type value_type;
01272 typedef typename A::const_reference const_reference;
01273 typedef typename A::reference reference;
01274 typedef typename A::const_pointer const_pointer;
01275 typedef typename A::pointer pointer;
01276
01277
01278 BOOST_UBLAS_INLINE
01279 indirect_array ():
01280 size_ (), data_ () {}
01281 explicit BOOST_UBLAS_INLINE
01282 indirect_array (size_type size):
01283 size_ (size), data_ (size) {}
01284 BOOST_UBLAS_INLINE
01285 indirect_array (size_type size, const array_type &data):
01286 size_ (size), data_ (data) {}
01287 BOOST_UBLAS_INLINE
01288 indirect_array (pointer start, pointer stop):
01289 size_ (stop - start), data_ (stop - start) {
01290 std::copy (start, stop, data_.begin ());
01291 }
01292
01293 BOOST_UBLAS_INLINE
01294 size_type size () const {
01295 return size_;
01296 }
01297 BOOST_UBLAS_INLINE
01298 const_array_type data () const {
01299 return data_;
01300 }
01301 BOOST_UBLAS_INLINE
01302 array_type data () {
01303 return data_;
01304 }
01305
01306
01307 BOOST_UBLAS_INLINE
01308 const_reference operator () (size_type i) const {
01309 BOOST_UBLAS_CHECK (i < size_, bad_index ());
01310 return data_ [i];
01311 }
01312 BOOST_UBLAS_INLINE
01313 reference operator () (size_type i) {
01314 BOOST_UBLAS_CHECK (i < size_, bad_index ());
01315 return data_ [i];
01316 }
01317
01318 BOOST_UBLAS_INLINE
01319 const_reference operator [] (size_type i) const {
01320 return (*this) (i);
01321 }
01322 BOOST_UBLAS_INLINE
01323 reference operator [] (size_type i) {
01324 return (*this) (i);
01325 }
01326
01327
01328 BOOST_UBLAS_INLINE
01329 indirect_array compose (const basic_range<size_type, difference_type> &r) const {
01330 BOOST_UBLAS_CHECK (r.start () + r.size () <= size_, bad_size ());
01331 array_type data (r.size ());
01332 for (size_type i = 0; i < r.size (); ++ i)
01333 data [i] = data_ [r.start () + i];
01334 return indirect_array (r.size (), data);
01335 }
01336 BOOST_UBLAS_INLINE
01337 indirect_array compose (const basic_slice<size_type, difference_type> &s) const {
01338 BOOST_UBLAS_CHECK (s.start () + s.stride () * (s.size () - (s.size () > 0)) <= size (), bad_size ());
01339 array_type data (s.size ());
01340 for (size_type i = 0; i < s.size (); ++ i)
01341 data [i] = data_ [s.start () + s.stride () * i];
01342 return indirect_array (s.size (), data);
01343 }
01344 BOOST_UBLAS_INLINE
01345 indirect_array compose (const indirect_array &ia) const {
01346 array_type data (ia.size_);
01347 for (size_type i = 0; i < ia.size_; ++ i) {
01348 BOOST_UBLAS_CHECK (ia.data_ [i] <= size_, bad_size ());
01349 data [i] = data_ [ia.data_ [i]];
01350 }
01351 return indirect_array (ia.size_, data);
01352 }
01353
01354
01355 template<class OA>
01356 BOOST_UBLAS_INLINE
01357 bool operator == (const indirect_array<OA> &ia) const {
01358 if (size_ != ia.size_)
01359 return false;
01360 for (size_type i = 0; i < BOOST_UBLAS_SAME (size_, ia.size_); ++ i)
01361 if (data_ [i] != ia.data_ [i])
01362 return false;
01363 return true;
01364 }
01365 template<class OA>
01366 BOOST_UBLAS_INLINE
01367 bool operator != (const indirect_array<OA> &ia) const {
01368 return ! (*this == ia);
01369 }
01370
01371
01372 private:
01373
01374 typedef difference_type const_subiterator_type;
01375
01376 public:
01377 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01378 typedef indexed_const_iterator<indirect_array, std::random_access_iterator_tag> const_iterator;
01379 #else
01380 class const_iterator:
01381 public container_const_reference<indirect_array>,
01382 public random_access_iterator_base<std::random_access_iterator_tag,
01383 const_iterator, value_type> {
01384 public:
01385 typedef typename indirect_array::value_type value_type;
01386 typedef typename indirect_array::difference_type difference_type;
01387 typedef typename indirect_array::const_reference reference;
01388 typedef typename indirect_array::const_pointer pointer;
01389
01390
01391 BOOST_UBLAS_INLINE
01392 const_iterator ():
01393 container_const_reference<indirect_array> (), it_ () {}
01394 BOOST_UBLAS_INLINE
01395 const_iterator (const indirect_array &ia, const const_subiterator_type &it):
01396 container_const_reference<indirect_array> (ia), it_ (it) {}
01397
01398
01399 BOOST_UBLAS_INLINE
01400 const_iterator &operator ++ () {
01401 ++ it_;
01402 return *this;
01403 }
01404 BOOST_UBLAS_INLINE
01405 const_iterator &operator -- () {
01406 -- it_;
01407 return *this;
01408 }
01409 BOOST_UBLAS_INLINE
01410 const_iterator &operator += (difference_type n) {
01411 it_ += n;
01412 return *this;
01413 }
01414 BOOST_UBLAS_INLINE
01415 const_iterator &operator -= (difference_type n) {
01416 it_ -= n;
01417 return *this;
01418 }
01419 BOOST_UBLAS_INLINE
01420 difference_type operator - (const const_iterator &it) const {
01421 return it_ - it.it_;
01422 }
01423
01424
01425 BOOST_UBLAS_INLINE
01426 const_reference operator * () const {
01427 return (*this) () (it_);
01428 }
01429
01430
01431 BOOST_UBLAS_INLINE
01432 size_type index () const {
01433 return it_;
01434 }
01435
01436
01437 BOOST_UBLAS_INLINE
01438 const_iterator &operator = (const const_iterator &it) {
01439
01440 this->assign (&it ());
01441 it_ = it.it_;
01442 return *this;
01443 }
01444
01445
01446 BOOST_UBLAS_INLINE
01447 bool operator == (const const_iterator &it) const {
01448 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01449 return it_ == it.it_;
01450 }
01451 BOOST_UBLAS_INLINE
01452 bool operator < (const const_iterator &it) const {
01453 BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
01454 return it_ < it.it_;
01455 }
01456
01457 private:
01458 const_subiterator_type it_;
01459 };
01460 #endif
01461
01462 BOOST_UBLAS_INLINE
01463 const_iterator begin () const {
01464 return const_iterator (*this, 0);
01465 }
01466 BOOST_UBLAS_INLINE
01467 const_iterator end () const {
01468 return const_iterator (*this, size_);
01469 }
01470
01471
01472 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
01473
01474 BOOST_UBLAS_INLINE
01475 const_reverse_iterator rbegin () const {
01476 return const_reverse_iterator (end ());
01477 }
01478 BOOST_UBLAS_INLINE
01479 const_reverse_iterator rend () const {
01480 return const_reverse_iterator (begin ());
01481 }
01482
01483 BOOST_UBLAS_INLINE
01484 indirect_array preprocess (size_type size) const {
01485 if (this != &all_)
01486 return *this;
01487 indirect_array ia (size);
01488 for (size_type i = 0; i < size; ++ i)
01489 ia (i) = i;
01490 return ia;
01491 }
01492 static
01493 BOOST_UBLAS_INLINE
01494 const indirect_array &all () {
01495 return all_;
01496 }
01497
01498 private:
01499 size_type size_;
01500 array_type data_;
01501 static const indirect_array all_;
01502 };
01503
01504 template<class A>
01505 const indirect_array<A> indirect_array<A>::all_;
01506
01507
01508
01509
01510
01511
01512 template <class V>
01513 class index_pair :
01514 private boost::noncopyable,
01515 public container_reference<V> {
01516
01517 typedef index_pair<V> self_type;
01518 public:
01519 typedef typename V::size_type size_type;
01520
01521 BOOST_UBLAS_INLINE
01522 index_pair(V& v, size_type i) :
01523 container_reference<V>(v), i_(i),
01524 v1_(v.data1_[i]), v2_(v.data2_[i]),
01525 dirty_(false), is_copy_(false) {}
01526 BOOST_UBLAS_INLINE
01527 index_pair(const self_type& rhs) :
01528 container_reference<V>(rhs()), i_(0),
01529 v1_(rhs.v1_), v2_(rhs.v2_),
01530 dirty_(false), is_copy_(true) {}
01531 BOOST_UBLAS_INLINE
01532 ~index_pair() {
01533 if (dirty_ && (!is_copy_) ) {
01534 (*this)().data1_[i_] = v1_;
01535 (*this)().data2_[i_] = v2_;
01536 }
01537 }
01538
01539 BOOST_UBLAS_INLINE
01540 self_type& operator=(const self_type& rhs) {
01541 v1_ = rhs.v1_;
01542 v2_ = rhs.v2_;
01543 dirty_ = true;
01544 return *this;
01545 }
01546
01547 BOOST_UBLAS_INLINE
01548 void swap(self_type rhs) {
01549 self_type tmp(rhs);
01550 rhs = *this;
01551 *this = tmp;
01552 }
01553 BOOST_UBLAS_INLINE
01554 friend void swap(self_type lhs, self_type rhs) {
01555 lhs.swap(rhs);
01556 }
01557
01558 BOOST_UBLAS_INLINE
01559 bool equal(const self_type& rhs) const {
01560 return (v1_ == rhs.v1_);
01561 }
01562 bool less(const self_type& rhs) const {
01563 return (v1_ < rhs.v1_);
01564 }
01565 BOOST_UBLAS_INLINE
01566 friend bool operator == (const self_type& lhs, const self_type& rhs) {
01567 return lhs.equal(rhs);
01568 }
01569 BOOST_UBLAS_INLINE
01570 friend bool operator != (const self_type& lhs, const self_type& rhs) {
01571 return !lhs.equal(rhs);
01572 }
01573 BOOST_UBLAS_INLINE
01574 friend bool operator < (const self_type& lhs, const self_type& rhs) {
01575 return lhs.less(rhs);
01576 }
01577
01578 private:
01579 size_type i_;
01580 typename V::value1_type v1_;
01581 typename V::value2_type v2_;
01582 bool dirty_;
01583 bool is_copy_;
01584 };
01585
01586 template <class V1, class V2>
01587 class index_pair_array:
01588 private boost::noncopyable {
01589
01590 typedef index_pair_array<V1, V2> self_type;
01591 public:
01592 typedef typename V1::value_type value1_type;
01593 typedef typename V2::value_type value2_type;
01594
01595 typedef typename V1::size_type size_type;
01596 typedef typename V1::difference_type difference_type;
01597 typedef index_pair<self_type> value_type;
01598
01599 typedef value_type reference;
01600 typedef const value_type const_reference;
01601
01602 BOOST_UBLAS_INLINE
01603 index_pair_array(size_type size, V1& data1, V2& data2) :
01604 size_(size),data1_(data1),data2_(data2) {}
01605
01606 BOOST_UBLAS_INLINE
01607 size_type size() const {
01608 return size_;
01609 }
01610
01611 BOOST_UBLAS_INLINE
01612 const_reference operator () (size_type i) const {
01613 return value_type((*this), i);
01614 }
01615 BOOST_UBLAS_INLINE
01616 reference operator () (size_type i) {
01617 return value_type((*this), i);
01618 }
01619
01620 typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
01621 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
01622
01623 BOOST_UBLAS_INLINE
01624 iterator begin() {
01625 return iterator( (*this), 0);
01626 }
01627 BOOST_UBLAS_INLINE
01628 iterator end() {
01629 return iterator( (*this), size());
01630 }
01631
01632 BOOST_UBLAS_INLINE
01633 const_iterator begin() const {
01634 return const_iterator( (*this), 0);
01635 }
01636 BOOST_UBLAS_INLINE
01637 const_iterator end() const {
01638 return const_iterator( (*this), size());
01639 }
01640
01641
01642 BOOST_UBLAS_INLINE
01643 bool equal(size_type i1, size_type i2) const {
01644 return data1_[i1] == data1_[i2];
01645 }
01646 BOOST_UBLAS_INLINE
01647 bool less(size_type i1, size_type i2) const {
01648 return data1_[i1] < data1_[i2];
01649 }
01650
01651
01652 BOOST_UBLAS_INLINE
01653 friend void iter_swap(const iterator& lhs, const iterator& rhs) {
01654 const size_type i1 = lhs.index();
01655 const size_type i2 = rhs.index();
01656 std::swap(lhs().data1_[i1], rhs().data1_[i2]);
01657 std::swap(lhs().data2_[i1], rhs().data2_[i2]);
01658 }
01659
01660 private:
01661 size_type size_;
01662 V1& data1_;
01663 V2& data2_;
01664
01665
01666 friend class index_pair<self_type>;
01667 };
01668
01669 template <class M>
01670 class index_triple :
01671 private boost::noncopyable,
01672 public container_reference<M> {
01673
01674 typedef index_triple<M> self_type;
01675 public:
01676 typedef typename M::size_type size_type;
01677
01678 BOOST_UBLAS_INLINE
01679 index_triple(M& m, size_type i) :
01680 container_reference<M>(m), i_(i),
01681 v1_(m.data1_[i]), v2_(m.data2_[i]), v3_(m.data3_[i]),
01682 dirty_(false), is_copy_(false) {}
01683 BOOST_UBLAS_INLINE
01684 index_triple(const self_type& rhs) :
01685 container_reference<M>(rhs()), i_(0),
01686 v1_(rhs.v1_), v2_(rhs.v2_), v3_(rhs.v3_),
01687 dirty_(false), is_copy_(true) {}
01688 BOOST_UBLAS_INLINE
01689 ~index_triple() {
01690 if (dirty_ && (!is_copy_) ) {
01691 (*this)().data1_[i_] = v1_;
01692 (*this)().data2_[i_] = v2_;
01693 (*this)().data3_[i_] = v3_;
01694 }
01695 }
01696
01697 BOOST_UBLAS_INLINE
01698 self_type& operator=(const self_type& rhs) {
01699 v1_ = rhs.v1_;
01700 v2_ = rhs.v2_;
01701 v3_ = rhs.v3_;
01702 dirty_ = true;
01703 return *this;
01704 }
01705
01706 BOOST_UBLAS_INLINE
01707 void swap(self_type rhs) {
01708 self_type tmp(rhs);
01709 rhs = *this;
01710 *this = tmp;
01711 }
01712 BOOST_UBLAS_INLINE
01713 friend void swap(self_type lhs, self_type rhs) {
01714 lhs.swap(rhs);
01715 }
01716
01717 BOOST_UBLAS_INLINE
01718 bool equal(const self_type& rhs) const {
01719 return ((v1_ == rhs.v1_) && (v2_ == rhs.v2_));
01720 }
01721 BOOST_UBLAS_INLINE
01722 bool less(const self_type& rhs) const {
01723 return ((v1_ < rhs.v1_) ||
01724 (v1_ == rhs.v1_ && v2_ < rhs.v2_));
01725 }
01726 BOOST_UBLAS_INLINE
01727 friend bool operator == (const self_type& lhs, const self_type& rhs) {
01728 return lhs.equal(rhs);
01729 }
01730 BOOST_UBLAS_INLINE
01731 friend bool operator != (const self_type& lhs, const self_type& rhs) {
01732 return !lhs.equal(rhs);
01733 }
01734 BOOST_UBLAS_INLINE
01735 friend bool operator < (const self_type& lhs, const self_type& rhs) {
01736 return lhs.less(rhs);
01737 }
01738
01739 private:
01740 size_type i_;
01741 typename M::value1_type v1_;
01742 typename M::value2_type v2_;
01743 typename M::value3_type v3_;
01744 bool dirty_;
01745 bool is_copy_;
01746 };
01747
01748 template <class V1, class V2, class V3>
01749 class index_triple_array:
01750 private boost::noncopyable {
01751
01752 typedef index_triple_array<V1, V2, V3> self_type;
01753 public:
01754 typedef typename V1::value_type value1_type;
01755 typedef typename V2::value_type value2_type;
01756 typedef typename V3::value_type value3_type;
01757
01758 typedef typename V1::size_type size_type;
01759 typedef typename V1::difference_type difference_type;
01760 typedef index_triple<self_type> value_type;
01761
01762 typedef value_type reference;
01763 typedef const value_type const_reference;
01764
01765 BOOST_UBLAS_INLINE
01766 index_triple_array(size_type size, V1& data1, V2& data2, V3& data3) :
01767 size_(size),data1_(data1),data2_(data2),data3_(data3) {}
01768
01769 BOOST_UBLAS_INLINE
01770 size_type size() const {
01771 return size_;
01772 }
01773
01774 BOOST_UBLAS_INLINE
01775 const_reference operator () (size_type i) const {
01776 return value_type((*this), i);
01777 }
01778 BOOST_UBLAS_INLINE
01779 reference operator () (size_type i) {
01780 return value_type((*this), i);
01781 }
01782
01783 typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
01784 typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
01785
01786 BOOST_UBLAS_INLINE
01787 iterator begin() {
01788 return iterator( (*this), 0);
01789 }
01790 BOOST_UBLAS_INLINE
01791 iterator end() {
01792 return iterator( (*this), size());
01793 }
01794
01795 BOOST_UBLAS_INLINE
01796 const_iterator begin() const {
01797 return const_iterator( (*this), 0);
01798 }
01799 BOOST_UBLAS_INLINE
01800 const_iterator end() const {
01801 return const_iterator( (*this), size());
01802 }
01803
01804
01805 BOOST_UBLAS_INLINE
01806 bool equal(size_type i1, size_type i2) const {
01807 return ((data1_[i1] == data1_[i2]) && (data2_[i1] == data2_[i2]));
01808 }
01809 BOOST_UBLAS_INLINE
01810 bool less(size_type i1, size_type i2) const {
01811 return ((data1_[i1] < data1_[i2]) ||
01812 (data1_[i1] == data1_[i2] && data2_[i1] < data2_[i2]));
01813 }
01814
01815
01816 BOOST_UBLAS_INLINE
01817 friend void iter_swap(const iterator& lhs, const iterator& rhs) {
01818 const size_type i1 = lhs.index();
01819 const size_type i2 = rhs.index();
01820 std::swap(lhs().data1_[i1], rhs().data1_[i2]);
01821 std::swap(lhs().data2_[i1], rhs().data2_[i2]);
01822 std::swap(lhs().data3_[i1], rhs().data3_[i2]);
01823 }
01824
01825 private:
01826 size_type size_;
01827 V1& data1_;
01828 V2& data2_;
01829 V3& data3_;
01830
01831
01832 friend class index_triple<self_type>;
01833 };
01834
01835 }}}
01836
01837 #endif