• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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