Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 } // end of namespace mln::util 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 } // end of namespace mln::convert::over_load 00076 00077 } // end of namespace mln::convert 00078 00079 00080 00081 namespace util 00082 { 00083 00084 // Forward declarations. 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 // public Function_v2v< mln::util::array<T> > 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 // array_fwd_iter<T> 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 // As a Proxy. 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 // array_bkd_iter<T> 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 // As a Proxy. 00317 subj_t subj_(); 00318 00320 unsigned index_() const; 00321 00322 protected: 00323 unsigned i_; 00324 const array<T>* a_; 00325 }; 00326 00327 } // end of namespace mln::util 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 } // end of namespace mln::internal 00380 00381 00382 # ifndef MLN_INCLUDE_ONLY 00383 00384 00385 // convert::from_to_ 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 } // end of namespace mln::convert::over_load 00415 00416 } // end of namespace mln::convert 00417 00418 00419 namespace util 00420 { 00421 00422 // util::array<T> 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 // No-op. 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 // util::array_fwd_iter<T> 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 // util::array_bkd_iter<T> 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 // Operator <<. 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 // Operator <<. 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 } // end of namespace mln::util 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 } // end of namespace mln::internal 00975 00976 # endif // ! MLN_INCLUDE_ONLY 00977 00978 00979 } // end of namespace mln 00980 00981 #endif // ! MLN_UTIL_ARRAY_HH