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
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
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 }
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 }
00323
00324 }
00325
00326 }
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