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

array.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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   } // end of namespace mln::util
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     } // end of namespace mln::convert::over_load
00070 
00071   } // end of namespace mln::convert
00072 
00073 
00074 
00075   namespace util
00076   {
00077 
00078     // Forward declarations.
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     // array_fwd_iter<T>
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       // As a Proxy.
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     // array_bkd_iter<T>
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       // As a Proxy.
00299       const T& subj_();
00300 
00302       unsigned index_() const;
00303 
00304     protected:
00305       unsigned i_;
00306       const array<T>* a_;
00307     };
00308 
00309   } // end of namespace mln::util
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   } // end of namespace mln::internal
00360 
00361 
00362 # ifndef MLN_INCLUDE_ONLY
00363 
00364 
00365   // convert::from_to_
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     } // end of namespace mln::convert::over_load
00384 
00385   } // end of namespace mln::convert
00386 
00387 
00388   namespace util
00389   {
00390 
00391     // util::array<T>
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         // No-op.
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     // util::array_fwd_iter<T>
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     // util::array_bkd_iter<T>
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     // Operator <<.
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     // Operator <<.
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   } // end of namespace mln::util
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   } // end of namespace mln::internal
00928 
00929 # endif // ! MLN_INCLUDE_ONLY
00930 
00931 
00932 } // end of namespace mln
00933 
00934 #endif // ! MLN_UTIL_ARRAY_HH

Generated on Thu Sep 8 2011 18:31:29 for Milena (Olena) by  doxygen 1.7.1