libstdc++: memory_resource.h Source File (original) (raw)

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#ifndef _GLIBCXX_MEMORY_RESOURCE_H

31#define _GLIBCXX_MEMORY_RESOURCE_H 1

32

33#pragma GCC system_header

34

35#if __cplusplus >= 201703L

36

37#include <new>

38#include <cstddef>

40#include <bits/uses_allocator.h>

44

45#if ! __glibcxx_make_obj_using_allocator

47# include

48#endif

49

50namespace std _GLIBCXX_VISIBILITY(default)

51{

52_GLIBCXX_BEGIN_NAMESPACE_VERSION

53namespace pmr

54{

55

56

57

58

59

60

62 {

63 static constexpr size_t _S_max_align = alignof(max_align_t);

64

65 public:

69

71

72 [[nodiscard]]

73 void*

74 allocate(size_t __bytes, size_t __alignment = _S_max_align)

75 __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))

76 { return ::operator new(__bytes, do_allocate(__bytes, __alignment)); }

77

78 void

79 deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)

80 __attribute__((__nonnull__))

81 { return do_deallocate(__p, __bytes, __alignment); }

82

83 [[nodiscard]]

84 bool

86 { return do_is_equal(__other); }

87

88 private:

89 virtual void*

90 do_allocate(size_t __bytes, size_t __alignment) = 0;

91

92 virtual void

93 do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;

94

95 virtual bool

96 do_is_equal(const memory_resource& __other) const noexcept = 0;

97 };

98

99 [[nodiscard]]

100 inline bool

102 { return &__a == &__b || __a.is_equal(__b); }

103

104#if __cpp_impl_three_way_comparison < 201907L

105 [[nodiscard]]

106 inline bool

107 operator!=(const memory_resource& __a, const memory_resource& __b) noexcept

108 { return !(__a == __b); }

109#endif

110

111

112

113

114

115

116

117

118

119 template<typename _Tp>

121 {

122

123

124 template<typename _Up>

125 struct __not_pair { using type = void; };

126

127 template<typename _Up1, typename _Up2>

128 struct __not_pair<pair<_Up1, _Up2>> { };

129

130 public:

131 using value_type = _Tp;

132

134 {

136 __attribute__((__returns_nonnull__));

138 }

139

141 __attribute__((__nonnull__))

142 : _M_resource(__r)

143 { _GLIBCXX_DEBUG_ASSERT(__r); }

144

146

147 template<typename _Up>

149 : _M_resource(__x.resource())

150 { }

151

154

155 [[nodiscard]]

156 _Tp*

157 allocate(size_t __n)

158 __attribute__((__returns_nonnull__))

159 {

161 std::__throw_bad_array_new_length();

162 return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),

163 alignof(_Tp)));

164 }

165

166 void

167 deallocate(_Tp* __p, size_t __n) noexcept

168 __attribute__((__nonnull__))

169 { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }

170

171#if __cplusplus > 201703L

172 [[nodiscard]] void*

173 allocate_bytes(size_t __nbytes,

174 size_t __alignment = alignof(max_align_t))

175 { return _M_resource->allocate(__nbytes, __alignment); }

176

177 void

178 deallocate_bytes(void* __p, size_t __nbytes,

179 size_t __alignment = alignof(max_align_t))

180 { _M_resource->deallocate(__p, __nbytes, __alignment); }

181

182 template<typename _Up>

183 [[nodiscard]] _Up*

184 allocate_object(size_t __n = 1)

185 {

187 std::__throw_bad_array_new_length();

188 return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up),

189 alignof(_Up)));

190 }

191

192 template<typename _Up>

193 void

194 deallocate_object(_Up* __p, size_t __n = 1)

195 { deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); }

196

197 template<typename _Up, typename... _CtorArgs>

198 [[nodiscard]] _Up*

199 new_object(_CtorArgs&&... __ctor_args)

200 {

201 _Up* __p = allocate_object<_Up>();

202 __try

203 {

204 construct(__p, std::forward<_CtorArgs>(__ctor_args)...);

205 }

206 __catch (...)

207 {

208 deallocate_object(__p);

209 __throw_exception_again;

210 }

211 return __p;

212 }

213

214 template<typename _Up>

215 void

216 delete_object(_Up* __p)

217 {

218 __p->~_Up();

219 deallocate_object(__p);

220 }

221#endif

222

223#if ! __glibcxx_make_obj_using_allocator

224 template<typename _Tp1, typename... _Args>

225 __attribute__((__nonnull__))

226 typename __not_pair<_Tp1>::type

227 construct(_Tp1* __p, _Args&&... __args)

228 {

229

230

231 using __use_tag

233 if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)

234 ::new(__p) _Tp1(std::forward<_Args>(__args)...);

235 else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)

236 ::new(__p) _Tp1(allocator_arg, *this,

237 std::forward<_Args>(__args)...);

238 else

239 ::new(__p) _Tp1(std::forward<_Args>(__args)..., *this);

240 }

241

242 template<typename _Tp1, typename _Tp2,

243 typename... _Args1, typename... _Args2>

244 __attribute__((__nonnull__))

245 void

248 {

249 auto __x_tag =

251 auto __y_tag =

255

257 _S_construct_p(__x_tag, __x_i, __x),

258 _S_construct_p(__y_tag, __y_i, __y));

259 }

260

261 template<typename _Tp1, typename _Tp2>

262 __attribute__((__nonnull__))

263 void

266

267 template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>

268 __attribute__((__nonnull__))

269 void

271 {

275 }

276

277 template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>

278 __attribute__((__nonnull__))

279 void

281 {

285 }

286

287 template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>

288 __attribute__((__nonnull__))

289 void

291 {

295 }

296#else

297 template<typename _Tp1, typename... _Args>

298 __attribute__((__nonnull__))

299 void

300 construct(_Tp1* __p, _Args&&... __args)

301 {

302 std::uninitialized_construct_using_allocator(__p, *this,

303 std::forward<_Args>(__args)...);

304 }

305#endif

306

307 template<typename _Up>

308 __attribute__((__nonnull__))

309 void

310 destroy(_Up* __p)

311 { __p->~_Up(); }

312

314 select_on_container_copy_construction() const noexcept

316

318 resource() const noexcept

319 __attribute__((__returns_nonnull__))

320 { return _M_resource; }

321

322

323

324 [[nodiscard]]

325 friend bool

328 { return *__a.resource() == *__b.resource(); }

329

330#if __cpp_impl_three_way_comparison < 201907L

331 [[nodiscard]]

332 friend bool

335 { return !(__a == __b); }

336#endif

337

338 private:

339#if ! __glibcxx_make_obj_using_allocator

340 using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;

341 using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;

342

343 template<typename _Ind, typename... _Args>

344 static tuple<_Args&&...>

345 _S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)

347

348 template<size_t... _Ind, typename... _Args>

352 {

353 return {

354 allocator_arg, *__ua._M_a, std::get<_Ind>(std::move(__t))...

355 };

356 }

357

358 template<size_t... _Ind, typename... _Args>

362 { return { std::get<_Ind>(std::move(__t))..., *__ua._M_a }; }

363#endif

364

366 };

367

368 template<typename _Tp1, typename _Tp2>

369 [[nodiscard]]

370 inline bool

373 { return *__a.resource() == *__b.resource(); }

374

375#if __cpp_impl_three_way_comparison < 201907L

376 template<typename _Tp1, typename _Tp2>

377 [[nodiscard]]

378 inline bool

379 operator!=(const polymorphic_allocator<_Tp1>& __a,

380 const polymorphic_allocator<_Tp2>& __b) noexcept

381 { return !(__a == __b); }

382#endif

383

384}

385

386 template<typename _Alloc> struct allocator_traits;

387

388

389

390

391

392

393

394 template<typename _Tp>

396 {

397

399

400

402

403

405

406

408

409

411

412

414

415

417

418

420

421

422

423

424

428

432

433

434

436

437 template<typename _Up>

439

440 template<typename _Up>

442

443

444

445

446

447

448

449

450 [[nodiscard]] static pointer

452 { return __a.allocate(__n); }

453

454

455

456

457

458

459

460

461

462

463

464

465 [[nodiscard]] static pointer

467 { return __a.allocate(__n); }

468

469

470

471

472

473

474

475

476

477 static void

479 { __a.deallocate(__p, __n); }

480

481

482

483

484

485

486

487

488

489

490

491

492 template<typename _Up, typename... _Args>

493 static void

495 { __a.construct(__p, std::forward<_Args>(__args)...); }

496

497

498

499

500

501

502

503

504 template<typename _Up>

505 static _GLIBCXX20_CONSTEXPR void

508 { __p->~_Up(); }

509

510

511

512

513

514 static _GLIBCXX20_CONSTEXPR size_type

516 { return size_t(-1) / sizeof(value_type); }

517 };

518

519_GLIBCXX_END_NAMESPACE_VERSION

520}

521

522#endif

523#endif

memory_resource * get_default_resource() noexcept

Get the current default memory resource pointer.

__bool_constant< false > false_type

The type used as a compile-time boolean with false value.

constexpr tuple< _Elements &&... > forward_as_tuple(_Elements &&... __args) noexcept

Create a tuple of lvalue or rvalue references to the arguments.

constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept

Convert a value to an rvalue.

constexpr piecewise_construct_t piecewise_construct

Tag for piecewise construction of std::pair objects.

ISO C++ entities toplevel namespace is std.

make_index_sequence< sizeof...(_Types)> index_sequence_for

Alias template index_sequence_for.

__numeric_traits_integer< _Tp > __int_traits

Convenience alias for __numeric_traits.

Primary class template, tuple.

Uniform interface to all allocator types.

__detected_or_t< value_type *, __pointer, _Alloc > pointer

The allocator's pointer type.

typename _Size< _Alloc, difference_type >::type size_type

The allocator's size type.

_Alloc::value_type value_type

The allocated type.

_Alloc allocator_type

The allocator type.

Class template polymorphic_allocator.

static void construct(allocator_type &__a, _Up *__p, _Args &&... __args)

Construct an object of type _Up

std::ptrdiff_t difference_type

The allocator's difference type.

static void deallocate(allocator_type &__a, pointer __p, size_type __n)

Deallocate memory.

_Tp value_type

The allocated type.

static constexpr void destroy(allocator_type &, _Up *__p) noexcept(is_nothrow_destructible< _Up >::value)

Destroy an object of type _Up

static constexpr size_type max_size(const allocator_type &) noexcept

The maximum supported allocation size.

static pointer allocate(allocator_type &__a, size_type __n)

Allocate memory.

false_type propagate_on_container_swap

_Tp * pointer

The allocator's pointer type.

const _Tp * const_pointer

The allocator's const pointer type.

false_type propagate_on_container_move_assignment

static pointer allocate(allocator_type &__a, size_type __n, const_void_pointer)

Allocate memory.

const void * const_void_pointer

The allocator's const void pointer type.

false_type propagate_on_container_copy_assignment

static allocator_type select_on_container_copy_construction(const allocator_type &) noexcept

void * void_pointer

The allocator's void pointer type.

false_type is_always_equal

Whether all instances of the allocator type compare equal.

std::size_t size_type

The allocator's size type.

Struct holding two objects of arbitrary type.

_T1 first

The first member.

_T2 second

The second member.

Tag type for piecewise construction of std::pair objects.

Class template integer_sequence.