Mirror reflection library 0.5.13
|
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