Mirror reflection library 0.5.13

mirror/meta_prog/is_a.hpp

Go to the documentation of this file.
00001 
00011 #ifndef MIRROR_META_PROG_IS_A_1011291729_HPP
00012 #define MIRROR_META_PROG_IS_A_1011291729_HPP
00013 
00014 #include <mirror/meta_prog/forward_decl.hpp>
00015 #include <mirror/meta_prog/not.hpp>
00016 #include <type_traits>
00017 
00018 MIRROR_NAMESPACE_BEGIN
00019 namespace mp {
00020 namespace aux {
00021 
00022 template <class X, class RealConcept, class QueriedConcept>
00023 struct is_a_helper : public ::std::is_base_of<
00024     QueriedConcept,
00025     RealConcept
00026 >{ };
00027 
00028 template <class X, class Concept>
00029 struct is_a_helper<X, Concept, Concept>
00030  : public std::true_type
00031 { };
00032 
00033 template <class QueriedConcept>
00034 struct is_a_helper<void*, non_meta_object_tag, QueriedConcept>
00035  : public std::false_type
00036 { };
00037 
00038 void* is_a_hlpr_fn(...);
00039 
00040 template <typename X>
00041 void* is_a_hlpr_fn2(X*, X*);
00042 
00043 template <typename X, typename Y>
00044 typename X::type is_a_hlpr_fn2(X*, Y*);
00045 
00046 template <typename X>
00047 auto is_a_hlpr_fn(X* x, typename X::type* y = nullptr) ->
00048 decltype(is_a_hlpr_fn2(x,y));
00049 
00050 
00051 template <class X, class QueriedConcept>
00052 struct is_a_helper<X, non_meta_object_tag, QueriedConcept>
00053  : public is_a_helper<
00054     decltype(is_a_hlpr_fn((X*)nullptr)),
00055     typename meta_object_category<
00056         decltype(is_a_hlpr_fn((X*)nullptr))
00057     >::type,
00058     QueriedConcept
00059 >
00060 { };
00061 
00062 
00063 } // namespace aux
00064 
00065 #ifdef MIRROR_DOCUMENTATION_ONLY
00066 
00067 
00073 template <class MetaObject, class Concept>
00074 struct is_a
00075 {
00077     typedef BooleanConstant type;
00078 };
00079 
00081 
00087 template <class MetaObject, class Concept>
00088 struct is_not_a
00089 {
00091     typedef BooleanConstant type;
00092 };
00093 #else
00094 
00095 // X is a concept
00096 template <class X, class Concept>
00097 struct is_a : aux::is_a_helper<
00098     X,
00099     typename meta_object_category<X>::type,
00100     typename eval_meta_object_tag<Concept>::type
00101 >
00102 { };
00103 
00104 // X isn't a concept
00105 template <class X, class Concept>
00106 struct is_not_a : not_<aux::is_a_helper<
00107     X,
00108     typename meta_object_category<X>::type,
00109     typename eval_meta_object_tag<Concept>::type
00110 > >
00111 { };
00112 #endif
00113 
00114 #define MIRROR_ASSERT_IS_A_META(OBJECT, EXPR, NAME) \
00115 static_assert( \
00116     mirror::mp::is_a< \
00117         EXPR, \
00118         typename mirror::meta_##OBJECT##_tag \
00119     >::value, \
00120     #NAME " is not a Meta" \
00121     MIRROR_META_OBJECT_NICE_NAME_STR(OBJECT) \
00122     " expression" \
00123 )
00124 
00125 #define MIRROR_ASSERT_RETURNS_META(OBJECT, X) \
00126     MIRROR_ASSERT_IS_A_META(OBJECT, typename X::type, X)
00127 
00128 } // namespace mp
00129 MIRROR_NAMESPACE_END
00130 
00131 #endif //include guard
00132 

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.