00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_UTIL_ARRAY_HH
00027 # define MLN_UTIL_ARRAY_HH
00028
00035
00036 # include <vector>
00037 # include <iostream>
00038 # include <algorithm>
00039
00040 # include <mln/core/concept/function.hh>
00041 # include <mln/core/concept/proxy.hh>
00042 # include <mln/core/concept/iterator.hh>
00043
00044
00045
00046 namespace mln
00047 {
00048
00049 namespace util
00050 {
00051
00053 template <typename T>
00054 class array;
00055
00056 }
00057
00058
00059 namespace convert
00060 {
00061
00062 namespace over_load
00063 {
00064
00065 template <typename T1, typename T2>
00066 void
00067 from_to_(const util::array<T1>& from, util::array<T2>& to);
00068
00069 }
00070
00071 }
00072
00073
00074
00075 namespace util
00076 {
00077
00078
00079 template <typename T> class array_fwd_iter;
00080 template <typename T> class array_bkd_iter;
00081
00082
00091
00092 template <typename T>
00093 class array : public Function_v2v< mln::util::array<T> >
00094 {
00095 public:
00096
00098 typedef T element;
00099
00103 typedef T result;
00104 typedef typename std::vector<T>::reference mutable_result;
00106
00107
00111 typedef array_fwd_iter<T> fwd_eiter;
00112
00114 typedef array_bkd_iter<T> bkd_eiter;
00115
00117 typedef fwd_eiter eiter;
00119
00120
00124 array();
00125
00127 array(unsigned n);
00128
00131 array(unsigned n, const T& value);
00133
00135 void reserve(unsigned n);
00136
00138 void resize(unsigned n);
00139
00141 void resize(unsigned n, const T& value);
00142
00143
00145 array<T>& append(const T& elt);
00146
00148 template <typename U>
00149 array<T>& append(const array<U>& other);
00150
00151
00153 unsigned nelements() const;
00154
00158 unsigned size() const;
00159
00161 bool is_empty() const;
00162
00163
00166 const T& operator()(unsigned i) const;
00167
00170 mutable_result operator()(unsigned i);
00171
00174 const T& operator[](unsigned i) const;
00175
00178 mutable_result operator[](unsigned i);
00179
00180
00183 void clear();
00184
00186 void fill(const T& value);
00187
00189 const std::vector<T>& std_vector() const;
00190
00192 std::vector<T>& hook_std_vector_();
00193
00195 std::size_t memory_size() const;
00196
00197 private:
00198 std::vector<T> v_;
00199 };
00200
00201
00203 template <typename T>
00204 std::ostream& operator<<(std::ostream& ostr,
00205 const array<T>& a);
00206
00208 template <typename T>
00209 bool operator==(const array<T>& lhs,
00210 const array<T>& rhs);
00211
00212
00213
00214
00215 template <typename T>
00216 class array_fwd_iter : public Proxy< array_fwd_iter<T> >,
00217 public mln::internal::proxy_impl< const T&,
00218 array_fwd_iter<T> >
00219 {
00220 public:
00221
00225 array_fwd_iter();
00226
00228 array_fwd_iter(const array<T>& a);
00230
00232 void change_target(const array<T>& a);
00233
00235 void start();
00236
00238 void next();
00239
00241 bool is_valid() const;
00242
00244 void invalidate();
00245
00247 const T& element() const;
00248
00249
00250 const T& subj_();
00251
00253 unsigned index_() const;
00254
00255 protected:
00256 unsigned i_;
00257 const array<T>* a_;
00258 };
00259
00260
00261
00262
00263
00264
00265 template <typename T>
00266 class array_bkd_iter : public Proxy< array_bkd_iter<T> >,
00267 public mln::internal::proxy_impl< const T&,
00268 array_bkd_iter<T> >
00269 {
00270 public:
00274 array_bkd_iter();
00275
00277 array_bkd_iter(const array<T>& a);
00279
00281 void change_target(const array<T>& a);
00282
00284 void start();
00285
00287 void next();
00288
00290 bool is_valid() const;
00291
00293 void invalidate();
00294
00296 const T& element() const;
00297
00298
00299 const T& subj_();
00300
00302 unsigned index_() const;
00303
00304 protected:
00305 unsigned i_;
00306 const array<T>* a_;
00307 };
00308
00309 }
00310
00311
00312 namespace internal
00313 {
00314
00315 template <typename T, typename E>
00316 struct subject_impl<const util::array<T>&, E>
00317 {
00318 unsigned nelements() const;
00319 unsigned size() const;
00320 bool is_empty() const;
00321 const T& operator()(unsigned i) const;
00322 const T& operator[](unsigned i) const;
00323 const std::vector<T>& std_vector() const;
00324
00325 private:
00326 const E& exact_() const;
00327 };
00328
00329
00330 template <typename T, typename E>
00331 struct subject_impl<util::array<T>&, E>
00332 : subject_impl<const util::array<T>&, E>
00333 {
00334 typedef typename util::array<T>::mutable_result mutable_result;
00335
00336 void reserve(unsigned n);
00337 void resize(unsigned n);
00338 void resize(unsigned n, const T& value);
00339
00340 util::array<T>& append(const T& elt);
00341
00342 template <typename U>
00343 util::array<T>& append(const util::array<U>& other);
00344
00345 mutable_result operator()(unsigned i);
00346 mutable_result operator[](unsigned i);
00347
00348 void clear();
00349
00350 void fill(const T& value);
00351
00352 std::vector<T>& hook_std_vector_();
00353
00354 private:
00355 E& exact_();
00356 };
00357
00358
00359 }
00360
00361
00362 # ifndef MLN_INCLUDE_ONLY
00363
00364
00365
00366
00367 namespace convert
00368 {
00369
00370 namespace over_load
00371 {
00372
00373 template <typename T1, typename T2>
00374 void
00375 from_to_(const util::array<T1>& from, util::array<T2>& to)
00376 {
00377 to.reserve(from.nelements());
00378
00379 for (unsigned i = 0; i < from.nelements(); ++i)
00380 to.append(convert::to<T2>(from[i]));
00381 }
00382
00383 }
00384
00385 }
00386
00387
00388 namespace util
00389 {
00390
00391
00392
00393
00394 template <typename T>
00395 inline
00396 array<T>::array()
00397 {
00398 }
00399
00400 template <typename T>
00401 inline
00402 array<T>::array(unsigned n)
00403 : v_(n)
00404 {
00405 }
00406
00407 template <typename T>
00408 inline
00409 array<T>::array(unsigned n, const T& value)
00410 : v_(n, value)
00411 {
00412 }
00413
00414 template <typename T>
00415 inline
00416 void
00417 array<T>::reserve(unsigned n)
00418 {
00419 v_.reserve(n);
00420 }
00421
00422 template <typename T>
00423 inline
00424 void
00425 array<T>::resize(unsigned n)
00426 {
00427 v_.resize(n);
00428 }
00429
00430 template <typename T>
00431 inline
00432 void
00433 array<T>::resize(unsigned n, const T& value)
00434 {
00435 v_.resize(n, value);
00436 }
00437
00438 template <typename T>
00439 inline
00440 array<T>&
00441 array<T>::append(const T& elt)
00442 {
00443 v_.push_back(elt);
00444 return *this;
00445 }
00446
00447 template <typename T>
00448 template <typename U>
00449 inline
00450 array<T>&
00451 array<T>::append(const array<U>& other)
00452 {
00453 if (other.is_empty())
00454
00455 return *this;
00456 v_.insert(v_.end(),
00457 other.std_vector().begin(), other.std_vector().end());
00458 return *this;
00459 }
00460
00461 template <typename T>
00462 inline
00463 void
00464 array<T>::clear()
00465 {
00466 v_.clear();
00467 mln_postcondition(is_empty());
00468 }
00469
00470 template <typename T>
00471 inline
00472 void
00473 array<T>::fill(const T& value)
00474 {
00475 std::fill(v_.begin(), v_.end(), value);
00476 }
00477
00478 template <typename T>
00479 inline
00480 unsigned
00481 array<T>::size() const
00482 {
00483 return nelements();
00484 }
00485
00486 template <typename T>
00487 inline
00488 unsigned
00489 array<T>::nelements() const
00490 {
00491 return v_.size();
00492 }
00493
00494 template <typename T>
00495 inline
00496 const T&
00497 array<T>::operator()(unsigned i) const
00498 {
00499 return (*this)[i];
00500 }
00501
00502 template <typename T>
00503 inline
00504 typename array<T>::mutable_result
00505 array<T>::operator()(unsigned i)
00506 {
00507 return (*this)[i];
00508 }
00509
00510 template <typename T>
00511 inline
00512 const T&
00513 array<T>::operator[](unsigned i) const
00514 {
00515 mln_precondition(i < nelements());
00516 return v_[i];
00517 }
00518
00519 template <typename T>
00520 inline
00521 typename array<T>::mutable_result
00522 array<T>::operator[](unsigned i)
00523 {
00524 mln_precondition(i < nelements());
00525 return v_[i];
00526 }
00527
00528 template <typename T>
00529 inline
00530 bool
00531 array<T>::is_empty() const
00532 {
00533 return nelements() == 0;
00534 }
00535
00536 template <typename T>
00537 inline
00538 const std::vector<T>&
00539 array<T>::std_vector() const
00540 {
00541 return v_;
00542 }
00543
00544 template <typename T>
00545 inline
00546 std::vector<T>&
00547 array<T>::hook_std_vector_()
00548 {
00549 return v_;
00550 }
00551
00552 template <typename T>
00553 inline
00554 std::size_t
00555 array<T>::memory_size() const
00556 {
00557 return sizeof(*this) + nelements() * sizeof(T);
00558 }
00559
00560
00561
00562
00563
00564
00565 template <typename T>
00566 inline
00567 array_fwd_iter<T>::array_fwd_iter()
00568 {
00569 a_ = 0;
00570 }
00571
00572 template <typename T>
00573 inline
00574 array_fwd_iter<T>::array_fwd_iter(const array<T>& a)
00575 {
00576 change_target(a);
00577 }
00578
00579 template <typename T>
00580 inline
00581 void
00582 array_fwd_iter<T>::change_target(const array<T>& a)
00583 {
00584 a_ = &a;
00585 invalidate();
00586 }
00587
00588 template <typename T>
00589 inline
00590 void
00591 array_fwd_iter<T>::start()
00592 {
00593 mln_precondition(a_ != 0);
00594 i_ = 0;
00595 }
00596
00597 template <typename T>
00598 inline
00599 void
00600 array_fwd_iter<T>::next()
00601 {
00602 mln_precondition(is_valid());
00603 ++i_;
00604 }
00605
00606 template <typename T>
00607 inline
00608 bool
00609 array_fwd_iter<T>::is_valid() const
00610 {
00611 return a_ != 0 && i_ != a_->nelements();
00612 }
00613
00614 template <typename T>
00615 inline
00616 void
00617 array_fwd_iter<T>::invalidate()
00618 {
00619 if (a_ != 0)
00620 i_ = a_->nelements();
00621 mln_postcondition(! is_valid());
00622 }
00623
00624 template <typename T>
00625 inline
00626 const T&
00627 array_fwd_iter<T>::element() const
00628 {
00629 mln_precondition(is_valid());
00630 return a_->operator[](i_);
00631 }
00632
00633 template <typename T>
00634 inline
00635 const T&
00636 array_fwd_iter<T>::subj_()
00637 {
00638 mln_precondition(is_valid());
00639 return a_->operator[](i_);
00640 }
00641
00642 template <typename T>
00643 inline
00644 unsigned
00645 array_fwd_iter<T>::index_() const
00646 {
00647 return i_;
00648 }
00649
00650
00651
00652
00653
00654
00655 template <typename T>
00656 inline
00657 array_bkd_iter<T>::array_bkd_iter()
00658 {
00659 a_ = 0;
00660 }
00661
00662 template <typename T>
00663 inline
00664 array_bkd_iter<T>::array_bkd_iter(const array<T>& a)
00665 {
00666 change_target(a);
00667 }
00668
00669 template <typename T>
00670 inline
00671 void
00672 array_bkd_iter<T>::change_target(const array<T>& a)
00673 {
00674 a_ = &a;
00675 invalidate();
00676 }
00677
00678 template <typename T>
00679 inline
00680 void
00681 array_bkd_iter<T>::start()
00682 {
00683 mln_precondition(a_ != 0);
00684 if (! a_->is_empty())
00685 i_ = a_->nelements() - 1;
00686 }
00687
00688 template <typename T>
00689 inline
00690 void
00691 array_bkd_iter<T>::next()
00692 {
00693 mln_precondition(is_valid());
00694 if (i_ == 0)
00695 invalidate();
00696 else
00697 --i_;
00698 }
00699
00700 template <typename T>
00701 inline
00702 bool
00703 array_bkd_iter<T>::is_valid() const
00704 {
00705 return a_ != 0 && i_ != a_->nelements();
00706 }
00707
00708 template <typename T>
00709 inline
00710 void
00711 array_bkd_iter<T>::invalidate()
00712 {
00713 if (a_ != 0)
00714 i_ = a_->nelements();
00715 mln_postcondition(! is_valid());
00716 }
00717
00718 template <typename T>
00719 inline
00720 const T&
00721 array_bkd_iter<T>::element() const
00722 {
00723 mln_precondition(is_valid());
00724 return a_->operator[](i_);
00725 }
00726
00727 template <typename T>
00728 inline
00729 const T&
00730 array_bkd_iter<T>::subj_()
00731 {
00732 mln_precondition(is_valid());
00733 return a_->operator[](i_);
00734 }
00735
00736 template <typename T>
00737 inline
00738 unsigned
00739 array_bkd_iter<T>::index_() const
00740 {
00741 return i_;
00742 }
00743
00744
00745
00746
00747
00748 template <typename T>
00749 std::ostream& operator<<(std::ostream& ostr,
00750 const array<T>& a)
00751 {
00752 ostr << '[';
00753 const unsigned n = a.nelements();
00754 for (unsigned i = 0; i < n; ++i)
00755 {
00756 ostr << a[i];
00757 if (i != n - 1)
00758 ostr << ", ";
00759 }
00760 ostr << ']';
00761 return ostr;
00762 }
00763
00764
00765
00766
00767 template <typename T>
00768 bool operator==(const array<T>& lhs,
00769 const array<T>& rhs)
00770 {
00771 return lhs.std_vector() == rhs.std_vector();
00772 }
00773
00774 }
00775
00776
00777 namespace internal
00778 {
00779
00780 template <typename T, typename E>
00781 inline
00782 void
00783 subject_impl<util::array<T>&, E>::reserve(unsigned n)
00784 {
00785 exact_().get_subject().reserve(n);
00786 }
00787
00788 template <typename T, typename E>
00789 inline
00790 void
00791 subject_impl<util::array<T>&, E>::resize(unsigned n)
00792 {
00793 exact_().get_subject().resize(n);
00794 }
00795
00796 template <typename T, typename E>
00797 inline
00798 void
00799 subject_impl<util::array<T>&, E>::resize(unsigned n, const T& value)
00800 {
00801 exact_().get_subject().resize(n, value);
00802 }
00803
00804 template <typename T, typename E>
00805 inline
00806 util::array<T>&
00807 subject_impl<util::array<T>&, E>::append(const T& elt)
00808 {
00809 return exact_().get_subject().append(elt);
00810 }
00811
00812 template <typename T, typename E>
00813 template <typename U>
00814 inline
00815 util::array<T>&
00816 subject_impl<util::array<T>&, E>::append(const util::array<U>& other)
00817 {
00818 return exact_().get_subject().append(other);
00819 }
00820
00821 template <typename T, typename E>
00822 inline
00823 typename util::array<T>::mutable_result
00824 subject_impl<util::array<T>&, E>::operator()(unsigned i)
00825 {
00826 return exact_().get_subject()(i);
00827 }
00828
00829 template <typename T, typename E>
00830 inline
00831 typename util::array<T>::mutable_result
00832 subject_impl<util::array<T>&, E>::operator[](unsigned i)
00833 {
00834 return exact_().get_subject()[i];
00835 }
00836
00837 template <typename T, typename E>
00838 inline
00839 void
00840 subject_impl<util::array<T>&, E>::clear()
00841 {
00842 exact_().get_subject().clear();
00843 }
00844
00845 template <typename T, typename E>
00846 inline
00847 void
00848 subject_impl<util::array<T>&, E>::fill(const T& value)
00849 {
00850 exact_().get_subject().fill(value);
00851 }
00852
00853 template <typename T, typename E>
00854 inline
00855 std::vector<T>&
00856 subject_impl<util::array<T>&, E>::hook_std_vector_()
00857 {
00858 return exact_().get_subject().hook_std_vector_();
00859 }
00860
00861 template <typename T, typename E>
00862 inline
00863 E&
00864 subject_impl<util::array<T>&, E >::exact_()
00865 {
00866 return internal::force_exact<E>(*this);
00867 }
00868
00869
00870 template <typename T, typename E>
00871 inline
00872 unsigned
00873 subject_impl<const util::array<T>&, E>::size() const
00874 {
00875 return exact_().get_subject().size();
00876 }
00877
00878 template <typename T, typename E>
00879 inline
00880 unsigned
00881 subject_impl<const util::array<T>&, E>::nelements() const
00882 {
00883 return exact_().get_subject().nelements();
00884 }
00885
00886 template <typename T, typename E>
00887 inline
00888 bool
00889 subject_impl<const util::array<T>&, E>::is_empty() const
00890 {
00891 return exact_().get_subject().is_empty();
00892 }
00893
00894 template <typename T, typename E>
00895 inline
00896 const T&
00897 subject_impl<const util::array<T>&, E>::operator()(unsigned i) const
00898 {
00899 return exact_().get_subject()(i);
00900 }
00901
00902 template <typename T, typename E>
00903 inline
00904 const T&
00905 subject_impl<const util::array<T>&, E>::operator[](unsigned i) const
00906 {
00907 return exact_().get_subject()[i];
00908 }
00909
00910 template <typename T, typename E>
00911 inline
00912 const std::vector<T>&
00913 subject_impl<const util::array<T>&, E>::std_vector() const
00914 {
00915 return exact_().get_subject().std_vector();
00916 }
00917
00918 template <typename T, typename E>
00919 inline
00920 const E&
00921 subject_impl<const util::array<T>&, E >::exact_() const
00922 {
00923 return internal::force_exact<const E>(*this);
00924 }
00925
00926
00927 }
00928
00929 # endif // ! MLN_INCLUDE_ONLY
00930
00931
00932 }
00933
00934 #endif // ! MLN_UTIL_ARRAY_HH