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_CORE_CONCEPT_PROXY_HH
00027 # define MLN_CORE_CONCEPT_PROXY_HH
00028
00039 # include <mln/core/concept/object.hh>
00040 # include <mln/value/ops.hh>
00041
00042 # include <mln/convert/from_to.hxx>
00043 # include <mln/core/concept/proxy.hxx>
00044
00045
00046 # define mln_decl_unop_proxy(Name, Symb) \
00047 \
00048 template <typename P> \
00049 mln_trait_op_##Name(P) \
00050 operator Symb (const Proxy<P>& rhs); \
00051 \
00052 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
00053
00054
00055 # define mln_def_unop_proxy(Name, Symb) \
00056 \
00057 template <typename P> \
00058 inline \
00059 mln_trait_op_##Name(P) \
00060 operator Symb (const mln::Proxy<P>& rhs) \
00061 { \
00062 return Symb exact(rhs).unproxy_(); \
00063 } \
00064 \
00065 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
00066
00067
00068
00069
00070
00071 # define mln_decl_binop_proxy(Name, Symb) \
00072 \
00073 template <typename L, typename R> \
00074 mln_trait_op_##Name(L, R) \
00075 operator Symb (const Proxy<L>& lhs, const Proxy<R>& rhs); \
00076 \
00077 template <typename P, typename O> \
00078 mln_trait_op_##Name(P, O) \
00079 operator Symb (const Proxy<P>& p, const Object<O>& o); \
00080 \
00081 template <typename O, typename P> \
00082 mln_trait_op_##Name(O, P) \
00083 operator Symb (const Object<O>& o, const Proxy<P>& p); \
00084 \
00085 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
00086
00087
00088
00089 # define mln_def_binop_proxy(Name, Symb) \
00090 \
00091 template <typename L, typename R> \
00092 inline \
00093 mln_trait_op_##Name(L, R) \
00094 operator Symb (const mln::Proxy<L>& lhs, const mln::Proxy<R>& rhs) \
00095 { \
00096 typedef typename internal::helper_unprox_binop<L, R>::L_helper L_helper; \
00097 typedef typename internal::helper_unprox_binop<L, R>::R_helper R_helper; \
00098 return L_helper::on(lhs) Symb R_helper::on(rhs); \
00099 } \
00100 \
00101 template <typename P, typename O> \
00102 inline \
00103 mln_trait_op_##Name(P, O) \
00104 operator Symb (const Proxy<P>& p, const Object<O>& o) \
00105 { \
00106 return exact(p).unproxy_() Symb exact(o); \
00107 } \
00108 \
00109 template <typename O, typename P> \
00110 inline \
00111 mln_trait_op_##Name(O, P) \
00112 operator Symb (const Object<O>& o, const Proxy<P>& p) \
00113 { \
00114 return exact(o) Symb exact(p).unproxy_(); \
00115 } \
00116 \
00117 template <typename P, typename L> \
00118 inline \
00119 mln_trait_op_##Name(P, L) \
00120 operator Symb (const Proxy<P>& p, const Literal<L>& l) \
00121 { \
00122 return exact(p).unproxy_() Symb exact(l); \
00123 } \
00124 \
00125 template <typename L, typename P> \
00126 inline \
00127 mln_trait_op_##Name(L, P) \
00128 operator Symb (const Literal<L>& l, const Proxy<P>& p) \
00129 { \
00130 return exact(l) Symb exact(p).unproxy_(); \
00131 } \
00132 \
00133 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
00134
00135
00136
00137
00138 namespace mln
00139 {
00140
00141
00142 template <typename E> struct Proxy;
00143 template <typename E> struct Literal;
00144
00145
00146 namespace convert
00147 {
00148
00149 template <typename F, typename T>
00150 void from_to(const F& from, T& to);
00151
00152 }
00153
00154
00155
00156 namespace trait
00157 {
00158
00159
00160
00161 template < template <class> class Op, typename P >
00162 struct set_unary_< Op, mln::Proxy, P >
00163 {
00164 typedef mlc_unqualif(mln_q_subject(P)) S;
00165 typedef mln_trait_unary(Op, S) ret;
00166 };
00167
00168
00169
00170 template < template <class, class> class Op,
00171 typename L, typename R >
00172 struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
00173 {
00174 typedef mln::internal::helper_unprox_binop<L, R> helper;
00175 typedef mln_trait_binary(Op,
00176 typename helper::L_ret,
00177 typename helper::R_ret) ret;
00178 };
00179
00180 template < template <class, class> class Op,
00181 typename P, typename O >
00182 struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
00183 {
00184 typedef mlc_unqualif(mln_q_subject(P)) S;
00185 typedef mln_trait_binary(Op, S, O) ret;
00186 };
00187
00188 template < template <class, class> class Op,
00189 typename O, typename P >
00190 struct set_binary_< Op, mln::Object, O, mln::Proxy, P >
00191 {
00192 typedef mlc_unqualif(mln_q_subject(P)) S;
00193 typedef mln_trait_binary(Op, O, S) ret;
00194 };
00195
00196
00197
00198
00199 template < template <class, class> class Op,
00200 typename P, typename L >
00201 struct set_binary_< Op, mln::Proxy, P, mln::Literal, L >
00202 {
00203 typedef mlc_unqualif(mln_q_subject(P)) S;
00204 typedef mln_trait_binary(Op, S, L) ret;
00205 };
00206
00207 template < template <class, class> class Op,
00208 typename L, typename P >
00209 struct set_binary_< Op, mln::Literal, L, mln::Proxy, P >
00210 {
00211 typedef mlc_unqualif(mln_q_subject(P)) S;
00212 typedef mln_trait_binary(Op, L, S) ret;
00213 };
00214
00215 }
00216
00217
00218
00219
00221 template <>
00222 struct Proxy<void>
00223 {
00224 typedef Object<void> super;
00225 };
00226
00227
00231 template <typename E>
00232 struct Proxy : Object<E>
00233 {
00234 typedef Proxy<void> category;
00235
00236
00237
00238
00239
00240
00241
00242 protected:
00243 Proxy();
00244 };
00245
00246
00247
00248
00249 namespace convert
00250 {
00251
00252 namespace over_load
00253 {
00254
00255 template <typename P, typename T>
00256 void
00257 from_to_(const Proxy<P>& from, T& to);
00258
00259 }
00260
00261 }
00262
00263
00264
00265
00266
00267 template <typename T>
00268 struct subject
00269 {
00270 typedef typename mln::internal::unproxy_rec_<T>::ret q_ret;
00271 typedef mlc_unqualif(q_ret) ret;
00272 };
00273
00274
00275
00276
00277 template <typename T>
00278 typename mln::internal::unproxy_rec_<T>::ret
00279 unproxy_rec(T& t);
00280
00281 template <typename T>
00282 typename mln::internal::unproxy_rec_<const T>::ret
00283 unproxy_rec(const T& t);
00284
00285
00286
00287
00288 template <typename P>
00289 std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p);
00290
00291
00292
00293
00294 mln_decl_unop_proxy(uplus, + );
00295 mln_decl_unop_proxy(uminus, - );
00296 mln_decl_unop_proxy(preinc, ++ );
00297 mln_decl_unop_proxy(predec, -- );
00298 mln_decl_unop_proxy(not, ! );
00299
00300 mln_decl_binop_proxy(plus, + );
00301 mln_decl_binop_proxy(minus, - );
00302 mln_decl_binop_proxy(times, * );
00303 mln_decl_binop_proxy(div, / );
00304 mln_decl_binop_proxy(mod, % );
00305
00306 mln_decl_binop_proxy(eq, == );
00307 mln_decl_binop_proxy(neq, != );
00308
00309 mln_decl_binop_proxy(less, < );
00310 mln_decl_binop_proxy(leq, <= );
00311 mln_decl_binop_proxy(geq, >= );
00312 mln_decl_binop_proxy(greater, > );
00313
00314 mln_decl_binop_proxy(and, && );
00315 mln_decl_binop_proxy(or, || );
00316 mln_decl_binop_proxy(xor, ^ );
00317
00318
00319
00320 # ifndef MLN_INCLUDE_ONLY
00321
00322
00323
00324
00325 template <typename E>
00326 inline
00327 Proxy<E>::Proxy()
00328 {
00329 enum { proxy_level = E::proxy_level };
00330
00331 typedef typename E::q_subject q_subject;
00332
00333 q_subject (E::*m_)() = & E::subj_;
00334 m_ = 0;
00335 }
00336
00337
00338
00339
00340
00341 namespace convert
00342 {
00343
00344 namespace over_load
00345 {
00346
00347 template <typename P, typename T>
00348 void
00349 from_to_(const Proxy<P>& from, T& to)
00350 {
00351 convert::from_to(exact(from).unproxy_(), to);
00352 }
00353
00354 }
00355
00356 }
00357
00358
00359
00360
00361 template <typename T>
00362 inline
00363 typename mln::internal::unproxy_rec_<T>::ret
00364 unproxy_rec(T& t)
00365 {
00366 return mln::internal::unproxy_rec_<T>::on(t);
00367 }
00368
00369 template <typename T>
00370 inline
00371 typename mln::internal::unproxy_rec_<const T>::ret
00372 unproxy_rec(const T& t)
00373 {
00374 return mln::internal::unproxy_rec_<const T>::on(t);
00375 }
00376
00377
00378
00379
00380 template <typename P>
00381 inline
00382 std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p)
00383 {
00384 return ostr << unproxy_rec(p);
00385 }
00386
00387
00388
00389
00390 mln_def_unop_proxy(uplus, + );
00391 mln_def_unop_proxy(uminus, - );
00392 mln_def_unop_proxy(preinc, ++ );
00393 mln_def_unop_proxy(predec, -- );
00394 mln_def_unop_proxy(not, ! );
00395
00396
00397
00398
00399 mln_def_binop_proxy(plus, + );
00400 mln_def_binop_proxy(minus, - );
00401 mln_def_binop_proxy(times, * );
00402 mln_def_binop_proxy(div, / );
00403 mln_def_binop_proxy(mod, % );
00404
00405 mln_def_binop_proxy(eq, == );
00406 mln_def_binop_proxy(neq, != );
00407
00408 mln_def_binop_proxy(less, < );
00409 mln_def_binop_proxy(leq, <= );
00410 mln_def_binop_proxy(geq, >= );
00411 mln_def_binop_proxy(greater, > );
00412
00413 mln_def_binop_proxy(and, && );
00414 mln_def_binop_proxy(or, || );
00415 mln_def_binop_proxy(xor, ^ );
00416
00417
00418 # endif // ! MLN_INCLUDE_ONLY
00419
00420 }
00421
00422
00423 #endif // ! MLN_CORE_CONCEPT_PROXY_HH