summaryrefslogtreecommitdiffstats
blob: c615127da3435770a8ebf145d98161fabfb120c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

//  (C) Copyright Runar Undheim, Robert Ramey & John Maddock 2008.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED
#define BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED

#include <new> // std::nothrow_t
#include <cstddef> // std::size_t
#include <boost/type_traits/config.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/detail/ice_or.hpp>

// should be the last #include
#include <boost/type_traits/detail/bool_trait_def.hpp>

#if defined(new) 
#  if BOOST_WORKAROUND(BOOST_MSVC, >= 1310)
#     define BOOST_TT_AUX_MACRO_NEW_DEFINED
#     pragma push_macro("new")
#     undef new
#  else
#     error "Sorry but you can't include this header if 'new' is defined as a macro."
#  endif
#endif

namespace boost {
namespace detail {
    template <class U, U x> 
    struct test;

    template <typename T>
    struct has_new_operator_impl {
        template<class U>
        static type_traits::yes_type check_sig1(
            U*, 
            test<
            void *(*)(std::size_t),
                &U::operator new
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig1(...);

        template<class U>
        static type_traits::yes_type check_sig2(
            U*, 
            test<
            void *(*)(std::size_t, const std::nothrow_t&),
                &U::operator new
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig2(...);

        template<class U>
        static type_traits::yes_type check_sig3(
            U*, 
            test<
            void *(*)(std::size_t, void*),
                &U::operator new
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig3(...);


        template<class U>
        static type_traits::yes_type check_sig4(
            U*, 
            test<
            void *(*)(std::size_t),
                &U::operator new[]
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig4(...);

        template<class U>
        static type_traits::yes_type check_sig5(
            U*, 
            test<
            void *(*)(std::size_t, const std::nothrow_t&),
                &U::operator new[]
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig5(...);

        template<class U>
        static type_traits::yes_type check_sig6(
            U*, 
            test<
            void *(*)(std::size_t, void*),
                &U::operator new[]
            >* = NULL
        );
        template<class U>
        static type_traits::no_type check_sig6(...);

        // GCC2 won't even parse this template if we embed the computation
        // of s1 in the computation of value.
        #ifdef __GNUC__
            BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(has_new_operator_impl<T>::template check_sig1<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(has_new_operator_impl<T>::template check_sig2<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(has_new_operator_impl<T>::template check_sig3<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(has_new_operator_impl<T>::template check_sig4<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(has_new_operator_impl<T>::template check_sig5<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(has_new_operator_impl<T>::template check_sig6<T>(0)));
        #else
            #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
                #pragma warning(push)
                #pragma warning(disable:6334)
            #endif

            BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(check_sig1<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(check_sig2<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(check_sig3<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(check_sig4<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(check_sig5<T>(0)));
            BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(check_sig6<T>(0)));

            #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
                #pragma warning(pop)
            #endif
        #endif
        BOOST_STATIC_CONSTANT(bool, value = 
           (::boost::type_traits::ice_or<
            (s1 == sizeof(type_traits::yes_type)),
            (s2 == sizeof(type_traits::yes_type)),
            (s3 == sizeof(type_traits::yes_type)),
            (s4 == sizeof(type_traits::yes_type)),
            (s5 == sizeof(type_traits::yes_type)),
            (s6 == sizeof(type_traits::yes_type))
           >::value)
        );
    };
} // namespace detail

BOOST_TT_AUX_BOOL_TRAIT_DEF1(has_new_operator,T,::boost::detail::has_new_operator_impl<T>::value)

} // namespace boost

#if defined(BOOST_TT_AUX_MACRO_NEW_DEFINED)
#  pragma pop_macro("new")
#endif

#include <boost/type_traits/detail/bool_trait_undef.hpp>

#endif // BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED