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