• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

array.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
00002 // (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 
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     // array_fwd_iter<T>
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       // As a Proxy.
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     // array_bkd_iter<T>
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       // As a Proxy.
00312       subj_t subj_();
00313 
00315       unsigned index_() const;
00316 
00317     protected:
00318       unsigned i_;
00319       const array<T>* a_;
00320     };
00321 
00322   } // end of namespace mln::util
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   } // end of namespace mln::internal
00375 
00376 
00377 # ifndef MLN_INCLUDE_ONLY
00378 
00379 
00380   // convert::from_to_
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     } // end of namespace mln::convert::over_load
00410 
00411   } // end of namespace mln::convert
00412 
00413 
00414   namespace util
00415   {
00416 
00417     // util::array<T>
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         // No-op.
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     // util::array_fwd_iter<T>
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     // util::array_bkd_iter<T>
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     // Operator <<.
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     // Operator <<.
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   } // end of namespace mln::util
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 subject_impl<util::array<T>&, E>::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 subject_impl<util::array<T>&, E>::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 subject_impl<const util::array<T>&, E>::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 subject_impl<const util::array<T>&, E>::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   } // end of namespace mln::internal
00954 
00955 # endif // ! MLN_INCLUDE_ONLY
00956 
00957 
00958 } // end of namespace mln
00959 
00960 #endif // ! MLN_UTIL_ARRAY_HH

Generated on Fri Oct 19 2012 04:15:36 for Milena (Olena) by  doxygen 1.7.1