diff options
author | mikhnenko <mikhnenko@yandex-team.com> | 2023-10-14 13:00:57 +0300 |
---|---|---|
committer | mikhnenko <mikhnenko@yandex-team.com> | 2023-10-14 13:22:30 +0300 |
commit | 4371a757495f375ca7c5b1730f4e9f741a71ec40 (patch) | |
tree | be8f3405e7b0534d29bfb8eec493c0dbe108adc5 /contrib/libs/cxxsupp | |
parent | ecb10029a72bb21f92858ff3c0d76c8f255cf4ba (diff) | |
download | ydb-4371a757495f375ca7c5b1730f4e9f741a71ec40.tar.gz |
Update libc++ to 1 May 2022 639b9618f46d75f4dabd2082b3f6ba8433c287bf
Diffstat (limited to 'contrib/libs/cxxsupp')
45 files changed, 3390 insertions, 1058 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h index b4045cd06a..00587ecb5b 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h @@ -12,6 +12,9 @@ #include <__algorithm/unwrap_iter.h> #include <__config> #include <__iterator/iterator_traits.h> +#include <__iterator/reverse_iterator.h> +#include <__utility/move.h> +#include <__utility/pair.h> #include <cstring> #include <type_traits> @@ -23,53 +26,74 @@ _LIBCPP_BEGIN_NAMESPACE_STD // copy -template <class _InputIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - for (; __first != __last; ++__first, (void) ++__result) - *__result = *__first; - return __result; +template <class _InIter, class _Sent, class _OutIter> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_InIter, _OutIter> __copy_impl(_InIter __first, _Sent __last, _OutIter __result) { + while (__first != __last) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InIter, _OutIter>(std::move(__first), std::move(__result)); } -template <class _InputIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY -_OutputIterator -__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - return _VSTD::__copy_constexpr(__first, __last, __result); +template <class _InValueT, + class _OutValueT, + class = __enable_if_t<is_same<typename remove_const<_InValueT>::type, _OutValueT>::value + && is_trivially_copy_assignable<_OutValueT>::value> > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_InValueT*, _OutValueT*> __copy_impl(_InValueT* __first, _InValueT* __last, _OutValueT* __result) { + if (__libcpp_is_constant_evaluated() +// TODO: Remove this once GCC supports __builtin_memmove during constant evaluation +#ifndef _LIBCPP_COMPILER_GCC + && !is_trivially_copyable<_InValueT>::value +#endif + ) + return std::__copy_impl<_InValueT*, _InValueT*, _OutValueT*>(__first, __last, __result); + const size_t __n = static_cast<size_t>(__last - __first); + if (__n > 0) + ::__builtin_memmove(__result, __first, __n * sizeof(_OutValueT)); + return std::make_pair(__first + __n, __result + __n); +} + +template <class _InValueT, + class _OutValueT, + class = __enable_if_t<is_same<typename remove_const<_InValueT>::type, _OutValueT>::value + && is_trivially_copy_assignable<_OutValueT>::value> > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<reverse_iterator<_InValueT*>, reverse_iterator<_OutValueT*> > +__copy_impl(reverse_iterator<_InValueT*> __first, + reverse_iterator<_InValueT*> __last, + reverse_iterator<_OutValueT*> __result) { + auto __first_base = __first.base(); + auto __last_base = __last.base(); + auto __result_base = __result.base(); + auto __result_first = __result_base - (__first_base - __last_base); + std::__copy_impl(__last_base, __first_base, __result_first); + return std::make_pair(__last, reverse_iterator<_OutValueT*>(__result_first)); +} + +template <class _InIter, class _Sent, class _OutIter> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) { + return std::__copy_impl(std::move(__first), std::move(__last), std::move(__result)); } -template <class _Tp, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_same<typename remove_const<_Tp>::type, _Up>::value && - is_trivially_copy_assignable<_Up>::value, - _Up* ->::type -__copy(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast<size_t>(__last - __first); - if (__n > 0) - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); - return __result + __n; +template <class _InIter, class _Sent, class _OutIter, + __enable_if_t<is_copy_constructible<_InIter>::value + && is_copy_constructible<_Sent>::value + && is_copy_constructible<_OutIter>::value> > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) { + auto __ret = std::__copy_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result)); + return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second)); } template <class _InputIterator, class _OutputIterator> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__copy_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__copy(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } +copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return std::__copy(__first, __last, __result).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h index 9754f0c95b..dd43a91ffa 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h @@ -9,9 +9,11 @@ #ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H #define _LIBCPP___ALGORITHM_COPY_BACKWARD_H +#include <__algorithm/copy.h> #include <__algorithm/unwrap_iter.h> #include <__config> #include <__iterator/iterator_traits.h> +#include <__iterator/reverse_iterator.h> #include <cstring> #include <type_traits> @@ -21,57 +23,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _BidirectionalIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - while (__first != __last) - *--__result = *--__last; - return __result; +template <class _Iter1, class _Sent1, class _Iter2> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Iter1, _Iter2> __copy_backward_impl(_Iter1 __first, _Sent1 __last, _Iter2 __result) { + auto __ret = std::__copy(reverse_iterator<_Iter1>(__last), + reverse_iterator<_Sent1>(__first), + reverse_iterator<_Iter2>(__result)); + return pair<_Iter1, _Iter2>(__ret.first.base(), __ret.second.base()); } -template <class _BidirectionalIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY -_OutputIterator -__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - return _VSTD::__copy_backward_constexpr(__first, __last, __result); -} - -template <class _Tp, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_same<typename remove_const<_Tp>::type, _Up>::value && - is_trivially_copy_assignable<_Up>::value, - _Up* ->::type -__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast<size_t>(__last - __first); - if (__n > 0) - { - __result -= __n; - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); - } - return __result; +template <class _Iter1, class _Sent1, class _Iter2> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Iter1, _Iter2> __copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) { + auto __ret = std::__copy_backward_impl(std::__unwrap_iter(__first), + std::__unwrap_iter(__last), + std::__unwrap_iter(__result)); + return pair<_Iter1, _Iter2>(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second)); } template <class _BidirectionalIterator1, class _BidirectionalIterator2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator2 -copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, - _BidirectionalIterator2 __result) -{ - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__copy_backward_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } +copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { + return std::__copy_backward(__first, __last, __result).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax.h index 30a119491a..7e10b8b835 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax.h @@ -10,7 +10,10 @@ #define _LIBCPP___ALGORITHM_MINMAX_H #include <__algorithm/comp.h> +#include <__algorithm/minmax_element.h> #include <__config> +#include <__functional/identity.h> +#include <__type_traits/is_callable.h> #include <__utility/pair.h> #include <initializer_list> @@ -36,47 +39,18 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair<const _Tp&, const _Tp&> minmax(const _Tp& __a, const _Tp& __b) { - return _VSTD::minmax(__a, __b, __less<_Tp>()); + return std::minmax(__a, __b, __less<_Tp>()); } #ifndef _LIBCPP_CXX03_LANG template<class _Tp, class _Compare> -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<_Tp, _Tp> -minmax(initializer_list<_Tp> __t, _Compare __comp) -{ - typedef typename initializer_list<_Tp>::const_iterator _Iter; - _Iter __first = __t.begin(); - _Iter __last = __t.end(); - pair<_Tp, _Tp> __result(*__first, *__first); - - ++__first; - if (__t.size() % 2 == 0) - { - if (__comp(*__first, __result.first)) - __result.first = *__first; - else - __result.second = *__first; - ++__first; - } - - while (__first != __last) - { - _Tp __prev = *__first++; - if (__comp(*__first, __prev)) { - if ( __comp(*__first, __result.first)) __result.first = *__first; - if (!__comp(__prev, __result.second)) __result.second = __prev; - } - else { - if ( __comp(__prev, __result.first)) __result.first = __prev; - if (!__comp(*__first, __result.second)) __result.second = *__first; - } - - __first++; - } - return __result; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { + static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); + __identity __proj; + auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); + return pair<_Tp, _Tp>(*__ret.first, *__ret.second); } template<class _Tp> @@ -85,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t) { - return _VSTD::minmax(__t, __less<_Tp>()); + return std::minmax(__t, __less<_Tp>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax_element.h index 80afbdf87a..fe5f20bf1c 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax_element.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/minmax_element.h @@ -11,8 +11,10 @@ #include <__algorithm/comp.h> #include <__config> +#include <__functional/identity.h> #include <__iterator/iterator_traits.h> #include <__utility/pair.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -20,64 +22,78 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template <class _Comp, class _Proj> +class _MinmaxElementLessFunc { + _Comp& __comp; + _Proj& __proj; + +public: + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + _MinmaxElementLessFunc(_Comp& __comp_, _Proj& __proj_) : __comp(__comp_), __proj(__proj_) {} + + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(_Iter& __it1, _Iter& __it2) { + return std::__invoke(__comp, std::__invoke(__proj, *__it1), std::__invoke(__proj, *__it2)); + } +}; + +template <class _Iter, class _Sent, class _Proj, class _Comp> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); + + pair<_Iter, _Iter> __result(__first, __first); + if (__first == __last || ++__first == __last) + return __result; + + if (__less(__first, __result.first)) + __result.first = __first; + else + __result.second = __first; + + while (++__first != __last) { + _Iter __i = __first; + if (++__first == __last) { + if (__less(__i, __result.first)) + __result.first = __i; + else if (!__less(__i, __result.second)) + __result.second = __i; + return __result; + } + + if (__less(__first, __i)) { + if (__less(__first, __result.first)) + __result.first = __first; + if (!__less(__i, __result.second)) + __result.second = __i; + } else { + if (__less(__i, __result.first)) + __result.first = __i; + if (!__less(__first, __result.second)) + __result.second = __first; + } + } + + return __result; +} + template <class _ForwardIterator, class _Compare> _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_ForwardIterator, _ForwardIterator> -minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ +minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, - "std::minmax_element requires a ForwardIterator"); - pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); - if (__first != __last) - { - if (++__first != __last) - { - if (__comp(*__first, *__result.first)) - __result.first = __first; - else - __result.second = __first; - while (++__first != __last) - { - _ForwardIterator __i = __first; - if (++__first == __last) - { - if (__comp(*__i, *__result.first)) - __result.first = __i; - else if (!__comp(*__i, *__result.second)) - __result.second = __i; - break; - } - else - { - if (__comp(*__first, *__i)) - { - if (__comp(*__first, *__result.first)) - __result.first = __first; - if (!__comp(*__i, *__result.second)) - __result.second = __i; - } - else - { - if (__comp(*__i, *__result.first)) - __result.first = __i; - if (!__comp(*__first, *__result.second)) - __result.second = __first; - } - } - } - } - } - return __result; + "std::minmax_element requires a ForwardIterator"); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, + "The comparator has to be callable"); + auto __proj = __identity(); + return std::__minmax_element_impl(__first, __last, __comp, __proj); } template <class _ForwardIterator> -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<_ForwardIterator, _ForwardIterator> -minmax_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::minmax_element(__first, __last, - __less<typename iterator_traits<_ForwardIterator>::value_type>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h new file mode 100644 index 0000000000..f5d6d5cd13 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _InIter, class _OutIter> +using copy_result = in_out_result<_InIter, _OutIter>; + +namespace __copy { +struct __fn { + + template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __ret = std::__copy(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template <input_range _Range, weakly_incrementable _OutIter> + requires indirectly_copyable<iterator_t<_Range>, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const { + auto __ret = std::__copy(ranges::begin(__r), ranges::end(__r), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy + +inline namespace __cpo { + inline constexpr auto copy = __copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h new file mode 100644 index 0000000000..49c1b26add --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H + +#include <__algorithm/copy_backward.h> +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template<class _Ip, class _Op> +using copy_backward_result = in_out_result<_Ip, _Op>; + +namespace __copy_backward { +struct __fn { + + template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2> + requires indirectly_copyable<_InIter1, _InIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { + auto __ret = std::__copy_backward(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template <bidirectional_range _Range, bidirectional_iterator _Iter> + requires indirectly_copyable<iterator_t<_Range>, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const { + auto __ret = std::__copy_backward(ranges::begin(__r), + ranges::end(__r), + std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy_backward + +inline namespace __cpo { + inline constexpr auto copy_backward = __copy_backward::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_if.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_if.h new file mode 100644 index 0000000000..492104fbbf --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_if.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template<class _Ip, class _Op> +using copy_if_result = in_out_result<_Ip, _Op>; + +namespace __copy_if { +struct __fn { + + template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred> + _LIBCPP_HIDE_FROM_ABI static constexpr + copy_if_result <_InIter, _OutIter> + __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) { + *__result = *__first; + ++__result; + } + } + return {std::move(__first), std::move(__result)}; + } + + template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity, + indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> + requires indirectly_copyable<_Iter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result<_Iter, _OutIter> + operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity, + indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> + requires indirectly_copyable<iterator_t<_Range>, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result<borrowed_iterator_t<_Range>, _OutIter> + operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj); + } +}; +} // namespace __copy_if + +inline namespace __cpo { + inline constexpr auto copy_if = __copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h new file mode 100644 index 0000000000..eaa05c9546 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/unreachable_sentinel.h> +#include <__iterator/wrap_iter.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +template <class _Ip, class _Op> +using copy_n_result = in_out_result<_Ip, _Op>; + +namespace __copy_n { +struct __fn { + + template <class _InIter, class _DiffType, class _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + while (__n != 0) { + *__result = *__first; + ++__first; + ++__result; + --__n; + } + return {std::move(__first), std::move(__result)}; + } + + template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + auto __ret = std::__copy(__first, __first + __n, __result); + return {__ret.first, __ret.second}; + } + + template <input_iterator _Ip, weakly_incrementable _Op> + requires indirectly_copyable<_Ip, _Op> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { + return __go(std::move(__first), __n, std::move(__result)); + } +}; +} // namespace __copy_n + +inline namespace __cpo { + inline constexpr auto copy_n = __copy_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax.h new file mode 100644 index 0000000000..c9f49f676c --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax.h @@ -0,0 +1,128 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <initializer_list> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template <class _T1> +using minmax_result = min_max_result<_T1>; + +namespace __minmax { +struct __fn { + template <class _Type, class _Proj = identity, + indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<const _Type&> + operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const { + if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a))) + return {__b, __a}; + return {__a, __b}; + } + + template <copyable _Type, class _Proj = identity, + indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); + auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj); + return ranges::minmax_result<_Type> { *__iters.first, *__iters.second }; + } + + template <input_range _Range, class _Proj = identity, + indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*> + _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result<range_value_t<_Range>> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + using _ValueT = range_value_t<_Range>; + + _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element"); + + if constexpr (forward_range<_Range>) { + auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj); + return {*__result.first, *__result.second}; + } else { + // input_iterators can't be copied, so the implementation for input_iterators has to store + // the values instead of a pointer to the correct values + auto __less = [&](auto&& __a, auto&& __b) -> bool { + return std::invoke(__comp, std::invoke(__proj, std::forward<decltype(__a)>(__a)), + std::invoke(__proj, std::forward<decltype(__b)>(__b))); + }; + + ranges::minmax_result<_ValueT> __result = {*__first, __result.min}; + if (__first == __last || ++__first == __last) + return __result; + + if (__less(*__first, __result.min)) + __result.min = *__first; + else + __result.max = *__first; + + while (++__first != __last) { + _ValueT __i = *__first; + if (++__first == __last) { + if (__less(__i, __result.min)) + __result.min = __i; + else if (!__less(__i, __result.max)) + __result.max = __i; + return __result; + } + + if (__less(*__first, __i)) { + if (__less(*__first, __result.min)) + __result.min = *__first; + if (!__less(__i, __result.max)) + __result.max = std::move(__i); + } else { + if (__less(__i, __result.min)) + __result.min = std::move(__i); + if (!__less(*__first, __result.max)) + __result.max = *__first; + } + } + return __result; + } + } +}; +} // namespace __minmax + +inline namespace __cpo { + inline constexpr auto minmax = __minmax::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax_element.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax_element.h new file mode 100644 index 0000000000..b7bb26cefe --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_minmax_element.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _T1> +using minmax_element_result = min_max_result<_T1>; + +namespace __minmax_element { +struct __fn { + template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, + indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); + return {__ret.first, __ret.second}; + } + + template <forward_range _Rp, class _Proj = identity, + indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result<borrowed_iterator_t<_Rp>> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + return {__ret.first, __ret.second}; + } +}; +} // namespace __minmax_element + +inline namespace __cpo { + inline constexpr auto minmax_element = __minmax_element::__fn{}; +} // namespace __cpo + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h index e738cb26fc..2edf16b70d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h +++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h @@ -64,14 +64,14 @@ __unwrap_iter(_Iter __i) _NOEXCEPT } template<class _OrigIter> -_LIBCPP_HIDE_FROM_ABI +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter, _OrigIter __result) { return __result; } template<class _OrigIter, class _UnwrappedIter> -_LIBCPP_HIDE_FROM_ABI +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result) { // Precondition: __result is reachable from __first diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit_reference b/contrib/libs/cxxsupp/libcxx/include/__bit_reference index 79d836222e..1a15afb720 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__bit_reference +++ b/contrib/libs/cxxsupp/libcxx/include/__bit_reference @@ -1109,7 +1109,11 @@ public: typedef typename _Cp::difference_type difference_type; typedef bool value_type; typedef __bit_iterator pointer; +#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference; +#else + using reference = typename conditional<_IsConst, bool, __bit_reference<_Cp> >::type; +#endif typedef random_access_iterator_tag iterator_category; private: @@ -1149,8 +1153,10 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT - {return reference(__seg_, __storage_type(1) << __ctz_);} + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT { + return typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > + ::type(__seg_, __storage_type(1) << __ctz_); + } _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() { diff --git a/contrib/libs/cxxsupp/libcxx/include/__config b/contrib/libs/cxxsupp/libcxx/include/__config index 99746b72f5..bea1b6a0b9 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__config +++ b/contrib/libs/cxxsupp/libcxx/include/__config @@ -145,6 +145,8 @@ # define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON // Remove vector base class # 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 #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -365,7 +367,8 @@ // Use rand_s(), for use on Windows. // When this option is used, the token passed to `std::random_device`'s // constructor *must* be "/dev/urandom" -- anything else is an error. -#if defined(__OpenBSD__) || defined(__APPLE__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) # define _LIBCPP_USING_ARC4_RANDOM #elif defined(__wasi__) # define _LIBCPP_USING_GETENTROPY diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h index 8bb3facfc5..845a20f3c7 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h +++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h @@ -160,17 +160,17 @@ private: }; __format::__arg_t __type_; - _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(bool __v) noexcept + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const bool& __v) noexcept : __boolean(__v), __type_(__format::__arg_t::__boolean) {} template <class _Tp> - _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept requires(same_as<_Tp, char_type> || (same_as<_Tp, char> && same_as<char_type, wchar_t>)) : __char_type(__v), __type_(__format::__arg_t::__char_type) {} template <__libcpp_signed_integer _Tp> - _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept { + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept { if constexpr (sizeof(_Tp) <= sizeof(int)) { __int = static_cast<int>(__v); __type_ = __format::__arg_t::__int; @@ -189,7 +189,7 @@ private: } template <__libcpp_unsigned_integer _Tp> - _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp __v) noexcept { + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept { if constexpr (sizeof(_Tp) <= sizeof(unsigned)) { __unsigned = static_cast<unsigned>(__v); __type_ = __format::__arg_t::__unsigned; diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/identity.h b/contrib/libs/cxxsupp/libcxx/include/__functional/identity.h index 646325aca4..2fe3acca08 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__functional/identity.h +++ b/contrib/libs/cxxsupp/libcxx/include/__functional/identity.h @@ -19,6 +19,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD +struct __identity { + template <class _Tp> + _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT { + return std::forward<_Tp>(__t); + } + + using is_transparent = void; +}; + #if _LIBCPP_STD_VER > 17 struct identity { diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h index e157b71a2f..f720fa5117 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h +++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h @@ -10,8 +10,20 @@ #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__concepts/same_as.h> #include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> +#include <__iterator/move_sentinel.h> +#include <__iterator/readable_traits.h> #include <__utility/move.h> #include <type_traits> @@ -21,20 +33,48 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER > 17 +template<class _Iter, class = void> +struct __move_iter_category_base {}; + +template<class _Iter> + requires requires { typename iterator_traits<_Iter>::iterator_category; } +struct __move_iter_category_base<_Iter> { + using iterator_category = _If< + derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + >; +}; + +template<class _Iter, class _Sent> +concept __move_iter_comparable = requires { + { declval<const _Iter&>() == declval<_Sent>() } -> convertible_to<bool>; +}; +#endif // _LIBCPP_STD_VER > 17 + template <class _Iter> class _LIBCPP_TEMPLATE_VIS move_iterator +#if _LIBCPP_STD_VER > 17 + : public __move_iter_category_base<_Iter> +#endif { public: #if _LIBCPP_STD_VER > 17 - typedef input_iterator_tag iterator_concept; -#endif - + using iterator_type = _Iter; + using iterator_concept = input_iterator_tag; + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; +#else typedef _Iter iterator_type; typedef _If< __is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, typename iterator_traits<_Iter>::iterator_category - > iterator_category; + > iterator_category; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; typedef iterator_type pointer; @@ -50,11 +90,59 @@ public: typedef typename iterator_traits<iterator_type>::reference reference; #endif +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const { return __current_; } + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr + explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator() requires is_constructible_v<_Iter> : __current_() {} + + template <class _Up> + requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template <class _Up> + requires (!_IsSame<_Up, _Iter>::value) && + convertible_to<const _Up&, _Iter> && + assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } + + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator& operator++() { ++__current_; return *this; } + + _LIBCPP_HIDE_FROM_ABI constexpr + auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); ++__current_; return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr + void operator++(int) { ++__current_; } +#else _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator() : __current_() {} + explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {} + move_iterator() : __current_() {} template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value @@ -79,14 +167,14 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator*() const { return static_cast<reference>(*__current_); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const { return __current_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator++() { ++__current_; return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator--() { --__current_; return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -100,7 +188,48 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } +#if _LIBCPP_STD_VER > 17 + template<sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } + + template<sized_sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) + { + return __x.base() - __y.base(); + } + + template<sized_sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) + { + return __x.base() - __y.base(); + } + + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + { + return ranges::iter_move(__i.__current_); + } + + template<indirectly_swappable<_Iter> _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr + void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } +#endif // _LIBCPP_STD_VER > 17 + private: + template<class _It2> friend class move_iterator; + _Iter __current_; }; @@ -111,12 +240,14 @@ bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _ return __x.base() == __y.base(); } +#if _LIBCPP_STD_VER <= 17 template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() != __y.base(); } +#endif // _LIBCPP_STD_VER <= 17 template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -146,6 +277,16 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _ return __x.base() >= __y.base(); } +#if _LIBCPP_STD_VER > 17 +template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> +inline _LIBCPP_HIDE_FROM_ABI constexpr +auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> compare_three_way_result_t<_Iter1, _Iter2> +{ + return __x.base() <=> __y.base(); +} +#endif // _LIBCPP_STD_VER > 17 + #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -162,8 +303,17 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } -#endif +#endif // !_LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template <class _Iter> +inline _LIBCPP_HIDE_FROM_ABI constexpr +move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { { __x.base() + __n } -> same_as<_Iter>; } +{ + return __x + __n; +} +#else template <class _Iter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> @@ -171,13 +321,14 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato { return move_iterator<_Iter>(__x.base() + __n); } +#endif // _LIBCPP_STD_VER > 17 template <class _Iter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> make_move_iterator(_Iter __i) { - return move_iterator<_Iter>(_VSTD::move(__i)); + return move_iterator<_Iter>(std::move(__i)); } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h new file mode 100644 index 0000000000..abacc91be8 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_MOVE_SENTINEL_H +#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H + +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <semiregular _Sent> +class _LIBCPP_TEMPLATE_VIS move_sentinel +{ +public: + _LIBCPP_HIDE_FROM_ABI + move_sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr + explicit move_sentinel(_Sent __s) : __last_(_VSTD::move(__s)) {} + + template <class _S2> + requires convertible_to<const _S2&, _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + + template <class _S2> + requires assignable_from<_Sent&, const _S2&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel& operator=(const move_sentinel<_S2>& __s) + { __last_ = __s.base(); return *this; } + + constexpr _Sent base() const { return __last_; } + +private: + _Sent __last_ = _Sent(); +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h new file mode 100644 index 0000000000..b040ea57b7 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h @@ -0,0 +1,259 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP___RANGES_FILTER_VIEW_H +#define _LIBCPP___RANGES_FILTER_VIEW_H + +#include <__algorithm/ranges_find_if.h> +#include <__config> +#include <__debug> +#include <__functional/bind_back.h> +#include <__functional/invoke.h> +#include <__functional/reference_wrapper.h> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/copyable_box.h> +#include <__ranges/non_propagating_cache.h> +#include <__ranges/range_adaptor.h> +#include <__ranges/view_interface.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> + requires view<_View> && is_object_v<_Pred> + class filter_view : public view_interface<filter_view<_View, _Pred>> { + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); + _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; + + // We cache the result of begin() to allow providing an amortized O(1) begin() whenever + // the underlying range is at least a forward_range. + static constexpr bool _UseCache = forward_range<_View>; + using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); + + class __iterator; + class __sentinel; + + public: + _LIBCPP_HIDE_FROM_ABI + filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr filter_view(_View __base, _Pred __pred) + : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) + { } + + template<class _Vp = _View> + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() const& requires copy_constructible<_Vp> { return __base_; } + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() && { return std::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Pred const& pred() const { return *__pred_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator begin() { + _LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate."); + if constexpr (_UseCache) { + if (!__cached_begin_.__has_value()) { + __cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_))); + } + return {*this, *__cached_begin_}; + } else { + return {*this, ranges::find_if(__base_, std::ref(*__pred_))}; + } + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() { + if constexpr (common_range<_View>) + return __iterator{*this, ranges::end(__base_)}; + else + return __sentinel{*this}; + } + }; + + template<class _Range, class _Pred> + filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>; + + template<class _View> + struct __filter_iterator_category { }; + + template<forward_range _View> + struct __filter_iterator_category<_View> { + using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; + using iterator_category = + _If<derived_from<_Cat, bidirectional_iterator_tag>, bidirectional_iterator_tag, + _If<derived_from<_Cat, forward_iterator_tag>, forward_iterator_tag, + /* else */ _Cat + >>; + }; + + template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> + requires view<_View> && is_object_v<_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; + + using iterator_concept = + _If<bidirectional_range<_View>, bidirectional_iterator_tag, + _If<forward_range<_View>, forward_iterator_tag, + /* else */ input_iterator_tag + >>; + // using iterator_category = inherited; + using value_type = range_value_t<_View>; + using difference_type = range_difference_t<_View>; + + _LIBCPP_HIDE_FROM_ABI + __iterator() requires default_initializable<iterator_t<_View>> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator(filter_view& __parent, iterator_t<_View> __current) + : __current_(std::move(__current)), __parent_(std::addressof(__parent)) + { } + + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_View> const& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_View> base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr range_reference_t<_View> operator*() const { return *__current_; } + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_View> operator->() const + requires __has_arrow<iterator_t<_View>> && copyable<iterator_t<_View>> + { + return __current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator++() { + __current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_), + std::ref(*__parent_->__pred_)); + return *this; + } + _LIBCPP_HIDE_FROM_ABI + constexpr void operator++(int) { ++*this; } + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator++(int) requires forward_range<_View> { + auto __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator--() requires bidirectional_range<_View> { + do { + --__current_; + } while (!std::invoke(*__parent_->__pred_, *__current_)); + return *this; + } + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator--(int) requires bidirectional_range<_View> { + auto tmp = *this; + --*this; + return tmp; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) + requires equality_comparable<iterator_t<_View>> + { + return __x.__current_ == __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + 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(__iterator const& __x, __iterator const& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + requires indirectly_swappable<iterator_t<_View>> + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } + }; + + template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> + requires view<_View> && is_object_v<_Pred> + class filter_view<_View, _Pred>::__sentinel { + public: + sentinel_t<_View> __end_ = sentinel_t<_View>(); + + _LIBCPP_HIDE_FROM_ABI + __sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __sentinel(filter_view& __parent) + : __end_(ranges::end(__parent.__base_)) + { } + + _LIBCPP_HIDE_FROM_ABI + constexpr sentinel_t<_View> base() const { return __end_; } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) { + return __x.__current_ == __y.__end_; + } + }; + +namespace views { +namespace __filter { + struct __fn { + template<class _Range, class _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Range&& __range, _Pred&& __pred) const + noexcept(noexcept(filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))) + -> decltype( filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) + { return filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); } + + template<class _Pred> + requires constructible_from<decay_t<_Pred>, _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Pred&& __pred) const + noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) + { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); } + }; +} // namespace __filter + +inline namespace __cpo { + inline constexpr auto filter = __filter::__fn{}; +} // namespace __cpo +} // namespace views + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_FILTER_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h index 1a1dfad1d2..6c16b68268 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h +++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h @@ -9,17 +9,22 @@ #ifndef _LIBCPP___RANGES_JOIN_VIEW_H #define _LIBCPP___RANGES_JOIN_VIEW_H +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/copyable.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> #include <__config> #include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> #include <__ranges/all.h> #include <__ranges/concepts.h> #include <__ranges/non_propagating_cache.h> -#include <__ranges/ref_view.h> -#include <__ranges/subrange.h> +#include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> -#include <__utility/declval.h> #include <__utility/forward.h> #include <optional> #include <type_traits> @@ -45,7 +50,8 @@ namespace ranges { using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category; using iterator_category = _If< - derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag>, + derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag> && + common_range<range_reference_t<_View>>, bidirectional_iterator_tag, _If< derived_from<_OuterC, forward_iterator_tag> && derived_from<_InnerC, forward_iterator_tag>, @@ -204,7 +210,8 @@ namespace ranges { public: using iterator_concept = _If< - __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>>, + __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> && + common_range<range_reference_t<_Base>>, bidirectional_iterator_tag, _If< __ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>, @@ -339,6 +346,21 @@ namespace ranges { template<class _Range> explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>; +namespace views { +namespace __join_view { +struct __fn : __range_adaptor_closure<__fn> { + template<class _Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Range&& __range) const + noexcept(noexcept(join_view<all_t<_Range&&>>(std::forward<_Range>(__range)))) + -> decltype( join_view<all_t<_Range&&>>(std::forward<_Range>(__range))) + { return join_view<all_t<_Range&&>>(std::forward<_Range>(__range)); } +}; +} // namespace __join_view +inline namespace __cpo { + inline constexpr auto join = __join_view::__fn{}; +} // namespace __cpo +} // namespace views } // namespace ranges #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/lazy_split_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/lazy_split_view.h new file mode 100644 index 0000000000..68617c48f8 --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/lazy_split_view.h @@ -0,0 +1,466 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H +#define _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H + +#include <__algorithm/in_in_result.h> +#include <__algorithm/ranges_find.h> +#include <__algorithm/ranges_mismatch.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__config> +#include <__functional/bind_back.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/non_propagating_cache.h> +#include <__ranges/range_adaptor.h> +#include <__ranges/single_view.h> +#include <__ranges/subrange.h> +#include <__ranges/view_interface.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +template <auto> struct __require_constant; + +template <class _Range> +concept __tiny_range = + sized_range<_Range> && + requires { typename __require_constant<remove_reference_t<_Range>::size()>; } && + (remove_reference_t<_Range>::size() <= 1); + +template <input_range _View, forward_range _Pattern> + requires view<_View> && view<_Pattern> && + indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to> && + (forward_range<_View> || __tiny_range<_Pattern>) +class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>> { + + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); + _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern(); + + using _MaybeCurrent = _If<!forward_range<_View>, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent(); + + template <bool> struct __outer_iterator; + template <bool> struct __inner_iterator; + +public: + _LIBCPP_HIDE_FROM_ABI + lazy_split_view() + requires default_initializable<_View> && default_initializable<_Pattern> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr lazy_split_view(_View __base, _Pattern __pattern) + : __base_(std::move(__base)), __pattern_(std::move(__pattern)) {} + + template <input_range _Range> + requires constructible_from<_View, views::all_t<_Range>> && + constructible_from<_Pattern, single_view<range_value_t<_Range>>> + _LIBCPP_HIDE_FROM_ABI + constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e) + : __base_(views::all(std::forward<_Range>(__r))) + // TODO(varconst): use `views::single` once it's implemented. + , __pattern_(ranges::single_view(std::move(__e))) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() const& requires copy_constructible<_View> { return __base_; } + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() && { return std::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() { + if constexpr (forward_range<_View>) { + return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::begin(__base_)}; + } else { + __current_.__emplace(ranges::begin(__base_)); + return __outer_iterator<false>{*this}; + } + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() const requires forward_range<_View> && forward_range<const _View> { + return __outer_iterator<true>{*this, ranges::begin(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() requires forward_range<_View> && common_range<_View> { + return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::end(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() const { + if constexpr (forward_range<_View> && forward_range<const _View> && common_range<const _View>) { + return __outer_iterator<true>{*this, ranges::end(__base_)}; + } else { + return default_sentinel; + } + } + +private: + + template <class> + struct __outer_iterator_category {}; + + template <forward_range _Tp> + struct __outer_iterator_category<_Tp> { + using iterator_category = input_iterator_tag; + }; + + template <bool _Const> + struct __outer_iterator : __outer_iterator_category<__maybe_const<_Const, _View>> { + private: + template <bool> + friend struct __inner_iterator; + friend __outer_iterator<true>; + + using _Parent = __maybe_const<_Const, lazy_split_view>; + using _Base = __maybe_const<_Const, _View>; + + _Parent* __parent_ = nullptr; + using _MaybeCurrent = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>; + _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent(); + bool __trailing_empty_ = false; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto& __current() noexcept { + if constexpr (forward_range<_View>) { + return __current_; + } else { + return *__parent_->__current_; + } + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr const auto& __current() const noexcept { + if constexpr (forward_range<_View>) { + return __current_; + } else { + return *__parent_->__current_; + } + } + + // Workaround for the GCC issue that doesn't allow calling `__parent_->__base_` from friend functions (because + // `__base_` is private). + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto& __parent_base() const noexcept { + return __parent_->__base_; + } + + public: + // using iterator_category = inherited; + using iterator_concept = conditional_t<forward_range<_Base>, forward_iterator_tag, input_iterator_tag>; + using difference_type = range_difference_t<_Base>; + + struct value_type : view_interface<value_type> { + private: + __outer_iterator __i_ = __outer_iterator(); + + public: + _LIBCPP_HIDE_FROM_ABI + value_type() = default; + _LIBCPP_HIDE_FROM_ABI + constexpr explicit value_type(__outer_iterator __i) + : __i_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr __inner_iterator<_Const> begin() const { return __inner_iterator<_Const>{__i_}; } + _LIBCPP_HIDE_FROM_ABI + constexpr default_sentinel_t end() const noexcept { return default_sentinel; } + }; + + _LIBCPP_HIDE_FROM_ABI + __outer_iterator() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __outer_iterator(_Parent& __parent) + requires (!forward_range<_Base>) + : __parent_(std::addressof(__parent)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current) + requires forward_range<_Base> + : __parent_(std::addressof(__parent)), __current_(std::move(__current)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr __outer_iterator(__outer_iterator<!_Const> __i) + requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> + : __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr value_type operator*() const { return value_type{*this}; } + + _LIBCPP_HIDE_FROM_ABI + constexpr __outer_iterator& operator++() { + const auto __end = ranges::end(__parent_->__base_); + if (__current() == __end) { + __trailing_empty_ = false; + return *this; + } + + const auto [__pbegin, __pend] = ranges::subrange{__parent_->__pattern_}; + if (__pbegin == __pend) { + // Empty pattern: split on every element in the input range + ++__current(); + + } else if constexpr (__tiny_range<_Pattern>) { + // One-element pattern: we can use `ranges::find`. + __current() = ranges::find(std::move(__current()), __end, *__pbegin); + if (__current() != __end) { + // Make sure we point to after the separator we just found. + ++__current(); + if (__current() == __end) + __trailing_empty_ = true; + } + + } else { + // General case for n-element pattern. + do { + const auto [__b, __p] = ranges::mismatch(__current(), __end, __pbegin, __pend); + if (__p == __pend) { + __current() = __b; + if (__current() == __end) { + __trailing_empty_ = true; + } + break; // The pattern matched; skip it. + } + } while (++__current() != __end); + } + + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator++(int) { + if constexpr (forward_range<_Base>) { + auto __tmp = *this; + ++*this; + return __tmp; + + } else { + ++*this; + } + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __outer_iterator& __x, const __outer_iterator& __y) + requires forward_range<_Base> { + return __x.__current_ == __y.__current_ && __x.__trailing_empty_ == __y.__trailing_empty_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) { + _LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator."); + return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_; + } + }; + + template <class> + struct __inner_iterator_category {}; + + template <forward_range _Tp> + struct __inner_iterator_category<_Tp> { + using iterator_category = _If< + derived_from<typename iterator_traits<iterator_t<_Tp>>::iterator_category, forward_iterator_tag>, + forward_iterator_tag, + typename iterator_traits<iterator_t<_Tp>>::iterator_category + >; + }; + + template <bool _Const> + struct __inner_iterator : __inner_iterator_category<__maybe_const<_Const, _View>> { + private: + using _Base = __maybe_const<_Const, _View>; + // Workaround for a GCC issue. + static constexpr bool _OuterConst = _Const; + __outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>(); + bool __incremented_ = false; + + // Note: these private functions are necessary because GCC doesn't allow calls to private members of `__i_` from + // free functions that are friends of `inner-iterator`. + + _LIBCPP_HIDE_FROM_ABI + constexpr bool __is_done() const { + _LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator."); + + auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_}; + auto __end = ranges::end(__i_.__parent_->__base_); + + if constexpr (__tiny_range<_Pattern>) { + const auto& __cur = __i_.__current(); + if (__cur == __end) + return true; + if (__pcur == __pend) + return __incremented_; + + return *__cur == *__pcur; + + } else { + auto __cur = __i_.__current(); + if (__cur == __end) + return true; + if (__pcur == __pend) + return __incremented_; + + do { + if (*__cur != *__pcur) + return false; + if (++__pcur == __pend) + return true; + } while (++__cur != __end); + + return false; + } + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto& __outer_current() noexcept { + return __i_.__current(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr const auto& __outer_current() const noexcept { + return __i_.__current(); + } + + public: + // using iterator_category = inherited; + using iterator_concept = typename __outer_iterator<_Const>::iterator_concept; + using value_type = range_value_t<_Base>; + using difference_type = range_difference_t<_Base>; + + _LIBCPP_HIDE_FROM_ABI + __inner_iterator() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) + : __i_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr const iterator_t<_Base>& base() const& noexcept { return __i_.__current(); } + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_Base> base() && + requires forward_range<_View> { return std::move(__i_.__current()); } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() const { return *__i_.__current(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr __inner_iterator& operator++() { + __incremented_ = true; + + if constexpr (!forward_range<_Base>) { + if constexpr (_Pattern::size() == 0) { + return *this; + } + } + + ++__i_.__current(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator++(int) { + if constexpr (forward_range<_Base>) { + auto __tmp = *this; + ++*this; + return __tmp; + + } else { + ++*this; + } + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __inner_iterator& __x, const __inner_iterator& __y) + requires forward_range<_Base> { + return __x.__outer_current() == __y.__outer_current(); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __inner_iterator& __x, default_sentinel_t) { + return __x.__is_done(); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr decltype(auto) iter_move(const __inner_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__outer_current()))) { + return ranges::iter_move(__i.__outer_current()); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr void iter_swap(const __inner_iterator& __x, const __inner_iterator& __y) + noexcept(noexcept(ranges::iter_swap(__x.__outer_current(), __y.__outer_current()))) + requires indirectly_swappable<iterator_t<_Base>> { + ranges::iter_swap(__x.__outer_current(), __y.__outer_current()); + } + }; + +}; + +template <class _Range, class _Pattern> +lazy_split_view(_Range&&, _Pattern&&) -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>; + +template <input_range _Range> +lazy_split_view(_Range&&, range_value_t<_Range>) + -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>; + +namespace views { +namespace __lazy_split_view { +struct __fn : __range_adaptor_closure<__fn> { + template <class _Range, class _Pattern> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const + noexcept(noexcept(lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))) + -> decltype( lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))) + { return lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); } + + template <class _Pattern> + requires constructible_from<decay_t<_Pattern>, _Pattern> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Pattern&& __pattern) const + noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) { + return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern))); + } +}; +} // namespace __lazy_split_view + +inline namespace __cpo { + inline constexpr auto lazy_split = __lazy_split_view::__fn{}; +} // namespace __cpo +} // namespace views + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h index 9602ee1b2a..3ad7810a9c 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h +++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h @@ -37,141 +37,143 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) namespace ranges { - template<view _View> - class take_view : public view_interface<take_view<_View>> { - _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); - range_difference_t<_View> __count_ = 0; - - template<bool> class __sentinel; - - public: - _LIBCPP_HIDE_FROM_ABI - take_view() requires default_initializable<_View> = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr take_view(_View __base, range_difference_t<_View> __count) - : __base_(std::move(__base)), __count_(__count) {} - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - - _LIBCPP_HIDE_FROM_ABI - constexpr _View base() && { return std::move(__base_); } - - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() requires (!__simple_view<_View>) { - if constexpr (sized_range<_View>) { - if constexpr (random_access_range<_View>) { - return ranges::begin(__base_); - } else { - using _DifferenceT = range_difference_t<_View>; - auto __size = size(); - return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); - } + +template<view _View> +class take_view : public view_interface<take_view<_View>> { + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); + range_difference_t<_View> __count_ = 0; + + template<bool> class __sentinel; + +public: + _LIBCPP_HIDE_FROM_ABI + take_view() requires default_initializable<_View> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr take_view(_View __base, range_difference_t<_View> __count) + : __base_(std::move(__base)), __count_(__count) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() const& requires copy_constructible<_View> { return __base_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() && { return std::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() requires (!__simple_view<_View>) { + if constexpr (sized_range<_View>) { + if constexpr (random_access_range<_View>) { + return ranges::begin(__base_); } else { - return counted_iterator(ranges::begin(__base_), __count_); + using _DifferenceT = range_difference_t<_View>; + auto __size = size(); + return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); } + } else { + return counted_iterator(ranges::begin(__base_), __count_); } + } - _LIBCPP_HIDE_FROM_ABI - constexpr auto begin() const requires range<const _View> { - if constexpr (sized_range<const _View>) { - if constexpr (random_access_range<const _View>) { - return ranges::begin(__base_); - } else { - using _DifferenceT = range_difference_t<const _View>; - auto __size = size(); - return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); - } + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() const requires range<const _View> { + if constexpr (sized_range<const _View>) { + if constexpr (random_access_range<const _View>) { + return ranges::begin(__base_); } else { - return counted_iterator(ranges::begin(__base_), __count_); + using _DifferenceT = range_difference_t<const _View>; + auto __size = size(); + return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); } + } else { + return counted_iterator(ranges::begin(__base_), __count_); } + } - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() requires (!__simple_view<_View>) { - if constexpr (sized_range<_View>) { - if constexpr (random_access_range<_View>) { - return ranges::begin(__base_) + size(); - } else { - return default_sentinel; - } + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() requires (!__simple_view<_View>) { + if constexpr (sized_range<_View>) { + if constexpr (random_access_range<_View>) { + return ranges::begin(__base_) + size(); } else { - return __sentinel<false>{ranges::end(__base_)}; + return default_sentinel; } + } else { + return __sentinel<false>{ranges::end(__base_)}; } + } - _LIBCPP_HIDE_FROM_ABI - constexpr auto end() const requires range<const _View> { - if constexpr (sized_range<const _View>) { - if constexpr (random_access_range<const _View>) { - return ranges::begin(__base_) + size(); - } else { - return default_sentinel; - } + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() const requires range<const _View> { + if constexpr (sized_range<const _View>) { + if constexpr (random_access_range<const _View>) { + return ranges::begin(__base_) + size(); } else { - return __sentinel<true>{ranges::end(__base_)}; + return default_sentinel; } + } else { + return __sentinel<true>{ranges::end(__base_)}; } + } - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() requires sized_range<_View> { - auto __n = ranges::size(__base_); - return ranges::min(__n, static_cast<decltype(__n)>(__count_)); - } + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() requires sized_range<_View> { + auto __n = ranges::size(__base_); + return ranges::min(__n, static_cast<decltype(__n)>(__count_)); + } - _LIBCPP_HIDE_FROM_ABI - constexpr auto size() const requires sized_range<const _View> { - auto __n = ranges::size(__base_); - return ranges::min(__n, static_cast<decltype(__n)>(__count_)); - } - }; + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const requires sized_range<const _View> { + auto __n = ranges::size(__base_); + return ranges::min(__n, static_cast<decltype(__n)>(__count_)); + } +}; - template<view _View> - template<bool _Const> - class take_view<_View>::__sentinel { - using _Base = __maybe_const<_Const, _View>; - template<bool _OtherConst> - using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; - _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); +template<view _View> +template<bool _Const> +class take_view<_View>::__sentinel { + using _Base = __maybe_const<_Const, _View>; + template<bool _OtherConst> + using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; + _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); - template<bool> - friend class take_view<_View>::__sentinel; + template<bool> + friend class take_view<_View>::__sentinel; public: - _LIBCPP_HIDE_FROM_ABI - __sentinel() = default; + _LIBCPP_HIDE_FROM_ABI + __sentinel() = default; - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __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 __sentinel(__sentinel<!_Const> __s) - requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> - : __end_(std::move(__s.__end_)) {} + _LIBCPP_HIDE_FROM_ABI + constexpr __sentinel(__sentinel<!_Const> __s) + requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> + : __end_(std::move(__s.__end_)) {} - _LIBCPP_HIDE_FROM_ABI - constexpr sentinel_t<_Base> base() const { return __end_; } + _LIBCPP_HIDE_FROM_ABI + constexpr sentinel_t<_Base> base() const { return __end_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { - return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; - } + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { + return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; + } - template<bool _OtherConst = !_Const> - requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { - return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; - } - }; + template<bool _OtherConst = !_Const> + requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { + return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; + } +}; + +template<class _Range> +take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; - template<class _Range> - take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; +template<class _Tp> +inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; - template<class _Tp> - inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; } // namespace ranges #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h new file mode 100644 index 0000000000..560452aa7c --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h @@ -0,0 +1,511 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP___RANGES_ZIP_VIEW_H +#define _LIBCPP___RANGES_ZIP_VIEW_H + +#include <__config> + +#include <__algorithm/ranges_min.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/equality_comparable.h> +#include <__functional/invoke.h> +#include <__functional/operations.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/empty_view.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <__utility/forward.h> +#include <__utility/integer_sequence.h> +#include <__utility/move.h> +#include <tuple> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +template <class... _Ranges> +concept __zip_is_common = (sizeof...(_Ranges) == 1 && (common_range<_Ranges> && ...)) || + (!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) || + ((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...)); + +template <typename _Tp, typename _Up> +auto __tuple_or_pair_test() -> pair<_Tp, _Up>; + +template <typename... _Types> + requires(sizeof...(_Types) != 2) +auto __tuple_or_pair_test() -> tuple<_Types...>; + +template <class... _Types> +using __tuple_or_pair = decltype(__tuple_or_pair_test<_Types...>()); + +template <class _Fun, class _Tuple> +_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) { + return std::apply( + [&]<class... _Types>(_Types&&... __elements) { + return __tuple_or_pair<invoke_result_t<_Fun&, _Types>...>( + std::invoke(__f, std::forward<_Types>(__elements))...); + }, + std::forward<_Tuple>(__tuple)); +} + +template <class _Fun, class _Tuple> +_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) { + std::apply( + [&]<class... _Types>(_Types&&... __elements) { (std::invoke(__f, std::forward<_Types>(__elements)), ...); }, + std::forward<_Tuple>(__tuple)); +} + +template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices> +_LIBCPP_HIDE_FROM_ABI constexpr __tuple_or_pair< + invoke_result_t<_Fun&, typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type, + typename tuple_element<_Indices, remove_cvref_t<_Tuple2>>::type>...> +__tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) { + return {std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)), + std::get<_Indices>(std::forward<_Tuple2>(__tuple2)))...}; +} + +template <class _Fun, class _Tuple1, class _Tuple2> +_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) { + return ranges::__tuple_zip_transform(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2), + std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>()); +} + +template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices> +_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, + index_sequence<_Indices...>) { + (std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)), + std::get<_Indices>(std::forward<_Tuple2>(__tuple2))), + ...); +} + +template <class _Fun, class _Tuple1, class _Tuple2> +_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) { + return ranges::__tuple_zip_for_each(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2), + std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>()); +} + +template <class _Tuple1, class _Tuple2> +_LIBCPP_HIDE_FROM_ABI constexpr bool __tuple_any_equals(const _Tuple1& __tuple1, const _Tuple2& __tuple2) { + const auto __equals = ranges::__tuple_zip_transform(std::equal_to<>(), __tuple1, __tuple2); + return std::apply([](auto... __bools) { return (__bools || ...); }, __equals); +} + +// abs in cstdlib is not constexpr +// TODO : remove __abs once P0533R9 is implemented. +template <class _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp __abs(_Tp __t) { + return __t < 0 ? -__t : __t; +} + +template <input_range... _Views> + requires(view<_Views> && ...) && (sizeof...(_Views) > 0) +class zip_view : public view_interface<zip_view<_Views...>> { + + _LIBCPP_NO_UNIQUE_ADDRESS tuple<_Views...> __views_; + + template <bool> + class __iterator; + + template <bool> + class __sentinel; + +public: + _LIBCPP_HIDE_FROM_ABI + zip_view() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit zip_view(_Views... __views) : __views_(std::move(__views)...) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() + requires(!(__simple_view<_Views> && ...)) { + return __iterator<false>(ranges::__tuple_transform(ranges::begin, __views_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() const + requires(range<const _Views> && ...) { + return __iterator<true>(ranges::__tuple_transform(ranges::begin, __views_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() + requires(!(__simple_view<_Views> && ...)) { + if constexpr (!__zip_is_common<_Views...>) { + return __sentinel<false>(ranges::__tuple_transform(ranges::end, __views_)); + } else if constexpr ((random_access_range<_Views> && ...)) { + return begin() + iter_difference_t<__iterator<false>>(size()); + } else { + return __iterator<false>(ranges::__tuple_transform(ranges::end, __views_)); + } + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() const + requires(range<const _Views> && ...) { + if constexpr (!__zip_is_common<const _Views...>) { + return __sentinel<true>(ranges::__tuple_transform(ranges::end, __views_)); + } else if constexpr ((random_access_range<const _Views> && ...)) { + return begin() + iter_difference_t<__iterator<true>>(size()); + } else { + return __iterator<true>(ranges::__tuple_transform(ranges::end, __views_)); + } + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() + requires(sized_range<_Views> && ...) { + return std::apply( + [](auto... __sizes) { + using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>; + return ranges::min({_CT(__sizes)...}); + }, + ranges::__tuple_transform(ranges::size, __views_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const + requires(sized_range<const _Views> && ...) { + return std::apply( + [](auto... __sizes) { + using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>; + return ranges::min({_CT(__sizes)...}); + }, + ranges::__tuple_transform(ranges::size, __views_)); + } +}; + +template <class... _Ranges> +zip_view(_Ranges&&...) -> zip_view<views::all_t<_Ranges>...>; + +template <bool _Const, class... _Views> +concept __zip_all_random_access = (random_access_range<__maybe_const<_Const, _Views>> && ...); + +template <bool _Const, class... _Views> +concept __zip_all_bidirectional = (bidirectional_range<__maybe_const<_Const, _Views>> && ...); + +template <bool _Const, class... _Views> +concept __zip_all_forward = (forward_range<__maybe_const<_Const, _Views>> && ...); + +template <bool _Const, class... _Views> +consteval auto __get_zip_view_iterator_tag() { + if constexpr (__zip_all_random_access<_Const, _Views...>) { + return random_access_iterator_tag(); + } else if constexpr (__zip_all_bidirectional<_Const, _Views...>) { + return bidirectional_iterator_tag(); + } else if constexpr (__zip_all_forward<_Const, _Views...>) { + return forward_iterator_tag(); + } else { + return input_iterator_tag(); + } +} + +template <bool _Const, class... _Views> +struct __zip_view_iterator_category_base {}; + +template <bool _Const, class... _Views> + requires __zip_all_forward<_Const, _Views...> +struct __zip_view_iterator_category_base<_Const, _Views...> { + using iterator_category = input_iterator_tag; +}; + +template <input_range... _Views> + requires(view<_Views> && ...) && (sizeof...(_Views) > 0) +template <bool _Const> +class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base<_Const, _Views...> { + + __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current_; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __iterator(__tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current) + : __current_(std::move(__current)) {} + + template <bool> + friend class zip_view<_Views...>::__iterator; + + template <bool> + friend class zip_view<_Views...>::__sentinel; + + friend class zip_view<_Views...>; + +public: + using iterator_concept = decltype(__get_zip_view_iterator_tag<_Const, _Views...>()); + using value_type = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>; + using difference_type = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>; + + _LIBCPP_HIDE_FROM_ABI + __iterator() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator(__iterator<!_Const> __i) + requires _Const && (convertible_to<iterator_t<_Views>, iterator_t<__maybe_const<_Const, _Views>>> && ...) + : __current_(std::move(__i.__current_)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator*() const { + return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator++() { + ranges::__tuple_for_each([](auto& __i) { ++__i; }, __current_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr void operator++(int) { ++*this; } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator++(int) + requires __zip_all_forward<_Const, _Views...> { + auto __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator--() + requires __zip_all_bidirectional<_Const, _Views...> { + ranges::__tuple_for_each([](auto& __i) { --__i; }, __current_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator operator--(int) + requires __zip_all_bidirectional<_Const, _Views...> { + auto __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator+=(difference_type __x) + requires __zip_all_random_access<_Const, _Views...> { + ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i += iter_difference_t<_Iter>(__x); }, __current_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator-=(difference_type __x) + requires __zip_all_random_access<_Const, _Views...> { + ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i -= iter_difference_t<_Iter>(__x); }, __current_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator[](difference_type __n) const + requires __zip_all_random_access<_Const, _Views...> { + return ranges::__tuple_transform( + [&]<class _Iter>(_Iter& __i) -> decltype(auto) { return __i[iter_difference_t<_Iter>(__n)]; }, __current_); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) + requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) { + if constexpr (__zip_all_bidirectional<_Const, _Views...>) { + return __x.__current_ == __y.__current_; + } else { + return ranges::__tuple_any_equals(__x.__current_, __y.__current_); + } + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) + requires __zip_all_random_access<_Const, _Views...> { + return __x.__current_ < __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) + requires __zip_all_random_access<_Const, _Views...> { + return __y < __x; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) + requires __zip_all_random_access<_Const, _Views...> { + return !(__y < __x); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) + requires __zip_all_random_access<_Const, _Views...> { + return !(__x < __y); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) + requires __zip_all_random_access<_Const, _Views...> && + (three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) { + return __x.__current_ <=> __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(const __iterator& __i, difference_type __n) + requires __zip_all_random_access<_Const, _Views...> { + auto __r = __i; + __r += __n; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(difference_type __n, const __iterator& __i) + requires __zip_all_random_access<_Const, _Views...> { + return __i + __n; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator-(const __iterator& __i, difference_type __n) + requires __zip_all_random_access<_Const, _Views...> { + auto __r = __i; + __r -= __n; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) + requires(sized_sentinel_for<iterator_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_Const, _Views>>> && + ...) { + const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __x.__current_, __y.__current_); + return std::apply( + [](auto... __ds) { + return ranges::min({difference_type(__ds)...}, + [](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); }); + }, + __diffs); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr auto iter_move(const __iterator& __i) noexcept( + (noexcept(ranges::iter_move(declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) && + (is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) { + return ranges::__tuple_transform(ranges::iter_move, __i.__current_); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept( + (noexcept(ranges::iter_swap(declval<const iterator_t<__maybe_const<_Const, _Views>>&>(), + declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && + ...)) + requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...) { + ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_); + } +}; + +template <input_range... _Views> + requires(view<_Views> && ...) && (sizeof...(_Views) > 0) +template <bool _Const> +class zip_view<_Views...>::__sentinel { + + __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end_; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __sentinel(__tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end) : __end_(__end) {} + + friend class zip_view<_Views...>; + + // hidden friend cannot access private member of iterator because they are friends of friends + template <bool _OtherConst> + _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) + __iter_current(zip_view<_Views...>::__iterator<_OtherConst> const& __it) { + return (__it.__current_); + } + +public: + _LIBCPP_HIDE_FROM_ABI + __sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __sentinel(__sentinel<!_Const> __i) + requires _Const && (convertible_to<sentinel_t<_Views>, sentinel_t<__maybe_const<_Const, _Views>>> && ...) + : __end_(std::move(__i.__end_)) {} + + template <bool _OtherConst> + requires(sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> && + ...) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { + return ranges::__tuple_any_equals(__iter_current(__x), __y.__end_); + } + + template <bool _OtherConst> + requires( + sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> && + ...) + _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...> + operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { + const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __iter_current(__x), __y.__end_); + return std::apply( + [](auto... __ds) { + using _Diff = common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>; + return ranges::min({_Diff(__ds)...}, + [](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); }); + }, + __diffs); + } + + template <bool _OtherConst> + requires( + sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> && + ...) + _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...> + operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) { + return -(__x - __y); + } +}; + +template <class... _Views> +inline constexpr bool enable_borrowed_range<zip_view<_Views...>> = (enable_borrowed_range<_Views> && ...); + +namespace views { +namespace __zip { + +struct __fn { + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const noexcept { return empty_view<tuple<>>{}; } + + template <class... _Ranges> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ranges&&... rs) const + noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...))) + -> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...)) { + return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(rs)...); + } +}; + +} // namespace __zip +inline namespace __cpo { + inline constexpr auto zip = __zip::__fn{}; +} // namespace __cpo +} // namespace views +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_ZIP_VIEW_H diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h b/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h index 49d66fde1e..f3917f333f 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h +++ b/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h @@ -16,4 +16,24 @@ #include <ctype.h> #include <cwctype> +#ifdef __cplusplus +extern "C" { +#endif + + +inline _LIBCPP_HIDE_FROM_ABI long +strtol_l(const char *nptr, char **endptr, int base, locale_t) { + return ::strtol(nptr, endptr, base); +} + +inline _LIBCPP_HIDE_FROM_ABI unsigned long +strtoul_l(const char *nptr, char **endptr, int base, locale_t) { + return ::strtoul(nptr, endptr, base); +} + + +#ifdef __cplusplus +} +#endif + #endif diff --git a/contrib/libs/cxxsupp/libcxx/include/algorithm b/contrib/libs/cxxsupp/libcxx/include/algorithm index 0589f5dcec..a86e466450 100644 --- a/contrib/libs/cxxsupp/libcxx/include/algorithm +++ b/contrib/libs/cxxsupp/libcxx/include/algorithm @@ -165,6 +165,79 @@ namespace ranges { indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> constexpr range_difference_t<R> count_if(R&& r, Pred pred, Proj proj = {}); // since C++20 + + template<class T, class Proj = identity, + indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> + constexpr ranges::minmax_result<const T&> + minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 + + template<copyable T, class Proj = identity, + indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> + constexpr ranges::minmax_result<T> + minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 + + template<input_range R, class Proj = identity, + indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> + requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> + constexpr ranges::minmax_result<range_value_t<R>> + minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 + + template<forward_iterator I, sentinel_for<I> S, class Proj = identity, + indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> + constexpr ranges::minmax_element_result<I> + minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 + + template<forward_range R, class Proj = identity, + indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> + constexpr ranges::minmax_element_result<borrowed_iterator_t<R>> + minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 + + template<class I, class O> + using copy_result = in_out_result<I, O>; // since C++20 + + template<class I, class O> + using copy_n_result = in_out_result<I, O>; // since C++20 + + template<class I, class O> + using copy_if_result = in_out_result<I, O>; // since C++20 + + template<class I1, class I2> + using copy_backward_result = in_out_result<I1, I2>; // since C++20 + + template<input_iterator I, sentinel_for<I> S, weakly_incrementable O> + requires indirectly_copyable<I, O> + constexpr ranges::copy_result<I, O> ranges::copy(I first, S last, O result); // since C++20 + + template<input_range R, weakly_incrementable O> + requires indirectly_copyable<iterator_t<R>, O> + constexpr ranges::copy_result<borrowed_iterator_t<R>, O> ranges::copy(R&& r, O result); // since C++20 + + template<input_iterator I, weakly_incrementable O> + requires indirectly_copyable<I, O> + constexpr ranges::copy_n_result<I, O> + ranges::copy_n(I first, iter_difference_t<I> n, O result); // since C++20 + + template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity, + indirect_unary_predicate<projected<I, Proj>> Pred> + requires indirectly_copyable<I, O> + constexpr ranges::copy_if_result<I, O> + ranges::copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // since C++20 + + template<input_range R, weakly_incrementable O, class Proj = identity, + indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> + requires indirectly_copyable<iterator_t<R>, O> + constexpr ranges::copy_if_result<borrowed_iterator_t<R>, O> + ranges::copy_if(R&& r, O result, Pred pred, Proj proj = {}); // since C++20 + + template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2> + requires indirectly_copyable<I1, I2> + constexpr ranges::copy_backward_result<I1, I2> + ranges::copy_backward(I1 first, S1 last, I2 result); // since C++20 + + template<bidirectional_range R, bidirectional_iterator I> + requires indirectly_copyable<iterator_t<R>, I> + constexpr ranges::copy_backward_result<borrowed_iterator_t<R>, I> + ranges::copy_backward(R&& r, I result); // since C++20 } constexpr bool // constexpr in C++20 @@ -808,7 +881,6 @@ template <class BidirectionalIterator, class Compare> #include <__debug> #include <cstddef> #include <cstring> -#include <functional> #include <initializer_list> #include <iterator> #include <memory> @@ -882,6 +954,10 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/pop_heap.h> #include <__algorithm/prev_permutation.h> #include <__algorithm/push_heap.h> +#include <__algorithm/ranges_copy.h> +#include <__algorithm/ranges_copy_backward.h> +#include <__algorithm/ranges_copy_if.h> +#include <__algorithm/ranges_copy_n.h> #include <__algorithm/ranges_count.h> #include <__algorithm/ranges_count_if.h> #include <__algorithm/ranges_find.h> @@ -891,6 +967,8 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/ranges_max_element.h> #include <__algorithm/ranges_min.h> #include <__algorithm/ranges_min_element.h> +#include <__algorithm/ranges_minmax.h> +#include <__algorithm/ranges_minmax_element.h> #include <__algorithm/ranges_mismatch.h> #include <__algorithm/ranges_swap_ranges.h> #include <__algorithm/ranges_transform.h> diff --git a/contrib/libs/cxxsupp/libcxx/include/bitset b/contrib/libs/cxxsupp/libcxx/include/bitset index 098d383e28..f4d9a643f9 100644 --- a/contrib/libs/cxxsupp/libcxx/include/bitset +++ b/contrib/libs/cxxsupp/libcxx/include/bitset @@ -719,9 +719,12 @@ public: bitset& flip(size_t __pos); // element access: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - const_reference operator[](size_t __p) const {return base::__make_ref(__p);} - _LIBCPP_INLINE_VISIBILITY reference operator[](size_t __p) {return base::__make_ref(__p);} +#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {return base::__make_ref(__p);} +#else + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {return base::__make_ref(__p);} +#endif + _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __p) {return base::__make_ref(__p);} _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const; _LIBCPP_INLINE_VISIBILITY diff --git a/contrib/libs/cxxsupp/libcxx/include/fstream b/contrib/libs/cxxsupp/libcxx/include/fstream index 907c59e888..7608daa3f9 100644 --- a/contrib/libs/cxxsupp/libcxx/include/fstream +++ b/contrib/libs/cxxsupp/libcxx/include/fstream @@ -419,25 +419,38 @@ basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) basic_streambuf<char_type, traits_type>::swap(__rhs); if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) { - _VSTD::swap(__extbuf_, __rhs.__extbuf_); - _VSTD::swap(__extbufnext_, __rhs.__extbufnext_); - _VSTD::swap(__extbufend_, __rhs.__extbufend_); + // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers. + std::swap(__extbuf_, __rhs.__extbuf_); + std::swap(__extbufnext_, __rhs.__extbufnext_); + std::swap(__extbufend_, __rhs.__extbufend_); } else { - ptrdiff_t __ln = __extbufnext_ - __extbuf_; - ptrdiff_t __le = __extbufend_ - __extbuf_; - ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_; - ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_; + ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0; + ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0; + ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0; + ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0; if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) { + // *this uses the small buffer, but __rhs doesn't. __extbuf_ = __rhs.__extbuf_; __rhs.__extbuf_ = __rhs.__extbuf_min_; + std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_)); } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) { + // *this doesn't use the small buffer, but __rhs does. __rhs.__extbuf_ = __extbuf_; __extbuf_ = __extbuf_min_; + std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_)); + } + else + { + // Both *this and __rhs use the small buffer. + char __tmp[sizeof(__extbuf_min_)]; + std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_)); + std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_)); + std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_)); } __extbufnext_ = __extbuf_ + __rn; __extbufend_ = __extbuf_ + __re; diff --git a/contrib/libs/cxxsupp/libcxx/include/iterator b/contrib/libs/cxxsupp/libcxx/include/iterator index 4060c2d9d4..1f0390e83a 100644 --- a/contrib/libs/cxxsupp/libcxx/include/iterator +++ b/contrib/libs/cxxsupp/libcxx/include/iterator @@ -660,6 +660,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; #include <__iterator/iterator_traits.h> #include <__iterator/mergeable.h> #include <__iterator/move_iterator.h> +#include <__iterator/move_sentinel.h> #include <__iterator/next.h> #include <__iterator/ostream_iterator.h> #include <__iterator/ostreambuf_iterator.h> diff --git a/contrib/libs/cxxsupp/libcxx/include/map b/contrib/libs/cxxsupp/libcxx/include/map index 8175bf95c0..46a00a0b10 100644 --- a/contrib/libs/cxxsupp/libcxx/include/map +++ b/contrib/libs/cxxsupp/libcxx/include/map @@ -539,7 +539,6 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 #include <__utility/forward.h> #include <__utility/swap.h> #include <compare> -#include <functional> #include <initializer_list> #include <iterator> // __libcpp_erase_if_container #include <memory> diff --git a/contrib/libs/cxxsupp/libcxx/include/mutex b/contrib/libs/cxxsupp/libcxx/include/mutex index 6888b29248..5a5f46923b 100644 --- a/contrib/libs/cxxsupp/libcxx/include/mutex +++ b/contrib/libs/cxxsupp/libcxx/include/mutex @@ -192,7 +192,6 @@ template<class Callable, class ...Args> #include <__threading_support> #include <__utility/forward.h> #include <cstdint> -#include <functional> #include <memory> #ifndef _LIBCPP_CXX03_LANG # include <tuple> diff --git a/contrib/libs/cxxsupp/libcxx/include/numeric b/contrib/libs/cxxsupp/libcxx/include/numeric index 2b96d0c15c..9378f98cc3 100644 --- a/contrib/libs/cxxsupp/libcxx/include/numeric +++ b/contrib/libs/cxxsupp/libcxx/include/numeric @@ -147,7 +147,6 @@ template<class T> #include <__assert> // all public C++ headers provide the assertion handler #include <__config> #include <cmath> // for isnormal -#include <functional> #include <iterator> #include <version> diff --git a/contrib/libs/cxxsupp/libcxx/include/optional b/contrib/libs/cxxsupp/libcxx/include/optional index f0d57a5a79..9adfccff7d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/optional +++ b/contrib/libs/cxxsupp/libcxx/include/optional @@ -162,10 +162,16 @@ template<class T> #include <__availability> #include <__concepts/invocable.h> #include <__config> +#include <__functional/hash.h> +#include <__functional/invoke.h> +#include <__functional/unary_function.h> +#include <__memory/construct_at.h> +#include <__tuple> +#include <__utility/forward.h> #include <__utility/in_place.h> +#include <__utility/move.h> #include <__utility/swap.h> #include <compare> -#include <functional> #include <initializer_list> #include <new> #include <stdexcept> diff --git a/contrib/libs/cxxsupp/libcxx/include/queue b/contrib/libs/cxxsupp/libcxx/include/queue index d15c141920..bd3a39f494 100644 --- a/contrib/libs/cxxsupp/libcxx/include/queue +++ b/contrib/libs/cxxsupp/libcxx/include/queue @@ -227,7 +227,6 @@ template <class T, class Container, class Compare> #include <__utility/forward.h> #include <compare> #include <deque> -#include <functional> #include <type_traits> #include <vector> #include <version> diff --git a/contrib/libs/cxxsupp/libcxx/include/ranges b/contrib/libs/cxxsupp/libcxx/include/ranges index 67a688bbba..82378a6b0d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/ranges +++ b/contrib/libs/cxxsupp/libcxx/include/ranges @@ -150,6 +150,15 @@ namespace std::ranges { template<class T> inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>; + // [range.filter], filter view + template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred> + requires view<V> && is_object_v<Pred> + class filter_view; + + namespace views { + inline constexpr unspecified filter = unspecified; + } + // [range.drop], drop view template<view V> class drop_view; @@ -204,6 +213,31 @@ namespace std::ranges { template<input_range V> requires view<V> && input_range<range_reference_t<V>> class join_view; + + // [range.lazy.split], lazy split view + template<class R> + concept tiny-range = see below; // exposition only + + template<input_range V, forward_range Pattern> + requires view<V> && view<Pattern> && + indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> && + (forward_range<V> || tiny-range<Pattern>) + class lazy_split_view; + + namespace views { + inline constexpr unspecified lazy_split = unspecified; + } + + // [range.zip], zip view + template<input_range... Views> + requires (view<Views> && ...) && (sizeof...(Views) > 0) + class zip_view; // C++2b + + template<class... Views> + inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++2b + (enable_borrowed_range<Views> && ...); + + namespace views { inline constexpr unspecified zip = unspecified; } // C++2b } namespace std { @@ -252,8 +286,10 @@ namespace std { #include <__ranges/empty_view.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> +#include <__ranges/filter_view.h> #include <__ranges/iota_view.h> #include <__ranges/join_view.h> +#include <__ranges/lazy_split_view.h> #include <__ranges/rbegin.h> #include <__ranges/ref_view.h> #include <__ranges/rend.h> @@ -265,6 +301,7 @@ namespace std { #include <__ranges/transform_view.h> #include <__ranges/view_interface.h> #include <__ranges/views.h> +#include <__ranges/zip_view.h> #include <__tuple> // TODO: <ranges> has to export std::tuple_size. Replace this, once <tuple> is granularized. #include <compare> // Required by the standard. #include <initializer_list> // Required by the standard. diff --git a/contrib/libs/cxxsupp/libcxx/include/regex b/contrib/libs/cxxsupp/libcxx/include/regex index 456f34d451..5d078744c5 100644 --- a/contrib/libs/cxxsupp/libcxx/include/regex +++ b/contrib/libs/cxxsupp/libcxx/include/regex @@ -763,6 +763,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; */ #include <__algorithm/find.h> +#include <__algorithm/search.h> #include <__assert> // all public C++ headers provide the assertion handler #include <__config> #include <__iterator/wrap_iter.h> diff --git a/contrib/libs/cxxsupp/libcxx/include/set b/contrib/libs/cxxsupp/libcxx/include/set index b33648b621..b764bbaf0d 100644 --- a/contrib/libs/cxxsupp/libcxx/include/set +++ b/contrib/libs/cxxsupp/libcxx/include/set @@ -481,7 +481,6 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 #include <__tree> #include <__utility/forward.h> #include <compare> -#include <functional> #include <initializer_list> #include <iterator> // __libcpp_erase_if_container #include <version> diff --git a/contrib/libs/cxxsupp/libcxx/include/string b/contrib/libs/cxxsupp/libcxx/include/string index aca6e28b7b..e47984f43e 100644 --- a/contrib/libs/cxxsupp/libcxx/include/string +++ b/contrib/libs/cxxsupp/libcxx/include/string @@ -95,248 +95,246 @@ public: static const size_type npos = -1; basic_string() - noexcept(is_nothrow_default_constructible<allocator_type>::value); - explicit basic_string(const allocator_type& a); - basic_string(const basic_string& str); + noexcept(is_nothrow_default_constructible<allocator_type>::value); // constexpr since C++20 + explicit basic_string(const allocator_type& a); // constexpr since C++20 + basic_string(const basic_string& str); // constexpr since C++20 basic_string(basic_string&& str) - noexcept(is_nothrow_move_constructible<allocator_type>::value); + noexcept(is_nothrow_move_constructible<allocator_type>::value); // constexpr since C++20 basic_string(const basic_string& str, size_type pos, - const allocator_type& a = allocator_type()); + const allocator_type& a = allocator_type()); // constexpr since C++20 basic_string(const basic_string& str, size_type pos, size_type n, - const Allocator& a = Allocator()); + const Allocator& a = Allocator()); // constexpr since C++20 template<class T> - basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 + basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17, constexpr since C++20 template <class T> - explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17 - basic_string(const value_type* s, const allocator_type& a = allocator_type()); - basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); + explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20 + basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20 + basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20 basic_string(nullptr_t) = delete; // C++2b - basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); + basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20 template<class InputIterator> basic_string(InputIterator begin, InputIterator end, - const allocator_type& a = allocator_type()); - basic_string(initializer_list<value_type>, const Allocator& = Allocator()); - basic_string(const basic_string&, const Allocator&); - basic_string(basic_string&&, const Allocator&); + const allocator_type& a = allocator_type()); // constexpr since C++20 + basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20 + basic_string(const basic_string&, const Allocator&); // constexpr since C++20 + basic_string(basic_string&&, const Allocator&); // constexpr since C++20 - ~basic_string(); + ~basic_string(); // constexpr since C++20 - operator basic_string_view<charT, traits>() const noexcept; + operator basic_string_view<charT, traits>() const noexcept; // constexpr since C++20 - basic_string& operator=(const basic_string& str); + basic_string& operator=(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& operator=(const T& t); // C++17 + basic_string& operator=(const T& t); // C++17, constexpr since C++20 basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || - allocator_type::is_always_equal::value ); // C++17 - basic_string& operator=(const value_type* s); + allocator_type::is_always_equal::value ); // C++17, constexpr since C++20 + basic_string& operator=(const value_type* s); // constexpr since C++20 basic_string& operator=(nullptr_t) = delete; // C++2b - basic_string& operator=(value_type c); - basic_string& operator=(initializer_list<value_type>); + basic_string& operator=(value_type c); // constexpr since C++20 + basic_string& operator=(initializer_list<value_type>); // constexpr since C++20 - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin() noexcept; // constexpr since C++20 + const_iterator begin() const noexcept; // constexpr since C++20 + iterator end() noexcept; // constexpr since C++20 + const_iterator end() const noexcept; // constexpr since C++20 - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin() noexcept; // constexpr since C++20 + const_reverse_iterator rbegin() const noexcept; // constexpr since C++20 + reverse_iterator rend() noexcept; // constexpr since C++20 + const_reverse_iterator rend() const noexcept; // constexpr since C++20 - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const noexcept; // constexpr since C++20 + const_iterator cend() const noexcept; // constexpr since C++20 + const_reverse_iterator crbegin() const noexcept; // constexpr since C++20 + const_reverse_iterator crend() const noexcept; // constexpr since C++20 - size_type size() const noexcept; - size_type length() const noexcept; - size_type max_size() const noexcept; - size_type capacity() const noexcept; + size_type size() const noexcept; // constexpr since C++20 + size_type length() const noexcept; // constexpr since C++20 + size_type max_size() const noexcept; // constexpr since C++20 + size_type capacity() const noexcept; // constexpr since C++20 - void resize(size_type n, value_type c); - void resize(size_type n); + void resize(size_type n, value_type c); // constexpr since C++20 + void resize(size_type n); // constexpr since C++20 template<class Operation> constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 - void reserve(size_type res_arg); + void reserve(size_type res_arg); // constexpr since C++20 void reserve(); // deprecated in C++20 - void shrink_to_fit(); - void clear() noexcept; - bool empty() const noexcept; + void shrink_to_fit(); // constexpr since C++20 + void clear() noexcept; // constexpr since C++20 + bool empty() const noexcept; // constexpr since C++20 - const_reference operator[](size_type pos) const; - reference operator[](size_type pos); + const_reference operator[](size_type pos) const; // constexpr since C++20 + reference operator[](size_type pos); // constexpr since C++20 - const_reference at(size_type n) const; - reference at(size_type n); + const_reference at(size_type n) const; // constexpr since C++20 + reference at(size_type n); // constexpr since C++20 - basic_string& operator+=(const basic_string& str); + basic_string& operator+=(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& operator+=(const T& t); // C++17 - basic_string& operator+=(const value_type* s); - basic_string& operator+=(value_type c); - basic_string& operator+=(initializer_list<value_type>); + basic_string& operator+=(const T& t); // C++17, constexpr since C++20 + basic_string& operator+=(const value_type* s); // constexpr since C++20 + basic_string& operator+=(value_type c); // constexpr since C++20 + basic_string& operator+=(initializer_list<value_type>); // constexpr since C++20 - basic_string& append(const basic_string& str); + basic_string& append(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& append(const T& t); // C++17 - basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 + basic_string& append(const T& t); // C++17, constexpr since C++20 + basic_string& append(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 template <class T> - basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 - basic_string& append(const value_type* s, size_type n); - basic_string& append(const value_type* s); - basic_string& append(size_type n, value_type c); + basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 + basic_string& append(const value_type* s, size_type n); // constexpr since C++20 + basic_string& append(const value_type* s); // constexpr since C++20 + basic_string& append(size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& append(InputIterator first, InputIterator last); - basic_string& append(initializer_list<value_type>); + basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20 + basic_string& append(initializer_list<value_type>); // constexpr since C++20 - void push_back(value_type c); - void pop_back(); - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; + void push_back(value_type c); // constexpr since C++20 + void pop_back(); // constexpr since C++20 + reference front(); // constexpr since C++20 + const_reference front() const; // constexpr since C++20 + reference back(); // constexpr since C++20 + const_reference back() const; // constexpr since C++20 - basic_string& assign(const basic_string& str); + basic_string& assign(const basic_string& str); // constexpr since C++20 template <class T> - basic_string& assign(const T& t); // C++17 - basic_string& assign(basic_string&& str); - basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 + basic_string& assign(const T& t); // C++17, constexpr since C++20 + basic_string& assign(basic_string&& str); // constexpr since C++20 + basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14, constexpr since C++20 template <class T> - basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17 - basic_string& assign(const value_type* s, size_type n); - basic_string& assign(const value_type* s); - basic_string& assign(size_type n, value_type c); + basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17, constexpr since C++20 + basic_string& assign(const value_type* s, size_type n); // constexpr since C++20 + basic_string& assign(const value_type* s); // constexpr since C++20 + basic_string& assign(size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& assign(InputIterator first, InputIterator last); - basic_string& assign(initializer_list<value_type>); + basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20 + basic_string& assign(initializer_list<value_type>); // constexpr since C++20 - basic_string& insert(size_type pos1, const basic_string& str); + basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& insert(size_type pos1, const T& t); + basic_string& insert(size_type pos1, const T& t); // constexpr since C++20 basic_string& insert(size_type pos1, const basic_string& str, - size_type pos2, size_type n); + size_type pos2, size_type n); // constexpr since C++20 template <class T> - basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17 - basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14 - basic_string& insert(size_type pos, const value_type* s); - basic_string& insert(size_type pos, size_type n, value_type c); - iterator insert(const_iterator p, value_type c); - iterator insert(const_iterator p, size_type n, value_type c); + basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17, constexpr since C++20 + basic_string& insert(size_type pos, const value_type* s, size_type n=npos); // C++14, constexpr since C++20 + basic_string& insert(size_type pos, const value_type* s); // constexpr since C++20 + basic_string& insert(size_type pos, size_type n, value_type c); // constexpr since C++20 + iterator insert(const_iterator p, value_type c); // constexpr since C++20 + iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - iterator insert(const_iterator p, InputIterator first, InputIterator last); - iterator insert(const_iterator p, initializer_list<value_type>); + iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20 + iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20 - basic_string& erase(size_type pos = 0, size_type n = npos); - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); + basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20 + iterator erase(const_iterator position); // constexpr since C++20 + iterator erase(const_iterator first, const_iterator last); // constexpr since C++20 - basic_string& replace(size_type pos1, size_type n1, const basic_string& str); + basic_string& replace(size_type pos1, size_type n1, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17 + basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17, constexpr since C++20 basic_string& replace(size_type pos1, size_type n1, const basic_string& str, - size_type pos2, size_type n2=npos); // C++14 + size_type pos2, size_type n2=npos); // C++14, constexpr since C++20 template <class T> basic_string& replace(size_type pos1, size_type n1, const T& t, - size_type pos2, size_type n); // C++17 - basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); - basic_string& replace(size_type pos, size_type n1, const value_type* s); - basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); - basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); + size_type pos2, size_type n); // C++17, constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2); // constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, const value_type* s); // constexpr since C++20 + basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); // constexpr since C++20 template <class T> - basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17 - basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); - basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); - basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); + basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17, constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20 template<class InputIterator> - basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); - basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); + basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20 + basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20 - size_type copy(value_type* s, size_type n, size_type pos = 0) const; - basic_string substr(size_type pos = 0, size_type n = npos) const; + size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20 + basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr since C++20 void swap(basic_string& str) noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value || - allocator_traits<allocator_type>::is_always_equal::value); // C++17 + allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20 - const value_type* c_str() const noexcept; - const value_type* data() const noexcept; - value_type* data() noexcept; // C++17 + const value_type* c_str() const noexcept; // constexpr since C++20 + const value_type* data() const noexcept; // constexpr since C++20 + value_type* data() noexcept; // C++17, constexpr since C++20 - allocator_type get_allocator() const noexcept; + allocator_type get_allocator() const noexcept; // constexpr since C++20 - size_type find(const basic_string& str, size_type pos = 0) const noexcept; + size_type find(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - size_type find(const value_type* s, size_type pos, size_type n) const noexcept; - size_type find(const value_type* s, size_type pos = 0) const noexcept; - size_type find(value_type c, size_type pos = 0) const noexcept; + size_type find(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; + size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension - size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; - size_type rfind(const value_type* s, size_type pos = npos) const noexcept; - size_type rfind(value_type c, size_type pos = npos) const noexcept; + size_type rfind(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type rfind(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type rfind(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; - size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; - size_type find_first_of(value_type c, size_type pos = 0) const noexcept; + size_type find_first_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find_first_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension - size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; - size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; - size_type find_last_of(value_type c, size_type pos = npos) const noexcept; + size_type find_last_of(const T& t, size_type pos = npos) const noexcept noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type find_last_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; // constexpr since C++20 template <class T> - size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension - size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; - size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; - size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; + size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; // constexpr since C++20 + size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; // constexpr since C++20 - size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; // constexpr since C++20 template <class T> - size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension - size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; - size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; - size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; + size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; // constexpr since C++20 + size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; // constexpr since C++20 + size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; // constexpr since C++20 - int compare(const basic_string& str) const noexcept; + int compare(const basic_string& str) const noexcept; // constexpr since C++20 template <class T> - int compare(const T& t) const noexcept; // C++17, noexcept as an extension - int compare(size_type pos1, size_type n1, const basic_string& str) const; + int compare(const T& t) const noexcept; // C++17, noexcept as an extension, constexpr since C++20 + int compare(size_type pos1, size_type n1, const basic_string& str) const; // constexpr since C++20 template <class T> - int compare(size_type pos1, size_type n1, const T& t) const; // C++17 + int compare(size_type pos1, size_type n1, const T& t) const; // C++17, constexpr since C++20 int compare(size_type pos1, size_type n1, const basic_string& str, - size_type pos2, size_type n2=npos) const; // C++14 + size_type pos2, size_type n2=npos) const; // C++14, constexpr since C++20 template <class T> int compare(size_type pos1, size_type n1, const T& t, - size_type pos2, size_type n2=npos) const; // C++17 - int compare(const value_type* s) const noexcept; - int compare(size_type pos1, size_type n1, const value_type* s) const; - int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; - - bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 - bool starts_with(charT c) const noexcept; // C++20 - bool starts_with(const charT* s) const; // C++20 - bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 - bool ends_with(charT c) const noexcept; // C++20 - bool ends_with(const charT* s) const; // C++20 - - constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b - constexpr bool contains(charT c) const noexcept; // C++2b - constexpr bool contains(const charT* s) const; // C++2b - - bool __invariants() const; + size_type pos2, size_type n2=npos) const; // C++17, constexpr since C++20 + int compare(const value_type* s) const noexcept; // constexpr since C++20 + int compare(size_type pos1, size_type n1, const value_type* s) const; // constexpr since C++20 + int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; // constexpr since C++20 + + constexpr bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 + constexpr bool starts_with(charT c) const noexcept; // C++20 + constexpr bool starts_with(const charT* s) const; // C++20 + constexpr bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++20 + constexpr bool ends_with(charT c) const noexcept; // C++20 + constexpr bool ends_with(const charT* s) const; // C++20 + + constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b + constexpr bool contains(charT c) const noexcept; // C++2b + constexpr bool contains(const charT* s) const; // C++2b }; template<class InputIterator, @@ -349,88 +347,88 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator()) template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs); + const basic_string<charT, traits, Allocator>& rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); +operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); +operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); +operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> -operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); +operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs); // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; +bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT,traits,Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, - const basic_string<charT, traits, Allocator>& rhs) noexcept; + const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; +bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> -bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; +bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; // constexpr since C++20 template<class charT, class traits, class Allocator> void swap(basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>& rhs) - noexcept(noexcept(lhs.swap(rhs))); + noexcept(noexcept(lhs.swap(rhs))); // constexpr since C++20 template<class charT, class traits, class Allocator> basic_istream<charT, traits>& @@ -508,11 +506,11 @@ template <> struct hash<u16string>; template <> struct hash<u32string>; template <> struct hash<wstring>; -basic_string<char> operator "" s( const char *str, size_t len ); // C++14 -basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14 -basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20 -basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14 -basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14 +basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20 +basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 +constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20 +basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 +basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 } // std @@ -532,6 +530,8 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #include <__utility/auto_cast.h> #include <__utility/move.h> #include <__utility/swap.h> +#include <__utility/unreachable.h> +#include <climits> #include <compare> #include <cstdio> // EOF #include <cstdlib> @@ -539,6 +539,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #include <initializer_list> #include <iosfwd> #include <iterator> +#include <limits> #include <memory> #include <stdexcept> #include <string_view> @@ -581,23 +582,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const basic_string<_CharT, _Traits, _Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); @@ -673,8 +678,8 @@ public: typedef __wrap_iter<pointer> iterator; typedef __wrap_iter<const_pointer> const_iterator; #endif - typedef _VSTD::reverse_iterator<iterator> reverse_iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; private: @@ -684,17 +689,10 @@ private: { pointer __data_; size_type __size_; - size_type __cap_; + size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; + size_type __is_long_ : 1; }; -#ifdef _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x01; - static const size_type __long_mask = 0x1ul; -#else // _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x80; - static const size_type __long_mask = ~(size_type(~0) >> 1); -#endif // _LIBCPP_BIG_ENDIAN - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? (sizeof(__long) - 1)/sizeof(value_type) : 2}; @@ -702,26 +700,46 @@ private: { value_type __data_[__min_cap]; unsigned char __padding[sizeof(value_type) - 1]; - unsigned char __size_; + unsigned char __size_ : 7; + unsigned char __is_long_ : 1; }; +// The __endian_factor is required because the field we use to store the size +// (either size_type or unsigned char depending on long/short) has one fewer +// bit than it would if it were not a bitfield. +// +// If the LSB is used to store the short-flag in the short string representation, +// we have to multiply the size by two when it is stored and divide it by two when +// it is loaded to make sure that we always store an even number. In the long string +// representation, we can ignore this because we can assume that we always allocate +// an even amount of value_types. +// +// If the MSB is used for the short-flag, the max_size() is numeric_limits<size_type>::max() / 2. +// This does not impact the short string representation, since we never need the MSB +// for representing the size of a short string anyway. + +#ifdef _LIBCPP_BIG_ENDIAN + static const size_type __endian_factor = 2; +#else + static const size_type __endian_factor = 1; +#endif + +#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + +#ifdef _LIBCPP_BIG_ENDIAN + static const size_type __endian_factor = 1; #else + static const size_type __endian_factor = 2; +#endif struct __long { - size_type __cap_; + size_type __is_long_ : 1; + size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; size_type __size_; pointer __data_; }; -#ifdef _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x80; - static const size_type __long_mask = ~(size_type(~0) >> 1); -#else // _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x01; - static const size_type __long_mask = 0x1ul; -#endif // _LIBCPP_BIG_ENDIAN - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? (sizeof(__long) - 1)/sizeof(value_type) : 2}; @@ -729,7 +747,10 @@ private: { union { - unsigned char __size_; + struct { + unsigned char __is_long_ : 1; + unsigned char __size_ : 7; + }; value_type __lx; }; value_type __data_[__min_cap]; @@ -761,7 +782,8 @@ private: // Construct a string with the given allocator and enough storage to hold `__size` characters, but // don't initialize the characters. The contents of the string, including the null terminator, must be // initialized separately. - _LIBCPP_HIDE_FROM_ABI explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + explicit basic_string(__uninitialized_size_tag, size_type __size, const allocator_type& __a) : __r_(__default_init_tag(), __a) { if (__size > max_size()) __throw_length_error(); @@ -771,6 +793,7 @@ private: } else { auto __capacity = __recommend(__size) + 1; auto __allocation = __alloc_traits::allocate(__alloc(), __capacity); + __begin_lifetime(__allocation, __capacity); __set_long_cap(__capacity); __set_long_pointer(__allocation); __set_long_size(__size); @@ -782,21 +805,21 @@ public: _LIBCPP_TEMPLATE_DATA_VIS static const size_type npos = -1; - _LIBCPP_INLINE_VISIBILITY basic_string() + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); - _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value); #else _NOEXCEPT; #endif - basic_string(const basic_string& __str); - basic_string(const basic_string& __str, const allocator_type& __a); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); @@ -808,160 +831,165 @@ public: basic_string(nullptr_t) = delete; #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); __init(__s, traits_type::length(__s)); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, const _Allocator& __a); - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(nullptr_t, size_t) = delete; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n); - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(nullptr_t, size_t, const _Allocator&) = delete; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c); template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(size_type __n, _CharT __c, const _Allocator& __a); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t); template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit basic_string(const _Tp& __t, const allocator_type& __a); template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last); template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string(initializer_list<_CharT> __il, const _Allocator& __a); #endif // _LIBCPP_CXX03_LANG - inline ~basic_string(); + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 ~basic_string(); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } - basic_string& operator=(const basic_string& __str); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const basic_string& __str); - basic_string& operator=(nullptr_t) = delete; + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(nullptr_t) = delete; - template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> > - basic_string& operator=(const _Tp& __t) - {__self_view __sv = __t; return assign(__sv);} + template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && + !__is_same_uncvref<_Tp, basic_string>::value> > + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(const _Tp& __t) { + __self_view __sv = __t; + return assign(__sv); + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} #endif - _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator=(const value_type* __s) {return assign(__s);} #if _LIBCPP_STD_VER > 20 basic_string& operator=(nullptr_t) = delete; #endif - basic_string& operator=(value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT {return iterator(this, __get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator begin() const _NOEXCEPT {return const_iterator(this, __get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end() _NOEXCEPT {return iterator(this, __get_pointer() + size());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator end() const _NOEXCEPT {return const_iterator(this, __get_pointer() + size());} #else - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT {return iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator begin() const _NOEXCEPT {return const_iterator(__get_pointer());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end() _NOEXCEPT {return iterator(__get_pointer() + size());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator end() const _NOEXCEPT {return const_iterator(__get_pointer() + size());} #endif // _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type size() const _NOEXCEPT {return __is_long() ? __get_long_size() : __get_short_size();} - _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();} - _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT - {return (__is_long() ? __get_long_cap() - : static_cast<size_type>(__min_cap)) - 1;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type length() const _NOEXCEPT {return size();} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type max_size() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type capacity() const _NOEXCEPT { + return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; + } #if _YNDX_LIBCXX_ENABLE_STRING_RESIZE_UNINITIALIZED == 1 @@ -971,69 +999,81 @@ public: } #endif - void resize(size_type __n, value_type __c); - _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} + _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n) { resize(__n, value_type()); } - void reserve(size_type __requested_capacity); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __requested_capacity); #if _LIBCPP_STD_VER > 20 template <class _Op> _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) { __resize_default_init(__n); - __erase_to_end(_VSTD::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); + __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); } #endif - _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __resize_default_init(size_type __n); + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT; - _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY - void reserve() _NOEXCEPT {shrink_to_fit();} - _LIBCPP_INLINE_VISIBILITY - void shrink_to_fit() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT; - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool empty() const _NOEXCEPT {return size() == 0;} - _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + const_reference operator[](size_type __pos) const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](size_type __pos) _NOEXCEPT; - const_reference at(size_type __n) const; - reference at(size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference at(size_type __n) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 reference at(size_type __n); - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const basic_string& __str) { + return append(__str); + } template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string >::value, basic_string& > - operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;} + operator+=(const _Tp& __t) { + __self_view __sv = __t; return append(__sv); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(const value_type* __s) { + return append(__s); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator+=(value_type __c) { + push_back(__c); + return *this; + } + #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& operator+=(initializer_list<value_type> __il) { return append(__il); } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t< __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); } - basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -1041,11 +1081,11 @@ public: basic_string& > append(const _Tp& __t, size_type __pos, size_type __n=npos); - basic_string& append(const value_type* __s, size_type __n); - basic_string& append(const value_type* __s); - basic_string& append(size_type __n, value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(size_type __n, value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __append_default_init(size_type __n); template<class _InputIterator> @@ -1055,7 +1095,7 @@ public: __is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_InputIterator __first, _InputIterator __last) { const basic_string __temp(__first, __last, __alloc()); append(__temp.data(), __temp.size()); @@ -1068,41 +1108,40 @@ public: __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_string& > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 append(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - void push_back(value_type __c); - _LIBCPP_INLINE_VISIBILITY - void pop_back(); - _LIBCPP_INLINE_VISIBILITY reference front() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY reference back() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void pop_back(); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference front() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& > assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) - {*this = _VSTD::move(__str); return *this;} + {*this = std::move(__str); return *this;} #endif - basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -1110,11 +1149,11 @@ public: basic_string& > assign(const _Tp & __t, size_type __pos, size_type __n=npos); - basic_string& assign(const value_type* __s, size_type __n); - basic_string& assign(const value_type* __s); - basic_string& assign(size_type __n, value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -1122,7 +1161,7 @@ public: > assign(_InputIterator __first, _InputIterator __last); template<class _ForwardIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -1130,15 +1169,15 @@ public: > assign(_ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos1, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1148,22 +1187,23 @@ public: { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); } template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos); - basic_string& insert(size_type __pos, const value_type* __s, size_type __n); - basic_string& insert(size_type __pos, const value_type* __s); - basic_string& insert(size_type __pos, size_type __n, value_type __c); - iterator insert(const_iterator __pos, value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, size_type __n, value_type __c); + _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -1171,7 +1211,7 @@ public: > insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); template<class _ForwardIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -1179,45 +1219,47 @@ public: > insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator insert(const_iterator __pos, initializer_list<value_type> __il) {return insert(__pos, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG - basic_string& erase(size_type __pos = 0, size_type __n = npos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __pos); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, basic_string& > replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); } + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, basic_string& > replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); - basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); - basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1225,14 +1267,14 @@ public: > replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c); template<class _InputIterator> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -1240,16 +1282,16 @@ public: > replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) {return replace(__i1, __i2, __il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG - size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string substr(size_type __pos = 0, size_type __n = npos) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; @@ -1258,123 +1300,129 @@ public: __is_nothrow_swappable<allocator_type>::value); #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const value_type* c_str() const _NOEXCEPT {return data();} - _LIBCPP_INLINE_VISIBILITY - const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());} #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY) - _LIBCPP_INLINE_VISIBILITY - value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());} #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator_type get_allocator() const _NOEXCEPT {return __alloc();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, size_type > find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const basic_string& __str) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1383,7 +1431,7 @@ public: compare(const _Tp &__t) const _NOEXCEPT; template <class _Tp> - _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -1391,72 +1439,69 @@ public: > compare(size_type __pos1, size_type __n1, const _Tp& __t) const; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; - int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 + int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, + size_type __n2 = npos) const; template <class _Tp> - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, int > compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const; - int compare(const value_type* __s) const _NOEXCEPT; - int compare(size_type __pos1, size_type __n1, const value_type* __s) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const value_type* __s) const _NOEXCEPT; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; + _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; //WARN: disabled std guards in order to allow using these options without switching to new std //#if _LIBCPP_STD_VER > 17 - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { return __self_view(data(), size()).starts_with(__sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept { return starts_with(__self_view(__s)); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { return __self_view(data(), size()).ends_with( __sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept { return ends_with(__self_view(__s)); } //#endif #if _LIBCPP_STD_VER >= 20 - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { return __self_view(data(), size()).contains(__sv); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return __self_view(data(), size()).contains(__c); } - constexpr _LIBCPP_INLINE_VISIBILITY + constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return __self_view(data(), size()).contains(__s); } #endif - _LIBCPP_INLINE_VISIBILITY bool __invariants() const; - - _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const; - _LIBCPP_INLINE_VISIBILITY void __shrink_or_extend(size_type __target_capacity); - - _LIBCPP_INLINE_VISIBILITY - bool __is_long() const _NOEXCEPT - {return bool(__r_.first().__s.__size_ & __short_mask);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT; #if _LIBCPP_DEBUG_LEVEL == 2 @@ -1468,6 +1513,49 @@ public: #endif // _LIBCPP_DEBUG_LEVEL == 2 private: + template<class _Alloc> + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + bool friend operator==(const basic_string<char, char_traits<char>, _Alloc>& __lhs, + const basic_string<char, char_traits<char>, _Alloc>& __rhs) _NOEXCEPT; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __shrink_or_extend(size_type __target_capacity); + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + bool __is_long() const _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) + return true; + return __r_.first().__s.__is_long_; + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __begin_lifetime(pointer __begin, size_type __n) { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + for (size_type __i = 0; __i != __n; ++__i) + std::construct_at(std::addressof(__begin[__i])); + } +#else + (void)__begin; + (void)__n; +#endif // _LIBCPP_STD_VER > 17 + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __default_init() { + __zero(); + if (__libcpp_is_constant_evaluated()) { + size_type __sz = __recommend(0) + 1; + pointer __ptr = __alloc_traits::allocate(__alloc(), __sz); + __begin_lifetime(__ptr, __sz); + __set_long_pointer(__ptr); + __set_long_cap(__sz); + __set_long_size(0); + } + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __deallocate_constexpr() { + if (__libcpp_is_constant_evaluated() && __get_pointer() != nullptr) + __alloc_traits::deallocate(__alloc(), __get_pointer(), __get_long_cap()); + } + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); @@ -1500,114 +1588,95 @@ private: return begin() + __ip; } - _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } - _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } - -#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - - _LIBCPP_INLINE_VISIBILITY - void __set_short_size(size_type __s) _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} -# else - {__r_.first().__s.__size_ = (unsigned char)(__s);} -# endif - - _LIBCPP_INLINE_VISIBILITY - size_type __get_short_size() const _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_ >> 1;} -# else - {return __r_.first().__s.__size_;} -# endif - -#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - - _LIBCPP_INLINE_VISIBILITY - void __set_short_size(size_type __s) _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s);} -# else - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} -# endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } - _LIBCPP_INLINE_VISIBILITY - size_type __get_short_size() const _NOEXCEPT -# ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_;} -# else - {return __r_.first().__s.__size_ >> 1;} -# endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __set_short_size(size_type __s) _NOEXCEPT { + _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); + __r_.first().__s.__size_ = __s; + __r_.first().__s.__is_long_ = false; + } -#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type __get_short_size() const _NOEXCEPT { + _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); + return __r_.first().__s.__size_; + } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_size(size_type __s) _NOEXCEPT {__r_.first().__l.__size_ = __s;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __get_long_size() const _NOEXCEPT {return __r_.first().__l.__size_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_size(size_type __s) _NOEXCEPT {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);} - _LIBCPP_INLINE_VISIBILITY - void __set_long_cap(size_type __s) _NOEXCEPT - {__r_.first().__l.__cap_ = __long_mask | __s;} - _LIBCPP_INLINE_VISIBILITY - size_type __get_long_cap() const _NOEXCEPT - {return __r_.first().__l.__cap_ & size_type(~__long_mask);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __set_long_cap(size_type __s) _NOEXCEPT { + __r_.first().__l.__cap_ = __s / __endian_factor; + __r_.first().__l.__is_long_ = true; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + size_type __get_long_cap() const _NOEXCEPT { + return __r_.first().__l.__cap_ * __endian_factor; + } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __set_long_pointer(pointer __p) _NOEXCEPT {__r_.first().__l.__data_ = __p;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_long_pointer() _NOEXCEPT {return __r_.first().__l.__data_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_long_pointer() const _NOEXCEPT {return __r_.first().__l.__data_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_short_pointer() _NOEXCEPT {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_short_pointer() const _NOEXCEPT {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pointer __get_pointer() _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 const_pointer __get_pointer() const _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} - _LIBCPP_INLINE_VISIBILITY - void __zero() _NOEXCEPT - { - size_type (&__a)[__n_words] = __r_.first().__r.__words; - for (unsigned __i = 0; __i < __n_words; ++__i) - __a[__i] = 0; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + void __zero() _NOEXCEPT { + __r_.first() = __rep(); + } template <size_type __a> static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __align_it(size_type __s) _NOEXCEPT {return (__s + (__a-1)) & ~(__a-1);} enum {__alignment = 16}; - static _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type __recommend(size_type __s) _NOEXCEPT - { - if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1; + { + if (__s < __min_cap) { + if (__libcpp_is_constant_evaluated()) + return static_cast<size_type>(__min_cap); + else + return static_cast<size_type>(__min_cap) - 1; + } size_type __guess = __align_it<sizeof(value_type) < __alignment ? __alignment/sizeof(value_type) : 1 > (__s+1) - 1; if (__guess == __min_cap) ++__guess; return __guess; - } + } - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(const value_type* __s, size_type __sz, size_type __reserve); - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(const value_type* __s, size_type __sz); - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init(size_type __n, value_type __c); // Slow path for the (inlined) copy constructor for 'long' strings. @@ -1618,10 +1687,10 @@ private: // to call the __init() functions as those are marked as inline which may // result in over-aggressive inlining by the compiler, where our aim is // to only inline the fast path code directly in the ctor. - void __init_copy_ctor_external(const value_type* __s, size_type __sz); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __init_copy_ctor_external(const value_type* __s, size_type __sz); template <class _InputIterator> - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value @@ -1629,15 +1698,17 @@ private: __init(_InputIterator __first, _InputIterator __last); template <class _ForwardIterator> - inline + inline _LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > __init(_ForwardIterator __first, _ForwardIterator __last); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add = 0); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff); @@ -1646,21 +1717,21 @@ private: // have proof that the input does not alias the current instance. // For example, operator=(basic_string) performs a 'self' check. template <bool __is_short> - basic_string& __assign_no_alias(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_no_alias(const value_type* __s, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_to_end(size_type __pos); // __erase_external_with_move is invoked for erase() invocations where // `n ~= npos`, likely requiring memory moves on the string data. - void __erase_external_with_move(size_type __pos, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_external_with_move(size_type __pos, size_type __n); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str) {__copy_assign_alloc(__str, integral_constant<bool, __alloc_traits::propagate_on_container_copy_assignment::value>());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string& __str, true_type) { if (__alloc() == __str.__alloc()) @@ -1676,8 +1747,9 @@ private: { allocator_type __a = __str.__alloc(); auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); + __begin_lifetime(__allocation.ptr, __allocation.count); __clear_and_shrink(); - __alloc() = _VSTD::move(__a); + __alloc() = std::move(__a); __set_long_pointer(__allocation.ptr); __set_long_cap(__allocation.count); __set_long_size(__str.size()); @@ -1685,15 +1757,15 @@ private: } } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT {} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 _NOEXCEPT; @@ -1702,7 +1774,7 @@ private: #endif #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __str) _NOEXCEPT_( @@ -1711,63 +1783,67 @@ private: {__move_assign_alloc(__str, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { - __alloc() = _VSTD::move(__c.__alloc()); + __alloc() = std::move(__c.__alloc()); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __move_assign_alloc(basic_string&, false_type) _NOEXCEPT {} - basic_string& __assign_external(const value_type* __s); - basic_string& __assign_external(const value_type* __s, size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s); + _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& __assign_external(const value_type* __s, size_type __n); // Assigns the value in __s, guaranteed to be __n < __min_cap in length. inline basic_string& __assign_short(const value_type* __s, size_type __n) { pointer __p = __is_long() ? (__set_long_size(__n), __get_long_pointer()) : (__set_short_size(__n), __get_short_pointer()); - traits_type::move(_VSTD::__to_address(__p), __s, __n); + traits_type::move(std::__to_address(__p), __s, __n); traits_type::assign(__p[__n], value_type()); return *this; } - _LIBCPP_HIDE_FROM_ABI basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { __set_size(__newsz); __invalidate_iterators_past(__newsz); traits_type::assign(__p[__newsz], value_type()); return *this; } - _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); - _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_all_iterators(); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void __invalidate_iterators_past(size_type); template<class _Tp> - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __addr_in_range(_Tp&& __t) const { - const volatile void *__p = _VSTD::addressof(__t); + // assume that the ranges overlap, because we can't check during constant evaluation + if (__libcpp_is_constant_evaluated()) + return true; + const volatile void *__p = std::addressof(__t); return data() <= __p && __p <= data() + size(); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { - _VSTD::__throw_length_error("basic_string"); + std::__throw_length_error("basic_string"); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { - _VSTD::__throw_out_of_range("basic_string"); + std::__throw_out_of_range("basic_string"); } - friend basic_string operator+<>(const basic_string&, const basic_string&); - friend basic_string operator+<>(const value_type*, const basic_string&); - friend basic_string operator+<>(value_type, const basic_string&); - friend basic_string operator+<>(const basic_string&, const value_type*); - friend basic_string operator+<>(const basic_string&, value_type); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*); + friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type); }; // These declarations must appear before any functions are implicitly used @@ -1814,7 +1890,7 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _ #endif template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() { @@ -1825,7 +1901,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) { @@ -1843,7 +1919,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type { (*__p)->__c_ = nullptr; if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); } } __get_db()->unlock(); @@ -1855,17 +1931,17 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) : __r_(__default_init_tag(), __default_init_tag()) { - _VSTD::__debug_db_insert_c(this); - __zero(); + std::__debug_db_insert_c(this); + __default_init(); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) @@ -1874,15 +1950,18 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #endif : __r_(__default_init_tag(), __a) { - _VSTD::__debug_db_insert_c(this); - __zero(); + std::__debug_db_insert_c(this); + __default_init(); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__reserve > max_size()) __throw_length_error(); pointer __p; @@ -1895,18 +1974,22 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, { auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__reserve) + 1); __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(std::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__sz > max_size()) __throw_length_error(); pointer __p; @@ -1919,57 +2002,61 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty { auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(std::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } template <class _CharT, class _Traits, class _Allocator> template <class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); __init(__s, __n); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( const basic_string& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) @@ -1977,14 +2064,17 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), + __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { + if (__libcpp_is_constant_evaluated()) + __zero(); pointer __p; if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); @@ -1994,27 +2084,28 @@ void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( __throw_length_error(); auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); __set_long_cap(__allocation.count); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); + traits_type::copy(std::__to_address(__p), __s, __sz + 1); } #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) #else _NOEXCEPT #endif - : __r_(_VSTD::move(__str.__r_)) + : __r_(std::move(__str.__r_)) { - __str.__zero(); - _VSTD::__debug_db_insert_c(this); + __str.__default_init(); + std::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 if (!__libcpp_is_constant_evaluated() && __is_long()) __get_db()->swap(this, &__str); @@ -2022,18 +2113,23 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) : __r_(__default_init_tag(), __a) { if (__str.__is_long() && __a != __str.__alloc()) // copy, not move - __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); + __init(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); else { - __r_.first().__r = __str.__r_.first().__r; - __str.__zero(); + if (__libcpp_is_constant_evaluated()) { + __zero(); + __r_.first().__l = __str.__r_.first().__l; + } else { + __r_.first().__r = __str.__r_.first().__r; + } + __str.__default_init(); } - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 if (!__libcpp_is_constant_evaluated() && __is_long()) __get_db()->swap(this, &__str); @@ -2043,9 +2139,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, co #endif // _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { + if (__libcpp_is_constant_evaluated()) + __zero(); if (__n > max_size()) __throw_length_error(); pointer __p; @@ -2058,33 +2157,36 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__n) + 1); __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); __set_long_cap(__allocation.count); __set_long_size(__n); } - traits_type::assign(_VSTD::__to_address(__p), __n, __c); + traits_type::assign(std::__to_address(__p), __n, __c); traits_type::assign(__p[__n], value_type()); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __init(__n, __c); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a) @@ -2093,12 +2195,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st size_type __str_sz = __str.size(); if (__pos > __str_sz) __throw_out_of_range(); - __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); - _VSTD::__debug_db_insert_c(this); + __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a) : __r_(__default_init_tag(), __a) @@ -2107,11 +2209,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st if (__pos > __str_sz) __throw_out_of_range(); __init(__str.data() + __pos, __str_sz - __pos); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) : __r_(__default_init_tag(), __a) @@ -2119,38 +2222,41 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) : __r_(__default_init_tag(), __default_init_tag()) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp, class> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value > basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) { - __zero(); + __default_init(); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2170,13 +2276,16 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template <class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value > basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) { - size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); + if (__libcpp_is_constant_evaluated()) + __zero(); + size_type __sz = static_cast<size_type>(std::distance(__first, __last)); if (__sz > max_size()) __throw_length_error(); pointer __p; @@ -2189,6 +2298,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For { auto __allocation = std::__allocate_at_least(__alloc(), __recommend(__sz) + 1); __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __set_long_pointer(__p); __set_long_cap(__allocation.count); __set_long_size(__sz); @@ -2214,51 +2324,51 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator, class> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator, class> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : __r_(__default_init_tag(), __a) { __init(__first, __last); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il) : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> -inline - +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il, const _Allocator& __a) : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); - _VSTD::__debug_db_insert_c(this); + std::__debug_db_insert_c(this); } #endif // _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::~basic_string() { #if _LIBCPP_DEBUG_LEVEL == 2 @@ -2270,6 +2380,7 @@ basic_string<_CharT, _Traits, _Allocator>::~basic_string() } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace (size_type __old_cap, size_type __delta_cap, size_type __old_sz, @@ -2280,21 +2391,22 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : + __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); pointer __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __invalidate_all_iterators(); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_address(__p), - _VSTD::__to_address(__old_p), __n_copy); + traits_type::copy(std::__to_address(__p), + std::__to_address(__old_p), __n_copy); if (__n_add != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); + traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, - _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) + traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, + std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); + if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated()) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__allocation.count); @@ -2305,6 +2417,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace template <class _CharT, class _Traits, class _Allocator> void +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add) { @@ -2313,21 +2426,22 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : + __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); pointer __p = __allocation.ptr; + __begin_lifetime(__p, __allocation.count); __invalidate_all_iterators(); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_address(__p), - _VSTD::__to_address(__old_p), __n_copy); + traits_type::copy(std::__to_address(__p), + std::__to_address(__old_p), __n_copy); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, - _VSTD::__to_address(__old_p) + __n_copy + __n_del, + traits_type::copy(std::__to_address(__p) + __n_copy + __n_add, + std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) - __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); + if (__libcpp_is_constant_evaluated() || __old_cap + 1 != __min_cap) + __alloc_traits::deallocate(__alloc(), __old_p, __old_cap + 1); __set_long_pointer(__p); __set_long_cap(__allocation.count); } @@ -2336,6 +2450,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t template <class _CharT, class _Traits, class _Allocator> template <bool __is_short> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( const value_type* __s, size_type __n) { @@ -2343,7 +2458,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( if (__n < __cap) { pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); __is_short ? __set_short_size(__n) : __set_long_size(__n); - traits_type::copy(_VSTD::__to_address(__p), __s, __n); + traits_type::copy(std::__to_address(__p), __s, __n); traits_type::assign(__p[__n], value_type()); __invalidate_iterators_past(__n); } else { @@ -2354,12 +2469,13 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_external( const value_type* __s, size_type __n) { size_type __cap = capacity(); if (__cap >= __n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::move(__p, __s, __n); return __null_terminate_at(__p, __n); } else { @@ -2370,6 +2486,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_external( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { @@ -2380,6 +2497,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_ty } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) { @@ -2389,12 +2507,13 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) size_type __sz = size(); __grow_by(__cap, __n - __cap, __sz, 0, __sz); } - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); return __null_terminate_at(__p, __n); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) { @@ -2416,6 +2535,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) { @@ -2437,7 +2557,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value) @@ -2449,7 +2569,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, fa } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 @@ -2470,12 +2590,16 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr } __move_assign_alloc(__str); __r_.first() = __str.__r_.first(); - __str.__set_short_size(0); - traits_type::assign(__str.__get_short_pointer()[0], value_type()); + if (__libcpp_is_constant_evaluated()) { + __str.__default_init(); + } else { + __str.__set_short_size(0); + traits_type::assign(__str.__get_short_pointer()[0], value_type()); + } } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) @@ -2489,6 +2613,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2503,6 +2628,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2512,7 +2638,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For { size_type __cap = capacity(); size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? - static_cast<size_type>(_VSTD::distance(__first, __last)) : 0; + static_cast<size_type>(std::distance(__first, __last)) : 0; if (__string_is_trivial_iterator<_ForwardIterator>::value && (__cap >= __n || !__addr_in_range(*__first))) @@ -2538,17 +2664,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { size_type __sz = __str.size(); if (__pos > __sz) __throw_out_of_range(); - return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return assign(__str.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -2561,17 +2689,19 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p size_type __sz = __sv.size(); if (__pos > __sz) __throw_out_of_range(); - return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { return __assign_external(__s, traits_type::length(__s)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { @@ -2585,6 +2715,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) // append template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) { @@ -2595,7 +2726,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty { if (__n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); traits_type::copy(__p + __sz, __s, __n); __sz += __n; __set_size(__sz); @@ -2608,6 +2739,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) { @@ -2618,7 +2750,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) if (__cap - __sz < __n) __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer(); - traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c); + traits_type::assign(std::__to_address(__p) + __sz, __n, __c); __sz += __n; __set_size(__sz); traits_type::assign(__p[__sz], value_type()); @@ -2627,7 +2759,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline void +_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) { if (__n) @@ -2644,6 +2776,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { @@ -2665,7 +2798,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) __grow_by(__cap, 1, __sz, __sz, 0); __is_short = false; // the string is always long after __grow_by } - pointer __p; + pointer __p = __get_pointer(); if (__is_short) { __p = __get_short_pointer() + __sz; @@ -2682,6 +2815,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2692,7 +2826,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( { size_type __sz = size(); size_type __cap = capacity(); - size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); + size_type __n = static_cast<size_type>(std::distance(__first, __last)); if (__n) { if (__string_is_trivial_iterator<_ForwardIterator>::value && @@ -2716,7 +2850,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) { @@ -2724,17 +2858,19 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) { size_type __sz = __str.size(); if (__pos > __sz) __throw_out_of_range(); - return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return append(__str.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -2746,10 +2882,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p size_type __sz = __sv.size(); if (__pos > __sz) __throw_out_of_range(); - return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); + return append(__sv.data() + __pos, std::min(__n, __sz - __pos)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2760,6 +2897,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) // insert template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) { @@ -2768,11 +2906,18 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t if (__pos > __sz) __throw_out_of_range(); size_type __cap = capacity(); + if (__libcpp_is_constant_evaluated()) { + if (__cap - __sz >= __n) + __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s); + else + __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s); + return *this; + } if (__cap - __sz >= __n) { if (__n) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + value_type* __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) { @@ -2792,6 +2937,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c) { @@ -2804,7 +2950,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n value_type* __p; if (__cap - __sz >= __n) { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) traits_type::move(__p + __pos + __n, __p + __pos, __n_move); @@ -2812,7 +2958,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n else { __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n, __c); __sz += __n; @@ -2824,6 +2970,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_exactly_cpp17_input_iterator<_InputIterator>::value, @@ -2840,6 +2987,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_forward_iterator<_ForwardIterator>::value, @@ -2867,7 +3015,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) { @@ -2875,6 +3023,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n) @@ -2882,11 +3031,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ size_type __str_sz = __str.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); + return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -2899,10 +3049,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _ size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); + return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { @@ -2911,6 +3062,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) { @@ -2925,11 +3077,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty if (__cap == __sz) { __grow_by(__cap, 1, __sz, __ip, 0, 1); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } else { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); size_type __n_move = __sz - __ip; if (__n_move != 0) traits_type::move(__p + __ip + 1, __p + __ip, __n_move); @@ -2941,7 +3093,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) { @@ -2956,6 +3108,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_typ // replace template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK @@ -2964,11 +3117,15 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - __n1 = _VSTD::min(__n1, __sz - __pos); + __n1 = std::min(__n1, __sz - __pos); size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) { - value_type* __p = _VSTD::__to_address(__get_pointer()); + if (__libcpp_is_constant_evaluated()) { + __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s); + return *this; + } + value_type* __p = std::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -3005,18 +3162,19 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c) { size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - __n1 = _VSTD::min(__n1, __sz - __pos); + __n1 = std::min(__n1, __sz - __pos); size_type __cap = capacity(); value_type* __p; if (__cap - __sz + __n1 >= __n2) { - __p = _VSTD::__to_address(__get_pointer()); + __p = std::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -3027,7 +3185,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ else { __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); - __p = _VSTD::__to_address(__get_long_pointer()); + __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n2, __c); return __null_terminate_at(__p, __sz - (__n1 - __n2)); @@ -3035,6 +3193,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __is_cpp17_input_iterator<_InputIterator>::value, @@ -3048,7 +3207,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) { @@ -3056,6 +3215,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) @@ -3063,11 +3223,12 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ size_type __str_sz = __str.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); + return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, @@ -3080,10 +3241,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) __throw_out_of_range(); - return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); + return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2)); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { @@ -3092,7 +3254,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { @@ -3101,7 +3263,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { @@ -3109,7 +3271,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { @@ -3117,7 +3279,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { @@ -3129,6 +3291,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it // 'externally instantiated' erase() implementation, called when __n != npos. // Does not check __pos against size() template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( size_type __pos, size_type __n) @@ -3136,8 +3299,8 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( if (__n) { size_type __sz = size(); - value_type* __p = _VSTD::__to_address(__get_pointer()); - __n = _VSTD::min(__n, __sz - __pos); + value_type* __p = std::__to_address(__get_pointer()); + __n = std::min(__n, __sz - __pos); size_type __n_move = __sz - __pos - __n; if (__n_move != 0) traits_type::move(__p + __pos, __p + __pos + __n, __n_move); @@ -3146,6 +3309,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { @@ -3160,7 +3324,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { @@ -3176,7 +3340,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { @@ -3192,7 +3356,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_i } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::pop_back() { @@ -3201,7 +3365,7 @@ basic_string<_CharT, _Traits, _Allocator>::pop_back() } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { @@ -3219,14 +3383,15 @@ basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { - __null_terminate_at(_VSTD::__to_address(__get_pointer()), __pos); + __null_terminate_at(std::__to_address(__get_pointer()), __pos); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) { @@ -3238,7 +3403,7 @@ basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline void +_LIBCPP_CONSTEXPR_AFTER_CXX17 inline void basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) { size_type __sz = size(); @@ -3249,19 +3414,21 @@ basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT { size_type __m = __alloc_traits::max_size(__alloc()); -#ifdef _LIBCPP_BIG_ENDIAN - return (__m <= ~__long_mask ? __m : __m/2) - __alignment; -#else - return __m - __alignment; -#endif + if (__m <= std::numeric_limits<size_type>::max() / 2) { + return __m - __alignment; + } else { + bool __uses_lsb = __endian_factor == 2; + return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment; + } } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { @@ -3274,7 +3441,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit if (__requested_capacity <= capacity()) return; - size_type __target_capacity = _VSTD::max(__requested_capacity, size()); + size_type __target_capacity = std::max(__requested_capacity, size()); __target_capacity = __recommend(__target_capacity); if (__target_capacity == capacity()) return; @@ -3282,7 +3449,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacit } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { @@ -3293,7 +3460,7 @@ basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity) { @@ -3302,7 +3469,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target pointer __new_data, __p; bool __was_long, __now_long; - if (__target_capacity == __min_cap - 1) + if (__fits_in_sso(__target_capacity)) { __was_long = true; __now_long = false; @@ -3336,12 +3503,13 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target return; #endif // _LIBCPP_NO_EXCEPTIONS } + __begin_lifetime(__new_data, __target_capacity + 1); __now_long = true; __was_long = __is_long(); __p = __get_pointer(); } - traits_type::copy(_VSTD::__to_address(__new_data), - _VSTD::__to_address(__p), size()+1); + traits_type::copy(std::__to_address(__new_data), + std::__to_address(__p), size()+1); if (__was_long) __alloc_traits::deallocate(__alloc(), __p, __cap+1); if (__now_long) @@ -3356,7 +3524,7 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT { @@ -3365,7 +3533,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NO } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { @@ -3374,6 +3542,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { @@ -3383,6 +3552,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { @@ -3392,7 +3562,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT { @@ -3401,7 +3571,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT { @@ -3410,7 +3580,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT { @@ -3419,7 +3589,7 @@ basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT { @@ -3428,19 +3598,20 @@ basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const { size_type __sz = size(); if (__pos > __sz) __throw_out_of_range(); - size_type __rlen = _VSTD::min(__n, __sz - __pos); + size_type __rlen = std::min(__n, __sz - __pos); traits_type::copy(__s, data() + __pos, __rlen); return __rlen; } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const { @@ -3448,7 +3619,7 @@ basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 @@ -3471,8 +3642,8 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || __alloc() == __str.__alloc(), "swapping non-equal allocators"); - _VSTD::swap(__r_.first(), __str.__r_.first()); - _VSTD::__swap_allocator(__alloc(), __str.__alloc()); + std::swap(__r_.first(), __str.__r_.first()); + std::__swap_allocator(__alloc(), __str.__alloc()); } // find @@ -3481,12 +3652,13 @@ template <class _Traits> struct _LIBCPP_HIDDEN __traits_eq { typedef typename _Traits::char_type char_type; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_HIDE_FROM_ABI bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT {return _Traits::eq(__x, __y);} }; template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos, @@ -3498,7 +3670,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3509,6 +3681,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3523,7 +3696,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3534,6 +3707,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT @@ -3545,6 +3719,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, // rfind template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos, @@ -3556,7 +3731,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3567,6 +3742,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3581,7 +3757,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3592,6 +3768,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT @@ -3603,6 +3780,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, // find_first_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos, @@ -3614,7 +3792,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3625,6 +3803,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3639,7 +3818,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3650,7 +3829,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3661,6 +3840,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, // find_last_of template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos, @@ -3672,7 +3852,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3683,6 +3863,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3697,7 +3878,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3708,7 +3889,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3719,6 +3900,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, // find_first_not_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos, @@ -3730,7 +3912,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3741,6 +3923,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3755,7 +3938,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3766,7 +3949,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3778,6 +3961,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, // find_last_not_of template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos, @@ -3789,7 +3973,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3800,6 +3984,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& template<class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3814,7 +3999,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3825,7 +4010,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3838,6 +4023,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3849,7 +4035,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE size_t __lhs_sz = size(); size_t __rhs_sz = __sv.size(); int __result = traits_type::compare(data(), __sv.data(), - _VSTD::min(__lhs_sz, __rhs_sz)); + std::min(__lhs_sz, __rhs_sz)); if (__result != 0) return __result; if (__lhs_sz < __rhs_sz) @@ -3860,7 +4046,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCE } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { @@ -3868,6 +4054,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) co } template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3878,8 +4065,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __sz = size(); if (__pos1 > __sz || __n2 == npos) __throw_out_of_range(); - size_type __rlen = _VSTD::min(__n1, __sz - __pos1); - int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); + size_type __rlen = std::min(__n1, __sz - __pos1); + int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2)); if (__r == 0) { if (__rlen < __n2) @@ -3892,6 +4079,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, @@ -3906,7 +4094,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3917,6 +4105,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, template <class _CharT, class _Traits, class _Allocator> template <class _Tp> +_LIBCPP_CONSTEXPR_AFTER_CXX17 __enable_if_t < __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value @@ -3934,6 +4123,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3945,6 +4135,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT { @@ -3953,6 +4144,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3965,7 +4157,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, // __invariants template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { @@ -3983,7 +4175,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const // __clear_and_shrink template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { @@ -4000,7 +4192,7 @@ basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT // operator== template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4012,7 +4204,7 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT @@ -4031,7 +4223,7 @@ operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4044,7 +4236,7 @@ operator==(const _CharT* __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4057,7 +4249,7 @@ operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4066,7 +4258,7 @@ operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4075,7 +4267,7 @@ operator!=(const _CharT* __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4086,7 +4278,7 @@ operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, // operator< template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4095,7 +4287,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4104,7 +4296,7 @@ operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator< (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4115,7 +4307,7 @@ operator< (const _CharT* __lhs, // operator> template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4124,7 +4316,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4133,7 +4325,7 @@ operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator> (const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4144,7 +4336,7 @@ operator> (const _CharT* __lhs, // operator<= template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4153,7 +4345,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4162,7 +4354,7 @@ operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4173,7 +4365,7 @@ operator<=(const _CharT* __lhs, // operator>= template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4182,7 +4374,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT @@ -4191,7 +4383,7 @@ operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT @@ -4202,6 +4394,7 @@ operator>=(const _CharT* __lhs, // operator + template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) @@ -4220,6 +4413,7 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4237,6 +4431,7 @@ operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& _ } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) { @@ -4253,7 +4448,7 @@ operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) } template<class _CharT, class _Traits, class _Allocator> -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { @@ -4271,6 +4466,7 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* } template<class _CharT, class _Traits, class _Allocator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) { @@ -4289,61 +4485,61 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs) #ifndef _LIBCPP_CXX03_LANG template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { - return _VSTD::move(__rhs.insert(0, __lhs)); + return std::move(__rhs.insert(0, __lhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs) { - return _VSTD::move(__rhs.insert(0, __lhs)); + return std::move(__rhs.insert(0, __lhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs) { __rhs.insert(__rhs.begin(), __lhs); - return _VSTD::move(__rhs); + return std::move(__rhs); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs) { - return _VSTD::move(__lhs.append(__rhs)); + return std::move(__lhs.append(__rhs)); } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<_CharT, _Traits, _Allocator> operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) { __lhs.push_back(__rhs); - return _VSTD::move(__lhs); + return std::move(__lhs); } #endif // _LIBCPP_CXX03_LANG @@ -4351,7 +4547,7 @@ operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs) // swap template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>& __rhs) @@ -4435,40 +4631,40 @@ getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm); template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str); #if _LIBCPP_STD_VER > 17 template <class _CharT, class _Traits, class _Allocator, class _Up> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { auto __old_size = __str.size(); - __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); + __str.erase(std::remove(__str.begin(), __str.end(), __v), __str.end()); return __old_size - __str.size(); } template <class _CharT, class _Traits, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename basic_string<_CharT, _Traits, _Allocator>::size_type erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { auto __old_size = __str.size(); - __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), + __str.erase(std::remove_if(__str.begin(), __str.end(), __pred), __str.end()); return __old_size - __str.size(); } @@ -4480,23 +4676,23 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return data() <= _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) < data() + size(); + return data() <= std::__to_address(__i->base()) && + std::__to_address(__i->base()) < data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const { - return data() < _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) <= data() + size(); + return data() < std::__to_address(__i->base()) && + std::__to_address(__i->base()) <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_address(__i->base()) + __n; + const value_type* __p = std::__to_address(__i->base()) + __n; return data() <= __p && __p <= data() + size(); } @@ -4504,7 +4700,7 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_address(__i->base()) + __n; + const value_type* __p = std::__to_address(__i->base()) + __n; return data() <= __p && __p < data() + size(); } @@ -4516,14 +4712,14 @@ inline namespace literals { inline namespace string_literals { - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char> operator "" s( const char *__str, size_t __len ) { return basic_string<char> (__str, __len); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) { return basic_string<wchar_t> (__str, __len); @@ -4531,20 +4727,20 @@ inline namespace literals #endif #ifndef _LIBCPP_HAS_NO_CHAR8_T - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT { return basic_string<char8_t> (__str, __len); } #endif - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) { return basic_string<char16_t> (__str, __len); } - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) { return basic_string<char32_t> (__str, __len); diff --git a/contrib/libs/cxxsupp/libcxx/include/thread b/contrib/libs/cxxsupp/libcxx/include/thread index 540f591f9d..837ee4a997 100644 --- a/contrib/libs/cxxsupp/libcxx/include/thread +++ b/contrib/libs/cxxsupp/libcxx/include/thread @@ -90,7 +90,6 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <__threading_support> #include <__utility/forward.h> #include <cstddef> -#include <functional> #include <iosfwd> #include <memory> #include <system_error> diff --git a/contrib/libs/cxxsupp/libcxx/include/type_traits b/contrib/libs/cxxsupp/libcxx/include/type_traits index bb1bf3f355..1337892256 100644 --- a/contrib/libs/cxxsupp/libcxx/include/type_traits +++ b/contrib/libs/cxxsupp/libcxx/include/type_traits @@ -416,7 +416,6 @@ namespace std } */ - #include <__assert> // all public C++ headers provide the assertion handler #include <__config> #include <__type_traits/integral_constant.h> @@ -3658,6 +3657,15 @@ struct __invoke_of { }; +#else + +// Assume that it's a functor in C++03 +template <class _Func, class... _Args> +_LIBCPP_HIDE_FROM_ABI +decltype(std::declval<_Func>()(std::declval<_Args>()...)) __invoke(_Func&& __func, _Args&&... __args) { + return static_cast<_Func&&>(__func)(static_cast<_Args&&>(__args)...); +} + #endif // _LIBCPP_CXX03_LANG // result_of diff --git a/contrib/libs/cxxsupp/libcxx/include/unordered_map b/contrib/libs/cxxsupp/libcxx/include/unordered_map index b7acfc3c8d..a31c2c6dde 100644 --- a/contrib/libs/cxxsupp/libcxx/include/unordered_map +++ b/contrib/libs/cxxsupp/libcxx/include/unordered_map @@ -525,7 +525,6 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__node_handle> #include <__utility/forward.h> #include <compare> -#include <functional> #include <iterator> // __libcpp_erase_if_container #include <stdexcept> #include <tuple> diff --git a/contrib/libs/cxxsupp/libcxx/include/unordered_set b/contrib/libs/cxxsupp/libcxx/include/unordered_set index f4ec9f5d5e..f23de20456 100644 --- a/contrib/libs/cxxsupp/libcxx/include/unordered_set +++ b/contrib/libs/cxxsupp/libcxx/include/unordered_set @@ -469,7 +469,6 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__node_handle> #include <__utility/forward.h> #include <compare> -#include <functional> #include <iterator> // __libcpp_erase_if_container #include <version> diff --git a/contrib/libs/cxxsupp/libcxx/include/valarray b/contrib/libs/cxxsupp/libcxx/include/valarray index dba3077d2c..bae7bc41d4 100644 --- a/contrib/libs/cxxsupp/libcxx/include/valarray +++ b/contrib/libs/cxxsupp/libcxx/include/valarray @@ -350,9 +350,13 @@ template <class T> unspecified2 end(const valarray<T>& v); #include <__algorithm/unwrap_iter.h> #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#include <__functional/operations.h> +#include <__memory/allocator.h> +#include <__memory/uninitialized_algorithms.h> +#include <__utility/move.h> +#include <__utility/swap.h> #include <cmath> #include <cstddef> -#include <functional> #include <initializer_list> #include <new> #include <version> diff --git a/contrib/libs/cxxsupp/libcxx/include/vector b/contrib/libs/cxxsupp/libcxx/include/vector index 1e9e9984da..d4cfaed952 100644 --- a/contrib/libs/cxxsupp/libcxx/include/vector +++ b/contrib/libs/cxxsupp/libcxx/include/vector @@ -2132,7 +2132,11 @@ private: __compressed_pair<size_type, __storage_allocator> __cap_alloc_; public: typedef __bit_reference<vector> reference; +#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + using const_reference = bool; +#else typedef __bit_const_reference<vector> const_reference; +#endif private: _LIBCPP_INLINE_VISIBILITY size_type& __cap() _NOEXCEPT @@ -2329,7 +2333,6 @@ public: iterator insert(const_iterator __position, const value_type& __x); iterator insert(const_iterator __position, size_type __n, const value_type& __x); - iterator insert(const_iterator __position, size_type __n, const_reference __x); template <class _InputIterator> typename enable_if < @@ -2418,8 +2421,10 @@ private: reference __make_ref(size_type __pos) _NOEXCEPT {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY - const_reference __make_ref(size_type __pos) const _NOEXCEPT - {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + const_reference __make_ref(size_type __pos) const _NOEXCEPT { + return __bit_const_reference<vector>(__begin_ + __pos / __bits_per_word, + __storage_type(1) << __pos % __bits_per_word); + } _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos) _NOEXCEPT {return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));} diff --git a/contrib/libs/cxxsupp/libcxx/include/version b/contrib/libs/cxxsupp/libcxx/include/version index 7bbb57a0a3..b8d03ac651 100644 --- a/contrib/libs/cxxsupp/libcxx/include/version +++ b/contrib/libs/cxxsupp/libcxx/include/version @@ -63,7 +63,7 @@ __cpp_lib_constexpr_functional 201907L <functional> __cpp_lib_constexpr_iterator 201811L <iterator> __cpp_lib_constexpr_memory 201811L <memory> __cpp_lib_constexpr_numeric 201911L <numeric> -__cpp_lib_constexpr_string 201811L <string> +__cpp_lib_constexpr_string 201907L <string> __cpp_lib_constexpr_string_view 201811L <string_view> __cpp_lib_constexpr_tuple 201811L <tuple> __cpp_lib_constexpr_typeinfo 202106L <typeinfo> @@ -324,7 +324,7 @@ __cpp_lib_void_t 201411L <type_traits> # define __cpp_lib_constexpr_iterator 201811L # define __cpp_lib_constexpr_memory 201811L # define __cpp_lib_constexpr_numeric 201911L -# define __cpp_lib_constexpr_string 201811L +# define __cpp_lib_constexpr_string 201907L # define __cpp_lib_constexpr_string_view 201811L # define __cpp_lib_constexpr_tuple 201811L # define __cpp_lib_constexpr_utility 201811L diff --git a/contrib/libs/cxxsupp/libcxx/src/thread.cpp b/contrib/libs/cxxsupp/libcxx/src/thread.cpp index 0734659d2d..ce2822dbac 100644 --- a/contrib/libs/cxxsupp/libcxx/src/thread.cpp +++ b/contrib/libs/cxxsupp/libcxx/src/thread.cpp @@ -115,8 +115,13 @@ sleep_for(const chrono::nanoseconds& ns) __thread_specific_ptr<__thread_struct>& __thread_local_data() { - static __thread_specific_ptr<__thread_struct> __p; - return __p; + // Even though __thread_specific_ptr's destructor doesn't actually destroy + // anything (see comments there), we can't call it at all because threads may + // outlive the static variable and calling its destructor means accessing an + // object outside of its lifetime, which is UB. + alignas(__thread_specific_ptr<__thread_struct>) static char __b[sizeof(__thread_specific_ptr<__thread_struct>)]; + static __thread_specific_ptr<__thread_struct>* __p = new (__b) __thread_specific_ptr<__thread_struct>(); + return *__p; } // __thread_struct_imp diff --git a/contrib/libs/cxxsupp/libcxx/ya.make b/contrib/libs/cxxsupp/libcxx/ya.make index b93f620823..411b23022f 100644 --- a/contrib/libs/cxxsupp/libcxx/ya.make +++ b/contrib/libs/cxxsupp/libcxx/ya.make @@ -13,9 +13,9 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(2022-04-12) +VERSION(2022-05-01) -ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/0cc34ca7ecfc9d0efee322f60ed6c3169f4f70ca.tar.gz) +ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/639b9618f46d75f4dabd2082b3f6ba8433c287bf.tar.gz) ADDINCL( GLOBAL contrib/libs/cxxsupp/libcxx/include |