Mirror reflection library - Rubber type-erasure utility 0.5.13
|
00001 00010 #ifndef RUBBER_WRAP_1103151301_HPP 00011 #define RUBBER_WRAP_1103151301_HPP 00012 00013 #include <rubber/config.hpp> 00014 #include <puddle/categories.hpp> 00015 00016 RUBBER_NAMESPACE_BEGIN 00017 00018 template <typename Tag> 00019 struct wrapper_by_tag; 00020 00021 template <typename Wrapper> 00022 struct tag_by_wrapper; 00023 00024 class meta_meta_object; 00025 00026 template <> 00027 struct wrapper_by_tag<mirror::meta_meta_object_tag> 00028 { 00029 typedef meta_meta_object type; 00030 }; 00031 00032 template <> 00033 struct tag_by_wrapper<meta_meta_object> 00034 { 00035 typedef mirror::meta_meta_object_tag type; 00036 }; 00037 00038 #define RUBBER_HELPER_MAKE_TAG_TO_META_OBJECT_MAP(OBJECT, I, X) \ 00039 class meta_ ## OBJECT; \ 00040 template <> \ 00041 struct wrapper_by_tag<mirror::meta_ ## OBJECT ## _tag> \ 00042 { \ 00043 typedef meta_ ## OBJECT type; \ 00044 }; \ 00045 template <> \ 00046 struct tag_by_wrapper<meta_ ## OBJECT> \ 00047 { \ 00048 typedef mirror::meta_ ## OBJECT ## _tag type; \ 00049 }; \ 00050 00051 MIRROR_FOR_EACH_META_OBJECT(RUBBER_HELPER_MAKE_TAG_TO_META_OBJECT_MAP, _) 00052 #undef RUBBER_HELPER_MAKE_TAG_TO_META_OBJECT_MAP 00053 00054 template <typename Wrapper> 00055 puddle::meta_object_category categorize_wrapper(Wrapper*) 00056 { 00057 return puddle::get_category( 00058 typename tag_by_wrapper<Wrapper>::type() 00059 ); 00060 } 00061 00062 template <class TypeErased, class MirrorMetaObject> 00063 inline typename aux::return_value<TypeErased>::type 00064 wrap_into(const MirrorMetaObject& mo) 00065 { 00066 #if RUBBER_POLYMORPHIC_META_OBJECT 00067 static TypeErased wrapped(mo); 00068 return wrapped; 00069 #else 00070 return TypeErased(mo); 00071 #endif 00072 } 00073 00074 template <class MetaObjectTag, class MirrorMetaObject> 00075 inline typename aux::return_value< 00076 typename wrapper_by_tag< 00077 MetaObjectTag 00078 >::type 00079 >::type wrap_by_tag(const MirrorMetaObject& mo) 00080 { 00081 return wrap_into< 00082 typename wrapper_by_tag< 00083 MetaObjectTag 00084 >::type 00085 >(mo); 00086 } 00087 00088 template <class MirrorMetaObject> 00089 inline typename aux::return_value< 00090 typename wrapper_by_tag< 00091 typename mirror::meta_object_category< 00092 MirrorMetaObject 00093 >::type 00094 >::type 00095 >::type wrap(void) 00096 { 00097 return wrap_by_tag< 00098 typename mirror::meta_object_category< 00099 MirrorMetaObject 00100 >::type 00101 >(MirrorMetaObject()); 00102 } 00103 00104 template <class MirrorMetaObject, class TypeErased> 00105 inline typename aux::return_value<TypeErased>::type wrap_shaped(void) 00106 { 00107 #if RUBBER_POLYMORPHIC_META_OBJECT 00108 return wrap<MirrorMetaObject>(); 00109 #else 00110 return wrap_into<TypeErased>(MirrorMetaObject()); 00111 #endif 00112 } 00113 00114 RUBBER_NAMESPACE_END 00115 00116 #endif //include guard 00117