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_STATIC_MEM_DATA_HPP)
8 #define BOOST_TTI_DETAIL_STATIC_MEM_DATA_HPP
9 
10 #include <boost/config.hpp>
11 #include <boost/function_types/is_function.hpp>
12 #include <boost/mpl/bool.hpp>
13 #include <boost/mpl/eval_if.hpp>
14 #include <boost/preprocessor/cat.hpp>
15 #include <boost/type_traits/is_class.hpp>
16 #include <boost/type_traits/detail/yes_no_type.hpp>
17 #include <boost/tti/detail/denclosing_type.hpp>
18 #include <boost/tti/detail/dmacro_sunfix.hpp>
19 #include <boost/tti/detail/dnullptr.hpp>
20 #include <boost/tti/gen/namespace_gen.hpp>
21 
22 #if defined(BOOST_MSVC)
23 
24 #define BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA_OP(trait,name) \
25   template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_TYPE> \
26   struct BOOST_PP_CAT(trait,_detail_hsd_op) \
27     { \
28     template<bool,typename BOOST_TTI_DETAIL_TP_U> \
29     struct menable_if; \
30     \
31     template<typename BOOST_TTI_DETAIL_TP_U> \
32     struct menable_if<true,BOOST_TTI_DETAIL_TP_U> \
33       { \
34       typedef BOOST_TTI_DETAIL_TP_U type; \
35       }; \
36     \
37     template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \
38     static ::boost::type_traits::yes_type check2(BOOST_TTI_DETAIL_TP_V *); \
39     \
40     template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \
41     static ::boost::type_traits::no_type check2(BOOST_TTI_DETAIL_TP_U); \
42     \
43     template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \
44     static typename \
45       menable_if \
46         < \
47         sizeof(check2<BOOST_TTI_DETAIL_TP_U,BOOST_TTI_DETAIL_TP_V>(&BOOST_TTI_DETAIL_TP_U::name))==sizeof(::boost::type_traits::yes_type), \
48         ::boost::type_traits::yes_type \
49         > \
50       ::type \
51     has_matching_member(int); \
52     \
53     template<typename BOOST_TTI_DETAIL_TP_U,typename BOOST_TTI_DETAIL_TP_V> \
54     static ::boost::type_traits::no_type has_matching_member(...); \
55     \
56     template<class BOOST_TTI_DETAIL_TP_U,class BOOST_TTI_DETAIL_TP_V> \
57     struct ttc_sd \
58       { \
59       typedef boost::mpl::bool_<sizeof(has_matching_member<BOOST_TTI_DETAIL_TP_V,BOOST_TTI_DETAIL_TP_U>(0))==sizeof(::boost::type_traits::yes_type)> type; \
60       }; \
61     \
62     typedef typename ttc_sd<BOOST_TTI_DETAIL_TP_TYPE,BOOST_TTI_DETAIL_TP_T>::type type; \
63     }; \
64 /**/
65 
66 #else
67 
68 #define BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA_OP(trait,name) \
69   template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_TYPE> \
70   struct BOOST_PP_CAT(trait,_detail_hsd_op) \
71     { \
72     template<BOOST_TTI_DETAIL_TP_TYPE *> \
73     struct helper BOOST_TTI_DETAIL_MACRO_SUNFIX ; \
74     \
75     template<class BOOST_TTI_DETAIL_TP_U> \
76     static ::boost::type_traits::yes_type chkt(helper<&BOOST_TTI_DETAIL_TP_U::name> *); \
77     \
78     template<class BOOST_TTI_DETAIL_TP_U> \
79     static ::boost::type_traits::no_type chkt(...); \
80     \
81     typedef boost::mpl::bool_<(!boost::function_types::is_function<BOOST_TTI_DETAIL_TP_TYPE>::value) && (sizeof(chkt<BOOST_TTI_DETAIL_TP_T>(BOOST_TTI_DETAIL_NULLPTR))==sizeof(::boost::type_traits::yes_type))> type; \
82     }; \
83 /**/
84 
85 #endif // defined(BOOST_MSVC)
86 
87 #if defined(BOOST_NO_CXX11_UNRESTRICTED_UNION)
88 
89 #define BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA(trait,name) \
90   BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA_OP(trait,name) \
91   template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_TYPE> \
92   struct BOOST_PP_CAT(trait,_detail_hsd) : \
93     boost::mpl::eval_if \
94         < \
95         boost::is_class<BOOST_TTI_DETAIL_TP_T>, \
96         BOOST_PP_CAT(trait,_detail_hsd_op)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_TYPE>, \
97         boost::mpl::false_ \
98         > \
99     { \
100     }; \
101 /**/
102 
103 #else
104 
105 #define BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA(trait,name) \
106   BOOST_TTI_DETAIL_TRAIT_HAS_STATIC_MEMBER_DATA_OP(trait,name) \
107   template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_TYPE> \
108   struct BOOST_PP_CAT(trait,_detail_hsd) : \
109     boost::mpl::eval_if \
110         < \
111         BOOST_TTI_NAMESPACE::detail::enclosing_type<BOOST_TTI_DETAIL_TP_T>, \
112         BOOST_PP_CAT(trait,_detail_hsd_op)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_TYPE>, \
113         boost::mpl::false_ \
114         > \
115     { \
116     }; \
117 /**/
118 
119 #endif
120 
121 #endif // BOOST_TTI_DETAIL_STATIC_MEM_DATA_HPP
122