Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_FUNCTION_1112121420_HPP 00011 #define MIRROR_META_FUNCTION_1112121420_HPP 00012 00013 #include <mirror/mirror_fwd.hpp> 00014 #include <mirror/meta_object_tags.hpp> 00015 #include <mirror/meta_namespace.hpp> 00016 #include <mirror/auxiliary/default_spec_tags.hpp> 00017 #include <mirror/auxiliary/free_functions.hpp> 00018 #include <mirror/meta_prog/only_if.hpp> 00019 #include <type_traits> 00020 00021 MIRROR_NAMESPACE_BEGIN 00022 00023 // implementation of the meta_free_function template 00024 template <typename FunctionSelector, int Index> 00025 class meta_free_function 00026 : public aux::scoped_named_impl< 00027 aux::meta_free_func_base<FunctionSelector, Index> 00028 > 00029 { 00030 public: 00031 typedef typename FunctionSelector::ct_name static_name; 00032 00033 // the scope of the function 00034 typedef typename mirror::aux::full_meta_object< 00035 typename FunctionSelector::scope 00036 >::type scope; 00037 00038 private: 00039 typedef std::integral_constant<int, Index> _idx; 00040 typedef decltype(FunctionSelector::res_type(_idx())) _res_type_idty; 00041 public: 00042 // the result type of the function 00043 typedef typename aux::reflect_type< 00044 typename _res_type_idty::type 00045 >::type result_type; 00046 00047 typedef typename aux::storage_class_tag_ff< 00048 decltype(FunctionSelector::ovld_linkage(_idx())) 00049 >::type linkage; 00050 typedef linkage storage_class; 00051 }; 00052 00053 template <typename FunctionSelector> 00054 struct meta_ovlded_free_funcs 00055 : aux::scoped_named_impl< FunctionSelector > 00056 { 00057 typedef typename FunctionSelector::ct_name static_name; 00058 00059 typedef typename mirror::aux::full_meta_object< 00060 typename FunctionSelector::scope 00061 >::type scope; 00062 00063 // NOTE: internal implementation detail do not use 00064 template <typename X> 00065 struct _by_name_typ 00066 { 00067 typedef typename FunctionSelector::template by_name_typ<X> type; 00068 }; 00069 }; 00070 00071 // The implementation of free_functions for instantiation of meta_namespace 00072 template <class X> 00073 struct free_functions<meta_namespace<X> > 00074 { 00075 typedef typename mp::only_if< 00076 typename members<meta_namespace<X> >::type, 00077 mp::is_a<mp::arg<1>, meta_overloaded_functions_tag> 00078 >::type type; 00079 }; 00080 00081 // The implementation of overloads for instantiations of meta_ovlded_free_funcs 00082 template <class FunctionSelector> 00083 struct overloads<meta_ovlded_free_funcs<FunctionSelector> > 00084 { 00085 // A range of MetaFreeFunctions reflecting the individual overloaded functions 00086 typedef typename mp::apply_on_seq_pack< 00087 aux::free_func_helper<FunctionSelector>, 00088 typename FunctionSelector::ovld_count 00089 >::type type; 00090 }; 00091 00092 // Implementation of meta_free_func_param template 00093 template <typename FunctionSelector, int OvldIndex, int ParamIndex> 00094 struct meta_free_func_param 00095 : public aux::scoped_named_impl< 00096 aux::meta_ffn_param_base< 00097 FunctionSelector, 00098 OvldIndex, 00099 ParamIndex 00100 > 00101 > 00102 { 00103 private: 00104 typedef decltype( 00105 FunctionSelector::ovld_params( 00106 std::integral_constant<int, OvldIndex>() 00107 ).type( 00108 std::integral_constant<int, ParamIndex>() 00109 ) 00110 ) type_helper; 00111 public: 00112 typedef decltype( 00113 FunctionSelector::ovld_params( 00114 std::integral_constant<int, OvldIndex>() 00115 ).ct_name( 00116 std::integral_constant<int, ParamIndex>() 00117 ) 00118 ) static_name; 00119 00120 typedef spec_auto_tag storage_class; 00121 00122 typedef meta_free_function<FunctionSelector, OvldIndex> scope; 00123 00124 typedef typename aux::reflect_type< 00125 typename type_helper::type 00126 >::type type; 00127 00128 // the type of the constructor parameter 00129 typedef std::integral_constant<int, ParamIndex> position; 00130 }; 00131 00132 // Implementation of the parameters meta-function template class 00133 template <typename FunctionSelector, int OvldIndex> 00134 struct parameters<meta_free_function<FunctionSelector, OvldIndex> > 00135 { 00136 private: 00137 typedef decltype( 00138 FunctionSelector::ovld_params( 00139 std::integral_constant<int, OvldIndex>() 00140 ) 00141 ) size_helper; 00142 public: 00143 // A range of MetaVariables reflecting 00144 // the parameters of a meta-function 00145 typedef typename mp::apply_on_seq_pack< 00146 aux::ffn_param_helper<FunctionSelector, OvldIndex>, 00147 typename size_helper::size 00148 >::type type; 00149 }; 00150 00151 // Implementation of the members meta-function for free-functions 00152 template <typename FunctionSelector, int OvldIndex> 00153 struct members<meta_free_function<FunctionSelector, OvldIndex> > 00154 { 00155 typedef typename parameters< 00156 meta_free_function<FunctionSelector, OvldIndex> 00157 >::type type; 00158 }; 00159 00160 // common helper macro used in the other macros for registering 00161 // global-scope or nested free functions 00162 #define MIRROR_REG_FREE_OVLD_FUNC_COMMON_HLPR_CTS( \ 00163 NAME, \ 00164 SPELLED \ 00165 ) \ 00166 MIRROR_IMPLEMENT_META_OBJECT_NAME_FUNCTIONS(#NAME) \ 00167 typedef typename mirror::cts::string< \ 00168 MIRROR_PP_EXPAND_ARGS SPELLED \ 00169 >::type ct_name; \ 00170 template <typename X> \ 00171 struct by_name_typ \ 00172 { \ 00173 typedef X NAME; \ 00174 }; \ 00175 typedef std::integral_constant<int, 0> 00176 00177 00178 #define MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_BEGIN_CTS( \ 00179 NAME, \ 00180 SPELLED \ 00181 ) \ 00182 namespace _function { \ 00183 template <typename Namespace> struct _ ## NAME; \ 00184 template <> struct _ ## NAME< mirror::_namespace::_ >\ 00185 { \ 00186 typedef mirror::_namespace::_ scope; \ 00187 MIRROR_REG_FREE_OVLD_FUNC_COMMON_HLPR_CTS( \ 00188 NAME, \ 00189 SPELLED \ 00190 ) 00191 00192 00193 #ifdef MIRROR_DOCUMENTATION_ONLY 00194 00195 00201 #define MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_END(NAME) 00202 #else 00203 #define MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_END(NAME) \ 00204 ovld_count; \ 00205 }; \ 00206 } MIRROR_ADD_TO_GLOBAL_LIST( \ 00207 mirror::_namespace::_, \ 00208 mirror::meta_ovlded_free_funcs< \ 00209 mirror::_function::_ ## NAME< \ 00210 mirror::_namespace::_ \ 00211 > > \ 00212 ) 00213 #endif 00214 00215 00216 #ifdef MIRROR_DOCUMENTATION_ONLY 00217 00218 00224 #define MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_BEGIN(NAME) 00225 #else 00226 #define MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_BEGIN(NAME) \ 00227 MIRROR_REG_GLOBAL_SCOPE_OVLD_FUNC_BEGIN_CTS(NAME, ()) 00228 #endif 00229 00230 00231 00232 #define MIRROR_REG_FREE_OVLD_FUNC_BEGIN_CTS( \ 00233 NAMESPACE, \ 00234 NAME, \ 00235 SPELLED \ 00236 ) \ 00237 namespace _function { \ 00238 template <typename Namespace> struct _ ## NAME; \ 00239 template <> struct _ ## NAME< mirror::_namespace:: NAMESPACE ::_ >\ 00240 { \ 00241 typedef mirror::_namespace:: NAMESPACE ::_ scope; \ 00242 MIRROR_REG_FREE_OVLD_FUNC_COMMON_HLPR_CTS( \ 00243 NAME, \ 00244 SPELLED \ 00245 ) \ 00246 00247 00248 #ifdef MIRROR_DOCUMENTATION_ONLY 00249 00250 00257 #define MIRROR_REG_FREE_OVLD_FUNC_END(NAMESPACE, NAME) 00258 #else 00259 #define MIRROR_REG_FREE_OVLD_FUNC_END(NAMESPACE, NAME) \ 00260 ovld_count; \ 00261 }; \ 00262 } MIRROR_ADD_TO_GLOBAL_LIST( \ 00263 mirror::_namespace:: NAMESPACE ::_, \ 00264 mirror::meta_ovlded_free_funcs< \ 00265 mirror::_function::_ ## NAME< \ 00266 mirror::_namespace:: NAMESPACE ::_ \ 00267 > > \ 00268 ) 00269 #endif 00270 00271 #ifdef MIRROR_DOCUMENTATION_ONLY 00272 00273 00284 #define MIRROR_REG_FREE_FUNCTION_BEGIN(LINKAGE, RESULT_TYPE, ID) 00285 #else 00286 #define MIRROR_REG_FREE_FUNCTION_BEGIN(LINKAGE, RESULT_TYPE, ID) \ 00287 ovld_index_ ## ID; \ 00288 static mirror::mp::identity<RESULT_TYPE> res_type(ovld_index_ ## ID); \ 00289 static spec_ ## LINKAGE ## _tag ovld_linkage(ovld_index_ ## ID); \ 00290 struct ovld_params_ ## ID \ 00291 { \ 00292 typedef std::integral_constant<int, 0> 00293 #endif 00294 00295 00296 #ifdef MIRROR_DOCUMENTATION_ONLY 00297 00298 00307 #define MIRROR_REG_FREE_FUNCTION_END(ID) 00308 #else 00309 #define MIRROR_REG_FREE_FUNCTION_END(ID) \ 00310 size; \ 00311 }; \ 00312 static ovld_params_ ## ID ovld_params(ovld_index_ ## ID); \ 00313 typedef std::integral_constant<int, ovld_index_ ## ID ::value + 1> 00314 #endif 00315 00316 00317 // registers the a function parameter 00318 #define MIRROR_REG_FREE_FUNCTION_PARAM_CTS(TYPE, NAME, SPELLED) \ 00319 param_idx_ ## NAME; \ 00320 template <typename _That> \ 00321 struct atr_typ_hlp_ ## NAME \ 00322 { \ 00323 typedef decltype(attr_type((TYPE*)nullptr, &_That::NAME))\ 00324 type; \ 00325 }; \ 00326 static mirror::mp::identity<TYPE> \ 00327 type(param_idx_ ## NAME); \ 00328 static const char* name( param_idx_ ## NAME) \ 00329 { \ 00330 return #NAME; \ 00331 } \ 00332 static size_t name_length( param_idx_ ## NAME) \ 00333 { \ 00334 return sizeof(#NAME) - 1; \ 00335 } \ 00336 static typename mirror::cts::string< \ 00337 MIRROR_PP_EXPAND_ARGS SPELLED \ 00338 >::type ct_name(param_idx_ ## NAME); \ 00339 typedef std::integral_constant<int, param_idx_ ## NAME ::value + 1> 00340 00341 00342 #ifdef MIRROR_DOCUMENTATION_ONLY 00343 00352 #define MIRROR_REG_FREE_FUNCTION_PARAM(TYPE, NAME) 00353 #else 00354 #define MIRROR_REG_FREE_FUNCTION_PARAM(TYPE, NAME) \ 00355 MIRROR_REG_FREE_FUNCTION_PARAM_CTS(TYPE, NAME, ()) 00356 #endif 00357 00358 00359 #ifdef MIRROR_DOCUMENTATION_ONLY 00360 00361 00372 #define MIRRORED_FREE_FUNCTIONS(NAMESPACE, NAME) mirror::MetaOverloadedFunctions 00373 #else 00374 #define MIRRORED_FREE_FUNCTIONS(NAMESPACE, NAME) \ 00375 mirror::meta_ovlded_free_funcs< \ 00376 mirror::_function::_ ## NAME< \ 00377 mirror::_namespace::NAMESPACE::_ \ 00378 > > 00379 #endif 00380 00381 #ifdef MIRROR_DOCUMENTATION_ONLY 00382 00383 00394 #define MIRRORED_GLOBAL_SCOPE_FUNCTIONS(NAME) mirror::MetaOverloadedFunctions 00395 #else 00396 #define MIRRORED_GLOBAL_SCOPE_FUNCTIONS(NAME) \ 00397 mirror::meta_ovlded_free_funcs< \ 00398 mirror::_function::_ ## NAME< \ 00399 mirror::_namespace::_ \ 00400 > > 00401 #endif 00402 00403 MIRROR_NAMESPACE_END 00404 00405 #endif //include guard 00406