1 2 // (C) Copyright Edward Diener 2011,2012,2013 3 // Use, modification and distribution are subject to the Boost Software License, 4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt). 6 7 #if !defined(BOOST_TTI_DETAIL_MEM_DATA_HPP) 8 #define BOOST_TTI_DETAIL_MEM_DATA_HPP 9 10 #include <boost/detail/workaround.hpp> 11 #include <boost/function_types/components.hpp> 12 #include <boost/function_types/is_member_object_pointer.hpp> 13 #include <boost/mpl/assert.hpp> 14 #include <boost/mpl/bool.hpp> 15 #include <boost/mpl/eval_if.hpp> 16 #include <boost/mpl/identity.hpp> 17 #include <boost/preprocessor/cat.hpp> 18 #include <boost/tti/detail/ddeftype.hpp> 19 #include <boost/tti/detail/dftclass.hpp> 20 #include <boost/tti/detail/denclosing_type.hpp> 21 #include <boost/tti/gen/namespace_gen.hpp> 22 #include <boost/type_traits/detail/yes_no_type.hpp> 23 #include <boost/type_traits/is_same.hpp> 24 #include <boost/type_traits/remove_const.hpp> 25 26 #if defined(BOOST_MSVC) || (BOOST_WORKAROUND(BOOST_GCC, >= 40400) && BOOST_WORKAROUND(BOOST_GCC, < 40600)) 27 28 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_OP(trait,name) \ 29 template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_C> \ 30 struct BOOST_PP_CAT(trait,_detail_hmd_op) \ 31 { \ 32 template<class> \ 33 struct return_of; \ 34 \ 35 template<class BOOST_TTI_DETAIL_TP_R,class BOOST_TTI_DETAIL_TP_IC> \ 36 struct return_of<BOOST_TTI_DETAIL_TP_R BOOST_TTI_DETAIL_TP_IC::*> \ 37 { \ 38 typedef BOOST_TTI_DETAIL_TP_R type; \ 39 }; \ 40 \ 41 template<bool,typename BOOST_TTI_DETAIL_TP_U> \ 42 struct menable_if; \ 43 \ 44 template<typename BOOST_TTI_DETAIL_TP_U> \ 45 struct menable_if<true,BOOST_TTI_DETAIL_TP_U> \ 46 { \ 47 typedef BOOST_TTI_DETAIL_TP_U type; \ 48 }; \ 49 \ 50 template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \ 51 static ::boost::type_traits::yes_type check2(BOOST_TTI_DETAIL_TP_V BOOST_TTI_DETAIL_TP_U::*); \ 52 \ 53 template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \ 54 static ::boost::type_traits::no_type check2(BOOST_TTI_DETAIL_TP_U); \ 55 \ 56 template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \ 57 static typename \ 58 menable_if \ 59 < \ 60 sizeof(check2<BOOST_TTI_DETAIL_TP_U,BOOST_TTI_DETAIL_TP_V>(&BOOST_TTI_DETAIL_TP_U::name))==sizeof(::boost::type_traits::yes_type), \ 61 ::boost::type_traits::yes_type \ 62 > \ 63 ::type \ 64 has_matching_member(int); \ 65 \ 66 template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \ 67 static ::boost::type_traits::no_type has_matching_member(...); \ 68 \ 69 template<class BOOST_TTI_DETAIL_TP_U,class BOOST_TTI_DETAIL_TP_V> \ 70 struct ttc_md \ 71 { \ 72 typedef boost::mpl::bool_<sizeof(has_matching_member<BOOST_TTI_DETAIL_TP_V,typename return_of<BOOST_TTI_DETAIL_TP_U>::type>(0))==sizeof(::boost::type_traits::yes_type)> type; \ 73 }; \ 74 \ 75 typedef typename ttc_md<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_C>::type type; \ 76 \ 77 }; \ 78 /**/ 79 80 #else // !defined(BOOST_MSVC) 81 82 #include <boost/tti/detail/dmem_fun.hpp> 83 84 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_OP(trait,name) \ 85 BOOST_TTI_DETAIL_TRAIT_HAS_TYPES_MEMBER_FUNCTION(trait,name) \ 86 template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_C> \ 87 struct BOOST_PP_CAT(trait,_detail_hmd_op) : \ 88 BOOST_PP_CAT(trait,_detail_hmf_types)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_C> \ 89 { \ 90 }; \ 91 /**/ 92 93 #endif // defined(BOOST_MSVC) 94 95 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_INVOKE_ENCLOSING_CLASS(trait) \ 96 template<class BOOST_TTI_DETAIL_TP_ET,class BOOST_TTI_DETAIL_TP_TYPE> \ 97 struct BOOST_PP_CAT(trait,_detail_hmd_invoke_enclosing_class) : \ 98 BOOST_PP_CAT(trait,_detail_hmd_op) \ 99 < \ 100 typename BOOST_TTI_NAMESPACE::detail::ptmd<BOOST_TTI_DETAIL_TP_ET,BOOST_TTI_DETAIL_TP_TYPE>::type, \ 101 typename boost::remove_const<BOOST_TTI_DETAIL_TP_ET>::type \ 102 > \ 103 { \ 104 }; \ 105 /**/ 106 107 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_INVOKE_PT_MEMBER(trait) \ 108 template<class BOOST_TTI_DETAIL_TP_ET,class BOOST_TTI_DETAIL_TP_TYPE> \ 109 struct BOOST_PP_CAT(trait,_detail_hmd_invoke_pt_member) : \ 110 BOOST_PP_CAT(trait,_detail_hmd_op) \ 111 < \ 112 typename BOOST_TTI_NAMESPACE::detail::dmem_get_type<BOOST_TTI_DETAIL_TP_ET,BOOST_TTI_DETAIL_TP_TYPE>::type, \ 113 typename boost::remove_const \ 114 < \ 115 typename BOOST_TTI_NAMESPACE::detail::dmem_get_enclosing<BOOST_TTI_DETAIL_TP_ET,BOOST_TTI_DETAIL_TP_TYPE>::type \ 116 >::type \ 117 > \ 118 { \ 119 }; \ 120 /**/ 121 122 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_WITH_ENCLOSING_CLASS(trait) \ 123 BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_INVOKE_ENCLOSING_CLASS(trait) \ 124 template<class BOOST_TTI_DETAIL_TP_ET,class BOOST_TTI_DETAIL_TP_TYPE> \ 125 struct BOOST_PP_CAT(trait,_detail_hmd_with_enclosing_class) : \ 126 boost::mpl::eval_if \ 127 < \ 128 BOOST_TTI_NAMESPACE::detail::enclosing_type<BOOST_TTI_DETAIL_TP_ET>, \ 129 BOOST_PP_CAT(trait,_detail_hmd_invoke_enclosing_class) \ 130 < \ 131 BOOST_TTI_DETAIL_TP_ET, \ 132 BOOST_TTI_DETAIL_TP_TYPE \ 133 >, \ 134 boost::mpl::false_ \ 135 > \ 136 { \ 137 }; \ 138 /**/ 139 140 #define BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA(trait,name) \ 141 BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_OP(trait,name) \ 142 BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_WITH_ENCLOSING_CLASS(trait) \ 143 BOOST_TTI_DETAIL_TRAIT_HAS_MEMBER_DATA_INVOKE_PT_MEMBER(trait) \ 144 template<class BOOST_TTI_DETAIL_TP_ET,class BOOST_TTI_DETAIL_TP_TYPE> \ 145 struct BOOST_PP_CAT(trait,_detail_hmd) : \ 146 boost::mpl::eval_if \ 147 < \ 148 boost::is_same<BOOST_TTI_DETAIL_TP_TYPE,BOOST_TTI_NAMESPACE::detail::deftype>, \ 149 BOOST_PP_CAT(trait,_detail_hmd_invoke_pt_member) \ 150 < \ 151 BOOST_TTI_DETAIL_TP_ET, \ 152 BOOST_TTI_DETAIL_TP_TYPE \ 153 >, \ 154 BOOST_PP_CAT(trait,_detail_hmd_with_enclosing_class) \ 155 < \ 156 BOOST_TTI_DETAIL_TP_ET, \ 157 BOOST_TTI_DETAIL_TP_TYPE \ 158 > \ 159 > \ 160 { \ 161 }; \ 162 /**/ 163 164 namespace boost 165 { 166 namespace tti 167 { 168 namespace detail 169 { 170 171 template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_R> 172 struct ptmd 173 { 174 typedef BOOST_TTI_DETAIL_TP_R BOOST_TTI_DETAIL_TP_T::* type; 175 }; 176 177 template<class BOOST_TTI_DETAIL_TP_T> 178 struct dmem_check_ptmd : 179 boost::mpl::identity<BOOST_TTI_DETAIL_TP_T> 180 { 181 BOOST_MPL_ASSERT((boost::function_types::is_member_object_pointer<BOOST_TTI_DETAIL_TP_T>)); 182 }; 183 184 template<class BOOST_TTI_DETAIL_TP_T> 185 struct dmem_check_ptec : 186 BOOST_TTI_NAMESPACE::detail::class_type<BOOST_TTI_DETAIL_TP_T> 187 { 188 BOOST_MPL_ASSERT((boost::function_types::is_member_object_pointer<BOOST_TTI_DETAIL_TP_T>)); 189 }; 190 191 template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_T2> 192 struct dmem_get_type : 193 boost::mpl::eval_if 194 < 195 boost::is_same<BOOST_TTI_DETAIL_TP_T2,BOOST_TTI_NAMESPACE::detail::deftype>, 196 BOOST_TTI_NAMESPACE::detail::dmem_check_ptmd<BOOST_TTI_DETAIL_TP_T>, 197 BOOST_TTI_NAMESPACE::detail::ptmd<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_T2> 198 > 199 { 200 }; 201 202 template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_T2> 203 struct dmem_get_enclosing : 204 boost::mpl::eval_if 205 < 206 boost::is_same<BOOST_TTI_DETAIL_TP_T2,BOOST_TTI_NAMESPACE::detail::deftype>, 207 BOOST_TTI_NAMESPACE::detail::dmem_check_ptec<BOOST_TTI_DETAIL_TP_T>, 208 boost::mpl::identity<BOOST_TTI_DETAIL_TP_T> 209 > 210 { 211 }; 212 213 } 214 } 215 } 216 217 #endif // BOOST_TTI_DETAIL_MEM_DATA_HPP 218