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_PSEUDO_SITE_HH
00027 # define MLN_CORE_CONCEPT_PSEUDO_SITE_HH
00028
00036
00037 # include <mln/core/concept/site_proxy.hh>
00038 # include <mln/metal/is_a.hh>
00039
00040
00041
00042 namespace mln
00043 {
00044
00045
00046 template <typename E> struct Pseudo_Site;
00047
00048
00049
00051 template <>
00052 struct Pseudo_Site<void>
00053 {
00054 typedef Site_Proxy<void> super;
00055 };
00056
00057
00063 template <typename E>
00064 struct Pseudo_Site : public Site_Proxy<E>
00065 {
00066 typedef Pseudo_Site<void> category;
00067
00068
00069
00070
00071
00072
00073 bool has_target() const;
00074
00075 protected:
00076 Pseudo_Site();
00077 };
00078
00079
00080 namespace if_possible
00081 {
00082
00083
00084
00085
00086 template <typename O, typename T>
00087 void change_target(Object<O>&, const T&);
00088
00089 }
00090
00091
00092 # ifndef MLN_INCLUDE_ONLY
00093
00094 template <typename E>
00095 inline
00096 Pseudo_Site<E>::Pseudo_Site()
00097 {
00098 typedef mln_target(E) target;
00099
00100 void (E::*m1)(const target&) = & E::change_target;
00101 m1 = 0;
00102 const target* (E::*m2)() const = & E::target_;
00103 m2 = 0;
00104 }
00105
00106 template <typename E>
00107 inline
00108 bool
00109 Pseudo_Site<E>::has_target() const
00110 {
00111 return exact(this)->target_() != 0;
00112 }
00113
00114
00115
00116 namespace if_possible
00117 {
00118
00119 namespace internal
00120 {
00121
00122 template <bool b> struct helper;
00123
00124 template <>
00125 struct helper< true >
00126 {
00127
00128 template <typename P>
00129 void change_target(Pseudo_Site<P>& p,
00130 const mln_target(P)& new_target) const
00131 {
00132 exact(p).change_target(new_target);
00133 }
00134
00135 template <typename O, typename D>
00136 void change_target(Object<O>&, const D&) const
00137 {
00138
00139 }
00140
00141 };
00142
00143 template <>
00144 struct helper< false >
00145 {
00146 template <typename O, typename D>
00147 void change_target(O&, const D&) const
00148 {
00149
00150 }
00151 };
00152
00153 }
00154
00155
00156 template <typename O, typename D>
00157 void change_target(O& o, const D& d)
00158 {
00159 enum { is_object = mlc_is_a(O, Object)::value };
00160 mln::if_possible::internal::helper< is_object >().change_target(exact(o),
00161 d);
00162 }
00163
00164 }
00165
00166 # endif // ! MLN_INCLUDE_ONLY
00167
00168 }
00169
00170
00171 #endif // ! MLN_CORE_CONCEPT_PSEUDO_SITE_HH