Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_VARIABLE_1103251718_HPP 00011 #define MIRROR_META_VARIABLE_1103251718_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/meta_prog/only_if.hpp> 00018 #include <type_traits> 00019 00020 MIRROR_NAMESPACE_BEGIN 00021 00022 template <typename VariableSelector> 00023 struct meta_free_variable 00024 : aux::scoped_named_impl< VariableSelector > 00025 { 00026 typedef typename VariableSelector::ct_name static_name; 00027 00028 typedef typename mirror::aux::storage_class_tag_fv< 00029 typename VariableSelector::storage_class 00030 >::type storage_class; 00031 00032 typedef typename mirror::aux::full_meta_object< 00033 typename VariableSelector::scope 00034 >::type scope; 00035 00036 typedef typename mirror::reflected< 00037 typename VariableSelector::type 00038 >::type type; 00039 00040 static const typename VariableSelector::type& get(void) 00041 { 00042 return VariableSelector::get(); 00043 } 00044 00045 static void set(const typename VariableSelector::type& val) 00046 { 00047 VariableSelector::set(val); 00048 } 00049 private: 00050 typedef decltype(VariableSelector::has_address()) has_address; 00051 00052 friend struct meta_object_category<meta_free_variable>; 00053 public: 00054 00055 static auto address(void) -> decltype(VariableSelector::address()) 00056 { 00057 return VariableSelector::address(); 00058 } 00059 00060 // NOTE: internal implementation detail do not use 00061 template <typename X> 00062 struct _by_name_typ 00063 { 00064 typedef typename VariableSelector::template by_name_typ<X> type; 00065 }; 00066 00067 // NOTE: internal implementation detail do not use 00068 template <typename X> 00069 struct _by_name_val 00070 { 00071 typedef typename VariableSelector::template by_name_val<X> type; 00072 }; 00073 }; 00074 00075 // Specialization of meta_object_category for meta_member_variables(s) 00076 template <typename Selector> 00077 struct meta_object_category<meta_free_variable<Selector> > 00078 { 00079 private: 00080 typedef meta_free_variable<Selector> mfv; 00081 00082 static meta_free_variable_tag _get_type(std::false_type); 00083 00084 static meta_plain_free_variable_tag _get_type(std::true_type); 00085 public: 00086 typedef decltype(_get_type(typename mfv::has_address())) type; 00087 }; 00088 00089 // The implementation of free_variables for instantiation of meta_namespace 00090 template <class X> 00091 struct free_variables<meta_namespace<X> > 00092 { 00093 typedef typename mp::only_if< 00094 typename members<meta_namespace<X> >::type, 00095 mp::is_a<mp::arg<1>, meta_free_variable_tag> 00096 >::type type; 00097 }; 00098 00099 #define MIRROR_REG_FREE_VARIABLE_COMMON_HLPR_CTS( \ 00100 STORAGE_CLASS, \ 00101 VARIABLE, \ 00102 SPELLED \ 00103 ) \ 00104 typedef mirror::spec_ ## STORAGE_CLASS ## _tag storage_class; \ 00105 MIRROR_IMPLEMENT_META_OBJECT_NAME_FUNCTIONS(#VARIABLE) \ 00106 typedef typename mirror::cts::string< \ 00107 MIRROR_PP_EXPAND_ARGS SPELLED \ 00108 >::type ct_name; \ 00109 template <typename X> \ 00110 struct by_name_typ \ 00111 { \ 00112 typedef X VARIABLE; \ 00113 }; \ 00114 template <typename X> \ 00115 struct by_name_val \ 00116 { \ 00117 X VARIABLE; \ 00118 by_name_val(void) = default; \ 00119 template <class Parent, typename Param> \ 00120 by_name_val(Parent& parent, Param param) \ 00121 : VARIABLE(parent, param) \ 00122 { } \ 00123 }; 00124 00125 #define MIRROR_REG_GLOBAL_SCOPE_VARIABLE_CTS( \ 00126 STORAGE_CLASS, \ 00127 VARIABLE, \ 00128 SPELLED \ 00129 ) \ 00130 namespace _variable { \ 00131 template <typename Namespace> struct _ ## VARIABLE ; \ 00132 template <> struct _ ## VARIABLE< mirror::_namespace::_ >\ 00133 { \ 00134 MIRROR_REG_FREE_VARIABLE_COMMON_HLPR_CTS( \ 00135 STORAGE_CLASS, \ 00136 VARIABLE, \ 00137 SPELLED \ 00138 ) \ 00139 typedef decltype(VARIABLE) type; \ 00140 typedef mirror::_namespace::_ scope; \ 00141 static inline const type& get(void) { return :: VARIABLE; } \ 00142 static inline void set(type val) { :: VARIABLE = val; } \ 00143 static inline type* address(void) { return & :: VARIABLE; } \ 00144 static std::true_type has_address(void); \ 00145 }; \ 00146 } MIRROR_ADD_TO_GLOBAL_LIST( \ 00147 mirror::_namespace::_, \ 00148 mirror::meta_free_variable< \ 00149 mirror::_variable::_ ## VARIABLE< \ 00150 mirror::_namespace::_ \ 00151 > > \ 00152 ) 00153 00154 #ifdef MIRROR_DOCUMENTATION_ONLY 00155 00156 00163 #define MIRROR_REG_GLOBAL_SCOPE_VARIABLE(STORAGE_CLASS, VARIABLE) 00164 #else 00165 #define MIRROR_REG_GLOBAL_SCOPE_VARIABLE(STORAGE_CLASS, VARIABLE) \ 00166 MIRROR_REG_GLOBAL_SCOPE_VARIABLE_CTS(STORAGE_CLASS, VARIABLE, ()) 00167 #endif 00168 00169 #define MIRROR_REG_FREE_VARIABLE_CTS( \ 00170 STORAGE_CLASS, \ 00171 NAMESPACE, \ 00172 VARIABLE, \ 00173 SPELLED \ 00174 ) \ 00175 namespace _variable { \ 00176 template <typename Namespace> struct _ ## VARIABLE ; \ 00177 template <> struct _ ## VARIABLE< mirror::_namespace:: NAMESPACE ::_ >\ 00178 { \ 00179 MIRROR_REG_FREE_VARIABLE_COMMON_HLPR_CTS( \ 00180 STORAGE_CLASS, \ 00181 VARIABLE, \ 00182 SPELLED \ 00183 ) \ 00184 typedef decltype(NAMESPACE :: VARIABLE) type; \ 00185 typedef mirror::_namespace:: NAMESPACE ::_ scope; \ 00186 static inline const type& get(void) { return :: NAMESPACE :: VARIABLE; } \ 00187 static inline void set(type val) { :: NAMESPACE :: VARIABLE = val; } \ 00188 static inline type* address(void) { return & :: NAMESPACE :: VARIABLE;}\ 00189 static std::true_type has_address(void); \ 00190 }; \ 00191 } MIRROR_ADD_TO_GLOBAL_LIST( \ 00192 mirror::_namespace:: NAMESPACE ::_, \ 00193 mirror::meta_free_variable< \ 00194 mirror::_variable::_ ## VARIABLE< \ 00195 mirror::_namespace:: NAMESPACE ::_ \ 00196 > > \ 00197 ) 00198 00199 #ifdef MIRROR_DOCUMENTATION_ONLY 00200 00201 00209 #define MIRROR_REG_FREE_VARIABLE(STORAGE_CLASS, NAMESPACE, VARIABLE) 00210 #else 00211 #define MIRROR_REG_FREE_VARIABLE(STORAGE_CLASS, NAMESPACE, VARIABLE) \ 00212 MIRROR_REG_FREE_VARIABLE_CTS(STORAGE_CLASS, NAMESPACE, VARIABLE, ()) 00213 #endif 00214 00215 00216 #ifdef MIRROR_DOCUMENTATION_ONLY 00217 00218 00228 #define MIRRORED_FREE_VARIABLE(NAMESPACE, VARIABLE) mirror::MetaFreeVariable 00229 #else 00230 #define MIRRORED_FREE_VARIABLE(NAMESPACE, VARIABLE) \ 00231 mirror::meta_free_variable< \ 00232 mirror::_variable::_ ## VARIABLE< \ 00233 mirror::_namespace::NAMESPACE::_ \ 00234 > > 00235 #endif 00236 00237 #ifdef MIRROR_DOCUMENTATION_ONLY 00238 00239 00249 #define MIRRORED_GLOBAL_SCOPE_VARIABLE(VARIABLE) mirror::MetaFreeVariable 00250 #else 00251 #define MIRRORED_GLOBAL_SCOPE_VARIABLE(VARIABLE) \ 00252 mirror::meta_free_variable< \ 00253 mirror::_variable::_ ## VARIABLE< \ 00254 mirror::_namespace::_ \ 00255 > > 00256 #endif 00257 00258 namespace aux { 00259 00260 template <typename StorageClassTag> 00261 struct meta_simple_var 00262 { 00263 typedef mirror::meta_variable_tag category; 00264 typedef typename mirror::aux::storage_class_tag_fv< 00265 StorageClassTag 00266 >::type storage_class; 00267 typedef MIRRORED_UNSPECIFIED_SCOPE() scope; 00268 }; 00269 00270 } // namespace aux 00271 00272 #ifdef MIRROR_DOCUMENTATION_ONLY 00273 00274 00284 #define MIRRORED_SIMPLE_VARIABLE(STORAGE_CLASS, VARIABLE) mirror::MetaVariable 00285 #else 00286 #define MIRRORED_SIMPLE_VARIABLE(STORAGE_CLASS, VARIABLE) \ 00287 struct _mirror_meta_simple_var_ ## VARIABLE \ 00288 : mirror::aux::meta_simple_var< \ 00289 mirror::spec_ ## STORAGE_CLASS ## _tag \ 00290 > \ 00291 { \ 00292 typedef mirror::reflected<decltype(VARIABLE)>::type type; \ 00293 static std::string base_name(void) \ 00294 { \ 00295 return std::string(#VARIABLE, sizeof(#VARIABLE) - 1); \ 00296 } \ 00297 static inline std::string full_name(void) { return base_name(); } \ 00298 static inline std::string local_name(void) { return base_name(); } \ 00299 } 00300 #endif 00301 00302 00303 MIRROR_NAMESPACE_END 00304 00305 #endif //include guard 00306