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

unary.hh

00001 // Copyright (C) 2007, 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_FUN_SPE_UNARY_HH
00028 # define MLN_FUN_SPE_UNARY_HH
00029 
00030 # include <mln/core/concept/function.hh>
00031 # include <mln/trait/next/solve.hh>
00032 # include <mln/trait/functions.hh>
00033 
00034 namespace mln
00035 {
00036 
00037   namespace fun
00038   {
00039 
00040     namespace spe
00041     {
00042 
00043       // Wrapper for bijective functions
00044       template <typename Fun, typename T>
00045       struct lwrapper
00046       {
00047         typedef typename Fun::result   result;
00048         typedef typename Fun::argument argument;
00049         typedef typename Fun::lvalue   lvalue;
00050         typedef lwrapper               lresult;
00051 
00052         lwrapper(const Fun& f, T& x)
00053         : x_(&x), f_(&f)
00054         {
00055         }
00056 
00057         result to_result() const
00058         {
00059           return (*f_)(*const_cast<const T*>(x_));
00060         };
00061 
00062         operator result() const
00063         {
00064           return to_result();
00065         };
00066 
00067         const result& operator = (const result& r) const
00068         {
00069           argument x(*x_);
00070           f_->set(x, r);
00071           *x_ = x;
00072 
00073           return r;
00074         }
00075 
00076         private:
00077           T *x_;
00078           const Fun *f_;
00079       };
00080 
00081       template <typename Fun>
00082       struct lwrapper<Fun, typename Fun::argument>
00083       {
00084         typedef typename Fun::result   result;
00085         typedef typename Fun::argument argument;
00086         typedef typename Fun::lvalue   lvalue;
00087         typedef lwrapper               lresult;
00088 
00089         lwrapper(const Fun& f, argument& x)
00090         : x_(&x), f_(&f)
00091         {
00092         }
00093 
00094         result to_result() const
00095         {
00096           return (*f_)(*const_cast<const argument*>(x_));
00097         };
00098 
00099         operator result() const
00100         {
00101           return to_result();
00102         };
00103 
00104         const result& operator = (const result& r) const
00105         {
00106           f_->set(*x_, r);
00107 
00108           return r;
00109         }
00110 
00111         private:
00112           argument *x_;
00113           const Fun *f_;
00114       };
00115 
00116       template <typename Fun, typename Any, typename T>
00117       struct lwrapper<Fun, lwrapper<Any, T> >
00118       {
00119         typedef typename Fun::result   result;
00120         typedef typename Fun::argument argument;
00121         typedef typename Fun::lvalue   lvalue;
00122         typedef lwrapper               lresult;
00123 
00124         lwrapper(const Fun& f, const lwrapper<Any, T>& m)
00125         : m_(m), f_(&f)
00126         {
00127         }
00128 
00129         result to_result() const
00130         {
00131           return (*f_)(m_.to_result());
00132         };
00133 
00134         operator result() const
00135         {
00136           return to_result();
00137         };
00138 
00139         const result& operator = (const result& r) const
00140         {
00141           argument m(m_);
00142           f_->set(m, r);
00143           m_ = m;
00144 
00145           return r;
00146         }
00147 
00148         private:
00149           const lwrapper<Any, T> m_;
00150           const Fun *f_;
00151       };
00152 
00153       template <typename Fun, typename T>
00154       struct unary;
00155 
00156       namespace impl
00157       {
00158 
00159         template <bool param, bool set, typename Fun, typename T>
00160         struct unary_impl;
00161 
00162         template <typename Fun, typename T>
00163         struct unary_impl<false, false, Fun, T> : Function_v2v< unary<Fun, T> >
00164         {
00165           typedef Fun flag;
00166           typedef mln_trait_nunary(Fun, T) def;
00167 
00168           typedef typename def::argument argument;
00169           typedef typename def::result   result;
00170 
00171           result operator () (const argument& value) const
00172           {
00173             return def::read(value);
00174           }
00175 
00176           template <typename U>
00177           void init(const U& value)
00178           {
00179             (void) value;
00180           };
00181 
00182         };
00183 
00184         template <typename Fun, typename T>
00185         struct unary_impl<false, true, Fun, T> : unary_impl<false, false, Fun, T>
00186         {
00187           typedef unary_impl<false, false, Fun, T> super;
00188           typedef typename super::def::lvalue lvalue;
00189 
00190           template <typename U>
00191           struct lresult_with
00192           {
00193             typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
00194           };
00195 
00196           typedef typename lresult_with<typename super::argument>::ret lresult;
00197 
00198           void set(lvalue l, const typename super::result& r) const
00199           {
00200             super::def::write(l, r);
00201           }
00202 
00203           using super::operator ();
00204 
00205           lresult apply_rw(typename super::argument& value) const
00206           {
00207             return lresult(exact(*this), value);
00208           }
00209 
00210           template <typename U>
00211           typename lresult_with<U>::ret apply_rw(U& value) const
00212           {
00213             return typename lresult_with<U>::ret(exact(*this), value);
00214           }
00215 
00216           lresult operator () (typename super::argument& value) const
00217           {
00218             return apply_rw(value);
00219           }
00220         };
00221 
00222         template <typename Fun, typename T>
00223         struct unary_impl<true, false, Fun, T> : Function_v2v< unary<Fun, T> >
00224         {
00225           typedef Fun flag;
00226           typedef mln_trait_nunary(Fun, T) def;
00227 
00228           typedef typename def::argument argument;
00229           typedef typename def::result   result;
00230 
00231           typedef mln_trait_fun_param(unary_impl) param;
00232           typedef mln_trait_fun_storage(unary_impl) storage;
00233 
00234           result operator () (const argument& value) const
00235           {
00236             return def::read(this->state_, value);
00237           }
00238 
00239           template <typename U>
00240           void init(const U& value)
00241           {
00242             state_ = mln::trait::function::internal::introspect::has_storage_t<def, void>::compute(value);
00243           };
00244 
00245           stored<storage>& state()
00246           {
00247             return state_;
00248           }
00249 
00250           const stored<storage>& state() const
00251           {
00252             return state_;
00253           }
00254 
00255         protected:
00256           stored<storage> state_;
00257         };
00258 
00259         template <typename Fun, typename T>
00260         struct unary_impl<true, true, Fun, T> : unary_impl<true, false, Fun, T>
00261         {
00262           typedef unary_impl<true, false, Fun, T> super;
00263           typedef typename super::def::lvalue lvalue;
00264 
00265           template <typename U>
00266           struct lresult_with
00267           {
00268             typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
00269           };
00270 
00271           typedef typename lresult_with<typename super::argument>::ret lresult;
00272 
00273           void set(lvalue l, const typename super::result& r) const
00274           {
00275             super::def::write(this->state(), l, r);
00276           }
00277 
00278           using super::operator ();
00279 
00280           lresult apply_rw(typename super::argument& value) const
00281           {
00282             return lresult(exact(*this), value);
00283           }
00284 
00285           template <typename U>
00286           typename lresult_with<U>::ret apply_rw(U& value) const
00287           {
00288             return typename lresult_with<U>::ret(exact(*this), value);
00289           }
00290 
00291           lresult operator () (typename super::argument& value) const
00292           {
00293             return apply_rw(value);
00294           }
00295         };
00296 
00297       } // end of namespace mln::fun::spe::impl
00298 
00299       template <typename Fun, typename T>
00300       struct unary
00301       : impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(mln_trait_nunary(Fun, T)), mln_trait_fun_is_parametrable(Fun))::value,
00302                          mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value, Fun, T>
00303       {
00304         typedef mln_trait_nunary(Fun, T) def;
00305         typedef impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(def), mln_trait_fun_is_parametrable(Fun))::value,
00306                                  mln_trait_fun_is_assignable_(def)::value,
00307                                  Fun,
00308                                  T>
00309                 super;
00310 
00311         unary() {}
00312 
00313         template <typename U>
00314         unary(const U& param)
00315         {
00316           this->init(param);
00317         }
00318 
00319         using super::operator();
00320       };
00321 
00322     } // end of namespace mln::fun::spe
00323 
00324   } // end of namespace mln::fun
00325 
00326 } // end of namespace mln
00327 
00328 template <typename F, typename T>
00329 std::ostream& operator << (std::ostream& o, const mln::fun::spe::lwrapper<F, T>& m)
00330 {
00331   return o << m.to_result();
00332 }
00333 
00334 #endif // ! MLN_FUN_SPE_UNARY_HH

Generated on Mon Jan 30 2012 17:36:25 for Milena (Olena) by  doxygen 1.7.1