@@ -8372,6 +8372,11 @@ int run_test()
8372
8372
#include < type_traits>
8373
8373
#include < utility>
8374
8374
8375
+ #if _HAS_CXX20
8376
+ #define CONSTEXPR20 constexpr
8377
+ #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
8378
+ #define CONSTEXPR20 inline
8379
+ #endif // ^^^ !_HAS_CXX20 ^^^
8375
8380
8376
8381
namespace msvc {
8377
8382
namespace size {
@@ -8422,12 +8427,6 @@ namespace msvc {
8422
8427
namespace lwg3836 {
8423
8428
static_assert (std::is_convertible_v<std::optional<int >, std::optional<bool >>);
8424
8429
static_assert (std::is_convertible_v<const std::optional<int >&, std::optional<bool >>);
8425
-
8426
- #if _HAS_CXX20
8427
- #define CONSTEXPR20 constexpr
8428
- #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
8429
- #define CONSTEXPR20 inline
8430
- #endif // ^^^ !_HAS_CXX20 ^^^
8431
8430
CONSTEXPR20 bool run_test () {
8432
8431
std::optional<int > oi = 0 ;
8433
8432
std::optional<bool > ob = oi;
@@ -8436,13 +8435,151 @@ namespace msvc {
8436
8435
8437
8436
return true ;
8438
8437
}
8439
- #undef CONSTEXPR20
8440
-
8441
8438
#if _HAS_CXX20
8442
8439
static_assert (run_test());
8443
8440
#endif // _HAS_CXX20
8444
8441
} // namespace lwg3836
8445
8442
8443
+ namespace lwg3886 {
8444
+ enum class Qualification {
8445
+ None,
8446
+ Const,
8447
+ Volatile,
8448
+ ConstVolatile,
8449
+ };
8450
+
8451
+ template <class T >
8452
+ constexpr Qualification CvQualOf =
8453
+ std::is_const_v<std::remove_reference_t <T>>
8454
+ ? (std::is_volatile_v<std::remove_reference_t <T>> ? Qualification::ConstVolatile : Qualification::Const)
8455
+ : (std::is_volatile_v<std::remove_reference_t <T>> ? Qualification::Volatile : Qualification::None);
8456
+
8457
+ struct QualDistinction {
8458
+ QualDistinction () = default ;
8459
+
8460
+ constexpr QualDistinction (QualDistinction&&) noexcept : qual_{Qualification::None} {}
8461
+ constexpr QualDistinction (const QualDistinction&) noexcept : qual_{Qualification::Const} {}
8462
+ template <class T ,
8463
+ std::enable_if_t <std::is_same_v<std::remove_cv_t <std::remove_reference_t <T>>, QualDistinction>, int > =
8464
+ 0 >
8465
+ constexpr QualDistinction (T&&) noexcept : qual_{CvQualOf<T>} {}
8466
+
8467
+ constexpr QualDistinction& operator =(QualDistinction&&) noexcept {
8468
+ qual_ = Qualification::None;
8469
+ return *this ;
8470
+ }
8471
+ constexpr QualDistinction& operator =(const QualDistinction&) noexcept {
8472
+ qual_ = Qualification::Const;
8473
+ return *this ;
8474
+ }
8475
+ template <class T ,
8476
+ std::enable_if_t <std::is_same_v<std::remove_cv_t <std::remove_reference_t <T>>, QualDistinction>, int > =
8477
+ 0 >
8478
+ constexpr QualDistinction& operator =(T&&) noexcept {
8479
+ qual_ = CvQualOf<T>;
8480
+ return *this ;
8481
+ }
8482
+ template <class T ,
8483
+ std::enable_if_t <std::is_same_v<std::remove_cv_t <std::remove_reference_t <T>>, QualDistinction>, int > =
8484
+ 0 >
8485
+ constexpr const QualDistinction& operator =(T&&) const noexcept {
8486
+ qual_ = CvQualOf<T>;
8487
+ return *this ;
8488
+ }
8489
+ template <class T ,
8490
+ std::enable_if_t <std::is_same_v<std::remove_cv_t <std::remove_reference_t <T>>, QualDistinction>, int > =
8491
+ 0 >
8492
+ volatile QualDistinction& operator =(T&&) volatile noexcept {
8493
+ qual_ = CvQualOf<T>;
8494
+ return *this ;
8495
+ }
8496
+ template <class T ,
8497
+ std::enable_if_t <std::is_same_v<std::remove_cv_t <std::remove_reference_t <T>>, QualDistinction>, int > =
8498
+ 0 >
8499
+ const volatile QualDistinction& operator =(T&&) const volatile noexcept {
8500
+ qual_ = CvQualOf<T>;
8501
+ return *this ;
8502
+ }
8503
+
8504
+ mutable Qualification qual_ = Qualification::None;
8505
+ };
8506
+
8507
+ constexpr bool test_value_or () {
8508
+ assert (std::optional<QualDistinction>{}.value_or ({}).qual_ == Qualification::None);
8509
+ assert (std::optional<const QualDistinction>{}.value_or ({}).qual_ == Qualification::None);
8510
+ {
8511
+ std::optional<QualDistinction> opt;
8512
+ assert (opt.value_or ({}).qual_ == Qualification::None);
8513
+ }
8514
+ {
8515
+ std::optional<const QualDistinction> opt;
8516
+ assert (opt.value_or ({}).qual_ == Qualification::None);
8517
+ }
8518
+ return true ;
8519
+ }
8520
+
8521
+ CONSTEXPR20 bool test_assignment () {
8522
+ assert ((std::optional<QualDistinction>{} = {QualDistinction{}}).value ().qual_ == Qualification::None);
8523
+ assert ((std::optional<const QualDistinction>{} = {QualDistinction{}}).value ().qual_ == Qualification::None);
8524
+ {
8525
+ std::optional<QualDistinction> opt{std::in_place};
8526
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8527
+ opt.reset ();
8528
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8529
+ }
8530
+ {
8531
+ std::optional<const QualDistinction> opt{std::in_place};
8532
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8533
+ opt.reset ();
8534
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8535
+ }
8536
+ return true ;
8537
+ }
8538
+
8539
+ bool test_volatile () {
8540
+ assert (std::optional<volatile QualDistinction>{}.value_or ({}).qual_ == Qualification::None);
8541
+ assert (std::optional<const volatile QualDistinction>{}.value_or ({}).qual_ == Qualification::None);
8542
+ {
8543
+ std::optional<volatile QualDistinction> opt;
8544
+ assert (opt.value_or ({}).qual_ == Qualification::None);
8545
+ }
8546
+ {
8547
+ std::optional<const volatile QualDistinction> opt;
8548
+ assert (opt.value_or ({}).qual_ == Qualification::None);
8549
+ }
8550
+
8551
+ assert (
8552
+ (std::optional<volatile QualDistinction>{} = {QualDistinction{}}).value ().qual_ == Qualification::None);
8553
+ assert ((std::optional<const volatile QualDistinction>{} = {QualDistinction{}}).value ().qual_
8554
+ == Qualification::None);
8555
+ {
8556
+ std::optional<volatile QualDistinction> opt{std::in_place};
8557
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8558
+ opt.reset ();
8559
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8560
+ }
8561
+ {
8562
+ std::optional<const volatile QualDistinction> opt{std::in_place};
8563
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8564
+ opt.reset ();
8565
+ assert ((opt = {QualDistinction{}}).value ().qual_ == Qualification::None);
8566
+ }
8567
+
8568
+ return true ;
8569
+ }
8570
+
8571
+ static_assert (test_value_or());
8572
+ #if _HAS_CXX20
8573
+ static_assert (test_assignment());
8574
+ #endif // _HAS_CXX20
8575
+
8576
+ void run_test () {
8577
+ test_value_or ();
8578
+ test_assignment ();
8579
+ test_volatile ();
8580
+ }
8581
+ } // namespace lwg3886
8582
+
8446
8583
namespace vso406124 {
8447
8584
// Defend against regression of VSO-406124
8448
8585
void run_test () {
@@ -8719,6 +8856,7 @@ int main() {
8719
8856
optional_includes_initializer_list::run_test ();
8720
8857
8721
8858
msvc::lwg3836::run_test ();
8859
+ msvc::lwg3886::run_test ();
8722
8860
8723
8861
msvc::vso406124::run_test ();
8724
8862
msvc::vso508126::run_test ();
0 commit comments