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_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
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 }
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 }
00321
00322 }
00323
00324 }
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