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_VALUE_EQUIV_HH
00027 # define MLN_VALUE_EQUIV_HH
00028
00034 # include <mln/core/concept/value.hh>
00035
00036
00037 # define mln_value_equiv(V) typename mln::value::internal::equiv_<V>::ret
00038 # define mln_value_equiv_(V) mln::value::internal::equiv_<V>::ret
00039
00040
00041
00042 namespace mln
00043 {
00044
00045 namespace value
00046 {
00047
00048
00049 namespace internal { template <typename T> struct equiv_; }
00050
00051
00052
00054 template <typename V>
00055 typename internal::equiv_<V>::ret
00056 equiv(const mln::Value<V>& v);
00057
00058
00059
00060 # ifndef MLN_INCLUDE_ONLY
00061
00062 namespace internal
00063 {
00064
00065 typedef char yes_;
00066 struct no_ { char dummy[2]; };
00067
00068 template <typename T>
00069 struct make_
00070 {
00071 static T* ptr();
00072 };
00073
00074
00075
00076 template <unsigned id, typename T>
00077 struct equiv_ret_;
00078
00079
00080 template <typename V>
00081 const typename internal::equiv_<V>::ret&
00082 run_equiv_(const V& v);
00083
00084
00085 template <typename V, typename T>
00086 inline
00087 const typename internal::equiv_<V>::ret&
00088 run_equiv_(const Value<V>* v, const T*)
00089 {
00090 return run_equiv_(exact(v)->to_equiv());
00091 }
00092
00093 template <typename V>
00094 inline
00095 const V&
00096 run_equiv_(const void*, const V* v)
00097 {
00098 return *v;
00099 }
00100
00101 template <typename V>
00102 inline
00103 const typename internal::equiv_<V>::ret&
00104 run_equiv_(const V& v)
00105 {
00106 return run_equiv_(&v, &v);
00107 }
00108
00109
00110 template <typename T>
00111 struct equiv_ret_< 1, T >
00112 {
00113 typedef typename T::equiv V;
00114 typedef typename equiv_<V>::ret ret;
00115 };
00116
00117 template <typename T>
00118 struct equiv_ret_< 2, T >
00119 {
00120 typedef T ret;
00121 };
00122
00123 template <typename V>
00124 yes_ equiv_selector_(Value<V>*);
00125
00126 no_ equiv_selector_(void*);
00127
00128 template <typename T>
00129 struct equiv_
00130 {
00131 enum { id = sizeof(equiv_selector_(make_<T>::ptr())) };
00132 typedef typename equiv_ret_<id, T>::ret ret;
00133
00134 inline
00135 static ret run(const T& t)
00136 {
00137 return ret::run(t);
00138 }
00139 };
00140
00141 }
00142
00143
00144
00145 template <typename V>
00146 inline
00147 typename internal::equiv_<V>::ret
00148 equiv(const mln::Value<V>& v)
00149 {
00150 return internal::run_equiv_(exact(v));
00151 }
00152
00153
00154 # endif // ! MLN_INCLUDE_ONLY
00155
00156 }
00157
00158 }
00159
00160 # include <mln/value/cast.hh>
00161
00162 #endif // ! MLN_VALUE_EQUIV_HH