1 | |
2 | // (C) Copyright Runar Undheim, Robert Ramey & John Maddock 2008. |
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 | // See http://www.boost.org/libs/type_traits for most recent version including documentation. |
8 | |
9 | #ifndef BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED |
10 | #define BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED |
11 | |
12 | #include <new> // std::nothrow_t |
13 | #include <cstddef> // std::size_t |
14 | #include <boost/type_traits/integral_constant.hpp> |
15 | #include <boost/type_traits/detail/yes_no_type.hpp> |
16 | #include <boost/detail/workaround.hpp> |
17 | |
18 | #if defined(new) |
19 | # if BOOST_WORKAROUND(BOOST_MSVC, >= 1310) |
20 | # define BOOST_TT_AUX_MACRO_NEW_DEFINED |
21 | # pragma push_macro("new") |
22 | # undef new |
23 | # else |
24 | # error "Sorry but you can't include this header if 'new' is defined as a macro." |
25 | # endif |
26 | #endif |
27 | |
28 | namespace boost { |
29 | namespace detail { |
30 | template <class U, U x> |
31 | struct test; |
32 | |
33 | template <typename T> |
34 | struct has_new_operator_impl { |
35 | template<class U> |
36 | static type_traits::yes_type check_sig1( |
37 | U*, |
38 | test< |
39 | void *(*)(std::size_t), |
40 | &U::operator new |
41 | >* = NULL |
42 | ); |
43 | template<class U> |
44 | static type_traits::no_type check_sig1(...); |
45 | |
46 | template<class U> |
47 | static type_traits::yes_type check_sig2( |
48 | U*, |
49 | test< |
50 | void *(*)(std::size_t, const std::nothrow_t&), |
51 | &U::operator new |
52 | >* = NULL |
53 | ); |
54 | template<class U> |
55 | static type_traits::no_type check_sig2(...); |
56 | |
57 | template<class U> |
58 | static type_traits::yes_type check_sig3( |
59 | U*, |
60 | test< |
61 | void *(*)(std::size_t, void*), |
62 | &U::operator new |
63 | >* = NULL |
64 | ); |
65 | template<class U> |
66 | static type_traits::no_type check_sig3(...); |
67 | |
68 | |
69 | template<class U> |
70 | static type_traits::yes_type check_sig4( |
71 | U*, |
72 | test< |
73 | void *(*)(std::size_t), |
74 | &U::operator new[] |
75 | >* = NULL |
76 | ); |
77 | template<class U> |
78 | static type_traits::no_type check_sig4(...); |
79 | |
80 | template<class U> |
81 | static type_traits::yes_type check_sig5( |
82 | U*, |
83 | test< |
84 | void *(*)(std::size_t, const std::nothrow_t&), |
85 | &U::operator new[] |
86 | >* = NULL |
87 | ); |
88 | template<class U> |
89 | static type_traits::no_type check_sig5(...); |
90 | |
91 | template<class U> |
92 | static type_traits::yes_type check_sig6( |
93 | U*, |
94 | test< |
95 | void *(*)(std::size_t, void*), |
96 | &U::operator new[] |
97 | >* = NULL |
98 | ); |
99 | template<class U> |
100 | static type_traits::no_type check_sig6(...); |
101 | |
102 | // GCC2 won't even parse this template if we embed the computation |
103 | // of s1 in the computation of value. |
104 | #ifdef __GNUC__ |
105 | BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(has_new_operator_impl<T>::template check_sig1<T>(0))); |
106 | BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(has_new_operator_impl<T>::template check_sig2<T>(0))); |
107 | BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(has_new_operator_impl<T>::template check_sig3<T>(0))); |
108 | BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(has_new_operator_impl<T>::template check_sig4<T>(0))); |
109 | BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(has_new_operator_impl<T>::template check_sig5<T>(0))); |
110 | BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(has_new_operator_impl<T>::template check_sig6<T>(0))); |
111 | #else |
112 | #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) |
113 | #pragma warning(push) |
114 | #pragma warning(disable:6334) |
115 | #endif |
116 | |
117 | BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(check_sig1<T>(0))); |
118 | BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(check_sig2<T>(0))); |
119 | BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(check_sig3<T>(0))); |
120 | BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(check_sig4<T>(0))); |
121 | BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(check_sig5<T>(0))); |
122 | BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(check_sig6<T>(0))); |
123 | |
124 | #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) |
125 | #pragma warning(pop) |
126 | #endif |
127 | #endif |
128 | BOOST_STATIC_CONSTANT(bool, value = |
129 | (s1 == sizeof(type_traits::yes_type)) || |
130 | (s2 == sizeof(type_traits::yes_type)) || |
131 | (s3 == sizeof(type_traits::yes_type)) || |
132 | (s4 == sizeof(type_traits::yes_type)) || |
133 | (s5 == sizeof(type_traits::yes_type)) || |
134 | (s6 == sizeof(type_traits::yes_type)) |
135 | ); |
136 | }; |
137 | } // namespace detail |
138 | |
139 | template <class T> struct has_new_operator : public integral_constant<bool, ::boost::detail::has_new_operator_impl<T>::value>{}; |
140 | |
141 | } // namespace boost |
142 | |
143 | #if defined(BOOST_TT_AUX_MACRO_NEW_DEFINED) |
144 | # pragma pop_macro("new") |
145 | #endif |
146 | |
147 | #endif // BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED |
148 | |