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_INTERNAL_EXACT_HH
00027 # define MLN_CORE_INTERNAL_EXACT_HH
00028
00032
00033
00034
00036 namespace mln
00037 {
00038
00039 template <typename T>
00040 struct Object;
00041
00042 }
00043
00044
00045 namespace mln
00046 {
00047
00048 namespace internal
00049 {
00050
00051 typedef char yes_;
00052 struct no_ { char dummy[2]; };
00053
00054 template <typename T>
00055 struct make_
00056 {
00057 static T* ptr();
00058 };
00059
00060 template <unsigned id, typename T>
00061 struct exact_ret_;
00062
00063 template <typename T>
00064 struct exact_ret_< 1, T >
00065 {
00066 typedef typename T::exact_t ret;
00067 };
00068
00069 template <typename T>
00070 struct exact_ret_< 2, T >
00071 {
00072 typedef T ret;
00073 };
00074
00075 template <typename E>
00076 yes_ exact_selector_(Object<E>*);
00077
00078 no_ exact_selector_(void*);
00079
00080 template <typename E, typename T>
00081 E* exact_run_(Object<E>* t, T*);
00082
00083 template <typename T>
00084 T* exact_run_(void*, T* t);
00085
00086 template <typename T>
00087 struct exact_
00088 {
00089 enum { id = sizeof(exact_selector_(make_<T>::ptr())) };
00090 typedef exact_ret_<id, T> helper;
00091 typedef typename helper::ret ret;
00092 static ret* run(T* t)
00093 {
00094 return exact_run_(t, t);
00095 }
00096 };
00097
00098 template <typename T>
00099 struct exact_<const T>
00100 {
00101 enum { id = sizeof(exact_selector_(make_<T>::ptr())) };
00102 typedef exact_ret_<id, T> helper;
00103 typedef const typename helper::ret ret;
00104 static ret* run(const T* t)
00105 {
00106 return exact_run_((T*)t, (T*)t);
00107 }
00108 };
00109
00110
00111 # ifndef MLN_INCLUDE_ONLY
00112
00113 template <typename T>
00114 inline
00115 T*
00116 make_<T>::ptr()
00117 {
00118 T* tmp;
00119 return tmp;
00120 }
00121
00122 template <typename E, typename T>
00123 inline
00124 E* exact_run_(Object<E>* t, T*)
00125 {
00126 return (E*)(void*)t;
00127 }
00128
00129 template <typename T>
00130 inline
00131 T* exact_run_(void*, T* t)
00132 {
00133 return t;
00134 }
00135
00136 # endif // ! MLN_INCLUDE_ONLY
00137
00138 }
00139
00140 }
00141
00142 # include <mln/core/concept/object.hh>
00143
00144 #endif // ! MLN_CORE_INTERNAL_EXACT_HH