• 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_UNARY_HH
00027 # define MLN_FUN_UNARY_HH
00028 
00029 # include <mln/core/concept/meta_function.hh>
00030 # include <mln/fun/spe/unary.hh>
00031 # include <mln/trait/next/solve.hh>
00032 
00033 
00034 namespace mln
00035 {
00036 
00037   namespace fun
00038   {
00039 
00040     // Forward declarations, for composition with unary::operator()(Fun)
00041     struct compose;
00042 
00043     namespace internal
00044     {
00045 
00046       template <typename U>
00047       struct unary_with {};
00048 
00049     }
00050 
00051     template <typename F, typename E = F>
00052     struct unary: mln::Meta_Function_v2v< E >
00053     {
00054       typedef F flag;
00055       typedef mln_trait_fun_param(flag) param;
00056       typedef mln_trait_fun_storage(flag) storage;
00057 
00058       template <typename T>
00059       struct with {
00060         typedef mln_trait_nunary(internal::unary_with<F>, T) def;
00061         typedef typename def::ret ret;
00062       };
00063 
00064       template <typename T>
00065       typename with<T>::ret::result operator()(const T& v) const
00066       {
00067         return with<T>::def::call(exact(*this), v);
00068       }
00069 
00070       template <typename T>
00071       typename with<T>::ret::template lresult_with<T>::ret operator()(T& v) const
00072       {
00073         // See the commentary in next method.
00074         typedef typename with<T>::ret fun_t;
00075         fun_t f(state());
00076         return f.apply_rw(v);
00077       }
00078 
00079       template <typename T, typename R>
00080       void set(T& v, const R& r) const
00081       {
00082         // Decomposing "with<T>::ret(state()).set(v, r)" into 3 lines
00083         // helps g++-3.3!
00084         typedef typename with<T>::ret fun_t;
00085         fun_t f(state());
00086         f.set(v, r);
00087       }
00088 
00089       template <typename U>
00090       void init(const U& value)
00091       {
00092         state_ = mln::trait::function::internal::introspect::has_storage_t<flag, void>::compute(value);
00093       };
00094 
00095       unary()
00096       {
00097       }
00098 
00099       template <typename U>
00100       unary(const U& param)
00101       {
00102         this->init(param);
00103       }
00104 
00105       stored<storage>& state()
00106       {
00107         return state_;
00108       }
00109 
00110       const stored<storage>& state() const
00111       {
00112         return state_;
00113       }
00114 
00115     protected:
00116       stored<storage> state_;
00117     };
00118 
00119   } // end of namespace mln::fun
00120 
00121   namespace trait
00122   {
00123 
00124     namespace next
00125     {
00126 
00127       // Any type
00128       template <typename F, typename T>
00129       struct set_unary_< mln::fun::internal::unary_with<F>, mln::Object, T>
00130       {
00131         struct ret_t
00132         {
00133           typedef mln::fun::spe::unary<F, T> ret;
00134 
00135           static typename ret::result call(const F& f, const T& v)
00136           {
00137             return ret(f.state())(v);
00138           }
00139         };
00140 
00141         typedef ret_t ret;
00142       };
00143 
00144       // Meta Function
00145       template <typename F, typename G>
00146       struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function, G>
00147       {
00148         // FIXME: Workaround for cyclic references (unary -> unary_with -> compose -> unary)
00149         template <typename T>
00150         struct identity
00151         {
00152           typedef T ret;
00153         };
00154 
00155         struct ret_t
00156         {
00157           typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret ret;
00158 
00159           static typename ret::result call(const F& f, const G& g)
00160           {
00161             return ret()(f, g);
00162           }
00163 
00164         };
00165 
00166         typedef ret_t ret;
00167       };
00168 
00169     } // end of namespace mln::trait::next
00170 
00171   } // end of namespace mln::trait
00172 
00173 } // end of namespace mln
00174 
00175 #endif // ! MLN_FUN_UNARY_HH

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