Mirror reflection library 0.5.13

mirror/object_tagging.hpp

Go to the documentation of this file.
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 

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.