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_TRAIT_FUNCTIONS_HH
00027 # define MLN_TRAIT_FUNCTIONS_HH
00028
00029 # include <mln/metal/bexpr.hh>
00030 # include <mln/metal/if.hh>
00031 # include <mln/fun/param.hh>
00032 # include <mln/trait/next/solve.hh>
00033
00034 # define mln_trait_fun_is_assignable(Fun) typename mln::trait::function::is_assignable< Fun >::ret
00035 # define mln_trait_fun_is_assignable_(Fun) mln::trait::function::is_assignable< Fun >::ret
00036 # define mln_trait_fun_is_assignable__1comma(A, B) typename mln::trait::function::is_assignable< A, B >::ret
00037 # define mln_trait_fun_is_assignable__1comma_(A, B) mln::trait::function::is_assignable< A, B >::ret
00038
00039 # define mln_trait_fun_is_parametrable(Fun) typename mln::trait::function::is_parametrable< Fun >::ret
00040 # define mln_trait_fun_is_parametrable_(Fun) mln::trait::function::is_parametrable< Fun >::ret
00041
00042 # define mln_trait_fun_lvalue(Fun) typename mln::trait::function::get_lvalue< Fun >::ret
00043 # define mln_trait_fun_param(Fun) typename mln::trait::function::get_param< Fun >::ret
00044 # define mln_trait_fun_storage(Fun) typename mln::trait::function::get_storage< Fun >::ret
00045
00046 namespace mln
00047 {
00048
00049 namespace trait
00050 {
00051
00052 namespace function
00053 {
00054
00055 namespace internal
00056 {
00057
00058 namespace introspect
00059 {
00060
00061 template <typename T>
00062 struct except_void_t
00063 {
00064 typedef void ret;
00065 };
00066
00067 template <>
00068 struct except_void_t<void>;
00069
00070
00071
00072 template <typename T, typename V>
00073 struct has_lvalue_t
00074 {
00075 typedef metal::false_ ret;
00076 typedef void type;
00077 };
00078
00079 template <typename T>
00080 struct has_lvalue_t<T, typename except_void_t<typename T::lvalue>::ret>
00081 {
00082 typedef metal::true_ ret;
00083 typedef typename T::lvalue type;
00084 };
00085
00086
00087 template <typename T, typename V>
00088 struct param_solver;
00089
00090 template <typename T, typename V>
00091 struct param_flag_solver
00092 {
00093 typedef typename mln::fun::parameter<T> ret;
00094 };
00095
00096 template <typename T>
00097 struct param_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::param>::ret>
00098 {
00099 typedef mln::fun::parameter<typename T::flag> ret;
00100 };
00101
00102 template <typename T, typename V>
00103 struct param_def_solver
00104 {
00105 typedef typename param_flag_solver<T, V>::ret ret;
00106 };
00107
00108 template <typename T>
00109 struct param_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::param>::ret>
00110 {
00111 typedef mln::fun::parameter<typename T::def> ret;
00112 };
00113
00114 template <typename T, typename V>
00115 struct param_solver : param_def_solver<T, V>
00116 {
00117 };
00118
00119 template <typename T>
00120 struct param_solver<T, typename except_void_t<typename T::param>::ret>
00121 {
00122 typedef T ret;
00123 };
00124
00125 template <typename T, typename V>
00126 struct has_param_t
00127 {
00128 typedef metal::false_ ret;
00129 typedef void type;
00130 };
00131
00132 template <typename T>
00133 struct has_param_t<T, typename except_void_t<typename param_solver<T,void>::ret::param>::ret>
00134 {
00135 typedef metal::true_ ret;
00136 typedef typename param_solver<T,void>::ret::param type;
00137 };
00138
00139 template <typename T, typename V>
00140 struct storage_solver;
00141
00142 template <typename T, typename V>
00143 struct storage_flag_solver
00144 {
00145 typedef typename mln::fun::parameter<T> ret;
00146 };
00147
00148 template <typename T>
00149 struct storage_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::storage>::ret>
00150 {
00151 typedef mln::fun::parameter<typename T::flag> ret;
00152 };
00153
00154 template <typename T, typename V>
00155 struct storage_def_solver
00156 {
00157 typedef typename storage_flag_solver<T, V>::ret ret;
00158 };
00159
00160 template <typename T>
00161 struct storage_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::storage>::ret>
00162 {
00163 typedef mln::fun::parameter<typename T::def> ret;
00164 };
00165
00166 template <typename T, typename V>
00167 struct storage_solver : storage_def_solver<T, V>
00168 {
00169 };
00170
00171 template <typename T>
00172 struct storage_solver<T, typename except_void_t<typename T::storage>::ret>
00173 {
00174 typedef T ret;
00175 };
00176
00177 template <typename T, typename V>
00178 struct has_storage_t
00179 {
00180 typedef has_param_t<T, V> has_param;
00181
00182 typedef metal::false_ ret;
00183 typedef typename has_param::type type;
00184
00185 template <typename U>
00186 static inline
00187 const U& compute(const U& t)
00188 {
00189 return t;
00190 }
00191
00192 };
00193
00194 template <typename T>
00195 struct has_storage_t<T, typename except_void_t<typename param_solver<T,void>::ret::storage>::ret>
00196 {
00197 typedef metal::true_ ret;
00198 typedef typename param_solver<T,void>::ret def;
00199
00200 typedef typename def::storage type;
00201
00202 template <typename U>
00203 static inline
00204 type compute(const U& p)
00205 {
00206 return def::compute(p);
00207 }
00208
00209 };
00210
00211 }
00212
00213 }
00214
00215 template <typename F>
00216 struct is_assignable
00217 {
00218 typedef typename internal::introspect::has_lvalue_t<F, void>::ret ret;
00219 };
00220
00221 template <typename F>
00222 struct is_parametrable
00223 {
00224 typedef typename internal::introspect::has_param_t<F, void>::ret ret;
00225 };
00226
00227 template <typename F>
00228 struct get_lvalue
00229 {
00230 typedef typename internal::introspect::has_lvalue_t<F, void>::type ret;
00231 };
00232
00233 template <typename F>
00234 struct get_param
00235 {
00236 typedef typename internal::introspect::has_param_t<F, void>::type ret;
00237 };
00238
00239 template <typename F>
00240 struct get_storage
00241 {
00242 typedef typename internal::introspect::has_storage_t<F, void>::type ret;
00243 };
00244
00245 }
00246
00247 }
00248
00249 }
00250
00251 #endif // ! MLN_TRAIT_FUNCTIONS_HH