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

array.hh

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

Generated on Tue Oct 4 2011 15:23:24 for Milena (Olena) by  doxygen 1.7.1