@@ -225,6 +225,7 @@ namespace std {
225
225
# include < __type_traits/is_convertible.h>
226
226
# include < __type_traits/is_core_convertible.h>
227
227
# include < __type_traits/is_destructible.h>
228
+ # include < __type_traits/is_function.h>
228
229
# include < __type_traits/is_nothrow_assignable.h>
229
230
# include < __type_traits/is_nothrow_constructible.h>
230
231
# include < __type_traits/is_object.h>
@@ -237,6 +238,7 @@ namespace std {
237
238
# include < __type_traits/is_trivially_constructible.h>
238
239
# include < __type_traits/is_trivially_destructible.h>
239
240
# include < __type_traits/is_trivially_relocatable.h>
241
+ # include < __type_traits/is_unbounded_array.h>
240
242
# include < __type_traits/negation.h>
241
243
# include < __type_traits/remove_const.h>
242
244
# include < __type_traits/remove_cv.h>
@@ -605,28 +607,46 @@ struct __is_std_optional : false_type {};
605
607
template <class _Tp >
606
608
struct __is_std_optional <optional<_Tp>> : true_type {};
607
609
608
- template <class _Tp >
609
- class _LIBCPP_DECLSPEC_EMPTY_BASES optional
610
- : private __optional_move_assign_base<_Tp>,
611
- private __optional_sfinae_ctor_base_t <_Tp>,
612
- private __optional_sfinae_assign_base_t <_Tp> {
613
- using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
610
+ template <class _Tp , class = void >
611
+ struct __optional_iterator_aliases {};
614
612
613
+ // disallow T (&)() and T (&)[]
614
+ template <class _Tp >
615
+ struct __optional_iterator_aliases <
616
+ _Tp,
617
+ __enable_if_t <!(is_reference<_Tp>::value && (is_function<__libcpp_remove_reference_t <_Tp>>::value ||
618
+ is_unbounded_array<__libcpp_remove_reference_t <_Tp>>::value))> > {
619
+ private:
615
620
using __pointer _LIBCPP_NODEBUG = std::add_pointer_t <_Tp>;
616
621
using __const_pointer _LIBCPP_NODEBUG = std::add_pointer_t <const _Tp>;
617
622
618
623
public:
619
- using value_type = _Tp;
620
624
# if _LIBCPP_STD_VER >= 26
621
625
# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
622
- using iterator = __bounded_iter<__wrap_iter<__pointer>>;
623
- using const_iterator = __bounded_iter<__wrap_iter<__const_pointer>>;
626
+ using __iterator _LIBCPP_NODEBUG = __bounded_iter<__wrap_iter<__pointer>>;
627
+ using __const_iterator _LIBCPP_NODEBUG = __bounded_iter<__wrap_iter<__const_pointer>>;
624
628
# else
625
- using iterator = __wrap_iter<__pointer>;
626
- using const_iterator = __wrap_iter<__const_pointer>;
629
+ using __iterator _LIBCPP_NODEBUG = __wrap_iter<__pointer>;
630
+ using __const_iterator _LIBCPP_NODEBUG = __wrap_iter<__const_pointer>;
627
631
# endif
628
632
# endif
633
+ };
634
+
635
+ template <class _Tp >
636
+ class _LIBCPP_DECLSPEC_EMPTY_BASES optional
637
+ : private __optional_move_assign_base<_Tp>,
638
+ private __optional_sfinae_ctor_base_t <_Tp>,
639
+ private __optional_sfinae_assign_base_t <_Tp>,
640
+ public __optional_iterator_aliases<_Tp> {
641
+ using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
629
642
643
+ public:
644
+ using value_type = _Tp;
645
+
646
+ # if _LIBCPP_STD_VER >= 26
647
+ using iterator = __optional_iterator_aliases<_Tp>::__iterator;
648
+ using const_iterator = __optional_iterator_aliases<_Tp>::__const_iterator;
649
+ # endif
630
650
using __trivially_relocatable _LIBCPP_NODEBUG =
631
651
conditional_t <__libcpp_is_trivially_relocatable<_Tp>::value, optional, void >;
632
652
using __replaceable _LIBCPP_NODEBUG = conditional_t <__is_replaceable_v<_Tp>, optional, void >;
0 commit comments