00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
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     
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         
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         
00083         
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   } 
00120 
00121   namespace trait
00122   {
00123 
00124     namespace next
00125     {
00126 
00127       
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       
00145       template <typename F, typename G>
00146       struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function, G>
00147       {
00148         
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     } 
00170 
00171   } 
00172 
00173 } 
00174 
00175 #endif // ! MLN_FUN_UNARY_HH