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

unary.hh

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

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