libstdc++: tuple 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#ifndef _GLIBCXX_TUPLE

30#define _GLIBCXX_TUPLE 1

31

32#pragma GCC system_header

33

34#if __cplusplus < 201103L

36#else

37

39#include <bits/uses_allocator.h>

42#if __cplusplus > 201703L

45#endif

46

47#define __glibcxx_want_constexpr_tuple

48#define __glibcxx_want_tuple_element_t

49#define __glibcxx_want_tuples_by_type

50#define __glibcxx_want_apply

51#define __glibcxx_want_make_from_tuple

52#define __glibcxx_want_ranges_zip

53#define __glibcxx_want_tuple_like

54#define __glibcxx_want_constrained_equality

56

57namespace std _GLIBCXX_VISIBILITY(default)

58{

59_GLIBCXX_BEGIN_NAMESPACE_VERSION

60

61

62

63

64

65

66 template<typename... _Elements>

67 class tuple;

68

69

70 template<typename _Tp>

71 struct __is_empty_non_tuple : is_empty<_Tp> { };

72

73

74 template<typename _El0, typename... _El>

75 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };

76

77

78 template<typename _Tp>

79 using __empty_not_final

80 = __conditional_t<__is_final(_Tp), false_type,

81 __is_empty_non_tuple<_Tp>>;

82

83 template<size_t _Idx, typename _Head,

84 bool = __empty_not_final<_Head>::value>

85 struct _Head_base;

86

87#if __has_cpp_attribute(__no_unique_address__)

88 template<size_t _Idx, typename _Head>

89 struct _Head_base<_Idx, _Head, true>

90 {

91 constexpr _Head_base()

92 : _M_head_impl() { }

93

94 constexpr _Head_base(const _Head& __h)

95 : _M_head_impl(__h) { }

96

97 constexpr _Head_base(const _Head_base&) = default;

98 constexpr _Head_base(_Head_base&&) = default;

99

100 template<typename _UHead>

101 constexpr _Head_base(_UHead&& __h)

102 : _M_head_impl(std::forward<_UHead>(__h)) { }

103

104 _GLIBCXX20_CONSTEXPR

105 _Head_base(allocator_arg_t, __uses_alloc0)

106 : _M_head_impl() { }

107

108 template<typename _Alloc>

109 _GLIBCXX20_CONSTEXPR

110 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)

111 : _M_head_impl(allocator_arg, *__a._M_a) { }

112

113 template<typename _Alloc>

114 _GLIBCXX20_CONSTEXPR

115 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)

116 : _M_head_impl(*__a._M_a) { }

117

118 template<typename _UHead>

119 _GLIBCXX20_CONSTEXPR

120 _Head_base(__uses_alloc0, _UHead&& __uhead)

121 : _M_head_impl(std::forward<_UHead>(__uhead)) { }

122

123 template<typename _Alloc, typename _UHead>

124 _GLIBCXX20_CONSTEXPR

125 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)

126 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))

127 { }

128

129 template<typename _Alloc, typename _UHead>

130 _GLIBCXX20_CONSTEXPR

131 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)

132 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }

133

134 static constexpr _Head&

135 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }

136

137 static constexpr const _Head&

138 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }

139

140 [[__no_unique_address__]] _Head _M_head_impl;

141 };

142#else

143 template<size_t _Idx, typename _Head>

144 struct _Head_base<_Idx, _Head, true>

145 : public _Head

146 {

147 constexpr _Head_base()

148 : _Head() { }

149

150 constexpr _Head_base(const _Head& __h)

151 : _Head(__h) { }

152

153 constexpr _Head_base(const _Head_base&) = default;

154 constexpr _Head_base(_Head_base&&) = default;

155

156 template<typename _UHead>

157 constexpr _Head_base(_UHead&& __h)

158 : _Head(std::forward<_UHead>(__h)) { }

159

160 _GLIBCXX20_CONSTEXPR

161 _Head_base(allocator_arg_t, __uses_alloc0)

162 : _Head() { }

163

164 template<typename _Alloc>

165 _GLIBCXX20_CONSTEXPR

166 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)

167 : _Head(allocator_arg, *__a._M_a) { }

168

169 template<typename _Alloc>

170 _GLIBCXX20_CONSTEXPR

171 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)

172 : _Head(*__a._M_a) { }

173

174 template<typename _UHead>

175 _GLIBCXX20_CONSTEXPR

176 _Head_base(__uses_alloc0, _UHead&& __uhead)

177 : _Head(std::forward<_UHead>(__uhead)) { }

178

179 template<typename _Alloc, typename _UHead>

180 _GLIBCXX20_CONSTEXPR

181 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)

182 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }

183

184 template<typename _Alloc, typename _UHead>

185 _GLIBCXX20_CONSTEXPR

186 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)

187 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }

188

189 static constexpr _Head&

190 _M_head(_Head_base& __b) noexcept { return __b; }

191

192 static constexpr const _Head&

193 _M_head(const _Head_base& __b) noexcept { return __b; }

194 };

195#endif

196

197 template<size_t _Idx, typename _Head>

198 struct _Head_base<_Idx, _Head, false>

199 {

200 constexpr _Head_base()

201 : _M_head_impl() { }

202

203 constexpr _Head_base(const _Head& __h)

204 : _M_head_impl(__h) { }

205

206 constexpr _Head_base(const _Head_base&) = default;

207 constexpr _Head_base(_Head_base&&) = default;

208

209 template<typename _UHead>

210 constexpr _Head_base(_UHead&& __h)

211 : _M_head_impl(std::forward<_UHead>(__h)) { }

212

213 _GLIBCXX20_CONSTEXPR

214 _Head_base(allocator_arg_t, __uses_alloc0)

215 : _M_head_impl() { }

216

217 template<typename _Alloc>

218 _GLIBCXX20_CONSTEXPR

219 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)

220 : _M_head_impl(allocator_arg, *__a._M_a) { }

221

222 template<typename _Alloc>

223 _GLIBCXX20_CONSTEXPR

224 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)

225 : _M_head_impl(*__a._M_a) { }

226

227 template<typename _UHead>

228 _GLIBCXX20_CONSTEXPR

229 _Head_base(__uses_alloc0, _UHead&& __uhead)

230 : _M_head_impl(std::forward<_UHead>(__uhead)) { }

231

232 template<typename _Alloc, typename _UHead>

233 _GLIBCXX20_CONSTEXPR

234 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)

235 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))

236 { }

237

238 template<typename _Alloc, typename _UHead>

239 _GLIBCXX20_CONSTEXPR

240 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)

241 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }

242

243 static constexpr _Head&

244 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }

245

246 static constexpr const _Head&

247 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }

248

249 _Head _M_head_impl;

250 };

251

252#if __cpp_lib_tuple_like

253 struct __tuple_like_tag_t { explicit __tuple_like_tag_t() = default; };

254

255

256

257 template<typename _Cat, typename _Tp, typename _Up, typename _IndexSeq>

258 constexpr _Cat

259 __tuple_cmp(const _Tp& __t, const _Up& __u, _IndexSeq);

260#endif

261

262

263

264

265

266

267

268

269

270 template<size_t _Idx, typename... _Elements>

271 struct _Tuple_impl;

272

273

274

275

276

277

278 template<size_t _Idx, typename _Head, typename... _Tail>

279 struct _Tuple_impl<_Idx, _Head, _Tail...>

280 : public _Tuple_impl<_Idx + 1, _Tail...>,

281 private _Head_base<_Idx, _Head>

282 {

283 template<size_t, typename...> friend struct _Tuple_impl;

284

285 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;

286 typedef _Head_base<_Idx, _Head> _Base;

287

288 static constexpr _Head&

289 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }

290

291 static constexpr const _Head&

292 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }

293

294 static constexpr _Inherited&

295 _M_tail(_Tuple_impl& __t) noexcept { return __t; }

296

297 static constexpr const _Inherited&

298 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }

300 constexpr _Tuple_impl()

301 : _Inherited(), _Base() { }

302

303 explicit constexpr

304 _Tuple_impl(const _Head& __head, const _Tail&... __tail)

305 : _Inherited(__tail...), _Base(__head)

306 { }

307

308 template<typename _UHead, typename... _UTail,

309 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>

310 explicit constexpr

311 _Tuple_impl(_UHead&& __head, _UTail&&... __tail)

312 : _Inherited(std::forward<_UTail>(__tail)...),

313 _Base(std::forward<_UHead>(__head))

314 { }

315

316 constexpr _Tuple_impl(const _Tuple_impl&) = default;

317

318

319

320 _Tuple_impl& operator=(const _Tuple_impl&) = delete;

321

322 _Tuple_impl(_Tuple_impl&&) = default;

323

324 template<typename... _UElements>

325 constexpr

326 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)

327 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),

328 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))

329 { }

330

331 template<typename _UHead, typename... _UTails>

332 constexpr

333 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)

335 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),

337 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))

338 { }

339

340#if __cpp_lib_ranges_zip

341 template<typename... _UElements>

342 constexpr

343 _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)

344 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),

345 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))

346 { }

347

348 template<typename _UHead, typename... _UTails>

349 constexpr

350 _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)

352 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),

354 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))

355 { }

356#endif

357

358#if __cpp_lib_tuple_like

359 template<typename _UTuple, size_t... _Is>

360 constexpr

361 _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<_Is...>)

362 : _Tuple_impl(std::get<_Is>(std::forward<_UTuple>(__u))...)

363 { }

364#endif

365

366 template<typename _Alloc>

367 _GLIBCXX20_CONSTEXPR

368 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)

369 : _Inherited(__tag, __a),

370 _Base(__tag, __use_alloc<_Head>(__a))

371 { }

372

373 template<typename _Alloc>

374 _GLIBCXX20_CONSTEXPR

375 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

376 const _Head& __head, const _Tail&... __tail)

377 : _Inherited(__tag, __a, __tail...),

378 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)

379 { }

380

381 template<typename _Alloc, typename _UHead, typename... _UTail,

382 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>

383 _GLIBCXX20_CONSTEXPR

384 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

385 _UHead&& __head, _UTail&&... __tail)

386 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),

387 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),

389 { }

390

391 template<typename _Alloc>

392 _GLIBCXX20_CONSTEXPR

393 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

394 const _Tuple_impl& __in)

395 : _Inherited(__tag, __a, _M_tail(__in)),

396 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))

397 { }

398

399 template<typename _Alloc>

400 _GLIBCXX20_CONSTEXPR

401 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

402 _Tuple_impl&& __in)

403 : _Inherited(__tag, __a, std::move(_M_tail(__in))),

404 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),

406 { }

407

408 template<typename _Alloc, typename _UHead, typename... _UTails>

409 _GLIBCXX20_CONSTEXPR

410 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

411 const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)

412 : _Inherited(__tag, __a,

413 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),

414 _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),

415 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))

416 { }

417

418 template<typename _Alloc, typename _UHead, typename... _UTails>

419 _GLIBCXX20_CONSTEXPR

420 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

421 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)

422 : _Inherited(__tag, __a, std::move

423 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),

424 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),

426 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))

427 { }

428

429#if __cpp_lib_ranges_zip

430 template<typename _Alloc, typename _UHead, typename... _UTails>

431 constexpr

432 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

433 _Tuple_impl<_Idx, _UHead, _UTails...>& __in)

434 : _Inherited(__tag, __a,

435 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),

436 _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),

437 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))

438 { }

439

440 template<typename _Alloc, typename _UHead, typename... _UTails>

441 constexpr

442 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,

443 const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)

444 : _Inherited(__tag, __a, std::move

445 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),

446 _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),

448 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))

449 { }

450#endif

451

452#if __cpp_lib_tuple_like

453 template<typename _Alloc, typename _UTuple, size_t... _Is>

454 constexpr

455 _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,

456 _UTuple&& __u, index_sequence<_Is...>)

457 : _Tuple_impl(__tag, __a, std::get<_Is>(std::forward<_UTuple>(__u))...)

458 { }

459#endif

460

461 template<typename... _UElements>

462 _GLIBCXX20_CONSTEXPR

463 void

464 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)

465 {

466 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);

467 _M_tail(*this)._M_assign(

468 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));

469 }

470

471 template<typename _UHead, typename... _UTails>

472 _GLIBCXX20_CONSTEXPR

473 void

474 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)

475 {

476 _M_head(*this) = std::forward<_UHead>

477 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));

478 _M_tail(*this)._M_assign(

479 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));

480 }

481

482#if __cpp_lib_ranges_zip

483 template<typename... _UElements>

484 constexpr void

485 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const

486 {

487 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);

488 _M_tail(*this)._M_assign(

489 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));

490 }

491

492 template<typename _UHead, typename... _UTails>

493 constexpr void

494 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const

495 {

496 _M_head(*this) = std::forward<_UHead>

497 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));

498 _M_tail(*this)._M_assign(

499 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));

500 }

501#endif

502

503#if __cpp_lib_tuple_like

504 template<typename _UTuple>

505 constexpr void

506 _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u)

507 {

508 _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));

509 _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));

510 }

511

512 template<typename _UTuple>

513 constexpr void

514 _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u) const

515 {

516 _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));

517 _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));

518 }

519#endif

520

521 protected:

522 _GLIBCXX20_CONSTEXPR

523 void

524 _M_swap(_Tuple_impl& __in)

525 {

526 using std::swap;

527 swap(_M_head(*this), _M_head(__in));

528 _Inherited::_M_swap(_M_tail(__in));

529 }

530

531#if __cpp_lib_ranges_zip

532 constexpr void

533 _M_swap(const _Tuple_impl& __in) const

534 {

535 using std::swap;

536 swap(_M_head(*this), _M_head(__in));

537 _Inherited::_M_swap(_M_tail(__in));

538 }

539#endif

540 };

541

542

543 template<size_t _Idx, typename _Head>

544 struct _Tuple_impl<_Idx, _Head>

545 : private _Head_base<_Idx, _Head>

546 {

547 template<size_t, typename...> friend struct _Tuple_impl;

548

549 typedef _Head_base<_Idx, _Head> _Base;

550

551 static constexpr _Head&

552 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }

553

554 static constexpr const _Head&

555 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }

556

557 constexpr

558 _Tuple_impl()

559 : _Base() { }

560

561 explicit constexpr

562 _Tuple_impl(const _Head& __head)

563 : _Base(__head)

564 { }

565

566 template<typename _UHead>

567 explicit constexpr

568 _Tuple_impl(_UHead&& __head)

569 : _Base(std::forward<_UHead>(__head))

570 { }

571

572 constexpr _Tuple_impl(const _Tuple_impl&) = default;

573

574

575

576 _Tuple_impl& operator=(const _Tuple_impl&) = delete;

577

578#if _GLIBCXX_INLINE_VERSION

579 _Tuple_impl(_Tuple_impl&&) = default;

580#else

581 constexpr

582 _Tuple_impl(_Tuple_impl&& __in)

583 noexcept(is_nothrow_move_constructible<_Head>::value)

584 : _Base(static_cast<_Base&&>(__in))

585 { }

586#endif

587

588 template<typename _UHead>

589 constexpr

590 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)

591 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))

592 { }

593

594 template<typename _UHead>

595 constexpr

596 _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)

597 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))

598 { }

599

600#if __cpp_lib_ranges_zip

601 template<typename _UHead>

602 constexpr

603 _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)

604 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))

605 { }

606

607 template<typename _UHead>

608 constexpr

609 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in)

610 : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))

611 { }

612#endif

613

614#if __cpp_lib_tuple_like

615 template<typename _UTuple>

616 constexpr

617 _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<0>)

618 : _Tuple_impl(std::get<0>(std::forward<_UTuple>(__u)))

619 { }

620#endif

621

622 template<typename _Alloc>

623 _GLIBCXX20_CONSTEXPR

624 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)

625 : _Base(__tag, __use_alloc<_Head>(__a))

626 { }

627

628 template<typename _Alloc>

629 _GLIBCXX20_CONSTEXPR

630 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

631 const _Head& __head)

632 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)

633 { }

634

635 template<typename _Alloc, typename _UHead>

636 _GLIBCXX20_CONSTEXPR

637 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

638 _UHead&& __head)

639 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),

641 { }

642

643 template<typename _Alloc>

644 _GLIBCXX20_CONSTEXPR

645 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

646 const _Tuple_impl& __in)

647 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))

648 { }

649

650 template<typename _Alloc>

651 _GLIBCXX20_CONSTEXPR

652 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

653 _Tuple_impl&& __in)

654 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),

656 { }

657

658 template<typename _Alloc, typename _UHead>

659 _GLIBCXX20_CONSTEXPR

660 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

661 const _Tuple_impl<_Idx, _UHead>& __in)

662 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),

663 _Tuple_impl<_Idx, _UHead>::_M_head(__in))

664 { }

665

666 template<typename _Alloc, typename _UHead>

667 _GLIBCXX20_CONSTEXPR

668 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

669 _Tuple_impl<_Idx, _UHead>&& __in)

670 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),

671 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))

672 { }

673

674#if __cpp_lib_ranges_zip

675 template<typename _Alloc, typename _UHead>

676 constexpr

677 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

678 _Tuple_impl<_Idx, _UHead>& __in)

679 : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),

680 _Tuple_impl<_Idx, _UHead>::_M_head(__in))

681 { }

682

683 template<typename _Alloc, typename _UHead>

684 constexpr

685 _Tuple_impl(allocator_arg_t, const _Alloc& __a,

686 const _Tuple_impl<_Idx, _UHead>&& __in)

687 : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),

688 std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))

689 { }

690#endif

691

692#if __cpp_lib_tuple_like

693 template<typename _Alloc, typename _UTuple>

694 constexpr

695 _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,

696 _UTuple&& __u, index_sequence<0>)

697 : _Tuple_impl(__tag, __a, std::get<0>(std::forward<_UTuple>(__u)))

698 { }

699#endif

700

701 template<typename _UHead>

702 _GLIBCXX20_CONSTEXPR

703 void

704 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)

705 {

706 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);

707 }

708

709 template<typename _UHead>

710 _GLIBCXX20_CONSTEXPR

711 void

712 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)

713 {

714 _M_head(*this)

715 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));

716 }

717

718#if __cpp_lib_ranges_zip

719 template<typename _UHead>

720 constexpr void

721 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const

722 {

723 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);

724 }

725

726 template<typename _UHead>

727 constexpr void

728 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const

729 {

730 _M_head(*this)

731 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));

732 }

733#endif

734

735#if __cpp_lib_tuple_like

736 template<typename _UTuple>

737 constexpr void

738 _M_assign(__tuple_like_tag_t, _UTuple&& __u)

739 { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }

740

741 template<typename _UTuple>

742 constexpr void

743 _M_assign(__tuple_like_tag_t, _UTuple&& __u) const

744 { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }

745#endif

746

747 protected:

748 _GLIBCXX20_CONSTEXPR

749 void

750 _M_swap(_Tuple_impl& __in)

751 {

752 using std::swap;

753 swap(_M_head(*this), _M_head(__in));

754 }

755

756#if __cpp_lib_ranges_zip

757 constexpr void

758 _M_swap(const _Tuple_impl& __in) const

759 {

760 using std::swap;

761 swap(_M_head(*this), _M_head(__in));

762 }

763#endif

764 };

765

766

767

768 template<bool, typename... _Types>

769 struct _TupleConstraints

770 {

771 template<typename... _UTypes>

772 using __constructible = __and_<is_constructible<_Types, _UTypes>...>;

773

774 template<typename... _UTypes>

775 using __convertible = __and_<is_convertible<_UTypes, _Types>...>;

776

777

778

779

780 template<typename... _UTypes>

781 static constexpr bool __is_implicitly_constructible()

782 {

783 return __and_<__constructible<_UTypes...>,

784 __convertible<_UTypes...>

785 >::value;

786 }

787

788

789

790

791 template<typename... _UTypes>

792 static constexpr bool __is_explicitly_constructible()

793 {

794 return __and_<__constructible<_UTypes...>,

795 __not_<__convertible<_UTypes...>>

796 >::value;

797 }

798

799 static constexpr bool __is_implicitly_default_constructible()

800 {

801 return __and_<std::__is_implicitly_default_constructible<_Types>...

802 >::value;

803 }

804

805 static constexpr bool __is_explicitly_default_constructible()

806 {

807 return __and_<is_default_constructible<_Types>...,

808 __not_<__and_<

809 std::__is_implicitly_default_constructible<_Types>...>

810 >>::value;

811 }

812 };

813

814

815

816 template<typename... _Types>

817 struct _TupleConstraints<false, _Types...>

818 {

819 template<typename... _UTypes>

820 static constexpr bool __is_implicitly_constructible()

821 { return false; }

822

823 template<typename... _UTypes>

824 static constexpr bool __is_explicitly_constructible()

825 { return false; }

826 };

827

828

829

830 template<typename... _Elements>

831 class tuple : public _Tuple_impl<0, _Elements...>

832 {

833 using _Inherited = _Tuple_impl<0, _Elements...>;

834

835#if __cpp_concepts && __cpp_consteval && __cpp_conditional_explicit

836 template<typename... _UTypes>

837 static consteval bool

838 __constructible()

839 {

840 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

842 else

843 return false;

844 }

845

846 template<typename... _UTypes>

847 static consteval bool

848 __nothrow_constructible()

849 {

850 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

852 else

853 return false;

854 }

855

856 template<typename... _UTypes>

857 static consteval bool

858 __convertible()

859 {

860 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

862 else

863 return false;

864 }

865

866

867

868 template<typename... _UTypes>

869 static consteval bool

870 __disambiguating_constraint()

871 {

872 if constexpr (sizeof...(_Elements) != sizeof...(_UTypes))

873 return false;

874 else if constexpr (sizeof...(_Elements) == 1)

875 {

876 using _U0 = typename _Nth_type<0, _UTypes...>::type;

877 return !is_same_v<remove_cvref_t<_U0>, tuple>;

878 }

879 else if constexpr (sizeof...(_Elements) < 4)

880 {

881 using _U0 = typename _Nth_type<0, _UTypes...>::type;

882 if constexpr (!is_same_v<remove_cvref_t<_U0>, allocator_arg_t>)

883 return true;

884 else

885 {

886 using _T0 = typename _Nth_type<0, _Elements...>::type;

887 return is_same_v<remove_cvref_t<_T0>, allocator_arg_t>;

888 }

889 }

890 return true;

891 }

892

893

894

895

896 template<typename _Tuple>

897 static consteval bool

898 __use_other_ctor()

899 {

900 if constexpr (sizeof...(_Elements) != 1)

901 return false;

902 else if constexpr (is_same_v<remove_cvref_t<_Tuple>, tuple>)

903 return true;

904 else

905 {

906 using _Tp = typename _Nth_type<0, _Elements...>::type;

907 if constexpr (is_convertible_v<_Tuple, _Tp>)

908 return true;

909 else if constexpr (is_constructible_v<_Tp, _Tuple>)

910 return true;

911 }

912 return false;

913 }

914

915 template<typename... _Up>

916 static consteval bool

917 __dangles()

918 {

919#if __has_builtin(__reference_constructs_from_temporary)

920 return (__reference_constructs_from_temporary(_Elements, _Up&&)

921 || ...);

922#else

923 return false;

924#endif

925 }

926

927#if __cpp_lib_tuple_like

928

929

930 template<typename _UTuple>

931 static consteval bool

932 __dangles_from_tuple_like()

933 {

935 return __dangles<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();

937 }

938

939 template<typename _UTuple>

940 static consteval bool

941 __constructible_from_tuple_like()

942 {

944 return __constructible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();

946 }

947

948 template<typename _UTuple>

949 static consteval bool

950 __convertible_from_tuple_like()

951 {

953 return __convertible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();

955 }

956#endif

957

958 public:

959 constexpr

960 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))

962 noexcept((is_nothrow_default_constructible_v<_Elements> && ...))

963 requires (is_default_constructible_v<_Elements> && ...)

964 : _Inherited()

965 { }

966

967 constexpr explicit(!__convertible<const _Elements&...>())

968 tuple(const _Elements&... __elements)

969 noexcept(__nothrow_constructible<const _Elements&...>())

970 requires (__constructible<const _Elements&...>())

971 : _Inherited(__elements...)

972 { }

973

974 template<typename... _UTypes>

975 requires (__disambiguating_constraint<_UTypes...>())

976 && (__constructible<_UTypes...>())

977 && (!__dangles<_UTypes...>())

978 constexpr explicit(!__convertible<_UTypes...>())

979 tuple(_UTypes&&... __u)

980 noexcept(__nothrow_constructible<_UTypes...>())

981 : _Inherited(std::forward<_UTypes>(__u)...)

982 { }

983

984 template<typename... _UTypes>

985 requires (__disambiguating_constraint<_UTypes...>())

986 && (__constructible<_UTypes...>())

987 && (__dangles<_UTypes...>())

988 tuple(_UTypes&&...) = delete;

989

990 constexpr tuple(const tuple&) = default;

991

993

994 template<typename... _UTypes>

995 requires (__constructible<const _UTypes&...>())

996 && (!__use_other_ctor<const tuple<_UTypes...>&>())

997 && (!__dangles<const _UTypes&...>())

998 constexpr explicit(!__convertible<const _UTypes&...>())

1000 noexcept(__nothrow_constructible<const _UTypes&...>())

1001 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))

1002 { }

1003

1004 template<typename... _UTypes>

1005 requires (__constructible<const _UTypes&...>())

1006 && (!__use_other_ctor<const tuple<_UTypes...>&>())

1007 && (__dangles<const _UTypes&...>())

1009

1010 template<typename... _UTypes>

1011 requires (__constructible<_UTypes...>())

1012 && (!__use_other_ctor<tuple<_UTypes...>>())

1013 && (!__dangles<_UTypes...>())

1014 constexpr explicit(!__convertible<_UTypes...>())

1016 noexcept(__nothrow_constructible<_UTypes...>())

1017 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))

1018 { }

1019

1020 template<typename... _UTypes>

1021 requires (__constructible<_UTypes...>())

1022 && (!__use_other_ctor<tuple<_UTypes...>>())

1023 && (__dangles<_UTypes...>())

1025

1026#if __cpp_lib_ranges_zip

1027 template<typename... _UTypes>

1028 requires (__constructible<_UTypes&...>())

1029 && (!__use_other_ctor<tuple<_UTypes...>&>())

1030 && (!__dangles<_UTypes&...>())

1031 constexpr explicit(!__convertible<_UTypes&...>())

1033 noexcept(__nothrow_constructible<_UTypes&...>())

1034 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&>(__u))

1035 { }

1036

1037 template<typename... _UTypes>

1038 requires (__constructible<_UTypes&...>())

1039 && (!__use_other_ctor<tuple<_UTypes...>&>())

1040 && (__dangles<_UTypes&...>())

1042

1043 template<typename... _UTypes>

1044 requires (__constructible<const _UTypes...>())

1045 && (!__use_other_ctor<const tuple<_UTypes...>>())

1046 && (!__dangles<const _UTypes...>())

1047 constexpr explicit(!__convertible<const _UTypes...>())

1049 noexcept(__nothrow_constructible<const _UTypes...>())

1050 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))

1051 { }

1052

1053 template<typename... _UTypes>

1054 requires (__constructible<const _UTypes...>())

1055 && (!__use_other_ctor<const tuple<_UTypes...>>())

1056 && (__dangles<const _UTypes...>())

1058#endif

1059

1060 template<typename _U1, typename _U2>

1061 requires (sizeof...(_Elements) == 2)

1062 && (__constructible<const _U1&, const _U2&>())

1063 && (!__dangles<const _U1&, const _U2&>())

1064 constexpr explicit(!__convertible<const _U1&, const _U2&>())

1066 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

1067 : _Inherited(__u.first, __u.second)

1068 { }

1069

1070 template<typename _U1, typename _U2>

1071 requires (sizeof...(_Elements) == 2)

1072 && (__constructible<const _U1&, const _U2&>())

1073 && (__dangles<const _U1&, const _U2&>())

1075

1076 template<typename _U1, typename _U2>

1077 requires (sizeof...(_Elements) == 2)

1078 && (__constructible<_U1, _U2>())

1079 && (!__dangles<_U1, _U2>())

1080 constexpr explicit(!__convertible<_U1, _U2>())

1082 noexcept(__nothrow_constructible<_U1, _U2>())

1083 : _Inherited(std::forward<_U1>(__u.first),

1084 std::forward<_U2>(__u.second))

1085 { }

1086

1087 template<typename _U1, typename _U2>

1088 requires (sizeof...(_Elements) == 2)

1089 && (__constructible<_U1, _U2>())

1090 && (__dangles<_U1, _U2>())

1092

1093#if __cpp_lib_ranges_zip

1094 template<typename _U1, typename _U2>

1095 requires (sizeof...(_Elements) == 2)

1096 && (__constructible<_U1&, _U2&>())

1097 && (!__dangles<_U1&, _U2&>())

1098 constexpr explicit(!__convertible<_U1&, _U2&>())

1100 noexcept(__nothrow_constructible<_U1&, _U2&>())

1101 : _Inherited(__u.first, __u.second)

1102 { }

1103

1104 template<typename _U1, typename _U2>

1105 requires (sizeof...(_Elements) == 2)

1106 && (__constructible<_U1&, _U2&>())

1107 && (__dangles<_U1&, _U2&>())

1109

1110 template<typename _U1, typename _U2>

1111 requires (sizeof...(_Elements) == 2)

1112 && (__constructible<const _U1, const _U2>())

1113 && (!__dangles<const _U1, const _U2>())

1114 constexpr explicit(!__convertible<const _U1, const _U2>())

1116 noexcept(__nothrow_constructible<const _U1, const _U2>())

1117 : _Inherited(std::forward<const _U1>(__u.first),

1118 std::forward<const _U2>(__u.second))

1119 { }

1120

1121 template<typename _U1, typename _U2>

1122 requires (sizeof...(_Elements) == 2)

1123 && (__constructible<const _U1, const _U2>())

1124 && (__dangles<const _U1, const _U2>())

1126#endif

1127

1128#if __cpp_lib_tuple_like

1129 template<__eligible_tuple_like _UTuple>

1130 requires (__constructible_from_tuple_like<_UTuple>())

1131 && (!__use_other_ctor<_UTuple>())

1132 && (!__dangles_from_tuple_like<_UTuple>())

1133 constexpr explicit(!__convertible_from_tuple_like<_UTuple>())

1134 tuple(_UTuple&& __u)

1135 : _Inherited(__tuple_like_tag_t{},

1136 std::forward<_UTuple>(__u),

1138 { }

1139

1140 template<__eligible_tuple_like _UTuple>

1141 requires (__constructible_from_tuple_like<_UTuple>())

1142 && (!__use_other_ctor<_UTuple>())

1143 && (__dangles_from_tuple_like<_UTuple>())

1144 tuple(_UTuple&&) = delete;

1145#endif

1146

1147

1148

1149 template<typename _Alloc>

1150 constexpr

1151 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))

1152 tuple(allocator_arg_t __tag, const _Alloc& __a)

1153 requires (is_default_constructible_v<_Elements> && ...)

1154 : _Inherited(__tag, __a)

1155 { }

1156

1157 template<typename _Alloc>

1158 constexpr explicit(!__convertible<const _Elements&...>())

1159 tuple(allocator_arg_t __tag, const _Alloc& __a,

1160 const _Elements&... __elements)

1161 requires (__constructible<const _Elements&...>())

1162 : _Inherited(__tag, __a, __elements...)

1163 { }

1164

1165 template<typename _Alloc, typename... _UTypes>

1166 requires (__disambiguating_constraint<_UTypes...>())

1167 && (__constructible<_UTypes...>())

1168 && (!__dangles<_UTypes...>())

1169 constexpr explicit(!__convertible<_UTypes...>())

1170 tuple(allocator_arg_t __tag, const _Alloc& __a, _UTypes&&... __u)

1171 : _Inherited(__tag, __a, std::forward<_UTypes>(__u)...)

1172 { }

1173

1174 template<typename _Alloc, typename... _UTypes>

1175 requires (__disambiguating_constraint<_UTypes...>())

1176 && (__constructible<_UTypes...>())

1177 && (__dangles<_UTypes...>())

1178 tuple(allocator_arg_t, const _Alloc&, _UTypes&&...) = delete;

1179

1180 template<typename _Alloc>

1181 constexpr

1182 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __u)

1183 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__u))

1184 { }

1185

1186 template<typename _Alloc>

1187 requires (__constructible<_Elements...>())

1188 constexpr

1189 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __u)

1190 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__u))

1191 { }

1192

1193 template<typename _Alloc, typename... _UTypes>

1194 requires (__constructible<const _UTypes&...>())

1195 && (!__use_other_ctor<const tuple<_UTypes...>&>())

1196 && (!__dangles<const _UTypes&...>())

1197 constexpr explicit(!__convertible<const _UTypes&...>())

1198 tuple(allocator_arg_t __tag, const _Alloc& __a,

1200 : _Inherited(__tag, __a,

1201 static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))

1202 { }

1203

1204 template<typename _Alloc, typename... _UTypes>

1205 requires (__constructible<const _UTypes&...>())

1206 && (!__use_other_ctor<const tuple<_UTypes...>&>())

1207 && (__dangles<const _UTypes&...>())

1209

1210 template<typename _Alloc, typename... _UTypes>

1211 requires (__constructible<_UTypes...>())

1212 && (!__use_other_ctor<tuple<_UTypes...>>())

1213 && (!__dangles<_UTypes...>())

1214 constexpr explicit(!__use_other_ctor<tuple<_UTypes...>>())

1216 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))

1217 { }

1218

1219 template<typename _Alloc, typename... _UTypes>

1220 requires (__constructible<_UTypes...>())

1221 && (!__use_other_ctor<tuple<_UTypes...>>())

1222 && (__dangles<_UTypes...>())

1224

1225#if __cpp_lib_ranges_zip

1226 template<typename _Alloc, typename... _UTypes>

1227 requires (__constructible<_UTypes&...>())

1228 && (!__use_other_ctor<tuple<_UTypes...>&>())

1229 && (!__dangles<_UTypes&...>())

1230 constexpr explicit(!__convertible<_UTypes&...>())

1232 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&>(__u))

1233 { }

1234

1235 template<typename _Alloc, typename... _UTypes>

1236 requires (__constructible<_UTypes&...>())

1237 && (!__use_other_ctor<tuple<_UTypes...>&>())

1238 && (__dangles<_UTypes&...>())

1240

1241 template<typename _Alloc, typename... _UTypes>

1242 requires (__constructible<const _UTypes...>())

1243 && (!__use_other_ctor<const tuple<_UTypes...>>())

1244 && (!__dangles<const _UTypes...>())

1245 constexpr explicit(!__convertible<const _UTypes...>())

1246 tuple(allocator_arg_t __tag, const _Alloc& __a,

1248 : _Inherited(__tag, __a,

1249 static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))

1250 { }

1251

1252 template<typename _Alloc, typename... _UTypes>

1253 requires (__constructible<const _UTypes...>())

1254 && (!__use_other_ctor<const tuple<_UTypes...>>())

1255 && (__dangles<const _UTypes...>())

1257#endif

1258

1259 template<typename _Alloc, typename _U1, typename _U2>

1260 requires (sizeof...(_Elements) == 2)

1261 && (__constructible<const _U1&, const _U2&>())

1262 && (!__dangles<const _U1&, const _U2&>())

1263 constexpr explicit(!__convertible<const _U1&, const _U2&>())

1264 tuple(allocator_arg_t __tag, const _Alloc& __a,

1266 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

1267 : _Inherited(__tag, __a, __u.first, __u.second)

1268 { }

1269

1270 template<typename _Alloc, typename _U1, typename _U2>

1271 requires (sizeof...(_Elements) == 2)

1272 && (__constructible<const _U1&, const _U2&>())

1273 && (__dangles<const _U1&, const _U2&>())

1275

1276 template<typename _Alloc, typename _U1, typename _U2>

1277 requires (sizeof...(_Elements) == 2)

1278 && (__constructible<_U1, _U2>())

1279 && (!__dangles<_U1, _U2>())

1280 constexpr explicit(!__convertible<_U1, _U2>())

1282 noexcept(__nothrow_constructible<_U1, _U2>())

1283 : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))

1284 { }

1285

1286 template<typename _Alloc, typename _U1, typename _U2>

1287 requires (sizeof...(_Elements) == 2)

1288 && (__constructible<_U1, _U2>())

1289 && (__dangles<_U1, _U2>())

1291

1292#if __cpp_lib_ranges_zip

1293 template<typename _Alloc, typename _U1, typename _U2>

1294 requires (sizeof...(_Elements) == 2)

1295 && (__constructible<_U1&, _U2&>())

1296 && (!__dangles<_U1&, _U2&>())

1297 constexpr explicit(!__convertible<_U1&, _U2&>())

1299 noexcept(__nothrow_constructible<_U1&, _U2&>())

1300 : _Inherited(__tag, __a, __u.first, __u.second)

1301 { }

1302

1303 template<typename _Alloc, typename _U1, typename _U2>

1304 requires (sizeof...(_Elements) == 2)

1305 && (__constructible<_U1&, _U2&>())

1306 && (__dangles<_U1&, _U2&>())

1308

1309 template<typename _Alloc, typename _U1, typename _U2>

1310 requires (sizeof...(_Elements) == 2)

1311 && (__constructible<const _U1, const _U2>())

1312 && (!__dangles<const _U1, const _U2>())

1313 constexpr explicit(!__convertible<const _U1, const _U2>())

1314 tuple(allocator_arg_t __tag, const _Alloc& __a,

1316 noexcept(__nothrow_constructible<const _U1, const _U2>())

1317 : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))

1318 { }

1319

1320 template<typename _Alloc, typename _U1, typename _U2>

1321 requires (sizeof...(_Elements) == 2)

1322 && (__constructible<const _U1, const _U2>())

1323 && (__dangles<const _U1, const _U2>())

1325#endif

1326

1327#if __cpp_lib_tuple_like

1328 template<typename _Alloc, __eligible_tuple_like _UTuple>

1329 requires (__constructible_from_tuple_like<_UTuple>())

1330 && (!__use_other_ctor<_UTuple>())

1331 && (!__dangles_from_tuple_like<_UTuple>())

1332 constexpr explicit(!__convertible_from_tuple_like<_UTuple>())

1333 tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u)

1334 : _Inherited(__tuple_like_tag_t{},

1335 __tag, __a, std::forward<_UTuple>(__u),

1337 { }

1338

1339 template<typename _Alloc, __eligible_tuple_like _UTuple>

1340 requires (__constructible_from_tuple_like<_UTuple>())

1341 && (!__use_other_ctor<_UTuple>())

1342 && (__dangles_from_tuple_like<_UTuple>())

1343 tuple(allocator_arg_t, const _Alloc&, _UTuple&&) = delete;

1344#endif

1345

1346#else

1347

1348 template<bool _Cond>

1349 using _TCC = _TupleConstraints<_Cond, _Elements...>;

1350

1351

1352 template<bool _Dummy>

1353 using _ImplicitDefaultCtor = __enable_if_t<

1354 _TCC<_Dummy>::__is_implicitly_default_constructible(),

1355 bool>;

1356

1357

1358 template<bool _Dummy>

1359 using _ExplicitDefaultCtor = __enable_if_t<

1360 _TCC<_Dummy>::__is_explicitly_default_constructible(),

1361 bool>;

1362

1363

1364 template<bool _Cond, typename... _Args>

1365 using _ImplicitCtor = __enable_if_t<

1366 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),

1367 bool>;

1368

1369

1370 template<bool _Cond, typename... _Args>

1371 using _ExplicitCtor = __enable_if_t<

1372 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),

1373 bool>;

1374

1375

1376 template<typename... _UElements>

1377 static constexpr bool __nothrow_constructible()

1378 {

1379 return

1380 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;

1381 }

1382

1383

1384 template<typename _Up>

1385 static constexpr bool __valid_args()

1386 {

1387 return sizeof...(_Elements) == 1

1388 && is\_same<tuple, __remove_cvref_t<_Up>>::value;

1389 }

1390

1391

1392 template<typename, typename, typename... _Tail>

1393 static constexpr bool __valid_args()

1394 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }

1395

1396

1397

1398

1399

1400

1401

1402

1403

1404

1405 template<typename _Tuple, typename = tuple,

1406 typename = __remove_cvref_t<_Tuple>>

1407 struct _UseOtherCtor

1409 { };

1410

1411

1412 template<typename _Tuple, typename _Tp, typename _Up>

1413 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>

1414 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type

1415 { };

1416

1417

1418 template<typename _Tuple, typename _Tp>

1419 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>

1421 { };

1422

1423

1424

1425

1426 template<typename _Tuple>

1427 static constexpr bool __use_other_ctor()

1428 { return _UseOtherCtor<_Tuple>::value; }

1429

1430

1431#undef __glibcxx_no_dangling_refs

1432#if __has_builtin(__reference_constructs_from_temporary) \

1433 && defined _GLIBCXX_DEBUG

1434

1435# if __cpp_fold_expressions

1436# define __glibcxx_dangling_refs(U) \

1437 (__reference_constructs_from_temporary(_Elements, U) || ...)

1438# else

1439# define __glibcxx_dangling_refs(U) \

1440 __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \

1441 >...>::value

1442# endif

1443# define __glibcxx_no_dangling_refs(U) \

1444 static_assert(!__glibcxx_dangling_refs(U), \

1445 "std::tuple constructor creates a dangling reference")

1446#else

1447# define __glibcxx_no_dangling_refs(U)

1448#endif

1449

1450

1451 public:

1452 template<typename _Dummy = void,

1453 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>

1454 constexpr

1456 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)

1457 : _Inherited() { }

1458

1459 template<typename _Dummy = void,

1460 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>

1461 explicit constexpr

1463 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)

1464 : _Inherited() { }

1465

1466 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),

1467 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>

1468 constexpr

1469 tuple(const _Elements&... __elements)

1470 noexcept(__nothrow_constructible<const _Elements&...>())

1471 : _Inherited(__elements...) { }

1472

1473 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),

1474 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>

1475 explicit constexpr

1476 tuple(const _Elements&... __elements)

1477 noexcept(__nothrow_constructible<const _Elements&...>())

1478 : _Inherited(__elements...) { }

1479

1480 template<typename... _UElements,

1481 bool _Valid = __valid_args<_UElements...>(),

1482 _ImplicitCtor<_Valid, _UElements...> = true>

1483 constexpr

1484 tuple(_UElements&&... __elements)

1485 noexcept(__nothrow_constructible<_UElements...>())

1486 : _Inherited(std::forward<_UElements>(__elements)...)

1487 { __glibcxx_no_dangling_refs(_UElements&&); }

1488

1489 template<typename... _UElements,

1490 bool _Valid = __valid_args<_UElements...>(),

1491 _ExplicitCtor<_Valid, _UElements...> = false>

1492 explicit constexpr

1493 tuple(_UElements&&... __elements)

1494 noexcept(__nothrow_constructible<_UElements...>())

1495 : _Inherited(std::forward<_UElements>(__elements)...)

1496 { __glibcxx_no_dangling_refs(_UElements&&); }

1497

1498 constexpr tuple(const tuple&) = default;

1499

1501

1502 template<typename... _UElements,

1503 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1505 _ImplicitCtor<_Valid, const _UElements&...> = true>

1506 constexpr

1508 noexcept(__nothrow_constructible<const _UElements&...>())

1509 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))

1510 { __glibcxx_no_dangling_refs(const _UElements&); }

1511

1512 template<typename... _UElements,

1513 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1515 _ExplicitCtor<_Valid, const _UElements&...> = false>

1516 explicit constexpr

1518 noexcept(__nothrow_constructible<const _UElements&...>())

1519 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))

1520 { __glibcxx_no_dangling_refs(const _UElements&); }

1521

1522 template<typename... _UElements,

1523 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1525 _ImplicitCtor<_Valid, _UElements...> = true>

1526 constexpr

1528 noexcept(__nothrow_constructible<_UElements...>())

1529 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))

1530 { __glibcxx_no_dangling_refs(_UElements&&); }

1531

1532 template<typename... _UElements,

1533 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1535 _ExplicitCtor<_Valid, _UElements...> = false>

1536 explicit constexpr

1538 noexcept(__nothrow_constructible<_UElements...>())

1539 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))

1540 { __glibcxx_no_dangling_refs(_UElements&&); }

1541

1542

1543

1544 template<typename _Alloc,

1545 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>

1546 _GLIBCXX20_CONSTEXPR

1547 tuple(allocator_arg_t __tag, const _Alloc& __a)

1548 : _Inherited(__tag, __a) { }

1549

1550 template<typename _Alloc,

1551 _ExplicitDefaultCtor<is_object<_Alloc>::value> = false>

1552 _GLIBCXX20_CONSTEXPR

1553 explicit

1554 tuple(allocator_arg_t __tag, const _Alloc& __a)

1555 : _Inherited(__tag, __a) { }

1556

1557 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),

1558 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>

1559 _GLIBCXX20_CONSTEXPR

1560 tuple(allocator_arg_t __tag, const _Alloc& __a,

1561 const _Elements&... __elements)

1562 : _Inherited(__tag, __a, __elements...) { }

1563

1564 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),

1565 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>

1566 _GLIBCXX20_CONSTEXPR

1567 explicit

1568 tuple(allocator_arg_t __tag, const _Alloc& __a,

1569 const _Elements&... __elements)

1570 : _Inherited(__tag, __a, __elements...) { }

1571

1572 template<typename _Alloc, typename... _UElements,

1573 bool _Valid = __valid_args<_UElements...>(),

1574 _ImplicitCtor<_Valid, _UElements...> = true>

1575 _GLIBCXX20_CONSTEXPR

1576 tuple(allocator_arg_t __tag, const _Alloc& __a,

1577 _UElements&&... __elements)

1578 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)

1579 { __glibcxx_no_dangling_refs(_UElements&&); }

1580

1581 template<typename _Alloc, typename... _UElements,

1582 bool _Valid = __valid_args<_UElements...>(),

1583 _ExplicitCtor<_Valid, _UElements...> = false>

1584 _GLIBCXX20_CONSTEXPR

1585 explicit

1586 tuple(allocator_arg_t __tag, const _Alloc& __a,

1587 _UElements&&... __elements)

1588 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)

1589 { __glibcxx_no_dangling_refs(_UElements&&); }

1590

1591 template<typename _Alloc>

1592 _GLIBCXX20_CONSTEXPR

1593 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)

1594 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }

1595

1596 template<typename _Alloc>

1597 _GLIBCXX20_CONSTEXPR

1598 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)

1599 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }

1600

1601 template<typename _Alloc, typename... _UElements,

1602 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1604 _ImplicitCtor<_Valid, const _UElements&...> = true>

1605 _GLIBCXX20_CONSTEXPR

1606 tuple(allocator_arg_t __tag, const _Alloc& __a,

1608 : _Inherited(__tag, __a,

1609 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))

1610 { __glibcxx_no_dangling_refs(const _UElements&); }

1611

1612 template<typename _Alloc, typename... _UElements,

1613 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1615 _ExplicitCtor<_Valid, const _UElements&...> = false>

1616 _GLIBCXX20_CONSTEXPR

1617 explicit

1618 tuple(allocator_arg_t __tag, const _Alloc& __a,

1620 : _Inherited(__tag, __a,

1621 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))

1622 { __glibcxx_no_dangling_refs(const _UElements&); }

1623

1624 template<typename _Alloc, typename... _UElements,

1625 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1627 _ImplicitCtor<_Valid, _UElements...> = true>

1628 _GLIBCXX20_CONSTEXPR

1629 tuple(allocator_arg_t __tag, const _Alloc& __a,

1631 : _Inherited(__tag, __a,

1632 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))

1633 { __glibcxx_no_dangling_refs(_UElements&&); }

1634

1635 template<typename _Alloc, typename... _UElements,

1636 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))

1638 _ExplicitCtor<_Valid, _UElements...> = false>

1639 _GLIBCXX20_CONSTEXPR

1640 explicit

1641 tuple(allocator_arg_t __tag, const _Alloc& __a,

1643 : _Inherited(__tag, __a,

1644 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))

1645 { __glibcxx_no_dangling_refs(_UElements&&); }

1646#endif

1647

1648

1649

1650#if __cpp_concepts && __cpp_consteval

1651 private:

1652 template<typename... _UTypes>

1653 static consteval bool

1654 __assignable()

1655 {

1656 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

1658 else

1659 return false;

1660 }

1661

1662 template<typename... _UTypes>

1663 static consteval bool

1664 __nothrow_assignable()

1665 {

1666 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

1668 else

1669 return false;

1670 }

1671

1672#if __cpp_lib_ranges_zip

1673 template<typename... _UTypes>

1674 static consteval bool

1675 __const_assignable()

1676 {

1677 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))

1679 else

1680 return false;

1681 }

1682#endif

1683

1684#if __cpp_lib_tuple_like

1685 template<typename _UTuple>

1686 static consteval bool

1687 __assignable_from_tuple_like()

1688 {

1690 return __assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();

1692 }

1693

1694 template<typename _UTuple>

1695 static consteval bool

1696 __const_assignable_from_tuple_like()

1697 {

1699 return __const_assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();

1701 }

1702#endif

1703

1704 public:

1705

1706 tuple& operator=(const tuple& __u) = delete;

1707

1708 constexpr tuple&

1709 operator=(const tuple& __u)

1710 noexcept(__nothrow_assignable<const _Elements&...>())

1711 requires (__assignable<const _Elements&...>())

1712 {

1713 this->_M_assign(__u);

1714 return *this;

1715 }

1716

1717 constexpr tuple&

1718 operator=(tuple&& __u)

1719 noexcept(__nothrow_assignable<_Elements...>())

1720 requires (__assignable<_Elements...>())

1721 {

1722 this->_M_assign(std::move(__u));

1723 return *this;

1724 }

1725

1726 template<typename... _UTypes>

1727 requires (__assignable<const _UTypes&...>())

1728 constexpr tuple&

1730 noexcept(__nothrow_assignable<const _UTypes&...>())

1731 {

1732 this->_M_assign(__u);

1733 return *this;

1734 }

1735

1736 template<typename... _UTypes>

1737 requires (__assignable<_UTypes...>())

1738 constexpr tuple&

1740 noexcept(__nothrow_assignable<_UTypes...>())

1741 {

1742 this->_M_assign(std::move(__u));

1743 return *this;

1744 }

1745

1746#if __cpp_lib_ranges_zip

1747 constexpr const tuple&

1748 operator=(const tuple& __u) const

1749 requires (__const_assignable<const _Elements&...>())

1750 {

1751 this->_M_assign(__u);

1752 return *this;

1753 }

1754

1755 constexpr const tuple&

1756 operator=(tuple&& __u) const

1757 requires (__const_assignable<_Elements...>())

1758 {

1759 this->_M_assign(std::move(__u));

1760 return *this;

1761 }

1762

1763 template<typename... _UTypes>

1764 constexpr const tuple&

1766 requires (__const_assignable<const _UTypes&...>())

1767 {

1768 this->_M_assign(__u);

1769 return *this;

1770 }

1771

1772 template<typename... _UTypes>

1773 constexpr const tuple&

1775 requires (__const_assignable<_UTypes...>())

1776 {

1777 this->_M_assign(std::move(__u));

1778 return *this;

1779 }

1780#endif

1781

1782 template<typename _U1, typename _U2>

1783 requires (__assignable<const _U1&, const _U2&>())

1784 constexpr tuple&

1786 noexcept(__nothrow_assignable<const _U1&, const _U2&>())

1787 {

1788 this->_M_head(*this) = __u.first;

1789 this->_M_tail(*this)._M_head(*this) = __u.second;

1790 return *this;

1791 }

1792

1793 template<typename _U1, typename _U2>

1794 requires (__assignable<_U1, _U2>())

1795 constexpr tuple&

1797 noexcept(__nothrow_assignable<_U1, _U2>())

1798 {

1799 this->_M_head(*this) = std::forward<_U1>(__u.first);

1800 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);

1801 return *this;

1802 }

1803

1804#if __cpp_lib_ranges_zip

1805 template<typename _U1, typename _U2>

1806 requires (__const_assignable<const _U1&, const _U2>())

1807 constexpr const tuple&

1809 {

1810 this->_M_head(*this) = __u.first;

1811 this->_M_tail(*this)._M_head(*this) = __u.second;

1812 return *this;

1813 }

1814

1815 template<typename _U1, typename _U2>

1816 requires (__const_assignable<_U1, _U2>())

1817 constexpr const tuple&

1819 {

1820 this->_M_head(*this) = std::forward<_U1>(__u.first);

1821 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);

1822 return *this;

1823 }

1824#endif

1825

1826#if __cpp_lib_tuple_like

1827 template<__eligible_tuple_like _UTuple>

1828 requires (__assignable_from_tuple_like<_UTuple>())

1829 constexpr tuple&

1830 operator=(_UTuple&& __u)

1831 {

1832 this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));

1833 return *this;

1834 }

1835

1836 template<__eligible_tuple_like _UTuple>

1837 requires (__const_assignable_from_tuple_like<_UTuple>())

1838 constexpr const tuple&

1839 operator=(_UTuple&& __u) const

1840 {

1841 this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));

1842 return *this;

1843 }

1844

1845 template<__tuple_like _UTuple>

1846 requires (!__is_tuple_v<_UTuple>)

1847 friend constexpr bool

1848 operator== [[nodiscard]] (const tuple& __t, const _UTuple& __u)

1849 {

1850 static_assert(sizeof...(_Elements) == tuple_size_v<_UTuple>,

1851 "tuple objects can only be compared if they have equal sizes.");

1853 return (bool(std::get<_Is>(__t) == std::get<_Is>(__u))

1854 && ...);

1856 }

1857

1858 template<__tuple_like _UTuple,

1860 struct __tuple_like_common_comparison_category;

1861

1862 template<__tuple_like _UTuple, size_t... _Is>

1863 requires requires

1864 { typename void_t<__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>; }

1865 struct __tuple_like_common_comparison_category<_UTuple, index_sequence<_Is...>>

1866 {

1867 using type = common_comparison_category_t

1868 <__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>;

1869 };

1870

1871 template<__tuple_like _UTuple>

1872 requires (!__is_tuple_v<_UTuple>)

1873 friend constexpr typename __tuple_like_common_comparison_category<_UTuple>::type

1874 operator<=>(const tuple& __t, const _UTuple& __u)

1875 {

1876 using _Cat = typename __tuple_like_common_comparison_category<_UTuple>::type;

1878 }

1879#endif

1880

1881#else

1882

1883 private:

1884 template<typename... _UElements>

1885 static constexpr

1886 __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>

1887 __assignable()

1888 { return __and_<is_assignable<_Elements&, _UElements>...>::value; }

1889

1890

1891 template<typename... _UElements>

1892 static constexpr bool __nothrow_assignable()

1893 {

1894 return

1895 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;

1896 }

1897

1898 public:

1899

1900 _GLIBCXX20_CONSTEXPR

1902 operator=(__conditional_t<__assignable<const _Elements&...>(),

1904 const __nonesuch&> __in)

1905 noexcept(__nothrow_assignable<const _Elements&...>())

1906 {

1907 this->_M_assign(__in);

1908 return *this;

1909 }

1910

1911 _GLIBCXX20_CONSTEXPR

1913 operator=(__conditional_t<__assignable<_Elements...>(),

1915 __nonesuch&&> __in)

1916 noexcept(__nothrow_assignable<_Elements...>())

1917 {

1918 this->_M_assign(std::move(__in));

1919 return *this;

1920 }

1921

1922 template<typename... _UElements>

1923 _GLIBCXX20_CONSTEXPR

1924 __enable_if_t<__assignable<const _UElements&...>(), tuple&>

1926 noexcept(__nothrow_assignable<const _UElements&...>())

1927 {

1928 this->_M_assign(__in);

1929 return *this;

1930 }

1931

1932 template<typename... _UElements>

1933 _GLIBCXX20_CONSTEXPR

1934 __enable_if_t<__assignable<_UElements...>(), tuple&>

1936 noexcept(__nothrow_assignable<_UElements...>())

1937 {

1938 this->_M_assign(std::move(__in));

1939 return *this;

1940 }

1941#endif

1942

1943

1944 _GLIBCXX20_CONSTEXPR

1945 void

1946 swap(tuple& __in)

1947 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)

1948 { _Inherited::_M_swap(__in); }

1949

1950#if __cpp_lib_ranges_zip

1951

1952

1953

1954

1955

1956

1957 constexpr void

1958 swap(const tuple& __in) const

1959 noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)

1960 requires (is_swappable_v<const _Elements> && ...)

1961 { _Inherited::_M_swap(__in); }

1962#endif

1963 };

1964

1965#if __cpp_deduction_guides >= 201606

1966 template<typename... _UTypes>

1967 tuple(_UTypes...) -> tuple<_UTypes...>;

1968 template<typename _T1, typename _T2>

1970 template<typename _Alloc, typename... _UTypes>

1971 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;

1972 template<typename _Alloc, typename _T1, typename _T2>

1974 template<typename _Alloc, typename... _UTypes>

1976#endif

1977

1978

1979 template<>

1981 {

1982 public:

1983 _GLIBCXX20_CONSTEXPR

1984 void swap(tuple&) noexcept { }

1985#if __cpp_lib_ranges_zip

1986 constexpr void swap(const tuple&) const noexcept { }

1987#endif

1988

1989

1990 tuple() = default;

1991

1992 template<typename _Alloc>

1993 _GLIBCXX20_CONSTEXPR

1994 tuple(allocator_arg_t, const _Alloc&) noexcept { }

1995 template<typename _Alloc>

1996 _GLIBCXX20_CONSTEXPR

1997 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }

1998 };

1999

2000#if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit)

2001

2002

2003 template<typename _T1, typename _T2>

2004 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>

2005 {

2006 typedef _Tuple_impl<0, _T1, _T2> _Inherited;

2007

2008

2009 template<bool _Dummy, typename _U1, typename _U2>

2010 using _ImplicitDefaultCtor = __enable_if_t<

2011 _TupleConstraints<_Dummy, _U1, _U2>::

2012 __is_implicitly_default_constructible(),

2013 bool>;

2014

2015

2016 template<bool _Dummy, typename _U1, typename _U2>

2017 using _ExplicitDefaultCtor = __enable_if_t<

2018 _TupleConstraints<_Dummy, _U1, _U2>::

2019 __is_explicitly_default_constructible(),

2020 bool>;

2021

2022 template<bool _Dummy>

2023 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;

2024

2025

2026 template<bool _Cond, typename _U1, typename _U2>

2027 using _ImplicitCtor = __enable_if_t<

2028 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),

2029 bool>;

2030

2031

2032 template<bool _Cond, typename _U1, typename _U2>

2033 using _ExplicitCtor = __enable_if_t<

2034 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),

2035 bool>;

2036

2037 template<typename _U1, typename _U2>

2038 static constexpr bool __assignable()

2039 {

2040 return __and_<is_assignable<_T1&, _U1>,

2042 }

2043

2044 template<typename _U1, typename _U2>

2045 static constexpr bool __nothrow_assignable()

2046 {

2047 return __and_<is_nothrow_assignable<_T1&, _U1>,

2049 }

2050

2051 template<typename _U1, typename _U2>

2052 static constexpr bool __nothrow_constructible()

2053 {

2054 return __and_<is_nothrow_constructible<_T1, _U1>,

2056 }

2057

2058 static constexpr bool __nothrow_default_constructible()

2059 {

2060 return __and_<is_nothrow_default_constructible<_T1>,

2062 }

2063

2064 template<typename _U1>

2065 static constexpr bool __is_alloc_arg()

2067

2068

2069#undef __glibcxx_no_dangling_refs

2070

2071#if __has_builtin(__reference_constructs_from_temporary) \

2072 && defined _GLIBCXX_DEBUG

2073# define __glibcxx_no_dangling_refs(_U1, _U2) \

2074 static_assert(!__reference_constructs_from_temporary(_T1, _U1) \

2075 && !__reference_constructs_from_temporary(_T2, _U2), \

2076 "std::tuple constructor creates a dangling reference")

2077#else

2078# define __glibcxx_no_dangling_refs(_U1, _U2)

2079#endif

2080

2081

2082 public:

2083 template<bool _Dummy = true,

2084 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>

2085 constexpr

2087 noexcept(__nothrow_default_constructible())

2088 : _Inherited() { }

2089

2090 template<bool _Dummy = true,

2091 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>

2092 explicit constexpr

2094 noexcept(__nothrow_default_constructible())

2095 : _Inherited() { }

2096

2097 template<bool _Dummy = true,

2098 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>

2099 constexpr

2100 tuple(const _T1& __a1, const _T2& __a2)

2101 noexcept(__nothrow_constructible<const _T1&, const _T2&>())

2102 : _Inherited(__a1, __a2) { }

2103

2104 template<bool _Dummy = true,

2105 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>

2106 explicit constexpr

2107 tuple(const _T1& __a1, const _T2& __a2)

2108 noexcept(__nothrow_constructible<const _T1&, const _T2&>())

2109 : _Inherited(__a1, __a2) { }

2110

2111 template<typename _U1, typename _U2,

2112 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>

2113 constexpr

2114 tuple(_U1&& __a1, _U2&& __a2)

2115 noexcept(__nothrow_constructible<_U1, _U2>())

2116 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))

2117 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2118

2119 template<typename _U1, typename _U2,

2120 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>

2121 explicit constexpr

2122 tuple(_U1&& __a1, _U2&& __a2)

2123 noexcept(__nothrow_constructible<_U1, _U2>())

2124 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))

2125 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2126

2127 constexpr tuple(const tuple&) = default;

2128

2130

2131 template<typename _U1, typename _U2,

2132 _ImplicitCtor<true, const _U1&, const _U2&> = true>

2133 constexpr

2135 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

2136 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))

2137 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2138

2139 template<typename _U1, typename _U2,

2140 _ExplicitCtor<true, const _U1&, const _U2&> = false>

2141 explicit constexpr

2143 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

2144 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))

2145 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2146

2147 template<typename _U1, typename _U2,

2148 _ImplicitCtor<true, _U1, _U2> = true>

2149 constexpr

2151 noexcept(__nothrow_constructible<_U1, _U2>())

2152 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))

2153 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2154

2155 template<typename _U1, typename _U2,

2156 _ExplicitCtor<true, _U1, _U2> = false>

2157 explicit constexpr

2159 noexcept(__nothrow_constructible<_U1, _U2>())

2160 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))

2161 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2162

2163 template<typename _U1, typename _U2,

2164 _ImplicitCtor<true, const _U1&, const _U2&> = true>

2165 constexpr

2167 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

2168 : _Inherited(__in.first, __in.second)

2169 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2170

2171 template<typename _U1, typename _U2,

2172 _ExplicitCtor<true, const _U1&, const _U2&> = false>

2173 explicit constexpr

2175 noexcept(__nothrow_constructible<const _U1&, const _U2&>())

2176 : _Inherited(__in.first, __in.second)

2177 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2178

2179 template<typename _U1, typename _U2,

2180 _ImplicitCtor<true, _U1, _U2> = true>

2181 constexpr

2183 noexcept(__nothrow_constructible<_U1, _U2>())

2184 : _Inherited(std::forward<_U1>(__in.first),

2185 std::forward<_U2>(__in.second))

2186 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2187

2188 template<typename _U1, typename _U2,

2189 _ExplicitCtor<true, _U1, _U2> = false>

2190 explicit constexpr

2192 noexcept(__nothrow_constructible<_U1, _U2>())

2193 : _Inherited(std::forward<_U1>(__in.first),

2194 std::forward<_U2>(__in.second))

2195 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2196

2197

2198

2199 template<typename _Alloc,

2200 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>

2201 _GLIBCXX20_CONSTEXPR

2202 tuple(allocator_arg_t __tag, const _Alloc& __a)

2203 : _Inherited(__tag, __a) { }

2204

2205 template<typename _Alloc,

2206 _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = false>

2207 _GLIBCXX20_CONSTEXPR

2208 explicit

2209 tuple(allocator_arg_t __tag, const _Alloc& __a)

2210 : _Inherited(__tag, __a) { }

2211

2212 template<typename _Alloc, bool _Dummy = true,

2213 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>

2214 _GLIBCXX20_CONSTEXPR

2215 tuple(allocator_arg_t __tag, const _Alloc& __a,

2216 const _T1& __a1, const _T2& __a2)

2217 : _Inherited(__tag, __a, __a1, __a2) { }

2218

2219 template<typename _Alloc, bool _Dummy = true,

2220 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>

2221 explicit

2222 _GLIBCXX20_CONSTEXPR

2223 tuple(allocator_arg_t __tag, const _Alloc& __a,

2224 const _T1& __a1, const _T2& __a2)

2225 : _Inherited(__tag, __a, __a1, __a2) { }

2226

2227 template<typename _Alloc, typename _U1, typename _U2,

2228 _ImplicitCtor<true, _U1, _U2> = true>

2229 _GLIBCXX20_CONSTEXPR

2230 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)

2231 : _Inherited(__tag, __a, std::forward<_U1>(__a1),

2232 std::forward<_U2>(__a2))

2233 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2234

2235 template<typename _Alloc, typename _U1, typename _U2,

2236 _ExplicitCtor<true, _U1, _U2> = false>

2237 explicit

2238 _GLIBCXX20_CONSTEXPR

2239 tuple(allocator_arg_t __tag, const _Alloc& __a,

2240 _U1&& __a1, _U2&& __a2)

2241 : _Inherited(__tag, __a, std::forward<_U1>(__a1),

2242 std::forward<_U2>(__a2))

2243 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2244

2245 template<typename _Alloc>

2246 _GLIBCXX20_CONSTEXPR

2247 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)

2248 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }

2249

2250 template<typename _Alloc>

2251 _GLIBCXX20_CONSTEXPR

2252 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)

2253 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }

2254

2255 template<typename _Alloc, typename _U1, typename _U2,

2256 _ImplicitCtor<true, const _U1&, const _U2&> = true>

2257 _GLIBCXX20_CONSTEXPR

2258 tuple(allocator_arg_t __tag, const _Alloc& __a,

2260 : _Inherited(__tag, __a,

2261 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))

2262 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2263

2264 template<typename _Alloc, typename _U1, typename _U2,

2265 _ExplicitCtor<true, const _U1&, const _U2&> = false>

2266 explicit

2267 _GLIBCXX20_CONSTEXPR

2268 tuple(allocator_arg_t __tag, const _Alloc& __a,

2270 : _Inherited(__tag, __a,

2271 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))

2272 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2273

2274 template<typename _Alloc, typename _U1, typename _U2,

2275 _ImplicitCtor<true, _U1, _U2> = true>

2276 _GLIBCXX20_CONSTEXPR

2278 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))

2279 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2280

2281 template<typename _Alloc, typename _U1, typename _U2,

2282 _ExplicitCtor<true, _U1, _U2> = false>

2283 explicit

2284 _GLIBCXX20_CONSTEXPR

2286 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))

2287 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2288

2289 template<typename _Alloc, typename _U1, typename _U2,

2290 _ImplicitCtor<true, const _U1&, const _U2&> = true>

2291 _GLIBCXX20_CONSTEXPR

2292 tuple(allocator_arg_t __tag, const _Alloc& __a,

2294 : _Inherited(__tag, __a, __in.first, __in.second)

2295 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2296

2297 template<typename _Alloc, typename _U1, typename _U2,

2298 _ExplicitCtor<true, const _U1&, const _U2&> = false>

2299 explicit

2300 _GLIBCXX20_CONSTEXPR

2301 tuple(allocator_arg_t __tag, const _Alloc& __a,

2303 : _Inherited(__tag, __a, __in.first, __in.second)

2304 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }

2305

2306 template<typename _Alloc, typename _U1, typename _U2,

2307 _ImplicitCtor<true, _U1, _U2> = true>

2308 _GLIBCXX20_CONSTEXPR

2310 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),

2311 std::forward<_U2>(__in.second))

2312 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2313

2314 template<typename _Alloc, typename _U1, typename _U2,

2315 _ExplicitCtor<true, _U1, _U2> = false>

2316 explicit

2317 _GLIBCXX20_CONSTEXPR

2319 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),

2320 std::forward<_U2>(__in.second))

2321 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }

2322

2323

2324

2325 _GLIBCXX20_CONSTEXPR

2327 operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),

2329 const __nonesuch&> __in)

2330 noexcept(__nothrow_assignable<const _T1&, const _T2&>())

2331 {

2332 this->_M_assign(__in);

2333 return *this;

2334 }

2335

2336 _GLIBCXX20_CONSTEXPR

2338 operator=(__conditional_t<__assignable<_T1, _T2>(),

2340 __nonesuch&&> __in)

2341 noexcept(__nothrow_assignable<_T1, _T2>())

2342 {

2343 this->_M_assign(std::move(__in));

2344 return *this;

2345 }

2346

2347 template<typename _U1, typename _U2>

2348 _GLIBCXX20_CONSTEXPR

2349 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>

2351 noexcept(__nothrow_assignable<const _U1&, const _U2&>())

2352 {

2353 this->_M_assign(__in);

2354 return *this;

2355 }

2356

2357 template<typename _U1, typename _U2>

2358 _GLIBCXX20_CONSTEXPR

2359 __enable_if_t<__assignable<_U1, _U2>(), tuple&>

2361 noexcept(__nothrow_assignable<_U1, _U2>())

2362 {

2363 this->_M_assign(std::move(__in));

2364 return *this;

2365 }

2366

2367 template<typename _U1, typename _U2>

2368 _GLIBCXX20_CONSTEXPR

2369 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>

2371 noexcept(__nothrow_assignable<const _U1&, const _U2&>())

2372 {

2373 this->_M_head(*this) = __in.first;

2374 this->_M_tail(*this)._M_head(*this) = __in.second;

2375 return *this;

2376 }

2377

2378 template<typename _U1, typename _U2>

2379 _GLIBCXX20_CONSTEXPR

2380 __enable_if_t<__assignable<_U1, _U2>(), tuple&>

2382 noexcept(__nothrow_assignable<_U1, _U2>())

2383 {

2384 this->_M_head(*this) = std::forward<_U1>(__in.first);

2385 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);

2386 return *this;

2387 }

2388

2389 _GLIBCXX20_CONSTEXPR

2390 void

2391 swap(tuple& __in)

2392 noexcept(__and_<__is_nothrow_swappable<_T1>,

2393 __is_nothrow_swappable<_T2>>::value)

2394 { _Inherited::_M_swap(__in); }

2395 };

2396#endif

2397

2398

2399 template<typename... _Elements>

2402

2403#if __cplusplus >= 201703L

2404 template<typename... _Types>

2405 inline constexpr size_t tuple_size_v<tuple<_Types...>>

2406 = sizeof...(_Types);

2407

2408 template<typename... _Types>

2409 inline constexpr size_t tuple_size_v<const tuple<_Types...>>

2410 = sizeof...(_Types);

2411#endif

2412

2413

2414 template<size_t __i, typename... _Types>

2416 {

2417 static_assert(__i < sizeof...(_Types), "tuple index must be in range");

2418

2419 using type = typename _Nth_type<__i, _Types...>::type;

2420 };

2421

2422 template<size_t __i, typename _Head, typename... _Tail>

2423 constexpr _Head&

2424 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept

2425 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }

2426

2427 template<size_t __i, typename _Head, typename... _Tail>

2428 constexpr const _Head&

2429 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept

2430 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }

2431

2432

2433 template<size_t __i, typename... _Types>

2434 __enable_if_t<(__i >= sizeof...(_Types))>

2435 __get_helper(const tuple<_Types...>&) = delete;

2436

2437

2438 template<size_t __i, typename... _Elements>

2439 constexpr __tuple_element_t<__i, tuple<_Elements...>>&

2441 { return std::__get_helper<__i>(__t); }

2442

2443

2444 template<size_t __i, typename... _Elements>

2445 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&

2447 { return std::__get_helper<__i>(__t); }

2448

2449

2450 template<size_t __i, typename... _Elements>

2451 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&

2453 {

2454 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;

2455 return std::forward<__element_type>(std::__get_helper<__i>(__t));

2456 }

2457

2458

2459 template<size_t __i, typename... _Elements>

2460 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&

2462 {

2463 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;

2464 return std::forward<const __element_type>(std::__get_helper<__i>(__t));

2465 }

2466

2467

2468

2469 template<size_t __i, typename... _Elements>

2470 constexpr __enable_if_t<(__i >= sizeof...(_Elements))>

2471 get(const tuple<_Elements...>&) = delete;

2472

2473

2474#ifdef __cpp_lib_tuples_by_type

2475

2476 template <typename _Tp, typename... _Types>

2477 constexpr _Tp&

2478 get(tuple<_Types...>& __t) noexcept

2479 {

2480 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();

2481 static_assert(__idx < sizeof...(_Types),

2482 "the type T in std::get must occur exactly once in the tuple");

2483 return std::__get_helper<__idx>(__t);

2484 }

2485

2486

2487 template <typename _Tp, typename... _Types>

2488 constexpr _Tp&&

2489 get(tuple<_Types...>&& __t) noexcept

2490 {

2491 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();

2492 static_assert(__idx < sizeof...(_Types),

2493 "the type T in std::get must occur exactly once in the tuple");

2494 return std::forward<_Tp>(std::__get_helper<__idx>(__t));

2495 }

2496

2497

2498 template <typename _Tp, typename... _Types>

2499 constexpr const _Tp&

2500 get(const tuple<_Types...>& __t) noexcept

2501 {

2502 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();

2503 static_assert(__idx < sizeof...(_Types),

2504 "the type T in std::get must occur exactly once in the tuple");

2505 return std::__get_helper<__idx>(__t);

2506 }

2507

2508

2509

2510 template <typename _Tp, typename... _Types>

2511 constexpr const _Tp&&

2512 get(const tuple<_Types...>&& __t) noexcept

2513 {

2514 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();

2515 static_assert(__idx < sizeof...(_Types),

2516 "the type T in std::get must occur exactly once in the tuple");

2517 return std::forward<const _Tp>(std::__get_helper<__idx>(__t));

2518 }

2519#endif

2520

2521#if __cpp_lib_three_way_comparison

2522 template<typename... _Tps, typename... _Ups>

2523 requires (sizeof...(_Tps) == sizeof...(_Ups))

2524 && (requires (const _Tps& __t, const _Ups& __u) {

2525 { __t == __u } -> __detail::__boolean_testable;

2526 } && ...)

2527 constexpr bool

2528 operator== [[nodiscard]] (const tuple<_Tps...>& __t,

2529 const tuple<_Ups...>& __u)

2530 {

2531 return [&]<size_t... _Inds>(index_sequence<_Inds...>) {

2532

2533 return ((std::get<_Inds>(__t) == std::get<_Inds>(__u)) && ...);

2535 }

2536

2537 template<typename _Cat, typename _Tp, typename _Up, typename _IndexSeq>

2538 [[nodiscard]]

2539 constexpr _Cat

2540 __tuple_cmp(const _Tp& __t, const _Up& __u, _IndexSeq __indices)

2541 {

2542 _Cat __c = _Cat::equivalent;

2543

2544

2545

2546 auto __cmp = [&]<size_t _Ind>(integral_constant<size_t, _Ind>) {

2547 __c = __detail::__synth3way(std::get<_Ind>(__t), std::get<_Ind>(__u));

2548 return __c == 0;

2549 };

2550

2552

2553 (void)(__cmp(integral_constant<size_t, _Inds>{}) && ...);

2554 }(__indices);

2555

2556 return __c;

2557 }

2558

2559 template<typename... _Tps, typename... _Ups>

2560 requires (sizeof...(_Tps) == sizeof...(_Ups))

2561 && (requires { typename __detail::__synth3way_t<_Tps, _Ups>; } && ...)

2562 constexpr

2563 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>

2564 operator<=> [[nodiscard]] (const tuple<_Tps...>& __t,

2565 const tuple<_Ups...>& __u)

2566 {

2567 using _Cat

2568 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;

2569 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());

2570 }

2571#else

2572

2573

2574 template<typename _Tp, typename _Up, size_t __i, size_t __size>

2575 struct __tuple_compare

2576 {

2577 static constexpr bool

2578 __eq(const _Tp& __t, const _Up& __u)

2579 {

2580 return bool(std::get<__i>(__t) == std::get<__i>(__u))

2581 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);

2582 }

2583

2584 static constexpr bool

2585 __less(const _Tp& __t, const _Up& __u)

2586 {

2587 return bool(std::get<__i>(__t) < std::get<__i>(__u))

2588 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))

2589 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));

2590 }

2591 };

2592

2593 template<typename _Tp, typename _Up, size_t __size>

2594 struct __tuple_compare<_Tp, _Up, __size, __size>

2595 {

2596 static constexpr bool

2597 __eq(const _Tp&, const _Up&) { return true; }

2598

2599 static constexpr bool

2600 __less(const _Tp&, const _Up&) { return false; }

2601 };

2602

2603 template<typename... _TElements, typename... _UElements>

2604 _GLIBCXX_NODISCARD

2605 constexpr bool

2606 operator==(const tuple<_TElements...>& __t,

2607 const tuple<_UElements...>& __u)

2608 {

2609 static_assert(sizeof...(_TElements) == sizeof...(_UElements),

2610 "tuple objects can only be compared if they have equal sizes.");

2611 using __compare = __tuple_compare<tuple<_TElements...>,

2612 tuple<_UElements...>,

2613 0, sizeof...(_TElements)>;

2614 return __compare::__eq(__t, __u);

2615 }

2616

2617 template<typename... _TElements, typename... _UElements>

2618 _GLIBCXX_NODISCARD

2619 constexpr bool

2620 operator<(const tuple<_TElements...>& __t,

2621 const tuple<_UElements...>& __u)

2622 {

2623 static_assert(sizeof...(_TElements) == sizeof...(_UElements),

2624 "tuple objects can only be compared if they have equal sizes.");

2625 using __compare = __tuple_compare<tuple<_TElements...>,

2626 tuple<_UElements...>,

2627 0, sizeof...(_TElements)>;

2628 return __compare::__less(__t, __u);

2629 }

2630

2631 template<typename... _TElements, typename... _UElements>

2632 _GLIBCXX_NODISCARD

2633 constexpr bool

2634 operator!=(const tuple<_TElements...>& __t,

2635 const tuple<_UElements...>& __u)

2636 { return !(__t == __u); }

2637

2638 template<typename... _TElements, typename... _UElements>

2639 _GLIBCXX_NODISCARD

2640 constexpr bool

2641 operator>(const tuple<_TElements...>& __t,

2642 const tuple<_UElements...>& __u)

2643 { return __u < __t; }

2644

2645 template<typename... _TElements, typename... _UElements>

2646 _GLIBCXX_NODISCARD

2647 constexpr bool

2648 operator<=(const tuple<_TElements...>& __t,

2649 const tuple<_UElements...>& __u)

2650 { return !(__u < __t); }

2651

2652 template<typename... _TElements, typename... _UElements>

2653 _GLIBCXX_NODISCARD

2654 constexpr bool

2655 operator>=(const tuple<_TElements...>& __t,

2656 const tuple<_UElements...>& __u)

2657 { return !(__t < __u); }

2658#endif

2659

2660

2661

2662 template<typename... _Elements>

2663 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>

2665 {

2667 __result_type;

2668 return __result_type(std::forward<_Elements>(__args)...);

2669 }

2670

2671

2672

2673

2674 template<typename... _Elements>

2675 constexpr tuple<_Elements&&...>

2677 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }

2678

2679

2680 template<size_t, typename, typename, size_t>

2681 struct __make_tuple_impl;

2682

2683 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>

2684 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>

2685 : __make_tuple_impl<_Idx + 1,

2686 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,

2687 _Tuple, _Nm>

2688 { };

2689

2690 template<size_t _Nm, typename _Tuple, typename... _Tp>

2691 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>

2692 {

2693 typedef tuple<_Tp...> __type;

2694 };

2695

2696 template<typename _Tuple>

2697 struct __do_make_tuple

2698 : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>

2699 { };

2700

2701

2702 template<typename _Tuple>

2703 struct __make_tuple

2704 : public __do_make_tuple<__remove_cvref_t<_Tuple>>

2705 { };

2706

2707

2708 template<typename...>

2709 struct __combine_tuples;

2710

2711 template<>

2712 struct __combine_tuples<>

2713 {

2714 typedef tuple<> __type;

2715 };

2716

2717 template<typename... _Ts>

2718 struct __combine_tuples<tuple<_Ts...>>

2719 {

2720 typedef tuple<_Ts...> __type;

2721 };

2722

2723 template<typename... _T1s, typename... _T2s, typename... _Rem>

2724 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>

2725 {

2726 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,

2727 _Rem...>::__type __type;

2728 };

2729

2730

2731 template<typename... _Tpls>

2732 struct __tuple_cat_result

2733 {

2734 typedef typename __combine_tuples

2735 <typename __make_tuple<_Tpls>::__type...>::__type __type;

2736 };

2737

2738

2739

2740 template<typename...>

2741 struct __make_1st_indices;

2742

2743 template<>

2744 struct __make_1st_indices<>

2745 {

2746 typedef _Index_tuple<> __type;

2747 };

2748

2749 template<typename _Tp, typename... _Tpls>

2750 struct __make_1st_indices<_Tp, _Tpls...>

2751 {

2752 typedef typename _Build_index_tuple<tuple_size<

2753 typename remove_reference<_Tp>::type>::value>::__type __type;

2754 };

2755

2756

2757

2758

2759 template<typename _Ret, typename _Indices, typename... _Tpls>

2760 struct __tuple_concater;

2761

2762 template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>

2763 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>

2764 {

2765 template<typename... _Us>

2766 static constexpr _Ret

2767 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)

2768 {

2769 typedef typename __make_1st_indices<_Tpls...>::__type __idx;

2770 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;

2771 return __next::_S_do(std::forward<_Tpls>(__tps)...,

2772 std::forward<_Us>(__us)...,

2773 std::get<_Is>(std::forward<_Tp>(__tp))...);

2774 }

2775 };

2776

2777 template<typename _Ret>

2778 struct __tuple_concater<_Ret, _Index_tuple<>>

2779 {

2780 template<typename... _Us>

2781 static constexpr _Ret

2782 _S_do(_Us&&... __us)

2783 {

2784 return _Ret(std::forward<_Us>(__us)...);

2785 }

2786 };

2787

2788 template<typename... _Tps>

2789 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type

2790 { };

2791

2792

2793

2794#if __cpp_lib_tuple_like

2795 template<__tuple_like... _Tpls>

2796#else

2797 template<typename... _Tpls, typename = typename

2798 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>

2799#endif

2800 constexpr auto

2802 -> typename __tuple_cat_result<_Tpls...>::__type

2803 {

2804 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;

2805 typedef typename __make_1st_indices<_Tpls...>::__type __idx;

2806 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;

2807 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);

2808 }

2809

2810

2811

2812

2813 template<typename... _Elements>

2814 constexpr tuple<_Elements&...>

2815 tie(_Elements&... __args) noexcept

2816 { return tuple<_Elements&...>(__args...); }

2817

2818

2819 template<typename... _Elements>

2820 _GLIBCXX20_CONSTEXPR

2821 inline

2822#if __cplusplus > 201402L || !defined(__STRICT_ANSI__)

2823

2824 typename enable_if<__and_<__is_swappable<_Elements>...>::value

2825 >::type

2826#else

2827 void

2828#endif

2830 noexcept(noexcept(__x.swap(__y)))

2831 { __x.swap(__y); }

2832

2833#if __cpp_lib_ranges_zip

2834 template<typename... _Elements>

2835 requires (is_swappable_v<const _Elements> && ...)

2836 constexpr void

2837 swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)

2838 noexcept(noexcept(__x.swap(__y)))

2839 { __x.swap(__y); }

2840#endif

2841

2842#if __cplusplus > 201402L || !defined(__STRICT_ANSI__)

2843

2844 template<typename... _Elements>

2845 _GLIBCXX20_CONSTEXPR

2846 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type

2847 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;

2848#endif

2849

2850

2851 template<typename... _Types, typename _Alloc>

2853

2854

2855

2856

2857

2858

2859

2860

2861

2862

2863 template<class _T1, class _T2>

2864 template<typename... _Args1, typename... _Args2>

2865 _GLIBCXX20_CONSTEXPR

2866 inline

2870 : pair(__first, __second,

2871 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),

2872 typename _Build_index_tuple<sizeof...(_Args2)>::__type())

2873 { }

2874

2875 template<class _T1, class _T2>

2876 template<typename... _Args1, size_t... _Indexes1,

2877 typename... _Args2, size_t... _Indexes2>

2878 _GLIBCXX20_CONSTEXPR inline

2881 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)

2882 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),

2883 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)

2884 { }

2885

2886#if defined(__cpp_lib_apply) || defined(__cpp_lib_make_from_tuple)

2887

2888

2889

2890

2891 template<template<typename...> class _Trait, typename _Tp, typename _Tuple>

2892 inline constexpr bool __unpack_std_tuple = false;

2893

2894 template<template<typename...> class _Trait, typename _Tp, typename... _Up>

2895 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>

2896 = _Trait<_Tp, _Up...>::value;

2897

2898 template<template<typename...> class _Trait, typename _Tp, typename... _Up>

2899 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>

2900 = _Trait<_Tp, _Up&...>::value;

2901

2902 template<template<typename...> class _Trait, typename _Tp, typename... _Up>

2903 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>

2904 = _Trait<_Tp, const _Up...>::value;

2905

2906 template<template<typename...> class _Trait, typename _Tp, typename... _Up>

2907 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>

2908 = _Trait<_Tp, const _Up&...>::value;

2909#endif

2910

2911#ifdef __cpp_lib_apply

2912 template <typename _Fn, typename _Tuple, size_t... _Idx>

2913 constexpr decltype(auto)

2914 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)

2915 {

2917 std::get<_Idx>(std::forward<_Tuple>(__t))...);

2918 }

2919

2920#if __cpp_lib_tuple_like

2921 template <typename _Fn, __tuple_like _Tuple>

2922#else

2923 template <typename _Fn, typename _Tuple>

2924#endif

2925 constexpr decltype(auto)

2926 apply(_Fn&& __f, _Tuple&& __t)

2927 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)

2928 {

2929 using _Indices

2930 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;

2931 return std::__apply_impl(std::forward<_Fn>(__f),

2932 std::forward<_Tuple>(__t),

2933 _Indices{});

2934 }

2935#endif

2936

2937#ifdef __cpp_lib_make_from_tuple

2938 template <typename _Tp, typename _Tuple, size_t... _Idx>

2939 constexpr _Tp

2940 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)

2941 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }

2942

2943#if __cpp_lib_tuple_like

2944 template <typename _Tp, __tuple_like _Tuple>

2945#else

2946 template <typename _Tp, typename _Tuple>

2947#endif

2948 constexpr _Tp

2949 make_from_tuple(_Tuple&& __t)

2950 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)

2951 {

2952 constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;

2953#if __has_builtin(__reference_constructs_from_temporary)

2954 if constexpr (__n == 1)

2955 {

2956 using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));

2957 static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));

2958 }

2959#endif

2960 return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),

2961 make_index_sequence<__n>{});

2962 }

2963#endif

2964

2965#if __cpp_lib_tuple_like

2966 template<__tuple_like _TTuple, __tuple_like _UTuple,

2967 template<typename> class _TQual, template<typename> class _UQual,

2968 typename = make_index_sequence<tuple_size_v<_TTuple>>>

2969 struct __tuple_like_common_reference;

2970

2971 template<__tuple_like _TTuple, __tuple_like _UTuple,

2972 template<typename> class _TQual, template<typename> class _UQual,

2973 size_t... _Is>

2974 requires requires

2975 { typename tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,

2976 _UQual<tuple_element_t<_Is, _UTuple>>>...>; }

2977 struct __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual, index_sequence<_Is...>>

2978 {

2979 using type = tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,

2980 _UQual<tuple_element_t<_Is, _UTuple>>>...>;

2981 };

2982

2983 template<__tuple_like _TTuple, __tuple_like _UTuple,

2984 template<typename> class _TQual, template<typename> class _UQual>

2985 requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)

2986 && is_same_v<_TTuple, decay_t<_TTuple>>

2987 && is_same_v<_UTuple, decay_t<_UTuple>>

2988 && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)

2989 && requires { typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type; }

2990 struct basic_common_reference<_TTuple, _UTuple, _TQual, _UQual>

2991 {

2992 using type = typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type;

2993 };

2994

2995 template<__tuple_like _TTuple, __tuple_like _UTuple,

2996 typename = make_index_sequence<tuple_size_v<_TTuple>>>

2997 struct __tuple_like_common_type;

2998

2999 template<__tuple_like _TTuple, __tuple_like _UTuple, size_t... _Is>

3000 requires requires

3001 { typename tuple<common_type_t<tuple_element_t<_Is, _TTuple>,

3002 tuple_element_t<_Is, _UTuple>>...>; }

3003 struct __tuple_like_common_type<_TTuple, _UTuple, index_sequence<_Is...>>

3004 {

3005 using type = tuple<common_type_t<tuple_element_t<_Is, _TTuple>,

3006 tuple_element_t<_Is, _UTuple>>...>;

3007 };

3008

3009 template<__tuple_like _TTuple, __tuple_like _UTuple>

3010 requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)

3011 && is_same_v<_TTuple, decay_t<_TTuple>>

3012 && is_same_v<_UTuple, decay_t<_UTuple>>

3013 && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)

3014 && requires { typename __tuple_like_common_type<_TTuple, _UTuple>::type; }

3015 struct common_type<_TTuple, _UTuple>

3016 {

3017 using type = typename __tuple_like_common_type<_TTuple, _UTuple>::type;

3018 };

3019#endif

3020

3021

3022

3023#undef __glibcxx_no_dangling_refs

3024

3025_GLIBCXX_END_NAMESPACE_VERSION

3026}

3027

3028#endif

3029

3030#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)

__bool_constant< true > true_type

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

__bool_constant< false > false_type

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

constexpr auto tuple_cat(_Tpls &&... __tpls) -> typename __tuple_cat_result< _Tpls... >::__type

Create a tuple containing all elements from multiple tuple-like objects.

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

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

constexpr tuple< typename __decay_and_strip< _Elements >::__type... > make_tuple(_Elements &&... __args)

Create a tuple containing copies of the arguments.

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

Convert a value to an rvalue.

constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)

Invoke a callable object.

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

Return a tuple of lvalue references bound to the arguments.

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

Forward an lvalue.

ISO C++ entities toplevel namespace is std.

make_integer_sequence< size_t, _Num > make_index_sequence

Alias template make_index_sequence.

integer_sequence< size_t, _Idx... > index_sequence

Alias template index_sequence.

make_index_sequence< sizeof...(_Types)> index_sequence_for

Alias template index_sequence_for.

Primary class template, tuple.

is_nothrow_default_constructible

Declare uses_allocator so it can be specialized in etc.

Struct holding two objects of arbitrary type.

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

Finds the size of a given tuple type.

Gives the type of the ith element of a given tuple type.

Class template integer_sequence.