Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_OBJECT_TAGGING_1011291729_HPP 00011 #define MIRROR_OBJECT_TAGGING_1011291729_HPP 00012 00013 #include <mirror/mirror_fwd.hpp> 00014 #include <mirror/auxiliary/named.hpp> 00015 #include <mirror/meta_prog/is_a.hpp> 00016 00017 MIRROR_NAMESPACE_BEGIN 00018 00019 namespace aux { 00020 00021 // Helper class used in the implementation of the tag template class 00022 /* Currently the only purpose of this class is to provide a sequence 00023 * of identifiers to the derived tag template class instantiations 00024 */ 00025 class tag_base 00026 { 00027 protected: 00028 static int& id_sequence(void) 00029 { 00030 static int current = 0; 00031 return current; 00032 } 00033 }; 00034 00035 } // namespace aux 00036 00038 00046 template <typename Selector> 00047 class tag : public aux::tag_base 00048 { 00049 public: 00050 typedef tag type; 00051 00053 00058 static int id(void) 00059 { 00060 static const int _id = ++id_sequence(); 00061 return _id; 00062 } 00063 00065 static std::string name(void) 00066 { 00067 return std::string( 00068 Selector::name(), 00069 Selector::name_length() 00070 ); 00071 } 00072 00073 template <typename OtherSelector> 00074 friend inline bool operator == ( 00075 const tag<Selector>& a, 00076 const tag<OtherSelector>& b 00077 ) 00078 { 00079 return a.id() == b.id(); 00080 } 00081 00082 template <typename OtherSelector> 00083 friend inline bool operator != ( 00084 const tag<Selector>& a, 00085 const tag<OtherSelector>& b 00086 ) 00087 { 00088 return a.id() != b.id(); 00089 } 00090 00091 template <typename OtherSelector> 00092 friend inline bool operator < ( 00093 const tag<Selector>& a, 00094 const tag<OtherSelector>& b 00095 ) 00096 { 00097 return a.id() < b.id(); 00098 } 00099 00100 template <typename OtherSelector> 00101 friend inline bool operator <= ( 00102 const tag<Selector>& a, 00103 const tag<OtherSelector>& b 00104 ) 00105 { 00106 return a.id() <= b.id(); 00107 } 00108 00109 template <typename OtherSelector> 00110 friend inline bool operator > ( 00111 const tag<Selector>& a, 00112 const tag<OtherSelector>& b 00113 ) 00114 { 00115 return a.id() > b.id(); 00116 } 00117 00118 template <typename OtherSelector> 00119 friend inline bool operator >= ( 00120 const tag<Selector>& a, 00121 const tag<OtherSelector>& b 00122 ) 00123 { 00124 return a.id() >= b.id(); 00125 } 00126 }; 00127 00128 // helper namespace containing the tag-related declarations 00129 namespace tagsel { 00130 00131 // template class for assigning tags to types 00132 template <typename Type> 00133 struct type_tags 00134 { 00135 typedef mp::range<> type; 00136 }; 00137 00138 } // namespace tagsel 00139 00140 namespace aux { 00141 00142 template <typename Expr, typename IsMetaObject> 00143 struct tags_helper; 00144 00145 } // namespace aux 00146 00147 template <typename Expr> 00148 struct tags : aux::tags_helper< 00149 Expr, 00150 typename mp::is_a< 00151 Expr, 00152 meta_object_tag 00153 >::type 00154 >{ }; 00155 00156 namespace aux { 00157 00158 template <typename Expr> 00159 struct tags_helper<Expr, std::true_type> 00160 { 00161 typedef mp::range<> type; 00162 }; 00163 00164 template <typename Expr> 00165 struct tags_helper<Expr, std::false_type> 00166 : public tags<typename Expr::type> 00167 { }; 00168 00169 } // namespace aux 00170 00171 #ifdef MIRROR_DOCUMENTATION_ONLY 00172 00173 00179 #define MIRROR_REG_OBJECT_TAG(TAG) 00180 #else 00181 #define MIRROR_REG_OBJECT_TAG(TAG) \ 00182 namespace tagsel { \ 00183 struct TAG \ 00184 { \ 00185 MIRROR_IMPLEMENT_META_OBJECT_NAME_FUNCTIONS(#TAG) \ 00186 };\ 00187 } /* namespace tagsel */ 00188 #endif 00189 00190 #ifdef MIRROR_DOCUMENTATION_ONLY 00191 00192 00199 #define MIRROR_OBJECT_TAG(TAG) 00200 #else 00201 #define MIRROR_OBJECT_TAG(TAG) \ 00202 mirror::tag< mirror::tagsel::TAG > 00203 #endif 00204 00205 namespace aux { 00206 00207 // the implementation of the tags template for meta-types 00208 template <typename Type> 00209 struct tags_helper<meta_type<Type>, std::true_type> 00210 { 00211 typedef typename mp::fold< 00212 tagsel::type_tags<Type>, 00213 mp::range<>, 00214 mp::push_back< 00215 mp::arg<1>, 00216 tag<mp::arg<2> > 00217 > 00218 >::type type; 00219 }; 00220 00221 // implementation of the tags template for meta-classes 00222 template <typename Class> 00223 struct tags_helper<meta_class<Class>, std::true_type> 00224 : tags_helper<meta_type<Class>, std::true_type> 00225 { }; 00226 00227 } // namespace aux 00228 00230 00239 #define MIRROR_TAG_TYPE(TYPE, TAGS) \ 00240 namespace tagsel { \ 00241 template <> \ 00242 struct type_tags< TYPE > \ 00243 { \ 00244 typedef mirror::mp::range< \ 00245 MIRROR_PP_EXPAND_ARGS TAGS \ 00246 > type; \ 00247 }; \ 00248 } /* namespace tagsel */ 00249 00250 MIRROR_NAMESPACE_END 00251 00252 #endif //include guard 00253