From 0d4e223ab58974361ea4dfbad82f2109cd5da664 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 17 Mar 2023 12:21:27 -0700 Subject: [PATCH] update libcxx to LLVM 16.0.0-rc4 --- .../__algorithm/ranges_binary_search.h | 4 +- lib/libcxx/include/__config | 29 +- lib/libcxx/include/__format/concepts.h | 5 +- .../include/__format/format_functions.h | 8 +- .../__format/formatter_floating_point.h | 3 +- lib/libcxx/include/__functional/function.h | 38 +- lib/libcxx/include/__functional/hash.h | 4 + lib/libcxx/include/__memory/construct_at.h | 10 + lib/libcxx/include/__memory/shared_ptr.h | 218 ++++++--- .../__memory/uninitialized_algorithms.h | 26 +- lib/libcxx/include/__ranges/elements_view.h | 118 +++-- lib/libcxx/include/__ranges/filter_view.h | 50 +- lib/libcxx/include/__ranges/iota_view.h | 432 +++++++++--------- lib/libcxx/include/__ranges/istream_view.h | 26 +- lib/libcxx/include/__ranges/join_view.h | 96 ++-- lib/libcxx/include/__ranges/split_view.h | 52 +-- lib/libcxx/include/__ranges/take_while_view.h | 30 +- lib/libcxx/include/__ranges/transform_view.h | 127 +++-- .../include/__type_traits/add_pointer.h | 4 +- .../include/__type_traits/remove_pointer.h | 4 +- lib/libcxx/include/any | 10 +- lib/libcxx/include/version | 2 + 22 files changed, 644 insertions(+), 652 deletions(-) diff --git a/lib/libcxx/include/__algorithm/ranges_binary_search.h b/lib/libcxx/include/__algorithm/ranges_binary_search.h index b2a8977652..d72d4e0574 100644 --- a/lib/libcxx/include/__algorithm/ranges_binary_search.h +++ b/lib/libcxx/include/__algorithm/ranges_binary_search.h @@ -36,7 +36,7 @@ struct __fn { _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); - return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } template (__first, __last, __value, __comp, __proj); - return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } }; } // namespace __binary_search diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config index a880738b53..83dbdccc4e 100644 --- a/lib/libcxx/include/__config +++ b/lib/libcxx/include/__config @@ -134,6 +134,15 @@ # define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON // According to the Standard, `bitset::operator[] const` returns bool # define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL +// Fix the implementation of CityHash used for std::hash. +// This is an ABI break because `std::hash` will return a different result, +// which means that hashing the same object in translation units built against +// different versions of libc++ can return inconsistent results. This is especially +// tricky since std::hash is used in the implementation of unordered containers. +// +// The incorrect implementation of CityHash has the problem that it drops some +// bits on the floor. +# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION // Remove the base 10 implementation of std::to_chars from the dylib. // The implementation moved to the header, but we still export the symbols from // the dylib for backwards compatibility. @@ -895,7 +904,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // Try to find out if RTTI is disabled. # if !defined(__cpp_rtti) || __cpp_rtti < 199711L -# define _LIBCPP_NO_RTTI +# define _LIBCPP_HAS_NO_RTTI # endif # ifndef _LIBCPP_WEAK @@ -1227,12 +1236,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // functions are declared by the C library. # define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 // GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if -// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately, -// determining the latter depends on internal GNU libc details. If the -// __cpp_char8_t feature test macro is not defined, then a char8_t typedef -// will be declared as well. -# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE) -# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X)) +// __cpp_char8_t is defined or if C2X extensions are enabled. Determining +// the latter depends on internal GNU libc details that are not appropriate +// to depend on here, so any declarations present when __cpp_char8_t is not +// defined are ignored. +# if defined(_LIBCPP_GLIBC_PREREQ) +# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t) # undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 # endif # endif @@ -1250,6 +1259,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") #endif +// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use +// compiler intrinsics in the Objective-C++ mode. +# ifdef __OBJC__ +# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS +# endif + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/lib/libcxx/include/__format/concepts.h b/lib/libcxx/include/__format/concepts.h index fe4a7b9625..ba8d8e3162 100644 --- a/lib/libcxx/include/__format/concepts.h +++ b/lib/libcxx/include/__format/concepts.h @@ -66,9 +66,8 @@ concept formattable = __formattable<_Tp, _CharT>; // TODO FMT Add a test to validate we fail when using that concept after P2165 // has been implemented. template -concept __fmt_pair_like = __is_specialization_v<_Tp, pair> || - // Use a requires since tuple_size_v may fail to instantiate, - (__is_specialization_v<_Tp, tuple> && requires { tuple_size_v<_Tp> == 2; }); +concept __fmt_pair_like = + __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); # endif //_LIBCPP_STD_VER > 20 #endif //_LIBCPP_STD_VER > 17 diff --git a/lib/libcxx/include/__format/format_functions.h b/lib/libcxx/include/__format/format_functions.h index 185148ccba..0f0001272d 100644 --- a/lib/libcxx/include/__format/format_functions.h +++ b/lib/libcxx/include/__format/format_functions.h @@ -258,10 +258,12 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { __arg_t __type = __ctx.arg(__r.__value); - if (__type == __arg_t::__handle) + if (__type == __arg_t::__none) + std::__throw_format_error("Argument index out of bounds"); + else if (__type == __arg_t::__handle) __ctx.__handle(__r.__value).__parse(__parse_ctx); - else - __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); + else if (__parse) + __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); } else _VSTD::__visit_format_arg( [&](auto __arg) { diff --git a/lib/libcxx/include/__format/formatter_floating_point.h b/lib/libcxx/include/__format/formatter_floating_point.h index a544b53f7e..ca065723e1 100644 --- a/lib/libcxx/include/__format/formatter_floating_point.h +++ b/lib/libcxx/include/__format/formatter_floating_point.h @@ -404,7 +404,6 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ // In fixed mode the algorithm truncates trailing spaces and possibly the // radix point. There's no good guess for the position of the radix point // therefore scan the output after the first digit. - __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); } } @@ -665,7 +664,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif if (__result.__exponent == __result.__last) // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X. // By including the radix point it calculates P - (1 + X) - __p -= __result.__radix_point - __buffer.begin(); + __p -= __result.__radix_point - __result.__integral; else // otherwise, the conversion is with style e or E and precision P - 1. --__p; diff --git a/lib/libcxx/include/__functional/function.h b/lib/libcxx/include/__functional/function.h index ca79d334a0..9f92f61814 100644 --- a/lib/libcxx/include/__functional/function.h +++ b/lib/libcxx/include/__functional/function.h @@ -268,10 +268,10 @@ public: virtual void destroy() _NOEXCEPT = 0; virtual void destroy_deallocate() _NOEXCEPT = 0; virtual _Rp operator()(_ArgTypes&& ...) = 0; -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT = 0; virtual const std::type_info& target_type() const _NOEXCEPT = 0; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; // __func implements __base for a given functor type. @@ -305,10 +305,10 @@ public: virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; virtual _Rp operator()(_ArgTypes&&... __arg); -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT; virtual const std::type_info& target_type() const _NOEXCEPT; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; template @@ -356,7 +356,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template const void* @@ -374,7 +374,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT return typeid(_Fp); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI // __value_func creates a value-type from a __func. @@ -553,7 +553,7 @@ template class __value_func<_Rp(_ArgTypes...)> _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { @@ -569,7 +569,7 @@ template class __value_func<_Rp(_ArgTypes...)> return nullptr; return (const _Tp*)__f_->target(typeid(_Tp)); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; // Storage for a functor object, to be used with __policy to manage copy and @@ -616,7 +616,7 @@ struct __policy { static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, true, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(void) #else nullptr @@ -642,7 +642,7 @@ struct __policy __choose_policy(/* is_small = */ false_type) { static const _LIBCPP_CONSTEXPR __policy __policy_ = { &__large_clone<_Fun>, &__large_destroy<_Fun>, false, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr @@ -657,7 +657,7 @@ struct __policy { static const _LIBCPP_CONSTEXPR __policy __policy_ = { nullptr, nullptr, false, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr @@ -861,7 +861,7 @@ template class __policy_func<_Rp(_ArgTypes...)> return !__policy_->__is_null; } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { @@ -878,7 +878,7 @@ template class __policy_func<_Rp(_ArgTypes...)> else return reinterpret_cast(&__buf_.__small); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) @@ -945,7 +945,7 @@ public: return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(type_info const& __ti) const _NOEXCEPT { if (__ti == typeid(__func::__block_type)) return &__f_; @@ -955,7 +955,7 @@ public: virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; #endif // _LIBCPP_HAS_EXTENSION_BLOCKS @@ -1056,12 +1056,12 @@ public: // function invocation: _Rp operator()(_ArgTypes...) const; -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI // function target access: const std::type_info& target_type() const _NOEXCEPT; template _Tp* target() _NOEXCEPT; template const _Tp* target() const _NOEXCEPT; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; #if _LIBCPP_STD_VER >= 17 @@ -1156,7 +1156,7 @@ function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template const std::type_info& @@ -1181,7 +1181,7 @@ function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT return __f_.template target<_Tp>(); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI template inline _LIBCPP_INLINE_VISIBILITY diff --git a/lib/libcxx/include/__functional/hash.h b/lib/libcxx/include/__functional/hash.h index dfd8ea2553..39382aa9bf 100644 --- a/lib/libcxx/include/__functional/hash.h +++ b/lib/libcxx/include/__functional/hash.h @@ -140,7 +140,11 @@ struct __murmur2_or_cityhash<_Size, 64> if (__len >= 4) { const uint32_t __a = std::__loadword(__s); const uint32_t __b = std::__loadword(__s + __len - 4); +#ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b); +#else + return __hash_len_16(__len + (__a << 3), __b); +#endif } if (__len > 0) { const unsigned char __a = static_cast(__s[0]); diff --git a/lib/libcxx/include/__memory/construct_at.h b/lib/libcxx/include/__memory/construct_at.h index ffee0022c2..14484dd6aa 100644 --- a/lib/libcxx/include/__memory/construct_at.h +++ b/lib/libcxx/include/__memory/construct_at.h @@ -83,6 +83,16 @@ _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) { return __first; } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last) { + while (__last != __first) { + --__last; + std::__destroy_at(std::addressof(*__last)); + } + return __last; +} + #if _LIBCPP_STD_VER > 14 template , int> = 0> diff --git a/lib/libcxx/include/__memory/shared_ptr.h b/lib/libcxx/include/__memory/shared_ptr.h index b77ce9230b..f0ffa26abf 100644 --- a/lib/libcxx/include/__memory/shared_ptr.h +++ b/lib/libcxx/include/__memory/shared_ptr.h @@ -219,7 +219,7 @@ public: __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a) : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {} -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI const void* __get_deleter(const type_info&) const _NOEXCEPT override; #endif @@ -228,7 +228,7 @@ private: void __on_zero_shared_weak() _NOEXCEPT override; }; -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template const void* @@ -237,7 +237,7 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) cons return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr; } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI template void @@ -260,7 +260,10 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT __a.deallocate(_PTraits::pointer_to(*this), 1); } -struct __default_initialize_tag {}; +// This tag is used to instantiate an allocator type. The various shared_ptr control blocks +// detect that the allocator has been instantiated for this type and perform alternative +// initialization/destruction based on that. +struct __for_overwrite_tag {}; template struct __shared_ptr_emplace @@ -271,25 +274,20 @@ struct __shared_ptr_emplace explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args) : __storage_(_VSTD::move(__a)) { -#if _LIBCPP_STD_VER > 17 - using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; - _TpAlloc __tmp(*__get_alloc()); - allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...); +#if _LIBCPP_STD_VER >= 20 + if constexpr (is_same_v) { + static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite"); + ::new ((void*)__get_elem()) _Tp; + } else { + using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; + _TpAlloc __tmp(*__get_alloc()); + allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...); + } #else ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...); #endif } - -#if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - explicit __shared_ptr_emplace(__default_initialize_tag, _Alloc __a) - : __storage_(std::move(__a)) - { - ::new ((void*)__get_elem()) _Tp; - } -#endif - _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); } @@ -299,9 +297,13 @@ struct __shared_ptr_emplace private: void __on_zero_shared() _NOEXCEPT override { #if _LIBCPP_STD_VER > 17 - using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; - _TpAlloc __tmp(*__get_alloc()); - allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); + if constexpr (is_same_v) { + __get_elem()->~_Tp(); + } else { + using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; + _TpAlloc __tmp(*__get_alloc()); + allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); + } #else __get_elem()->~_Tp(); #endif @@ -367,13 +369,57 @@ public: template class _LIBCPP_TEMPLATE_VIS enable_shared_from_this; -template +// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6 +// A pointer type Y* is said to be compatible with a pointer type T* +// when either Y* is convertible to T* or Y is U[N] and T is cv U[]. +#if _LIBCPP_STD_VER >= 17 +template +struct __bounded_convertible_to_unbounded : false_type {}; + +template +struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp> + : is_same<__remove_cv_t<_Tp>, _Up[]> {}; + +template struct __compatible_with -#if _LIBCPP_STD_VER > 14 - : is_convertible*, remove_extent_t<_Up>*> {}; + : _Or< + is_convertible<_Yp*, _Tp*>, + __bounded_convertible_to_unbounded<_Yp, _Tp> + > {}; #else - : is_convertible<_Tp*, _Up*> {}; -#endif // _LIBCPP_STD_VER > 14 +template +struct __compatible_with + : is_convertible<_Yp*, _Tp*> {}; +#endif // _LIBCPP_STD_VER >= 17 + +// Constructors that take raw pointers have a different set of "compatible" constraints +// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1 +// - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*, +// or T is U[] and Y(*)[] is convertible to T*. +// - If T is not an array type, then Y* is convertible to T*. +#if _LIBCPP_STD_VER >= 17 +template +struct __raw_pointer_compatible_with : _And< + _Not>, + is_convertible<_Yp*, _Tp*> + > {}; + +template +struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t< + is_convertible<_Yp(*)[_Np], _Up(*)[_Np]>::value> > + : true_type {}; + +template +struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t< + is_convertible<_Yp(*)[], _Up(*)[]>::value> > + : true_type {}; + +#else +template +struct __raw_pointer_compatible_with + : is_convertible<_Yp*, _Tp*> {}; +#endif // _LIBCPP_STD_VER >= 17 + template struct __is_deletable : false_type { }; @@ -395,12 +441,12 @@ static false_type __well_formed_deleter_test(...); template struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {}; -template +template struct __shared_ptr_deleter_ctor_reqs { - static const bool value = __compatible_with<_Tp, _Yp>::value && + static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value && is_move_constructible<_Dp>::value && - __well_formed_deleter<_Dp, _Tp*>::value; + __well_formed_deleter<_Dp, _Yp*>::value; }; #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) @@ -439,7 +485,7 @@ public: template + __raw_pointer_compatible_with<_Yp, _Tp> // In C++03 we get errors when trying to do SFINAE with the // delete operator, so we always pretend that it's deletable. // The same happens on GCC. @@ -457,7 +503,7 @@ public: __enable_weak_this(__p, __p); } - template::value> > + template::value> > _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) @@ -484,7 +530,7 @@ public: #endif // _LIBCPP_NO_EXCEPTIONS } - template::value> > + template::value> > _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) @@ -646,6 +692,7 @@ public: template ::value && + __compatible_with<_Yp, _Tp>::value && is_convertible::pointer, element_type*>::value > > _LIBCPP_HIDE_FROM_ABI @@ -668,6 +715,7 @@ public: template ::value && + __compatible_with<_Yp, _Tp>::value && is_convertible::pointer, element_type*>::value > > _LIBCPP_HIDE_FROM_ABI @@ -740,9 +788,10 @@ public: } #endif - template ::pointer, element_type*>::value - > > + template , + is_convertible::pointer, element_type*> + >::value> > _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r) { @@ -764,7 +813,7 @@ public: } template::value + __raw_pointer_compatible_with<_Yp, _Tp>::value > > _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p) @@ -773,8 +822,7 @@ public: } template::value - > > + __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> > _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d) { @@ -782,8 +830,7 @@ public: } template::value - > > + __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> > _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d, _Alloc __a) { @@ -858,7 +905,7 @@ public: } #endif -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template _LIBCPP_HIDE_FROM_ABI _Dp* __get_deleter() const _NOEXCEPT @@ -867,7 +914,7 @@ public: ? const_cast(__cntrl_->__get_deleter(typeid(_Dp))) : nullptr); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI template _LIBCPP_HIDE_FROM_ABI @@ -963,12 +1010,9 @@ template::value, int> = 0> _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { - using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; - using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; - __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); - ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__default_initialize_tag{}, __a); - auto __control_block = __guard.__release_ptr(); - return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block)); + using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; + _ForOverwriteAllocator __alloc(__a); + return std::allocate_shared<_Tp>(__alloc); } template::value, int> = 0> @@ -1000,26 +1044,25 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg) : __alloc_(__alloc), __count_(__count) { - std::__uninitialized_allocator_fill_n(__alloc_, std::begin(__data_), __count_, __arg); + std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg); } _LIBCPP_HIDE_FROM_ABI explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count) : __alloc_(__alloc), __count_(__count) { - std::__uninitialized_allocator_value_construct_n(__alloc_, std::begin(__data_), __count_); - } - #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, __default_initialize_tag) - : __alloc_(__alloc), __count_(__count) - { - // We are purposefully not using an allocator-aware default construction because the spec says so. - // There's currently no way of expressing default initialization in an allocator-aware manner anyway. - std::uninitialized_default_construct_n(std::begin(__data_), __count_); - } + if constexpr (is_same_v) { + // We are purposefully not using an allocator-aware default construction because the spec says so. + // There's currently no way of expressing default initialization in an allocator-aware manner anyway. + std::uninitialized_default_construct_n(std::begin(__data_), __count_); + } else { + std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_); + } +#else + std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_); #endif + } // Returns the number of bytes required to store a control block followed by the given number // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment. @@ -1042,8 +1085,17 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count private: void __on_zero_shared() _NOEXCEPT override { +#if _LIBCPP_STD_VER >= 20 + if constexpr (is_same_v) { + std::__reverse_destroy(__data_, __data_ + __count_); + } else { + __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); + std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_); + } +#else __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_); +#endif } void __on_zero_shared_weak() _NOEXCEPT override { @@ -1096,30 +1148,40 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc> _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) { - std::__uninitialized_allocator_fill_n(__alloc_, std::addressof(__data_[0]), _Count, __arg); + std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg); } _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) { - std::__uninitialized_allocator_value_construct_n(__alloc_, std::addressof(__data_[0]), _Count); - } - #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - explicit __bounded_array_control_block(_Alloc const& __alloc, __default_initialize_tag) : __alloc_(__alloc) { - // We are purposefully not using an allocator-aware default construction because the spec says so. - // There's currently no way of expressing default initialization in an allocator-aware manner anyway. - std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count); - } + if constexpr (is_same_v) { + // We are purposefully not using an allocator-aware default construction because the spec says so. + // There's currently no way of expressing default initialization in an allocator-aware manner anyway. + std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count); + } else { + std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count); + } +#else + std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count); #endif + } _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_ private: void __on_zero_shared() _NOEXCEPT override { +#if _LIBCPP_STD_VER >= 20 + if constexpr (is_same_v) { + std::__reverse_destroy(__data_, __data_ + _Count); + } else { + __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); + std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count); + } +#else __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count); +#endif } void __on_zero_shared_weak() _NOEXCEPT override { @@ -1175,7 +1237,9 @@ template::value, in _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { - return std::__allocate_shared_bounded_array<_Tp>(__a, __default_initialize_tag{}); + using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; + _ForOverwriteAllocator __alloc(__a); + return std::__allocate_shared_bounded_array<_Tp>(__alloc); } template::value>> @@ -1196,7 +1260,7 @@ template::value, int> = 0> _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { - return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __default_initialize_tag{}); + return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>()); } // unbounded array variants @@ -1218,7 +1282,9 @@ template::value, _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) { - return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __default_initialize_tag{}); + using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; + _ForOverwriteAllocator __alloc(__a); + return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n); } template::value>> @@ -1239,7 +1305,7 @@ template::value, int> = 0> _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) { - return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __default_initialize_tag{}); + return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n); } #endif // _LIBCPP_STD_VER > 17 @@ -1465,7 +1531,7 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT typename shared_ptr<_Tp>::element_type*>(__r.get())); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template inline _LIBCPP_INLINE_VISIBILITY @@ -1475,7 +1541,7 @@ get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT return __p.template __get_deleter<_Dp>(); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI template class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr diff --git a/lib/libcxx/include/__memory/uninitialized_algorithms.h b/lib/libcxx/include/__memory/uninitialized_algorithms.h index 63a45b2ac8..0067780c3f 100644 --- a/lib/libcxx/include/__memory/uninitialized_algorithms.h +++ b/lib/libcxx/include/__memory/uninitialized_algorithms.h @@ -410,7 +410,7 @@ constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter // This function assumes that the allocator is bound to the correct type. template _LIBCPP_HIDE_FROM_ABI -constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) { +constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc) { static_assert(is_same_v::value_type, _Tp>, "The allocator should already be rebound to the correct type"); @@ -426,7 +426,7 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) { }); for (; __i != extent_v<_Tp>; ++__i) { - std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i])); + std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i])); } __guard.__complete(); } else { @@ -446,13 +446,13 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) { // This function assumes that the allocator is bound to the correct type. template _LIBCPP_HIDE_FROM_ABI -constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) { +constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) { static_assert(is_same_v::value_type, _Tp>, "The allocator should already be rebound to the correct type"); if constexpr (is_array_v<_Tp>) { static_assert(is_array_v<_Arg>, - "Provided non-array initialization argument to __allocator_construct_at when " + "Provided non-array initialization argument to __allocator_construct_at_multidimensional when " "trying to construct an array."); using _Element = remove_extent_t<_Tp>; @@ -465,7 +465,7 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); }); for (; __i != extent_v<_Tp>; ++__i) { - std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]); + std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i]), __arg[__i]); } __guard.__complete(); } else { @@ -481,8 +481,8 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& // initialization using allocator_traits destruction. If the elements in the range are C-style // arrays, they are initialized element-wise using allocator construction, and recursively so. template::difference_type> -_LIBCPP_HIDE_FROM_ABI -constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) { +_LIBCPP_HIDE_FROM_ABI constexpr void +__uninitialized_allocator_fill_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) { using _ValueType = typename iterator_traits<_BidirIter>::value_type; __allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc); _BidirIter __begin = __it; @@ -490,16 +490,16 @@ constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it // If an exception is thrown, destroy what we have constructed so far in reverse order. __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); for (; __n != 0; --__n, ++__it) { - std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value); + std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it), __value); } __guard.__complete(); } -// Same as __uninitialized_allocator_fill_n, but doesn't pass any initialization argument +// Same as __uninitialized_allocator_fill_n_multidimensional, but doesn't pass any initialization argument // to the allocator's construct method, which results in value initialization. -template::difference_type> -_LIBCPP_HIDE_FROM_ABI -constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _BidirIter __it, _Size __n) { +template ::difference_type> +_LIBCPP_HIDE_FROM_ABI constexpr void +__uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n) { using _ValueType = typename iterator_traits<_BidirIter>::value_type; __allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc); _BidirIter __begin = __it; @@ -507,7 +507,7 @@ constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _Bid // If an exception is thrown, destroy what we have constructed so far in reverse order. __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); }); for (; __n != 0; --__n, ++__it) { - std::__allocator_construct_at(__value_alloc, std::addressof(*__it)); + std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it)); } __guard.__complete(); } diff --git a/lib/libcxx/include/__ranges/elements_view.h b/lib/libcxx/include/__ranges/elements_view.h index 3afd6ddbe8..997380ee9c 100644 --- a/lib/libcxx/include/__ranges/elements_view.h +++ b/lib/libcxx/include/__ranges/elements_view.h @@ -49,12 +49,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template -class __elements_view_iterator; - -template -class __elements_view_sentinel; - template concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value; @@ -66,6 +60,13 @@ template __has_tuple_element>, _Np> && __returnable_element, _Np> class elements_view : public view_interface> { +private: + template + class __iterator; + + template + class __sentinel; + public: _LIBCPP_HIDE_FROM_ABI elements_view() requires default_initializable<_View> @@ -130,12 +131,6 @@ public: } private: - template - using __iterator = __elements_view_iterator<_View, _Np, _Const>; - - template - using __sentinel = __elements_view_sentinel<_View, _Np, _Const>; - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); }; @@ -160,13 +155,18 @@ struct __elements_view_iterator_category_base<_Base, _Np> { using iterator_category = decltype(__get_iterator_category()); }; -template -class __elements_view_iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { - template - friend class __elements_view_iterator; +template + requires view<_View> && __has_tuple_element, _Np> && + __has_tuple_element>, _Np> && + __returnable_element, _Np> +template +class elements_view<_View, _Np>::__iterator + : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { + template + friend class __iterator; - template - friend class __elements_view_sentinel; + template + friend class __sentinel; using _Base = __maybe_const<_Const, _View>; @@ -198,14 +198,13 @@ public: using value_type = remove_cvref_t>>; using difference_type = range_difference_t<_Base>; - _LIBCPP_HIDE_FROM_ABI __elements_view_iterator() + _LIBCPP_HIDE_FROM_ABI __iterator() requires default_initializable> = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_iterator(iterator_t<_Base> __current) - : __current_(std::move(__current)) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator(__elements_view_iterator<_View, _Np, !_Const> __i) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) requires _Const && convertible_to, iterator_t<_Base>> : __current_(std::move(__i.__current_)) {} @@ -215,14 +214,14 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { ++__current_; return *this; } _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator++(int) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) requires forward_range<_Base> { auto temp = *this; @@ -230,14 +229,14 @@ public: return temp; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator--() + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() requires bidirectional_range<_Base> { --__current_; return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator--(int) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) requires bidirectional_range<_Base> { auto temp = *this; @@ -245,14 +244,14 @@ public: return temp; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator+=(difference_type __n) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) requires random_access_range<_Base> { __current_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator-=(difference_type __n) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) requires random_access_range<_Base> { __current_ -= __n; @@ -265,99 +264,91 @@ public: return __get_element(__current_ + __n); } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) requires equality_comparable> { return __x.__current_ == __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __x.__current_ < __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __y < __x; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<=(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return !(__y < __x); } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>=(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return !(__x < __y); } - _LIBCPP_HIDE_FROM_ABI friend constexpr auto - operator<=>(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> && three_way_comparable> { return __x.__current_ <=> __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator - operator+(const __elements_view_iterator& __x, difference_type __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y) requires random_access_range<_Base> { - return __elements_view_iterator{__x} += __y; + return __iterator{__x} += __y; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator - operator+(difference_type __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y) requires random_access_range<_Base> { return __y + __x; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator - operator-(const __elements_view_iterator& __x, difference_type __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y) requires random_access_range<_Base> { - return __elements_view_iterator{__x} -= __y; + return __iterator{__x} -= __y; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type - operator-(const __elements_view_iterator& __x, const __elements_view_iterator& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) requires sized_sentinel_for, iterator_t<_Base>> { return __x.__current_ - __y.__current_; } }; -template -class __elements_view_sentinel { +template + requires view<_View> && __has_tuple_element, _Np> && + __has_tuple_element>, _Np> && + __returnable_element, _Np> +template +class elements_view<_View, _Np>::__sentinel { private: using _Base = __maybe_const<_Const, _View>; _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - template - friend class __elements_view_sentinel; + template + friend class __sentinel; template - _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) - __get_current(const __elements_view_iterator<_View, _Np, _AnyConst>& __iter) { + _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) { return (__iter.__current_); } public: - _LIBCPP_HIDE_FROM_ABI __elements_view_sentinel() = default; + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_sentinel(sentinel_t<_Base> __end) - : __end_(std::move(__end)) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} - _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_sentinel(__elements_view_sentinel<_View, _Np, !_Const> __other) + _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __other) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__other.__end_)) {} @@ -365,22 +356,21 @@ public: template requires sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { return __get_current(__x) == __y.__end_; } template requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) { + operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { return __get_current(__x) - __y.__end_; } template requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __elements_view_sentinel& __x, const __elements_view_iterator<_View, _Np, _OtherConst>& __y) { + operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { return __x.__end_ - __get_current(__y); } }; diff --git a/lib/libcxx/include/__ranges/filter_view.h b/lib/libcxx/include/__ranges/filter_view.h index f8633a3fee..e14a9abeb9 100644 --- a/lib/libcxx/include/__ranges/filter_view.h +++ b/lib/libcxx/include/__ranges/filter_view.h @@ -46,15 +46,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 namespace ranges { - - template > _Pred> - requires view<_View> && is_object_v<_Pred> - class __filter_view_iterator; - - template > _Pred> - requires view<_View> && is_object_v<_Pred> - class __filter_view_sentinel; - template> _Pred> requires view<_View> && is_object_v<_Pred> class filter_view : public view_interface> { @@ -67,11 +58,8 @@ namespace ranges { using _Cache = _If<_UseCache, __non_propagating_cache>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); - using __iterator = __filter_view_iterator<_View, _Pred>; - using __sentinel = __filter_view_sentinel<_View, _Pred>; - - friend __iterator; - friend __sentinel; + class __iterator; + class __sentinel; public: _LIBCPP_HIDE_FROM_ABI @@ -131,13 +119,11 @@ namespace ranges { template> _Pred> requires view<_View> && is_object_v<_Pred> - class __filter_view_iterator : public __filter_iterator_category<_View> { - - using __filter_view = filter_view<_View, _Pred>; + class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> { public: _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>(); - _LIBCPP_NO_UNIQUE_ADDRESS __filter_view* __parent_ = nullptr; + _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr; using iterator_concept = _If, bidirectional_iterator_tag, @@ -149,10 +135,10 @@ namespace ranges { using difference_type = range_difference_t<_View>; _LIBCPP_HIDE_FROM_ABI - __filter_view_iterator() requires default_initializable> = default; + __iterator() requires default_initializable> = default; _LIBCPP_HIDE_FROM_ABI - constexpr __filter_view_iterator(__filter_view& __parent, iterator_t<_View> __current) + constexpr __iterator(filter_view& __parent, iterator_t<_View> __current) : __current_(std::move(__current)), __parent_(std::addressof(__parent)) { } @@ -171,7 +157,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - constexpr __filter_view_iterator& operator++() { + constexpr __iterator& operator++() { __current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_), std::ref(*__parent_->__pred_)); return *this; @@ -179,42 +165,42 @@ namespace ranges { _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } _LIBCPP_HIDE_FROM_ABI - constexpr __filter_view_iterator operator++(int) requires forward_range<_View> { + constexpr __iterator operator++(int) requires forward_range<_View> { auto __tmp = *this; ++*this; return __tmp; } _LIBCPP_HIDE_FROM_ABI - constexpr __filter_view_iterator& operator--() requires bidirectional_range<_View> { + constexpr __iterator& operator--() requires bidirectional_range<_View> { do { --__current_; } while (!std::invoke(*__parent_->__pred_, *__current_)); return *this; } _LIBCPP_HIDE_FROM_ABI - constexpr __filter_view_iterator operator--(int) requires bidirectional_range<_View> { + constexpr __iterator operator--(int) requires bidirectional_range<_View> { auto tmp = *this; --*this; return tmp; } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(__filter_view_iterator const& __x, __filter_view_iterator const& __y) + friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) requires equality_comparable> { return __x.__current_ == __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr range_rvalue_reference_t<_View> iter_move(__filter_view_iterator const& __it) + friend constexpr range_rvalue_reference_t<_View> iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) { return ranges::iter_move(__it.__current_); } _LIBCPP_HIDE_FROM_ABI - friend constexpr void iter_swap(__filter_view_iterator const& __x, __filter_view_iterator const& __y) + friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) requires indirectly_swappable> { @@ -224,17 +210,15 @@ namespace ranges { template> _Pred> requires view<_View> && is_object_v<_Pred> - class __filter_view_sentinel { - using __filter_view = filter_view<_View, _Pred>; - + class filter_view<_View, _Pred>::__sentinel { public: sentinel_t<_View> __end_ = sentinel_t<_View>(); _LIBCPP_HIDE_FROM_ABI - __filter_view_sentinel() = default; + __sentinel() = default; _LIBCPP_HIDE_FROM_ABI - constexpr explicit __filter_view_sentinel(__filter_view& __parent) + constexpr explicit __sentinel(filter_view& __parent) : __end_(ranges::end(__parent.__base_)) { } @@ -242,7 +226,7 @@ namespace ranges { constexpr sentinel_t<_View> base() const { return __end_; } _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(__filter_view_iterator<_View, _Pred> const& __x, __filter_view_sentinel const& __y) { + operator==(__iterator const& __x, __sentinel const& __y) { return __x.__current_ == __y.__end_; } }; diff --git a/lib/libcxx/include/__ranges/iota_view.h b/lib/libcxx/include/__ranges/iota_view.h index 3654096b7e..8f9148a684 100644 --- a/lib/libcxx/include/__ranges/iota_view.h +++ b/lib/libcxx/include/__ranges/iota_view.h @@ -83,14 +83,6 @@ namespace ranges { { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>; }; - template - requires copyable<_Start> - struct __iota_view_iterator; - - template - requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> - struct __iota_view_sentinel; - template struct __iota_iterator_category {}; @@ -102,9 +94,211 @@ namespace ranges { template requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> class iota_view : public view_interface> { + struct __iterator : public __iota_iterator_category<_Start> { + friend class iota_view; - using __iterator = __iota_view_iterator<_Start>; - using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>; + using iterator_concept = + _If<__advanceable<_Start>, random_access_iterator_tag, + _If<__decrementable<_Start>, bidirectional_iterator_tag, + _If, forward_iterator_tag, + /*Else*/ input_iterator_tag>>>; + + using value_type = _Start; + using difference_type = _IotaDiffT<_Start>; + + _Start __value_ = _Start(); + + _LIBCPP_HIDE_FROM_ABI + __iterator() requires default_initializable<_Start> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) { + return __value_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator++() { + ++__value_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr void operator++(int) { ++*this; } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator++(int) requires incrementable<_Start> { + auto __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator--() requires __decrementable<_Start> { + --__value_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator--(int) requires __decrementable<_Start> { + auto __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator+=(difference_type __n) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { + if (__n >= difference_type(0)) { + __value_ += static_cast<_Start>(__n); + } else { + __value_ -= static_cast<_Start>(-__n); + } + } else { + __value_ += __n; + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator-=(difference_type __n) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { + if (__n >= difference_type(0)) { + __value_ -= static_cast<_Start>(__n); + } else { + __value_ += static_cast<_Start>(-__n); + } + } else { + __value_ -= __n; + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Start operator[](difference_type __n) const + requires __advanceable<_Start> + { + return _Start(__value_ + __n); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) + requires equality_comparable<_Start> + { + return __x.__value_ == __y.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) + requires totally_ordered<_Start> + { + return __x.__value_ < __y.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) + requires totally_ordered<_Start> + { + return __y < __x; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) + requires totally_ordered<_Start> + { + return !(__y < __x); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) + requires totally_ordered<_Start> + { + return !(__x < __y); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) + requires totally_ordered<_Start> && three_way_comparable<_Start> + { + return __x.__value_ <=> __y.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(__iterator __i, difference_type __n) + requires __advanceable<_Start> + { + __i += __n; + return __i; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(difference_type __n, __iterator __i) + requires __advanceable<_Start> + { + return __i + __n; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator-(__iterator __i, difference_type __n) + requires __advanceable<_Start> + { + __i -= __n; + return __i; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) + requires __advanceable<_Start> + { + if constexpr (__integer_like<_Start>) { + if constexpr (__signed_integer_like<_Start>) { + return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); + } + if (__y.__value_ > __x.__value_) { + return difference_type(-difference_type(__y.__value_ - __x.__value_)); + } + return difference_type(__x.__value_ - __y.__value_); + } + return __x.__value_ - __y.__value_; + } + }; + + struct __sentinel { + friend class iota_view; + + private: + _BoundSentinel __bound_sentinel_ = _BoundSentinel(); + + public: + _LIBCPP_HIDE_FROM_ABI + __sentinel() = default; + constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {} + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { + return __x.__value_ == __y.__bound_sentinel_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y) + requires sized_sentinel_for<_BoundSentinel, _Start> + { + return __x.__value_ - __y.__bound_sentinel_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y) + requires sized_sentinel_for<_BoundSentinel, _Start> + { + return -(__y - __x); + } + }; _Start __value_ = _Start(); _BoundSentinel __bound_sentinel_ = _BoundSentinel(); @@ -185,224 +379,6 @@ namespace ranges { template inline constexpr bool enable_borrowed_range> = true; - template - requires copyable<_Start> - struct __iota_view_iterator : public __iota_iterator_category<_Start> { - - template - requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT> - friend class iota_view; - - using iterator_concept = - _If<__advanceable<_Start>, random_access_iterator_tag, - _If<__decrementable<_Start>, bidirectional_iterator_tag, - _If, forward_iterator_tag, - /*Else*/ input_iterator_tag>>>; - - using value_type = _Start; - using difference_type = _IotaDiffT<_Start>; - - _Start __value_ = _Start(); - - _LIBCPP_HIDE_FROM_ABI - __iota_view_iterator() requires default_initializable<_Start> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __iota_view_iterator(_Start __value) : __value_(std::move(__value)) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) { - return __value_; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator& operator++() { - ++__value_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr void operator++(int) { ++*this; } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator operator++(int) requires incrementable<_Start> { - auto __tmp = *this; - ++*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator& operator--() requires __decrementable<_Start> { - --__value_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator operator--(int) requires __decrementable<_Start> { - auto __tmp = *this; - --*this; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator& operator+=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_type(0)) { - __value_ += static_cast<_Start>(__n); - } else { - __value_ -= static_cast<_Start>(-__n); - } - } else { - __value_ += __n; - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr __iota_view_iterator& operator-=(difference_type __n) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { - if (__n >= difference_type(0)) { - __value_ -= static_cast<_Start>(__n); - } else { - __value_ += static_cast<_Start>(-__n); - } - } else { - __value_ -= __n; - } - return *this; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr _Start operator[](difference_type __n) const - requires __advanceable<_Start> - { - return _Start(__value_ + __n); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires equality_comparable<_Start> - { - return __x.__value_ == __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires totally_ordered<_Start> - { - return __x.__value_ < __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires totally_ordered<_Start> - { - return __y < __x; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires totally_ordered<_Start> - { - return !(__y < __x); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires totally_ordered<_Start> - { - return !(__x < __y); - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr auto operator<=>(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires totally_ordered<_Start> && three_way_comparable<_Start> - { - return __x.__value_ <=> __y.__value_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iota_view_iterator operator+(__iota_view_iterator __i, difference_type __n) - requires __advanceable<_Start> - { - __i += __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iota_view_iterator operator+(difference_type __n, __iota_view_iterator __i) - requires __advanceable<_Start> - { - return __i + __n; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr __iota_view_iterator operator-(__iota_view_iterator __i, difference_type __n) - requires __advanceable<_Start> - { - __i -= __n; - return __i; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr difference_type operator-(const __iota_view_iterator& __x, const __iota_view_iterator& __y) - requires __advanceable<_Start> - { - if constexpr (__integer_like<_Start>) { - if constexpr (__signed_integer_like<_Start>) { - return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); - } - if (__y.__value_ > __x.__value_) { - return difference_type(-difference_type(__y.__value_ - __x.__value_)); - } - return difference_type(__x.__value_ - __y.__value_); - } - return __x.__value_ - __y.__value_; - } - }; - - template - requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start> - struct __iota_view_sentinel { - - template - requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT> - friend class iota_view; - - using __iterator = __iota_view_iterator<_Start>; - - private: - _BoundSentinel __bound_sentinel_ = _BoundSentinel(); - - public: - _LIBCPP_HIDE_FROM_ABI - __iota_view_sentinel() = default; - constexpr explicit __iota_view_sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {} - - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator& __x, const __iota_view_sentinel& __y) { - return __x.__value_ == __y.__bound_sentinel_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __iota_view_sentinel& __y) - requires sized_sentinel_for<_BoundSentinel, _Start> - { - return __x.__value_ - __y.__bound_sentinel_; - } - - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Start> operator-(const __iota_view_sentinel& __x, const __iterator& __y) - requires sized_sentinel_for<_BoundSentinel, _Start> - { - return -(__y - __x); - } - }; - namespace views { namespace __iota { struct __fn { diff --git a/lib/libcxx/include/__ranges/istream_view.h b/lib/libcxx/include/__ranges/istream_view.h index 69a9df35a4..66cd915276 100644 --- a/lib/libcxx/include/__ranges/istream_view.h +++ b/lib/libcxx/include/__ranges/istream_view.h @@ -36,18 +36,10 @@ namespace ranges { template concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; }; -template - requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits> -class __basic_istream_view_iterator; - template > requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits> class basic_istream_view : public view_interface> { - using __iterator = __basic_istream_view_iterator<_Val, _CharT, _Traits>; - - template - requires default_initializable<_ValueType> && __stream_extractable<_ValueType, _CharType, _TraitsType> - friend class __basic_istream_view_iterator; + class __iterator; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream) @@ -67,23 +59,23 @@ private: template requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits> -class __basic_istream_view_iterator { +class basic_istream_view<_Val, _CharT, _Traits>::__iterator { public: using iterator_concept = input_iterator_tag; using difference_type = ptrdiff_t; using value_type = _Val; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __basic_istream_view_iterator( + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator( basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept : __parent_(std::addressof(__parent)) {} - __basic_istream_view_iterator(const __basic_istream_view_iterator&) = delete; - _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator(__basic_istream_view_iterator&&) = default; + __iterator(const __iterator&) = delete; + _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default; - __basic_istream_view_iterator& operator=(const __basic_istream_view_iterator&) = delete; - _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator=(__basic_istream_view_iterator&&) = default; + __iterator& operator=(const __iterator&) = delete; + _LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default; - _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI __iterator& operator++() { *__parent_->__stream_ >> __parent_->__value_; return *this; } @@ -92,7 +84,7 @@ public: _LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; } - _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __basic_istream_view_iterator& __x, default_sentinel_t) { + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __x, default_sentinel_t) { return !*__x.__get_parent_stream(); } diff --git a/lib/libcxx/include/__ranges/join_view.h b/lib/libcxx/include/__ranges/join_view.h index 869540fc99..7c078422e9 100644 --- a/lib/libcxx/include/__ranges/join_view.h +++ b/lib/libcxx/include/__ranges/join_view.h @@ -40,7 +40,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER > 17 +// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in +// the pipeline (https://isocpp.org/files/papers/D2770R0.html). +// TODO: make `join_view` non-experimental once D2770 is implemented. +#if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) namespace ranges { template @@ -66,14 +69,6 @@ namespace ranges { >; }; - template - requires view<_View> && input_range> - struct __join_view_iterator; - - template - requires view<_View> && input_range> - struct __join_view_sentinel; - template requires view<_View> && input_range> class join_view @@ -81,19 +76,9 @@ namespace ranges { private: using _InnerRange = range_reference_t<_View>; - template - using __iterator = __join_view_iterator<_View, _Const>; + template struct __iterator; - template - using __sentinel = __join_view_sentinel<_View, _Const>; - - template - requires view<_View2> && input_range> - friend struct __join_view_iterator; - - template - requires view<_View2> && input_range> - friend struct __join_view_sentinel; + template struct __sentinel; template friend struct std::__segmented_iterator_traits; @@ -164,12 +149,12 @@ namespace ranges { } }; - template + template requires view<_View> && input_range> - struct __join_view_sentinel { - template - requires view<_View2> && input_range> - friend struct __join_view_sentinel; + template + struct join_view<_View>::__sentinel { + template + friend struct __sentinel; private: using _Parent = __maybe_const<_Const, join_view<_View>>; @@ -178,37 +163,42 @@ namespace ranges { public: _LIBCPP_HIDE_FROM_ABI - __join_view_sentinel() = default; + __sentinel() = default; _LIBCPP_HIDE_FROM_ABI - constexpr explicit __join_view_sentinel(_Parent& __parent) + constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {} _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_sentinel(__join_view_sentinel<_View, !_Const> __s) + constexpr __sentinel(__sentinel __s) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__s.__end_)) {} template requires sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __join_view_iterator<_View, _OtherConst>& __x, const __join_view_sentinel& __y) { + friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { return __x.__outer_ == __y.__end_; } }; - template + // https://reviews.llvm.org/D142811#inline-1383022 + // To simplify the segmented iterator traits specialization, + // make the iterator `final` + template requires view<_View> && input_range> - struct __join_view_iterator + template + struct join_view<_View>::__iterator final : public __join_view_iterator_category<__maybe_const<_Const, _View>> { - template - requires view<_View2> && input_range> - friend struct __join_view_iterator; + template + friend struct __iterator; template friend struct std::__segmented_iterator_traits; + static constexpr bool __is_join_view_iterator = true; + private: using _Parent = __maybe_const<_Const, join_view<_View>>; using _Base = __maybe_const<_Const, _View>; @@ -243,7 +233,7 @@ namespace ranges { __inner_.reset(); } - _LIBCPP_HIDE_FROM_ABI constexpr __join_view_iterator(_Parent* __parent, _Outer __outer, _Inner __inner) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent* __parent, _Outer __outer, _Inner __inner) : __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {} public: @@ -264,17 +254,17 @@ namespace ranges { range_difference_t<_Base>, range_difference_t>>; _LIBCPP_HIDE_FROM_ABI - __join_view_iterator() requires default_initializable<_Outer> = default; + __iterator() requires default_initializable<_Outer> = default; _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator(_Parent& __parent, _Outer __outer) + constexpr __iterator(_Parent& __parent, _Outer __outer) : __outer_(std::move(__outer)) , __parent_(std::addressof(__parent)) { __satisfy(); } _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator(__join_view_iterator<_View, !_Const> __i) + constexpr __iterator(__iterator __i) requires _Const && convertible_to, _Outer> && convertible_to, _Inner> @@ -295,7 +285,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator& operator++() { + constexpr __iterator& operator++() { auto&& __inner = [&]() -> auto&& { if constexpr (__ref_is_glvalue) return *__outer_; @@ -315,7 +305,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator operator++(int) + constexpr __iterator operator++(int) requires __ref_is_glvalue && forward_range<_Base> && forward_range> @@ -326,7 +316,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator& operator--() + constexpr __iterator& operator--() requires __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range> && @@ -345,7 +335,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - constexpr __join_view_iterator operator--(int) + constexpr __iterator operator--(int) requires __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range> && @@ -357,7 +347,7 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __join_view_iterator& __x, const __join_view_iterator& __y) + friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) requires __ref_is_glvalue && equality_comparable> && equality_comparable>> @@ -366,14 +356,14 @@ namespace ranges { } _LIBCPP_HIDE_FROM_ABI - friend constexpr decltype(auto) iter_move(const __join_view_iterator& __i) + friend constexpr decltype(auto) iter_move(const __iterator& __i) noexcept(noexcept(ranges::iter_move(*__i.__inner_))) { return ranges::iter_move(*__i.__inner_); } _LIBCPP_HIDE_FROM_ABI - friend constexpr void iter_swap(const __join_view_iterator& __x, const __join_view_iterator& __y) + friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y) noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_))) requires indirectly_swappable<_Inner> { @@ -401,12 +391,12 @@ inline namespace __cpo { } // namespace views } // namespace ranges -template - requires(ranges::common_range::_Parent> && - __is_cpp17_random_access_iterator::_Outer>::value && - __is_cpp17_random_access_iterator::_Inner>::value) -struct __segmented_iterator_traits> { - using _JoinViewIterator = ranges::__join_view_iterator<_View, _Const>; +template + requires(_JoinViewIterator::__is_join_view_iterator && + ranges::common_range && + __is_cpp17_random_access_iterator::value && + __is_cpp17_random_access_iterator::value) +struct __segmented_iterator_traits<_JoinViewIterator> { using __segment_iterator = _LIBCPP_NODEBUG __iterator_with_data; @@ -445,7 +435,7 @@ struct __segmented_iterator_traits> } }; -#endif // _LIBCPP_STD_VER > 17 +#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/__ranges/split_view.h b/lib/libcxx/include/__ranges/split_view.h index 9758ee935f..6ebe5a43ed 100644 --- a/lib/libcxx/include/__ranges/split_view.h +++ b/lib/libcxx/include/__ranges/split_view.h @@ -42,12 +42,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template -struct __split_view_iterator; - -template -struct __split_view_sentinel; - template requires view<_View> && view<_Pattern> && indirectly_comparable, iterator_t<_Pattern>, ranges::equal_to> @@ -59,13 +53,13 @@ private: _Cache __cached_begin_ = _Cache(); template - friend struct __split_view_iterator; + friend struct __iterator; template - friend struct __split_view_sentinel; + friend struct __sentinel; - using __iterator = __split_view_iterator<_View, _Pattern>; - using __sentinel = __split_view_sentinel<_View, _Pattern>; + struct __iterator; + struct __sentinel; _LIBCPP_HIDE_FROM_ABI constexpr subrange> __find_next(iterator_t<_View> __it) { auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_); @@ -120,16 +114,17 @@ split_view(_Range&&, _Pattern&&) -> split_view, views::all_ template split_view(_Range&&, range_value_t<_Range>) -> split_view, single_view>>; -template -struct __split_view_iterator { +template + requires view<_View> && view<_Pattern> && + indirectly_comparable, iterator_t<_Pattern>, ranges::equal_to> +struct split_view<_View, _Pattern>::__iterator { private: - split_view<_View, _Pattern>* __parent_ = nullptr; + split_view* __parent_ = nullptr; _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_ = iterator_t<_View>(); _LIBCPP_NO_UNIQUE_ADDRESS subrange> __next_ = subrange>(); bool __trailing_empty_ = false; - template - friend struct __split_view_sentinel; + friend struct __sentinel; public: using iterator_concept = forward_iterator_tag; @@ -137,9 +132,9 @@ public: using value_type = subrange>; using difference_type = range_difference_t<_View>; - _LIBCPP_HIDE_FROM_ABI __split_view_iterator() = default; + _LIBCPP_HIDE_FROM_ABI __iterator() = default; - _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator( + _LIBCPP_HIDE_FROM_ABI constexpr __iterator( split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange> __next) : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {} @@ -147,7 +142,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; } - _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { __cur_ = __next_.begin(); if (__cur_ != ranges::end(__parent_->__base_)) { __cur_ = __next_.end(); @@ -163,36 +158,35 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { auto __tmp = *this; ++*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const __split_view_iterator& __x, const __split_view_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) { return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_; } }; -template -struct __split_view_sentinel { +template + requires view<_View> && view<_Pattern> && + indirectly_comparable, iterator_t<_Pattern>, ranges::equal_to> +struct split_view<_View, _Pattern>::__sentinel { private: _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>(); - _LIBCPP_HIDE_FROM_ABI static constexpr bool - __equals(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) { + _LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) { return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_; } public: - _LIBCPP_HIDE_FROM_ABI __split_view_sentinel() = default; + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __split_view_sentinel(split_view<_View, _Pattern>& __parent) + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent) : __end_(ranges::end(__parent.__base_)) {} - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { return __equals(__x, __y); } }; diff --git a/lib/libcxx/include/__ranges/take_while_view.h b/lib/libcxx/include/__ranges/take_while_view.h index 59c0a4f828..77d7390dce 100644 --- a/lib/libcxx/include/__ranges/take_while_view.h +++ b/lib/libcxx/include/__ranges/take_while_view.h @@ -53,17 +53,11 @@ template concept __take_while_const_is_range = range && indirect_unary_predicate>; -template -class __take_while_view_sentinel; - template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> class take_while_view : public view_interface> { - template - friend class __take_while_view_sentinel; - - template - using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>; + template + class __sentinel; _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; @@ -114,37 +108,37 @@ public: template take_while_view(_Range&&, _Pred) -> take_while_view, _Pred>; -template -class __take_while_view_sentinel { +template + requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> +template +class take_while_view<_View, _Pred>::__sentinel { using _Base = __maybe_const<_Const, _View>; sentinel_t<_Base> __end_ = sentinel_t<_Base>(); const _Pred* __pred_ = nullptr; - template - friend class __take_while_view_sentinel; + friend class __sentinel; public: - _LIBCPP_HIDE_FROM_ABI __take_while_view_sentinel() = default; + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __take_while_view_sentinel(sentinel_t<_Base> __end, const _Pred* __pred) + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred) : __end_(std::move(__end)), __pred_(__pred) {} - _LIBCPP_HIDE_FROM_ABI constexpr __take_while_view_sentinel(__take_while_view_sentinel<_View, _Pred, !_Const> __s) + _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel __s) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {} _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const iterator_t<_Base>& __x, const __take_while_view_sentinel& __y) { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) { return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); } template requires sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __take_while_view_sentinel& __y) { + operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) { return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x); } }; diff --git a/lib/libcxx/include/__ranges/transform_view.h b/lib/libcxx/include/__ranges/transform_view.h index 66d9e80e6e..0b5ced3df4 100644 --- a/lib/libcxx/include/__ranges/transform_view.h +++ b/lib/libcxx/include/__ranges/transform_view.h @@ -57,31 +57,11 @@ concept __transform_view_constraints = regular_invocable<_Fn&, range_reference_t<_View>> && __can_reference>>; -template - requires __transform_view_constraints<_View, _Function> -class __transform_view_iterator; - -template - requires __transform_view_constraints<_View, _Function> -class __transform_view_sentinel; - template requires __transform_view_constraints<_View, _Fn> class transform_view : public view_interface> { - - template - using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>; - - template - using __sentinel = __transform_view_sentinel<_View, _Fn, _IsConst>; - - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; - - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template class __iterator; + template class __sentinel; _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_; _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); @@ -176,23 +156,22 @@ struct __transform_view_iterator_category_base<_View, _Fn> { >; }; -template +template requires __transform_view_constraints<_View, _Fn> -class __transform_view_iterator +template +class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn> { - using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>; + using _Parent = __maybe_const<_Const, transform_view>; using _Base = __maybe_const<_Const, _View>; _Parent *__parent_ = nullptr; - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; + template + friend class transform_view<_View, _Fn>::__iterator; - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template + friend class transform_view<_View, _Fn>::__sentinel; public: iterator_t<_Base> __current_ = iterator_t<_Base>(); @@ -202,17 +181,17 @@ public: using difference_type = range_difference_t<_Base>; _LIBCPP_HIDE_FROM_ABI - __transform_view_iterator() requires default_initializable> = default; + __iterator() requires default_initializable> = default; _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator(_Parent& __parent, iterator_t<_Base> __current) + constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current) : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} - // Note: `__i` should always be `__transform_view_iterator`, but directly using - // `__transform_view_iterator` is ill-formed when `_Const` is false + // Note: `__i` should always be `__iterator`, but directly using + // `__iterator` is ill-formed when `_Const` is false // (see http://wg21.link/class.copy.ctor#5). _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator(__transform_view_iterator<_View, _Fn, !_Const> __i) + constexpr __iterator(__iterator __i) requires _Const && convertible_to, iterator_t<_Base>> : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {} @@ -234,7 +213,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator++() { + constexpr __iterator& operator++() { ++__current_; return *this; } @@ -243,7 +222,7 @@ public: constexpr void operator++(int) { ++__current_; } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator operator++(int) + constexpr __iterator operator++(int) requires forward_range<_Base> { auto __tmp = *this; @@ -252,7 +231,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator--() + constexpr __iterator& operator--() requires bidirectional_range<_Base> { --__current_; @@ -260,7 +239,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator operator--(int) + constexpr __iterator operator--(int) requires bidirectional_range<_Base> { auto __tmp = *this; @@ -269,7 +248,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator+=(difference_type __n) + constexpr __iterator& operator+=(difference_type __n) requires random_access_range<_Base> { __current_ += __n; @@ -277,7 +256,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_iterator& operator-=(difference_type __n) + constexpr __iterator& operator-=(difference_type __n) requires random_access_range<_Base> { __current_ -= __n; @@ -293,77 +272,77 @@ public: } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) requires equality_comparable> { return __x.__current_ == __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __x.__current_ < __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __x.__current_ > __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __x.__current_ <= __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> { return __x.__current_ >= __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr auto operator<=>(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> && three_way_comparable> { return __x.__current_ <=> __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr __transform_view_iterator operator+(__transform_view_iterator __i, difference_type __n) + friend constexpr __iterator operator+(__iterator __i, difference_type __n) requires random_access_range<_Base> { - return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n}; + return __iterator{*__i.__parent_, __i.__current_ + __n}; } _LIBCPP_HIDE_FROM_ABI - friend constexpr __transform_view_iterator operator+(difference_type __n, __transform_view_iterator __i) + friend constexpr __iterator operator+(difference_type __n, __iterator __i) requires random_access_range<_Base> { - return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n}; + return __iterator{*__i.__parent_, __i.__current_ + __n}; } _LIBCPP_HIDE_FROM_ABI - friend constexpr __transform_view_iterator operator-(__transform_view_iterator __i, difference_type __n) + friend constexpr __iterator operator-(__iterator __i, difference_type __n) requires random_access_range<_Base> { - return __transform_view_iterator{*__i.__parent_, __i.__current_ - __n}; + return __iterator{*__i.__parent_, __i.__current_ - __n}; } _LIBCPP_HIDE_FROM_ABI - friend constexpr difference_type operator-(const __transform_view_iterator& __x, const __transform_view_iterator& __y) + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) requires sized_sentinel_for, iterator_t<_Base>> { return __x.__current_ - __y.__current_; } _LIBCPP_HIDE_FROM_ABI - friend constexpr decltype(auto) iter_move(const __transform_view_iterator& __i) + friend constexpr decltype(auto) iter_move(const __iterator& __i) noexcept(noexcept(*__i)) { if constexpr (is_lvalue_reference_v) @@ -373,37 +352,33 @@ public: } }; -template +template requires __transform_view_constraints<_View, _Fn> -class __transform_view_sentinel { - using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>; +template +class transform_view<_View, _Fn>::__sentinel { + using _Parent = __maybe_const<_Const, transform_view>; using _Base = __maybe_const<_Const, _View>; - template - using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>; - sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_iterator; + template + friend class transform_view<_View, _Fn>::__iterator; - template - requires __transform_view_constraints<_ViewType, _FunctionType> - friend class __transform_view_sentinel; + template + friend class transform_view<_View, _Fn>::__sentinel; public: _LIBCPP_HIDE_FROM_ABI - __transform_view_sentinel() = default; + __sentinel() = default; _LIBCPP_HIDE_FROM_ABI - constexpr explicit __transform_view_sentinel(sentinel_t<_Base> __end) : __end_(__end) {} + constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {} - // Note: `__i` should always be `__transform_view_sentinel`, but directly using - // `__transform_view_sentinel` is ill-formed when `_Const` is false + // Note: `__i` should always be `__sentinel`, but directly using + // `__sentinel` is ill-formed when `_Const` is false // (see http://wg21.link/class.copy.ctor#5). _LIBCPP_HIDE_FROM_ABI - constexpr __transform_view_sentinel(__transform_view_sentinel<_View, _Fn, !_Const> __i) + constexpr __sentinel(__sentinel __i) requires _Const && convertible_to, sentinel_t<_Base>> : __end_(std::move(__i.__end_)) {} @@ -413,7 +388,7 @@ public: template requires sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) { + friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { return __x.__current_ == __y.__end_; } @@ -421,7 +396,7 @@ public: requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) { + operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { return __x.__current_ - __y.__end_; } @@ -429,7 +404,7 @@ public: requires sized_sentinel_for, iterator_t<__maybe_const<_OtherConst, _View>>> _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> - operator-(const __transform_view_sentinel& __x, const __iterator<_OtherConst>& __y) { + operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { return __x.__end_ - __y.__current_; } }; diff --git a/lib/libcxx/include/__type_traits/add_pointer.h b/lib/libcxx/include/__type_traits/add_pointer.h index 9d0c201007..1af5eca65c 100644 --- a/lib/libcxx/include/__type_traits/add_pointer.h +++ b/lib/libcxx/include/__type_traits/add_pointer.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__add_pointer) +#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template using __add_pointer_t = __add_pointer(_Tp); @@ -39,7 +39,7 @@ template struct __add_pointer_impl<_Tp, false> template using __add_pointer_t = typename __add_pointer_impl<_Tp>::type; -#endif // __has_builtin(__add_pointer) +#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template struct add_pointer { diff --git a/lib/libcxx/include/__type_traits/remove_pointer.h b/lib/libcxx/include/__type_traits/remove_pointer.h index 33ddb7103f..2f810ba666 100644 --- a/lib/libcxx/include/__type_traits/remove_pointer.h +++ b/lib/libcxx/include/__type_traits/remove_pointer.h @@ -17,7 +17,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_pointer) +#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) template struct remove_pointer { using type _LIBCPP_NODEBUG = __remove_pointer(_Tp); @@ -34,7 +34,7 @@ template struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volat template using __remove_pointer_t = typename remove_pointer<_Tp>::type; -#endif // __has_builtin(__remove_pointer) +#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) #if _LIBCPP_STD_VER > 11 template using remove_pointer_t = __remove_pointer_t<_Tp>; diff --git a/lib/libcxx/include/any b/lib/libcxx/include/any index 92cbc9a6c9..50a44d7f4d 100644 --- a/lib/libcxx/include/any +++ b/lib/libcxx/include/any @@ -175,7 +175,7 @@ namespace __any_imp inline _LIBCPP_INLINE_VISIBILITY bool __compare_typeid(type_info const* __id, const void* __fallback_id) { -#if !defined(_LIBCPP_NO_RTTI) +#if !defined(_LIBCPP_HAS_NO_RTTI) if (__id && *__id == typeid(_Tp)) return true; #endif @@ -294,7 +294,7 @@ public: _LIBCPP_INLINE_VISIBILITY bool has_value() const _NOEXCEPT { return __h_ != nullptr; } -#if !defined(_LIBCPP_NO_RTTI) +#if !defined(_LIBCPP_HAS_NO_RTTI) _LIBCPP_INLINE_VISIBILITY const type_info & type() const _NOEXCEPT { if (__h_) { @@ -426,7 +426,7 @@ namespace __any_imp _LIBCPP_INLINE_VISIBILITY static void* __type_info() { -#if !defined(_LIBCPP_NO_RTTI) +#if !defined(_LIBCPP_HAS_NO_RTTI) return const_cast(static_cast(&typeid(_Tp))); #else return nullptr; @@ -514,7 +514,7 @@ namespace __any_imp _LIBCPP_INLINE_VISIBILITY static void* __type_info() { -#if !defined(_LIBCPP_NO_RTTI) +#if !defined(_LIBCPP_HAS_NO_RTTI) return const_cast(static_cast(&typeid(_Tp))); #else return nullptr; @@ -680,7 +680,7 @@ any_cast(any * __any) _NOEXCEPT typedef add_pointer_t<_ValueType> _ReturnType; if (__any && __any->__h_) { void *__p = __any->__call(_Action::_Get, nullptr, -#if !defined(_LIBCPP_NO_RTTI) +#if !defined(_LIBCPP_HAS_NO_RTTI) &typeid(_ValueType), #else nullptr, diff --git a/lib/libcxx/include/version b/lib/libcxx/include/version index 9705229a1c..28c4a50cda 100644 --- a/lib/libcxx/include/version +++ b/lib/libcxx/include/version @@ -139,6 +139,7 @@ __cpp_lib_polymorphic_allocator 201902L __cpp_lib_ranges 202106L +__cpp_lib_ranges_as_rvalue 202207L __cpp_lib_ranges_chunk 202202L __cpp_lib_ranges_chunk_by 202202L __cpp_lib_ranges_iota 202202L @@ -401,6 +402,7 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_optional # define __cpp_lib_optional 202110L // # define __cpp_lib_out_ptr 202106L +# define __cpp_lib_ranges_as_rvalue 202207L // # define __cpp_lib_ranges_chunk 202202L // # define __cpp_lib_ranges_chunk_by 202202L // # define __cpp_lib_ranges_iota 202202L