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