@@ -604,69 +604,20 @@ private:
604604 static_assert (!is_array_v<value_type>, " instantiation of optional with an array type is ill-formed" );
605605
606606 // LWG2756: conditionally explicit conversion from _Up
607- struct _CheckOptionalArgsConstructor {
608- template <class _Up >
609- _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit () {
610- return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>;
611- }
612607
613- template <class _Up >
614- _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit () {
615- return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>;
616- }
617- };
618- template <class _Up >
619- using _CheckOptionalArgsCtor _LIBCPP_NODEBUG =
620- _If< _IsNotSame<__remove_cvref_t <_Up>, in_place_t >::value && _IsNotSame<__remove_cvref_t <_Up>, optional>::value &&
621- (!is_same_v<remove_cv_t <_Tp>, bool > || !__is_std_optional<__remove_cvref_t <_Up>>::value),
622- _CheckOptionalArgsConstructor,
623- __check_tuple_constructor_fail >;
624- template <class _QualUp >
625- struct _CheckOptionalLikeConstructor {
626- template <class _Up , class _Opt = optional<_Up>>
627- using __check_constructible_from_opt _LIBCPP_NODEBUG =
628- _Or< is_constructible<_Tp, _Opt&>,
629- is_constructible<_Tp, _Opt const &>,
630- is_constructible<_Tp, _Opt&&>,
631- is_constructible<_Tp, _Opt const &&>,
632- is_convertible<_Opt&, _Tp>,
633- is_convertible<_Opt const &, _Tp>,
634- is_convertible<_Opt&&, _Tp>,
635- is_convertible<_Opt const &&, _Tp> >;
636- template <class _Up , class _Opt = optional<_Up>>
637- using __check_assignable_from_opt _LIBCPP_NODEBUG =
638- _Or< is_assignable<_Tp&, _Opt&>,
639- is_assignable<_Tp&, _Opt const &>,
640- is_assignable<_Tp&, _Opt&&>,
641- is_assignable<_Tp&, _Opt const &&> >;
642- template <class _Up , class _QUp = _QualUp>
643- _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit () {
644- return is_convertible<_QUp, _Tp>::value &&
645- (is_same_v<remove_cv_t <_Tp>, bool > || !__check_constructible_from_opt<_Up>::value);
646- }
647- template <class _Up , class _QUp = _QualUp>
648- _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit () {
649- return !is_convertible<_QUp, _Tp>::value &&
650- (is_same_v<remove_cv_t <_Tp>, bool > || !__check_constructible_from_opt<_Up>::value);
651- }
652- template <class _Up , class _QUp = _QualUp>
653- _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign () {
654- // Construction and assignability of _QUp to _Tp has already been
655- // checked.
656- return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value;
657- }
658- };
608+ template <class _Up , class _Opt = optional<_Up>>
609+ using __check_constructible_from_opt _LIBCPP_NODEBUG =
610+ _Or<is_constructible<_Tp, _Opt&>,
611+ is_constructible<_Tp, _Opt const &>,
612+ is_constructible<_Tp, _Opt&&>,
613+ is_constructible<_Tp, _Opt const &&>>;
659614
660- template <class _Up , class _QualUp >
661- using _CheckOptionalLikeCtor _LIBCPP_NODEBUG =
662- _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value,
663- _CheckOptionalLikeConstructor<_QualUp>,
664- __check_tuple_constructor_fail >;
665- template <class _Up , class _QualUp >
666- using _CheckOptionalLikeAssign _LIBCPP_NODEBUG =
667- _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value,
668- _CheckOptionalLikeConstructor<_QualUp>,
669- __check_tuple_constructor_fail >;
615+ template <class _Up , class _Opt = optional<_Up>>
616+ using __check_assignable_from_opt _LIBCPP_NODEBUG =
617+ _Or<is_assignable<_Tp&, _Opt&>,
618+ is_assignable<_Tp&, _Opt const &>,
619+ is_assignable<_Tp&, _Opt&&>,
620+ is_assignable<_Tp&, _Opt const &&>>;
670621
671622public:
672623 _LIBCPP_HIDE_FROM_ABI constexpr optional () noexcept {}
@@ -686,30 +637,34 @@ public:
686637 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional (in_place_t , initializer_list<_Up> __il, _Args&&... __args)
687638 : __base(in_place, __il, std::forward<_Args>(__args)...) {}
688639
689- template <class _Up = value_type,
690- enable_if_t <_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int > = 0 >
691- _LIBCPP_HIDE_FROM_ABI constexpr optional (_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
692-
693- template <class _Up , enable_if_t <_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int > = 0 >
694- _LIBCPP_HIDE_FROM_ABI constexpr explicit optional (_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
640+ template <class _Up ,
641+ class _DependentU = enable_if_t <
642+ !is_same_v<__remove_cvref_t <_Up>, in_place_t > && !is_same_v<__remove_cvref_t <_Up>, optional> &&
643+ (!is_same_v<remove_cv_t <_Tp>, bool > || !__is_std_optional<__remove_cvref_t <_Up>>::value),
644+ _Up>,
645+ enable_if_t <is_constructible_v<_Tp, _DependentU>, int > = 0 >
646+ _LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_Up&&, _Tp>) optional(_Up&& __v)
647+ : __base(in_place, std::forward<_Up>(__v)) {}
695648
696649 // LWG2756: conditionally explicit conversion from const optional<_Up>&
697- template <class _Up , enable_if_t <_CheckOptionalLikeCtor<_Up, _Up const &>::template __enable_implicit<_Up>(), int > = 0 >
698- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional (const optional<_Up>& __v) {
699- this ->__construct_from (__v);
700- }
701- template <class _Up , enable_if_t <_CheckOptionalLikeCtor<_Up, _Up const &>::template __enable_explicit<_Up>(), int > = 0 >
702- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional (const optional<_Up>& __v) {
650+ template <class _Up ,
651+ class _DependentU = enable_if_t <!is_same_v<_Up, _Tp>, _Up>,
652+ enable_if_t <is_constructible_v<_Tp, const _DependentU&> &&
653+ (is_same_v<remove_cv_t <_Tp>, bool > || !__check_constructible_from_opt<_DependentU>::value),
654+ int > = 0 >
655+ _LIBCPP_HIDE_FROM_ABI
656+ _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit (!is_convertible_v<const _Up&, _Tp>) optional(const optional<_Up>& __v) {
703657 this ->__construct_from (__v);
704658 }
705659
706660 // LWG2756: conditionally explicit conversion from optional<_Up>&&
707- template <class _Up , enable_if_t <_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int > = 0 >
708- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional (optional<_Up>&& __v) {
709- this ->__construct_from (std::move (__v));
710- }
711- template <class _Up , enable_if_t <_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int > = 0 >
712- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional (optional<_Up>&& __v) {
661+ template <class _Up ,
662+ class _DependentU = enable_if_t <!is_same_v<_Up, _Tp>, _Up>,
663+ enable_if_t <is_constructible_v<_Tp, _DependentU&&> &&
664+ (is_same_v<remove_cv_t <_Tp>, bool > || !__check_constructible_from_opt<_DependentU>::value),
665+ int > = 0 >
666+ _LIBCPP_HIDE_FROM_ABI
667+ _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit (!is_convertible_v<_Up&&, _Tp>) optional(optional<_Up>&& __v) {
713668 this ->__construct_from (std::move (__v));
714669 }
715670
@@ -746,14 +701,22 @@ public:
746701 }
747702
748703 // LWG2756
749- template <class _Up , enable_if_t <_CheckOptionalLikeAssign<_Up, _Up const &>::template __enable_assign<_Up>(), int > = 0 >
704+ template <class _Up ,
705+ class _DependentU = enable_if_t <!is_same_v<_Tp, _Up>, _Up>,
706+ enable_if_t <is_constructible_v<_Tp, const _DependentU&> && is_assignable_v<_Tp&, const _DependentU&> &&
707+ !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value,
708+ int > = 0 >
750709 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator =(const optional<_Up>& __v) {
751710 this ->__assign_from (__v);
752711 return *this ;
753712 }
754713
755714 // LWG2756
756- template <class _Up , enable_if_t <_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int > = 0 >
715+ template <class _Up ,
716+ class _DependentU = enable_if_t <!is_same_v<_Tp, _Up>, _Up>,
717+ enable_if_t <is_constructible_v<_Tp, _DependentU&&> && is_assignable_v<_Tp&, _DependentU&&> &&
718+ !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value,
719+ int > = 0 >
757720 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator =(optional<_Up>&& __v) {
758721 this ->__assign_from (std::move (__v));
759722 return *this ;
0 commit comments