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