summaryrefslogtreecommitdiff
path: root/include/new
blob: 4e527501b1e286ce8d965eae79b85c3bda688760 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
// -*- C++ -*-
//===----------------------------- new ------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_NEW
#define _LIBCPP_NEW

/*
    new synopsis

namespace std
{

class bad_alloc
    : public exception
{
public:
    bad_alloc() noexcept;
    bad_alloc(const bad_alloc&) noexcept;
    bad_alloc& operator=(const bad_alloc&) noexcept;
    virtual const char* what() const noexcept;
};

class bad_array_length : public bad_alloc // FIXME: Not part of C++
{
public:
    bad_array_length() noexcept;
};

class bad_array_new_length : public bad_alloc // C++14
{
public:
    bad_array_new_length() noexcept;
};

enum class align_val_t : size_t {}; // C++17
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler set_new_handler(new_handler new_p) noexcept;
new_handler get_new_handler() noexcept;

// 21.6.4, pointer optimization barrier
template <class T> constexpr T* launder(T* p) noexcept; // C++17
}  // std

void* operator new(std::size_t size);                                   // replaceable, nodiscard in C++2a
void* operator new(std::size_t size, std::align_val_t alignment);       // replaceable, C++17, nodiscard in C++2a
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable, nodiscard in C++2a
void* operator new(std::size_t size, std::align_val_t alignment,
                   const std::nothrow_t&) noexcept;                     // replaceable, C++17, nodiscard in C++2a
void  operator delete(void* ptr) noexcept;                              // replaceable
void  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14
void  operator delete(void* ptr, std::align_val_t alignment) noexcept;  // replaceable, C++17
void  operator delete(void* ptr, std::size_t size,
                      std::align_val_t alignment) noexcept;             // replaceable, C++17
void  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
void  operator delete(void* ptr, std:align_val_t alignment,
                      const std::nothrow_t&) noexcept;                  // replaceable, C++17

void* operator new[](std::size_t size);                                 // replaceable, nodiscard in C++2a
void* operator new[](std::size_t size,
                     std::align_val_t alignment) noexcept;              // replaceable, C++17, nodiscard in C++2a
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a
void* operator new[](std::size_t size, std::align_val_t alignment,
                     const std::nothrow_t&) noexcept;                   // replaceable, C++17, nodiscard in C++2a
void  operator delete[](void* ptr) noexcept;                            // replaceable
void  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14
void  operator delete[](void* ptr,
                        std::align_val_t alignment) noexcept;           // replaceable, C++17
void  operator delete[](void* ptr, std::size_t size,
                        std::align_val_t alignment) noexcept;           // replaceable, C++17
void  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
void  operator delete[](void* ptr, std::align_val_t alignment,
                        const std::nothrow_t&) noexcept;                // replaceable, C++17

void* operator new  (std::size_t size, void* ptr) noexcept;             // nodiscard in C++2a
void* operator new[](std::size_t size, void* ptr) noexcept;             // nodiscard in C++2a
void  operator delete  (void* ptr, void*) noexcept;
void  operator delete[](void* ptr, void*) noexcept;

*/

#include <__config>
#include <exception>
#include <cstddef>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif

#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#include <new.h>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#endif

#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
    (!(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
    (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)))
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#endif

namespace std  // purposefully not using versioning namespace
{

#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
struct _LIBCPP_TYPE_VIS nothrow_t {};
extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;

class _LIBCPP_EXCEPTION_ABI bad_alloc
    : public exception
{
public:
    bad_alloc() _NOEXCEPT;
    virtual ~bad_alloc() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

class _LIBCPP_EXCEPTION_ABI bad_array_new_length
    : public bad_alloc
{
public:
    bad_array_new_length() _NOEXCEPT;
    virtual ~bad_array_new_length() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

typedef void (*new_handler)();
_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;

#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME

_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec

#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)

class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
    bad_array_length : public bad_alloc {
public:
    bad_array_length() _NOEXCEPT;
    virtual ~bad_array_length() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED

#endif  // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)

#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
#ifndef _LIBCPP_CXX03_LANG
enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
#else
enum align_val_t { __zero = 0, __max = (size_t)-1 };
#endif
#endif

}  // std

#if defined(_LIBCPP_CXX03_LANG)
#define _THROW_BAD_ALLOC throw(std::bad_alloc)
#else
#define _THROW_BAD_ALLOC
#endif

#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)

_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
#endif

_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
#endif

#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif

_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
#endif

_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
inline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
inline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}

#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME

_LIBCPP_BEGIN_NAMESPACE_STD

inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
  return ::operator new(__size);
#else
  return __builtin_operator_new(__size);
#endif
}

inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void *__ptr) {
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
  ::operator delete(__ptr);
#else
  __builtin_operator_delete(__ptr);
#endif
}

#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#endif
void __throw_bad_array_length()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw bad_array_length();
#else
	_VSTD::abort();
#endif
}
#endif

template <class _Tp>
_LIBCPP_NODISCARD_AFTER_CXX17 inline 
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
    static_assert (!(is_function<_Tp>::value), "can't launder functions" );
    static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
    return __builtin_launder(__p);
#else
    return __p;
#endif
}


#if _LIBCPP_STD_VER > 14
template <class _Tp>
_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
constexpr _Tp* launder(_Tp* __p) noexcept
{
    return _VSTD::__launder(__p);
}
#endif

_LIBCPP_END_NAMESPACE_STD

#endif  // _LIBCPP_NEW