[libcxx][optional] adds missing constexpr operations

Makes the following operations constexpr:
  * `std::swap(optional, optional)`
  * `optional(optional<U> const&)`
  * `optional(optional<U>&&)`
  * `~optional()`
  * `operator=(nullopt_t)`
  * `operator=(U&&)`
  * `operator=(optional<U> const&)`
  * `operator=(optional<U>&&)`
  * `emplace(Args&&...)`
  * `emplace(initializer_list<U>, Args&&...)`
  * `swap(optional&)`
  * `reset()`

P2231 has been accepted by plenary, with the committee recommending
implementers retroactively apply to C++20. It's necessary for us to
implement _`semiregular-box`_ and _`non-propagating-cache`_, both of
which are required for ranges (otherwise we'll need to reimplement
`std::optional` with these members `constexpr`ified).

Differential Revision: https://reviews.llvm.org/D102119

NOKEYCHECK=True
GitOrigin-RevId: 546449938a39dcc65f60f8d6e44e7b058a026549
diff --git a/include/optional b/include/optional
index b6a464f..8a291a6 100644
--- a/include/optional
+++ b/include/optional
@@ -69,7 +69,7 @@
   template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
 
   // 23.6.9, specialized algorithms
-  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
+  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
   template <class T> constexpr optional<see below > make_optional(T&&);
   template <class T, class... Args>
     constexpr optional<T> make_optional(Args&&... args);
@@ -95,26 +95,26 @@
     template <class U = T>
       constexpr EXPLICIT optional(U &&);
     template <class U>
-      constexpr EXPLICIT optional(const optional<U> &);
+      EXPLICIT optional(const optional<U> &);   // constexpr in C++20
     template <class U>
-      constexpr EXPLICIT optional(optional<U> &&);
+      EXPLICIT optional(optional<U> &&);        // constexpr in C++20
 
     // 23.6.3.2, destructor
-    ~optional();
+    ~optional(); // constexpr in C++20
 
     // 23.6.3.3, assignment
-    optional &operator=(nullopt_t) noexcept;
-    optional &operator=(const optional &);                // constexpr in C++20
-    optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
-    template <class U = T> optional &operator=(U &&);
-    template <class U> optional &operator=(const optional<U> &);
-    template <class U> optional &operator=(optional<U> &&);
-    template <class... Args> T& emplace(Args &&...);
+    optional &operator=(nullopt_t) noexcept;                     // constexpr in C++20
+    optional &operator=(const optional &);                       // constexpr in C++20
+    optional &operator=(optional &&) noexcept(see below);        // constexpr in C++20
+    template <class U = T> optional &operator=(U &&);            // constexpr in C++20
+    template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
+    template <class U> optional &operator=(optional<U> &&);      // constexpr in C++20
+    template <class... Args> T& emplace(Args &&...);             // constexpr in C++20
     template <class U, class... Args>
-      T& emplace(initializer_list<U>, Args &&...);
+      T& emplace(initializer_list<U>, Args &&...);               // constexpr in C++20
 
     // 23.6.3.4, swap
-    void swap(optional &) noexcept(see below );
+    void swap(optional &) noexcept(see below ); // constexpr in C++20
 
     // 23.6.3.5, observers
     constexpr T const *operator->() const;
@@ -133,7 +133,7 @@
     template <class U> constexpr T value_or(U &&) &&;
 
     // 23.6.3.6, modifiers
-    void reset() noexcept;
+    void reset() noexcept; // constexpr in C++20
 
   private:
     T *val; // exposition only
@@ -221,7 +221,7 @@
     bool __engaged_;
 
     _LIBCPP_INLINE_VISIBILITY
-    ~__optional_destruct_base()
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__optional_destruct_base()
     {
         if (__engaged_)
             __val_.~value_type();
@@ -239,7 +239,7 @@
            __engaged_(true) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    void reset() noexcept
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
     {
         if (__engaged_)
         {
@@ -274,7 +274,7 @@
            __engaged_(true) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    void reset() noexcept
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
     {
         if (__engaged_)
         {
@@ -319,16 +319,20 @@
 
     template <class... _Args>
     _LIBCPP_INLINE_VISIBILITY
-    void __construct(_Args&&... __args)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_Args&&... __args)
     {
         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
+#if _LIBCPP_STD_VER > 17
+        _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
+#else
         ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
+#endif
         this->__engaged_ = true;
     }
 
     template <class _That>
     _LIBCPP_INLINE_VISIBILITY
-    void __construct_from(_That&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
     {
         if (__opt.has_value())
             __construct(_VSTD::forward<_That>(__opt).__get());
@@ -336,7 +340,7 @@
 
     template <class _That>
     _LIBCPP_INLINE_VISIBILITY
-    void __assign_from(_That&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
     {
         if (this->__engaged_ == __opt.has_value())
         {
@@ -394,7 +398,7 @@
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    void reset() noexcept { __value_ = nullptr; }
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept { __value_ = nullptr; }
 
     _LIBCPP_INLINE_VISIBILITY
     constexpr bool has_value() const noexcept
@@ -410,7 +414,7 @@
 
     template <class _UArg>
     _LIBCPP_INLINE_VISIBILITY
-    void __construct(_UArg&& __val)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_UArg&& __val)
     {
         _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
         static_assert(__can_bind_reference<_UArg>(),
@@ -421,7 +425,7 @@
 
     template <class _That>
     _LIBCPP_INLINE_VISIBILITY
-    void __construct_from(_That&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
     {
         if (__opt.has_value())
             __construct(_VSTD::forward<_That>(__opt).__get());
@@ -429,7 +433,7 @@
 
     template <class _That>
     _LIBCPP_INLINE_VISIBILITY
-    void __assign_from(_That&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
     {
         if (has_value() == __opt.has_value())
         {
@@ -461,7 +465,7 @@
     __optional_copy_base() = default;
 
     _LIBCPP_INLINE_VISIBILITY
-    __optional_copy_base(const __optional_copy_base& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_base(const __optional_copy_base& __opt)
     {
         this->__construct_from(__opt);
     }
@@ -492,7 +496,7 @@
     __optional_move_base(const __optional_move_base&) = default;
 
     _LIBCPP_INLINE_VISIBILITY
-    __optional_move_base(__optional_move_base&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_base(__optional_move_base&& __opt)
         noexcept(is_nothrow_move_constructible_v<value_type>)
     {
         this->__construct_from(_VSTD::move(__opt));
@@ -526,7 +530,7 @@
     __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
 
     _LIBCPP_INLINE_VISIBILITY
-    __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
     {
         this->__assign_from(__opt);
         return *this;
@@ -561,7 +565,7 @@
     __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
 
     _LIBCPP_INLINE_VISIBILITY
-    __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
         noexcept(is_nothrow_move_assignable_v<value_type> &&
                  is_nothrow_move_constructible_v<value_type>)
     {
@@ -728,7 +732,7 @@
         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    optional(const optional<_Up>& __v)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(const optional<_Up>& __v)
     {
         this->__construct_from(__v);
     }
@@ -736,7 +740,7 @@
         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    explicit optional(const optional<_Up>& __v)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(const optional<_Up>& __v)
     {
         this->__construct_from(__v);
     }
@@ -746,7 +750,7 @@
         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    optional(optional<_Up>&& __v)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional(optional<_Up>&& __v)
     {
         this->__construct_from(_VSTD::move(__v));
     }
@@ -754,13 +758,13 @@
         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    explicit optional(optional<_Up>&& __v)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(optional<_Up>&& __v)
     {
         this->__construct_from(_VSTD::move(__v));
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    optional& operator=(nullopt_t) noexcept
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional& operator=(nullopt_t) noexcept
     {
         reset();
         return *this;
@@ -783,7 +787,7 @@
                       >::value>
              >
     _LIBCPP_INLINE_VISIBILITY
-    optional&
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
     operator=(_Up&& __v)
     {
         if (this->has_value())
@@ -798,7 +802,7 @@
         _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    optional&
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
     operator=(const optional<_Up>& __v)
     {
         this->__assign_from(__v);
@@ -810,7 +814,7 @@
         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
     , int> = 0>
     _LIBCPP_INLINE_VISIBILITY
-    optional&
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
     operator=(optional<_Up>&& __v)
     {
         this->__assign_from(_VSTD::move(__v));
@@ -824,7 +828,7 @@
                       >
              >
     _LIBCPP_INLINE_VISIBILITY
-    _Tp &
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
     emplace(_Args&&... __args)
     {
         reset();
@@ -839,7 +843,7 @@
                       >
              >
     _LIBCPP_INLINE_VISIBILITY
-    _Tp &
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
     emplace(initializer_list<_Up> __il, _Args&&... __args)
     {
         reset();
@@ -848,7 +852,7 @@
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    void swap(optional& __opt)
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(optional& __opt)
         noexcept(is_nothrow_move_constructible_v<value_type> &&
                  is_nothrow_swappable_v<value_type>)
     {
@@ -1006,7 +1010,7 @@
 private:
     template <class _Up>
     _LIBCPP_INLINE_VISIBILITY
-    static _Up*
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17 _Up*
     __operator_arrow(true_type, _Up& __x)
     {
         return _VSTD::addressof(__x);
@@ -1367,7 +1371,7 @@
 
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _EnableIf<
     is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
     void