Index: include/optional =================================================================== --- include/optional +++ include/optional @@ -439,46 +439,122 @@ } }; -template ::value> -struct __optional_storage; - -template -struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp> +template ::value> +struct __optional_copy_base : __optional_storage_base<_Tp> { using __optional_storage_base<_Tp>::__optional_storage_base; }; template -struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp> +struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> { - using value_type = _Tp; using __optional_storage_base<_Tp>::__optional_storage_base; _LIBCPP_INLINE_VISIBILITY - __optional_storage() = default; + __optional_copy_base() = default; _LIBCPP_INLINE_VISIBILITY - __optional_storage(const __optional_storage& __opt) + __optional_copy_base(const __optional_copy_base& __opt) { this->__construct_from(__opt); } _LIBCPP_INLINE_VISIBILITY - __optional_storage(__optional_storage&& __opt) + __optional_copy_base(__optional_copy_base&&) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base& operator=(const __optional_copy_base&) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_copy_base& operator=(__optional_copy_base&&) = default; +}; + +template ::value> +struct __optional_move_base : __optional_copy_base<_Tp> +{ + using __optional_copy_base<_Tp>::__optional_copy_base; +}; + +template +struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> +{ + using value_type = _Tp; + using __optional_copy_base<_Tp>::__optional_copy_base; + + _LIBCPP_INLINE_VISIBILITY + __optional_move_base() = default; + _LIBCPP_INLINE_VISIBILITY + __optional_move_base(const __optional_move_base&) = default; + + _LIBCPP_INLINE_VISIBILITY + __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v) { this->__construct_from(_VSTD::move(__opt)); } _LIBCPP_INLINE_VISIBILITY - __optional_storage& operator=(const __optional_storage& __opt) + __optional_move_base& operator=(const __optional_move_base&) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_move_base& operator=(__optional_move_base&&) = default; +}; + +template ::value && + is_trivially_copy_constructible<_Tp>::value && + is_trivially_copy_assignable<_Tp>::value> +struct __optional_copy_assign_base : __optional_move_base<_Tp> +{ + using __optional_move_base<_Tp>::__optional_move_base; +}; + +template +struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> +{ + using __optional_move_base<_Tp>::__optional_move_base; + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_assign_base() = default; + _LIBCPP_INLINE_VISIBILITY + __optional_copy_assign_base(const __optional_copy_assign_base&) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_copy_assign_base(__optional_copy_assign_base&&) = default; + + _LIBCPP_INLINE_VISIBILITY + __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt) { this->__assign_from(__opt); return *this; } _LIBCPP_INLINE_VISIBILITY - __optional_storage& operator=(__optional_storage&& __opt) + __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; +}; + +template ::value && + is_trivially_move_constructible<_Tp>::value && + is_trivially_move_assignable<_Tp>::value> +struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> +{ + using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; +}; + +template +struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> +{ + using value_type = _Tp; + using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; + + _LIBCPP_INLINE_VISIBILITY + __optional_move_assign_base() = default; + _LIBCPP_INLINE_VISIBILITY + __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_move_assign_base(__optional_move_assign_base&&) = default; + _LIBCPP_INLINE_VISIBILITY + __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; + + _LIBCPP_INLINE_VISIBILITY + __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt) noexcept(is_nothrow_move_assignable_v && is_nothrow_move_constructible_v) { @@ -501,11 +577,11 @@ template class optional - : private __optional_storage<_Tp> + : private __optional_move_assign_base<_Tp> , private __optional_sfinae_ctor_base_t<_Tp> , private __optional_sfinae_assign_base_t<_Tp> { - using __base = __optional_storage<_Tp>; + using __base = __optional_move_assign_base<_Tp>; public: using value_type = _Tp; Index: test/libcxx/utilities/optional/optional.object/special_member_gen.pass.cpp =================================================================== --- test/libcxx/utilities/optional/optional.object/special_member_gen.pass.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 -// - - -#include -#include -#include - -#include "archetypes.hpp" - -template -struct SpecialMemberTest { - using O = std::optional; - - template