libstdc++: shared_ptr.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

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49#ifndef _SHARED_PTR_H

50#define _SHARED_PTR_H 1

51

52#include <iosfwd>

54

55namespace std _GLIBCXX_VISIBILITY(default)

56{

57_GLIBCXX_BEGIN_NAMESPACE_VERSION

58

59

60

61

62

63

64

65

66

67

68 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>

71 const __shared_ptr<_Tp, _Lp>& __p)

72 {

73 __os << __p.get();

74 return __os;

75 }

76

77 template<typename _Del, typename _Tp, _Lock_policy _Lp>

78 inline _Del*

79 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept

80 {

81#if __cpp_rtti

82 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));

83#else

84 return 0;

85#endif

86 }

87

88

89

90

91

92 template<typename _Del, typename _Tp>

93 inline _Del*

95 {

96#if __cpp_rtti

97 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));

98#else

99 return 0;

100#endif

101 }

102

103

104

105

106#if __cpp_concepts && __glibcxx_type_trait_variable_templates

107 template<typename _Tp>

108 requires (!is_array_v<_Tp>)

109 using _NonArray = _Tp;

110#else

111 template<typename _Tp>

112 using _NonArray = __enable_if_t<!is_array<_Tp>::value, _Tp>;

113#endif

114

115#if __glibcxx_shared_ptr_arrays >= 201707L

116

117#if __cpp_concepts

118 template<typename _Tp>

119 requires is_array_v<_Tp> && (extent_v<_Tp> == 0)

120 using _UnboundedArray = _Tp;

121#else

122 template<typename _Tp>

123 using _UnboundedArray

124 = __enable_if_t<__is_array_unknown_bounds<_Tp>::value, _Tp>;

125#endif

126

127

128#if __cpp_concepts

129 template<typename _Tp>

130 requires (extent_v<_Tp> != 0)

131 using _BoundedArray = _Tp;

132#else

133 template<typename _Tp>

134 using _BoundedArray

135 = __enable_if_t<__is_array_known_bounds<_Tp>::value, _Tp>;

136#endif

137

138#if __glibcxx_smart_ptr_for_overwrite

139

140#if __cpp_concepts

141 template<typename _Tp>

142 requires (!is_array_v<_Tp>) || (extent_v<_Tp> != 0)

143 using _NotUnboundedArray = _Tp;

144#else

145 template<typename _Tp>

146 using _NotUnboundedArray

147 = __enable_if_t<!__is_array_unknown_bounds<_Tp>::value, _Tp>;

148#endif

149#endif

150#endif

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174 template<typename _Tp>

176 {

177 template<typename... _Args>

178 using _Constructible = typename enable_if<

180 >::type;

181

182 template<typename _Arg>

183 using _Assignable = typename enable_if<

185 >::type;

186

187 public:

188

189

190 using element_type = typename __shared_ptr<_Tp>::element_type;

191

192#ifdef __glibcxx_shared_ptr_weak_type

193

194

195 using weak_type = weak_ptr<_Tp>;

196#endif

197

198

199

200

201 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }

202

204

205

206

207

208

209

210

211 template<typename _Yp, typename = _Constructible<_Yp*>>

212 explicit

213 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228 template<typename _Yp, typename _Deleter,

229 typename = _Constructible<_Yp*, _Deleter>>

231 : __shared_ptr<_Tp>(__p, std::move(__d)) { }

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246 template<typename _Deleter>

248 : __shared_ptr<_Tp>(__p, std::move(__d)) { }

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265 template<typename _Yp, typename _Deleter, typename _Alloc,

266 typename = _Constructible<_Yp*, _Deleter, _Alloc>>

268 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285 template<typename _Deleter, typename _Alloc>

286 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)

287 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309 template<typename _Yp>

311 : __shared_ptr<_Tp>(__r, __p) { }

312

313#if __cplusplus > 201703L

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337 template<typename _Yp>

339 : __shared_ptr<_Tp>(std::move(__r), __p) { }

340#endif

341

342

343

344

345

346

347

348 template<typename _Yp,

349 typename = _Constructible<const shared_ptr<_Yp>&>>

351 : __shared_ptr<_Tp>(__r) { }

352

353

354

355

356

357

359 : __shared_ptr<_Tp>(std::move(__r)) { }

360

361

362

363

364

365

366 template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>

368 : __shared_ptr<_Tp>(std::move(__r)) { }

369

370

371

372

373

374

375

376

377

378 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>

380 : __shared_ptr<_Tp>(__r) { }

381

382#if _GLIBCXX_USE_DEPRECATED

383#pragma GCC diagnostic push

384#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

385 template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>

387#pragma GCC diagnostic pop

388#endif

389

390

391

392 template<typename _Yp, typename _Del,

393 typename = _Constructible<unique_ptr<_Yp, _Del>>>

395 : __shared_ptr<_Tp>(std::move(__r)) { }

396

397#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED

398

399

400

401 template<typename _Yp, typename _Del,

402 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>

403 shared_ptr(unique_ptr<_Yp, _Del>&& __r)

404 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }

405#endif

406

407

408

409

410

412

414

415 template<typename _Yp>

416 _Assignable<const shared_ptr<_Yp>&>

418 {

419 this->__shared_ptr<_Tp>::operator=(__r);

420 return *this;

421 }

422

423#if _GLIBCXX_USE_DEPRECATED

424#pragma GCC diagnostic push

425#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

426 template<typename _Yp>

427 _Assignable<auto_ptr<_Yp>>

428 operator=(auto_ptr<_Yp>&& __r)

429 {

430 this->__shared_ptr<_Tp>::operator=(std::move(__r));

431 return *this;

432 }

433#pragma GCC diagnostic pop

434#endif

435

438 {

439 this->__shared_ptr<_Tp>::operator=(std::move(__r));

440 return *this;

441 }

442

443 template<class _Yp>

444 _Assignable<shared_ptr<_Yp>>

445 operator=(shared_ptr<_Yp>&& __r) noexcept

446 {

447 this->__shared_ptr<_Tp>::operator=(std::move(__r));

448 return *this;

449 }

450

451 template<typename _Yp, typename _Del>

452 _Assignable<unique_ptr<_Yp, _Del>>

453 operator=(unique_ptr<_Yp, _Del>&& __r)

454 {

455 this->__shared_ptr<_Tp>::operator=(std::move(__r));

456 return *this;

457 }

458

459 private:

460

461 template<typename _Alloc, typename... _Args>

462 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)

463 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)

464 { }

465

466 template<typename _Yp, typename _Alloc, typename... _Args>

467 friend shared_ptr<_NonArray<_Yp>>

468 allocate_shared(const _Alloc&, _Args&&...);

469

470 template<typename _Yp, typename... _Args>

471 friend shared_ptr<_NonArray<_Yp>>

472 make_shared(_Args&&...);

473

474#if __glibcxx_shared_ptr_arrays >= 201707L

475

476 template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>

477 shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,

478 _Init __init = nullptr)

479 : __shared_ptr<_Tp>(__a, __init)

480 { }

481

482 template<typename _Yp, typename _Alloc>

483 friend shared_ptr<_UnboundedArray<_Yp>>

484 allocate_shared(const _Alloc&, size_t);

485

486 template<typename _Yp>

487 friend shared_ptr<_UnboundedArray<_Yp>>

488 make_shared(size_t);

489

490 template<typename _Yp, typename _Alloc>

491 friend shared_ptr<_UnboundedArray<_Yp>>

492 allocate_shared(const _Alloc&, size_t, const remove_extent_t<_Yp>&);

493

494 template<typename _Yp>

495 friend shared_ptr<_UnboundedArray<_Yp>>

496 make_shared(size_t, const remove_extent_t<_Yp>&);

497

498 template<typename _Yp, typename _Alloc>

499 friend shared_ptr<_BoundedArray<_Yp>>

500 allocate_shared(const _Alloc&);

501

502 template<typename _Yp>

503 friend shared_ptr<_BoundedArray<_Yp>>

504 make_shared();

505

506 template<typename _Yp, typename _Alloc>

507 friend shared_ptr<_BoundedArray<_Yp>>

508 allocate_shared(const _Alloc&, const remove_extent_t<_Yp>&);

509

510 template<typename _Yp>

511 friend shared_ptr<_BoundedArray<_Yp>>

512 make_shared(const remove_extent_t<_Yp>&);

513

514#if __glibcxx_smart_ptr_for_overwrite

515 template<typename _Yp, typename _Alloc>

516 friend shared_ptr<_NotUnboundedArray<_Yp>>

517 allocate_shared_for_overwrite(const _Alloc&);

518

519 template<typename _Yp>

520 friend shared_ptr<_NotUnboundedArray<_Yp>>

521 make_shared_for_overwrite();

522

523 template<typename _Yp, typename _Alloc>

524 friend shared_ptr<_UnboundedArray<_Yp>>

525 allocate_shared_for_overwrite(const _Alloc&, size_t);

526

527 template<typename _Yp>

528 friend shared_ptr<_UnboundedArray<_Yp>>

529 make_shared_for_overwrite(size_t);

530#endif

531#endif

532

533

534 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept

535 : __shared_ptr<_Tp>(__r, std::nothrow) { }

536

537 friend class weak_ptr<_Tp>;

538 };

539

540#if __cpp_deduction_guides >= 201606

541 template<typename _Tp>

542 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;

543 template<typename _Tp, typename _Del>

544 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;

545#endif

546

547

548

549

550

551

552 template<typename _Tp, typename _Up>

553 _GLIBCXX_NODISCARD inline bool

555 { return __a.get() == __b.get(); }

556

557

558 template<typename _Tp>

559 _GLIBCXX_NODISCARD inline bool

561 { return !__a; }

562

563#ifdef __cpp_lib_three_way_comparison

564 template<typename _Tp, typename _Up>

565 inline strong_ordering

568 { return compare_three_way()(__a.get(), __b.get()); }

569

570 template<typename _Tp>

571 inline strong_ordering

572 operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

573 {

575 return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));

576 }

577#else

578

579 template<typename _Tp>

580 _GLIBCXX_NODISCARD inline bool

581 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

582 { return !__a; }

583

584

585 template<typename _Tp, typename _Up>

586 _GLIBCXX_NODISCARD inline bool

587 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept

588 { return __a.get() != __b.get(); }

589

590

591 template<typename _Tp>

592 _GLIBCXX_NODISCARD inline bool

593 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

594 { return (bool)__a; }

595

596

597 template<typename _Tp>

598 _GLIBCXX_NODISCARD inline bool

599 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

600 { return (bool)__a; }

601

602

603 template<typename _Tp, typename _Up>

604 _GLIBCXX_NODISCARD inline bool

605 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept

606 {

609 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;

610 return less<_Vp>()(__a.get(), __b.get());

611 }

612

613

614 template<typename _Tp>

615 _GLIBCXX_NODISCARD inline bool

616 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

617 {

619 return less<_Tp_elt*>()(__a.get(), nullptr);

620 }

621

622

623 template<typename _Tp>

624 _GLIBCXX_NODISCARD inline bool

625 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

626 {

628 return less<_Tp_elt*>()(nullptr, __a.get());

629 }

630

631

632 template<typename _Tp, typename _Up>

633 _GLIBCXX_NODISCARD inline bool

634 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept

635 { return !(__b < __a); }

636

637

638 template<typename _Tp>

639 _GLIBCXX_NODISCARD inline bool

640 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

641 { return !(nullptr < __a); }

642

643

644 template<typename _Tp>

645 _GLIBCXX_NODISCARD inline bool

646 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

647 { return !(__a < nullptr); }

648

649

650 template<typename _Tp, typename _Up>

651 _GLIBCXX_NODISCARD inline bool

652 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept

653 { return (__b < __a); }

654

655

656 template<typename _Tp>

657 _GLIBCXX_NODISCARD inline bool

658 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

659 { return nullptr < __a; }

660

661

662 template<typename _Tp>

663 _GLIBCXX_NODISCARD inline bool

664 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

665 { return __a < nullptr; }

666

667

668 template<typename _Tp, typename _Up>

669 _GLIBCXX_NODISCARD inline bool

670 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept

671 { return !(__a < __b); }

672

673

674 template<typename _Tp>

675 _GLIBCXX_NODISCARD inline bool

676 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept

677 { return !(__a < nullptr); }

678

679

680 template<typename _Tp>

681 _GLIBCXX_NODISCARD inline bool

682 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept

683 { return !(nullptr < __a); }

684#endif

685

686

687

688

689 template<typename _Tp>

690 inline void

692 { __a.swap(__b); }

693

694

695

696

697 template<typename _Tp, typename _Up>

700 {

702 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));

703 }

704

705

706 template<typename _Tp, typename _Up>

709 {

711 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));

712 }

713

714

715 template<typename _Tp, typename _Up>

718 {

720 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))

721 return _Sp(__r, __p);

722 return _Sp();

723 }

724

725#if __cplusplus >= 201703L

726

727

728 template<typename _Tp, typename _Up>

731 {

733 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));

734 }

735

736#if __cplusplus > 201703L

737

738

739

740

741

742 template<typename _Tp, typename _Up>

745 {

748 static_cast<typename _Sp::element_type*>(__r.get()));

749 }

750

751

752

753 template<typename _Tp, typename _Up>

756 {

759 const_cast<typename _Sp::element_type*>(__r.get()));

760 }

761

762

763

764 template<typename _Tp, typename _Up>

767 {

769 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))

771 return _Sp();

772 }

773

774

775

776 template<typename _Tp, typename _Up>

779 {

782 reinterpret_cast<typename _Sp::element_type*>(__r.get()));

783 }

784#endif

785#endif

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809 template<typename _Tp>

811 {

812 template<typename _Arg>

813 using _Constructible = typename enable_if<

815 >::type;

816

817 template<typename _Arg>

818 using _Assignable = typename enable_if<

820 >::type;

821

822 public:

823 constexpr weak_ptr() noexcept = default;

824

825 template<typename _Yp,

826 typename = _Constructible<const shared_ptr<_Yp>&>>

828 : __weak_ptr<_Tp>(__r) { }

829

831

832 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>

834 : __weak_ptr<_Tp>(__r) { }

835

837

838 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>

840 : __weak_ptr<_Tp>(std::move(__r)) { }

841

843 operator=(const weak_ptr& __r) noexcept = default;

844

845 template<typename _Yp>

846 _Assignable<const weak_ptr<_Yp>&>

848 {

849 this->__weak_ptr<_Tp>::operator=(__r);

850 return *this;

851 }

852

853 template<typename _Yp>

854 _Assignable<const shared_ptr<_Yp>&>

856 {

857 this->__weak_ptr<_Tp>::operator=(__r);

858 return *this;

859 }

860

862 operator=(weak_ptr&& __r) noexcept = default;

863

864 template<typename _Yp>

865 _Assignable<weak_ptr<_Yp>>

867 {

868 this->__weak_ptr<_Tp>::operator=(std::move(__r));

869 return *this;

870 }

871

873 lock() const noexcept

875 };

876

877#if __cpp_deduction_guides >= 201606

878 template<typename _Tp>

880#endif

881

882

883

884

885 template<typename _Tp>

886 inline void

888 { __a.swap(__b); }

889

890

891

892 template<typename _Tp = void>

894

895

896 template<>

897 struct owner_less : _Sp_owner_less<void, void>

898 { };

899

900

901 template<typename _Tp>

903 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>

904 { };

905

906

907 template<typename _Tp>

909 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>

910 { };

911

912

913

914

915

916

917 template<typename _Tp>

919 {

920 protected:

922

924

927 { return *this; }

928

930

931 public:

933 shared_from_this()

935

937 shared_from_this() const

939

940#ifdef __glibcxx_enable_shared_from_this

941

942

943

944

947 { return this->_M_weak_this; }

948

951 { return this->_M_weak_this; }

952

953#endif

954

955 private:

956 template<typename _Tp1>

957 void

958 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept

959 { _M_weak_this._M_assign(__p, __n); }

960

961

962 friend const enable_shared_from_this*

963 __enable_shared_from_this_base(const __shared_count<>&,

964 const enable_shared_from_this* __p)

965 { return __p; }

966

967 template<typename, _Lock_policy>

968 friend class __shared_ptr;

969

970 mutable weak_ptr<_Tp> _M_weak_this;

971 };

972

973

974

975

976

977

978

979

980

981

982

983

984

985

986 template<typename _Tp, typename _Alloc, typename... _Args>

987 inline shared_ptr<_NonArray<_Tp>>

989 {

990 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},

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

992 }

993

994

995

996

997

998

999

1000

1001 template<typename _Tp, typename... _Args>

1004 {

1006 _Alloc __a;

1007 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},

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

1009 }

1010

1011#if __glibcxx_shared_ptr_arrays >= 201707L

1012

1013 template<typename _Tp, typename _Alloc = allocator<void>>

1014 auto

1015 __make_shared_arr_tag(size_t __n, const _Alloc& __a = _Alloc()) noexcept

1016 {

1018 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;

1020 if (__builtin_mul_overflow(__s, __n, &__n))

1021 std::__throw_bad_array_new_length();

1022 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};

1023 }

1024

1025

1026 template<typename _Tp, typename _Alloc>

1027 inline shared_ptr<_UnboundedArray<_Tp>>

1029 {

1030 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a));

1031 }

1032

1033 template<typename _Tp>

1035 make_shared(size_t __n)

1036 {

1037 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n));

1038 }

1039

1040 template<typename _Tp, typename _Alloc>

1041 inline shared_ptr<_UnboundedArray<_Tp>>

1042 allocate_shared(const _Alloc& __a, size_t __n,

1043 const remove_extent_t<_Tp>& __u)

1044 {

1045 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),

1047 }

1048

1049 template<typename _Tp>

1050 inline shared_ptr<_UnboundedArray<_Tp>>

1051 make_shared(size_t __n, const remove_extent_t<_Tp>& __u)

1052 {

1053 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),

1055 }

1056

1057

1058 template<typename _Tp, typename _Alloc = allocator<void>>

1059 auto

1060 __make_shared_arrN_tag(const _Alloc& __a = _Alloc()) noexcept

1061 {

1062 using _Up = remove_all_extents_t<_Tp>;

1063 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;

1064 size_t __n = sizeof(_Tp) / sizeof(_Up);

1065 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};

1066 }

1067

1068

1069 template<typename _Tp, typename _Alloc>

1070 inline shared_ptr<_BoundedArray<_Tp>>

1072 {

1073 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a));

1074 }

1075

1076 template<typename _Tp>

1078 make_shared()

1079 {

1080 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>());

1081 }

1082

1083 template<typename _Tp, typename _Alloc>

1084 inline shared_ptr<_BoundedArray<_Tp>>

1085 allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u)

1086 {

1087 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),

1089 }

1090

1091 template<typename _Tp>

1092 inline shared_ptr<_BoundedArray<_Tp>>

1093 make_shared(const remove_extent_t<_Tp>& __u)

1094 {

1095 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),

1097 }

1098

1099#if __glibcxx_smart_ptr_for_overwrite

1100 template<typename _Tp, typename _Alloc>

1101 inline shared_ptr<_NotUnboundedArray<_Tp>>

1102 allocate_shared_for_overwrite(const _Alloc& __a)

1103 {

1104 if constexpr (is_array_v<_Tp>)

1105 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),

1106 _Sp_overwrite_tag{});

1107 else

1108 {

1109

1110

1111 using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;

1112 _Alloc2 __a2 = __a;

1113 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc2>{__a2});

1114 }

1115 }

1116

1117 template<typename _Tp>

1118 inline shared_ptr<_NotUnboundedArray<_Tp>>

1119 make_shared_for_overwrite()

1120 {

1121 if constexpr (is_array_v<_Tp>)

1122 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),

1123 _Sp_overwrite_tag{});

1124 else

1125 {

1126 using _Alloc = allocator<_Sp_overwrite_tag>;

1127 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{{}});

1128 }

1129 }

1130

1131 template<typename _Tp, typename _Alloc>

1132 inline shared_ptr<_UnboundedArray<_Tp>>

1133 allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)

1134 {

1135 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),

1136 _Sp_overwrite_tag{});

1137 }

1138

1139 template<typename _Tp>

1140 inline shared_ptr<_UnboundedArray<_Tp>>

1141 make_shared_for_overwrite(size_t __n)

1142 {

1143 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),

1144 _Sp_overwrite_tag{});

1145 }

1146#endif

1147#endif

1148

1149

1150 template<typename _Tp>

1152 : public __hash_base<size_t, shared_ptr<_Tp>>

1153 {

1154 size_t

1156 {

1158 }

1159 };

1160

1161#if __cpp_variable_templates

1162 template<typename _Tp>

1163 static constexpr bool __is_shared_ptr = false;

1164 template<typename _Tp>

1165 static constexpr bool __is_shared_ptr<shared_ptr<_Tp>> = true;

1166#endif

1167

1168

1169

1170

1171#if __cplusplus >= 201703L

1172 namespace __detail::__variant

1173 {

1174 template<typename> struct _Never_valueless_alt;

1175

1176

1177

1178 template<typename _Tp>

1179 struct _Never_valueless_alt<std::shared_ptr<_Tp>>

1181 { };

1182

1183

1184

1185 template<typename _Tp>

1186 struct _Never_valueless_alt<std::weak_ptr<_Tp>>

1188 { };

1189 }

1190#endif

1191

1192_GLIBCXX_END_NAMESPACE_VERSION

1193}

1194

1195#endif

constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)

constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)

constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)

constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)

shared_ptr< _BoundedArray< _Tp > > allocate_shared(const _Alloc &__a)

Create an object that is owned by a shared_ptr.

bool operator==(const shared_ptr< _Tp > &__a, nullptr_t) noexcept

shared_ptr comparison with nullptr

shared_ptr< _NonArray< _Tp > > make_shared(_Args &&... __args)

Create an object that is owned by a shared_ptr.

shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept

Convert type of shared_ptr, via static_cast

shared_ptr< _Tp > const_pointer_cast(shared_ptr< _Up > &&__r) noexcept

Convert type of shared_ptr rvalue, via const_cast

_Del * get_deleter(const shared_ptr< _Tp > &__p) noexcept

20.7.2.2.10 shared_ptr get_deleter

bool operator==(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept

shared_ptr< _Tp > static_pointer_cast(shared_ptr< _Up > &&__r) noexcept

Convert type of shared_ptr rvalue, via static_cast

shared_ptr< _Tp > reinterpret_pointer_cast(const shared_ptr< _Up > &__r) noexcept

Convert type of shared_ptr, via reinterpret_cast

shared_ptr< _NonArray< _Tp > > allocate_shared(const _Alloc &__a, _Args &&... __args)

Create an object that is owned by a shared_ptr.

void swap(weak_ptr< _Tp > &__a, weak_ptr< _Tp > &__b) noexcept

Swap overload for weak_ptr.

shared_ptr< _Tp > reinterpret_pointer_cast(shared_ptr< _Up > &&__r) noexcept

Convert type of shared_ptr rvalue, via reinterpret_cast

shared_ptr< _Tp > dynamic_pointer_cast(const shared_ptr< _Up > &__r) noexcept

Convert type of shared_ptr, via dynamic_cast

shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept

Convert type of shared_ptr, via const_cast

void swap(shared_ptr< _Tp > &__a, shared_ptr< _Tp > &__b) noexcept

Swap overload for shared_ptr.

shared_ptr< _UnboundedArray< _Tp > > allocate_shared(const _Alloc &__a, size_t __n)

Create an object that is owned by a shared_ptr.

shared_ptr< _Tp > dynamic_pointer_cast(shared_ptr< _Up > &&__r) noexcept

Convert type of shared_ptr rvalue, via dynamic_cast

__bool_constant< true > true_type

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

typename remove_all_extents< _Tp >::type remove_all_extents_t

Alias template for remove_all_extents.

typename remove_extent< _Tp >::type remove_extent_t

Alias template for remove_extent.

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

Convert a value to an rvalue.

constexpr _Tp * __addressof(_Tp &__r) noexcept

Same as C++11 std::addressof.

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

Forward an lvalue.

ISO C++ entities toplevel namespace is std.

std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)

Global I/O operators for bitsets.

Template class basic_ostream.

Primary class template hash.

Define a member typedef type only if a boolean constant is true.

The standard allocator, as per C++03 [20.4.1].

A smart pointer with reference-counted copy semantics.

typename __shared_ptr< _Tp >::element_type element_type

The type pointed to by the stored pointer, remove_extent_t<_Tp>

shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)

Construct a shared_ptr that owns a null pointer and the deleter __d.

shared_ptr(const shared_ptr< _Yp > &__r) noexcept

If __r is empty, constructs an empty shared_ptr; otherwise construct a shared_ptr that shares ownersh...

shared_ptr(shared_ptr< _Yp > &&__r) noexcept

Move-constructs a shared_ptr instance from __r.

shared_ptr(_Yp *__p, _Deleter __d, _Alloc __a)

Construct a shared_ptr that owns the pointer __p and the deleter __d.

constexpr shared_ptr() noexcept

Construct an empty shared_ptr.

shared_ptr(const shared_ptr &) noexcept=default

Copy constructor.

shared_ptr(shared_ptr &&__r) noexcept

Move-constructs a shared_ptr instance from __r.

shared_ptr(_Yp *__p)

Construct a shared_ptr that owns the pointer __p.

shared_ptr(nullptr_t __p, _Deleter __d)

Construct a shared_ptr that owns a null pointer and the deleter __d.

shared_ptr(_Yp *__p, _Deleter __d)

Construct a shared_ptr that owns the pointer __p and the deleter __d.

shared_ptr(const shared_ptr< _Yp > &__r, element_type *__p) noexcept

Constructs a shared_ptr instance that stores __p and shares ownership with __r.

shared_ptr(const weak_ptr< _Yp > &__r)

Constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r...

constexpr shared_ptr(nullptr_t) noexcept

Construct an empty shared_ptr.

shared_ptr(shared_ptr< _Yp > &&__r, element_type *__p) noexcept

Constructs a shared_ptr instance that stores __p and shares ownership with __r.

A non-owning observer for a pointer owned by a shared_ptr.

Primary template owner_less.

Base class allowing use of the member function shared_from_this.

weak_ptr< _Tp > weak_from_this() noexcept

weak_ptr< const _Tp > weak_from_this() const noexcept

A simple smart pointer providing strict ownership semantics.

A move-only smart pointer that manages unique ownership of a resource.