Remove some more code duplication in std::optional
authorJonathan Wakely <jwakely@redhat.com>
Wed, 9 Jan 2019 10:40:49 +0000 (10:40 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 9 Jan 2019 10:40:49 +0000 (10:40 +0000)
Hoist the duplicated code from the _Optional_payload partial
specializations into the _Optional_payload_base base class.

* include/std/optional (_Optional_payload_base::_M_copy_assign): New
member function to perform non-trivial assignment.
(_Optional_payload_base::_M_move_assign): Likewise.
(_Optional_payload<T, true, false, true>::operator=)
(_Optional_payload<T, true, true, false>::operator=)
(_Optional_payload<T, true, false, false>::operator=): Call
_M_copy_assign and/or _M_move_assign to do non-trivial assignments.

From-SVN: r267761

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/optional

index 870fce269e66e25d95e27ae34e0301d8e3049c74..d0f060d79555f1ddd4f744a56414637a1987685f 100644 (file)
@@ -1,5 +1,13 @@
 2019-01-09  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/std/optional (_Optional_payload_base::_M_copy_assign): New
+       member function to perform non-trivial assignment.
+       (_Optional_payload_base::_M_move_assign): Likewise.
+       (_Optional_payload<T, true, false, true>::operator=)
+       (_Optional_payload<T, true, true, false>::operator=)
+       (_Optional_payload<T, true, false, false>::operator=): Call
+       _M_copy_assign and/or _M_move_assign to do non-trivial assignments.
+
        PR libstdc++/88204
        * testsuite/26_numerics/complex/operators/more_constexpr.cc: Do not
        test std::complex<long double> if long double format is IBM128.
index b06e30fbd6721aab2cfd6f7bddb358f05232cda2..c5e66bdd140c430f836f8a32e127d491edc03f75 100644 (file)
@@ -157,6 +157,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Optional_payload_base&
       operator=(_Optional_payload_base&&) = default;
 
+      // used to perform non-trivial copy assignment.
+      constexpr void
+      _M_copy_assign(const _Optional_payload_base& __other)
+      {
+        if (this->_M_engaged && __other._M_engaged)
+          this->_M_get() = __other._M_get();
+        else
+         {
+           if (__other._M_engaged)
+             this->_M_construct(__other._M_get());
+           else
+             this->_M_reset();
+         }
+      }
+
+      // used to perform non-trivial move assignment.
+      constexpr void
+      _M_move_assign(_Optional_payload_base&& __other)
+      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
+                      is_nothrow_move_assignable<_Tp>>)
+      {
+       if (this->_M_engaged && __other._M_engaged)
+         this->_M_get() = std::move(__other._M_get());
+       else
+         {
+           if (__other._M_engaged)
+             this->_M_construct(std::move(__other._M_get()));
+           else
+             this->_M_reset();
+         }
+      }
+
       struct _Empty_byte { };
 
       template<typename _Up, bool = is_trivially_destructible_v<_Up>>
@@ -286,15 +318,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Optional_payload&
       operator=(const _Optional_payload& __other)
       {
-        if (this->_M_engaged && __other._M_engaged)
-          this->_M_get() = __other._M_get();
-        else
-         {
-           if (__other._M_engaged)
-             this->_M_construct(__other._M_get());
-           else
-             this->_M_reset();
-         }
+       this->_M_copy_assign(__other);
        return *this;
       }
     };
@@ -319,15 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
                       is_nothrow_move_assignable<_Tp>>)
       {
-       if (this->_M_engaged && __other._M_engaged)
-         this->_M_get() = std::move(__other._M_get());
-       else
-         {
-           if (__other._M_engaged)
-             this->_M_construct(std::move(__other._M_get()));
-           else
-             this->_M_reset();
-         }
+       this->_M_move_assign(std::move(__other));
        return *this;
       }
     };
@@ -344,20 +360,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Optional_payload(const _Optional_payload&) = default;
       _Optional_payload(_Optional_payload&&) = default;
 
-      // Non-trivial copy
+      // Non-trivial copy assignment.
       constexpr
       _Optional_payload&
       operator=(const _Optional_payload& __other)
       {
-        if (this->_M_engaged && __other._M_engaged)
-          this->_M_get() = __other._M_get();
-        else
-         {
-           if (__other._M_engaged)
-             this->_M_construct(__other._M_get());
-           else
-             this->_M_reset();
-         }
+       this->_M_copy_assign(__other);
        return *this;
       }
 
@@ -368,15 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
                       is_nothrow_move_assignable<_Tp>>)
       {
-       if (this->_M_engaged && __other._M_engaged)
-         this->_M_get() = std::move(__other._M_get());
-       else
-         {
-           if (__other._M_engaged)
-             this->_M_construct(std::move(__other._M_get()));
-           else
-             this->_M_reset();
-         }
+       this->_M_move_assign(std::move(__other));
        return *this;
       }
     };