diff options
Diffstat (limited to 'libcxx/include')
27 files changed, 393 insertions, 229 deletions
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index ed54751..51444ec 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -381,6 +381,7 @@ set(files __format/enable_insertable.h __format/escaped_output_table.h __format/extended_grapheme_cluster_table.h + __format/fmt_pair_like.h __format/format_arg.h __format/format_arg_store.h __format/format_args.h diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h index ea98031..6387728 100644 --- a/libcxx/include/__algorithm/copy.h +++ b/libcxx/include/__algorithm/copy.h @@ -182,7 +182,7 @@ struct __copy_impl { } }; - template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> + template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result)); @@ -192,7 +192,7 @@ struct __copy_impl { template <class _InIter, class _OutIter, __enable_if_t<__has_random_access_iterator_category<_InIter>::value && - !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h index 9f89064..807c64b 100644 --- a/libcxx/include/__algorithm/copy_backward.h +++ b/libcxx/include/__algorithm/copy_backward.h @@ -170,7 +170,7 @@ struct __copy_backward_impl { return std::make_pair(std::move(__original_last_iter), std::move(__result)); } - template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> + template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_InIter>; @@ -200,7 +200,7 @@ struct __copy_backward_impl { template <class _InIter, class _OutIter, __enable_if_t<__has_random_access_iterator_category<_InIter>::value && - !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index a7d9374..8c8cb58 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -149,7 +149,7 @@ struct __find_segment; template <class _SegmentedIterator, class _Tp, class _Proj, - __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0> + __enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator __find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) { return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj); diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h index 4167eec..e31fcae 100644 --- a/libcxx/include/__algorithm/for_each.h +++ b/libcxx/include/__algorithm/for_each.h @@ -39,7 +39,7 @@ __for_each(_InputIterator __first, _Sent __last, _Func& __f, _Proj& __proj) { template <class _SegmentedIterator, class _Func, class _Proj, - __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0> + __enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator __for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Func& __func, _Proj& __proj) { using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; diff --git a/libcxx/include/__algorithm/for_each_n.h b/libcxx/include/__algorithm/for_each_n.h index 9a6c6bb..04650e1 100644 --- a/libcxx/include/__algorithm/for_each_n.h +++ b/libcxx/include/__algorithm/for_each_n.h @@ -37,8 +37,8 @@ template <class _InputIterator, class _Func, class _Proj, __enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value && - _Or< _Not<__is_segmented_iterator<_InputIterator> >, - _Not<__has_random_access_local_iterator<_InputIterator> > >::value, + _Or<integral_constant<bool, !__is_segmented_iterator_v<_InputIterator> >, + _Not<__has_random_access_local_iterator<_InputIterator> > >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator __for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) { @@ -71,7 +71,7 @@ template <class _SegmentedIterator, class _Func, class _Proj, __enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value && - __is_segmented_iterator<_SegmentedIterator>::value && + __is_segmented_iterator_v<_SegmentedIterator> && __has_random_access_iterator_category< typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value, int> = 0> diff --git a/libcxx/include/__algorithm/for_each_n_segment.h b/libcxx/include/__algorithm/for_each_n_segment.h index 1b522fb..a433df5 100644 --- a/libcxx/include/__algorithm/for_each_n_segment.h +++ b/libcxx/include/__algorithm/for_each_n_segment.h @@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _SegmentedIterator, class _Size, class _Functor> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator __for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) { - static_assert(__is_segmented_iterator<_SegmentedIterator>::value && + static_assert(__is_segmented_iterator_v<_SegmentedIterator> && __has_random_access_iterator_category< typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value, "__for_each_n_segment only works with segmented iterators with random-access local iterators"); diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h index a3320e9..73b780d 100644 --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -65,7 +65,7 @@ struct __move_impl { } }; - template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> + template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result)); @@ -75,7 +75,7 @@ struct __move_impl { template <class _InIter, class _OutIter, __enable_if_t<__has_random_access_iterator_category<_InIter>::value && - !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h index 14482fe..e3e61c7b 100644 --- a/libcxx/include/__algorithm/move_backward.h +++ b/libcxx/include/__algorithm/move_backward.h @@ -51,7 +51,7 @@ struct __move_backward_impl { return std::make_pair(std::move(__original_last_iter), std::move(__result)); } - template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> + template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_InIter>; @@ -81,7 +81,7 @@ struct __move_backward_impl { template <class _InIter, class _OutIter, __enable_if_t<__has_random_access_iterator_category<_InIter>::value && - !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _InIter __last, _OutIter __result) const { diff --git a/libcxx/include/__assert b/libcxx/include/__assert index 90eaa60..a9451da 100644 --- a/libcxx/include/__assert +++ b/libcxx/include/__assert @@ -20,8 +20,8 @@ #define _LIBCPP_ASSERT(expression, message) \ (__builtin_expect(static_cast<bool>(expression), 1) \ ? (void)0 \ - : _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING( \ - expression) " failed: " message "\n")) + : _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING( \ + __LINE__) ": libc++ Hardening assertion " _LIBCPP_TOSTRING(expression) " failed: " message "\n")) // WARNING: __builtin_assume can currently inhibit optimizations. Only add assumptions with a clear // optimization intent. See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a diff --git a/libcxx/include/__config b/libcxx/include/__config index 3fe377a..77a71b6 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -38,11 +38,47 @@ # define _LIBCPP_FREESTANDING # endif +// NOLINTNEXTLINE(libcpp-cpp-version-check) +# if __cplusplus < 201103L +# define _LIBCPP_CXX03_LANG +# endif + +# if __has_feature(experimental_library) +# ifndef _LIBCPP_ENABLE_EXPERIMENTAL +# define _LIBCPP_ENABLE_EXPERIMENTAL +# endif +# endif + +// Incomplete features get their own specific disabling flags. This makes it +// easier to grep for target specific flags once the feature is complete. +# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 +# else +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 +# endif + +# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY + // HARDENING { -// TODO: Remove in LLVM 21. We're making this an error to catch folks who might not have migrated. -# ifdef _LIBCPP_ENABLE_ASSERTIONS -# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE instead" +// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated. +// Since hardening went through several changes (many of which impacted user-facing macros), +// we're keeping these checks around for a bit longer than usual. Failure to properly configure +// hardening results in checks being dropped silently, which is a pretty big deal. +# if defined(_LIBCPP_ENABLE_ASSERTIONS) +# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +# endif +# if defined(_LIBCPP_ENABLE_HARDENED_MODE) +# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +# endif +# if defined(_LIBCPP_ENABLE_SAFE_MODE) +# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +# endif +# if defined(_LIBCPP_ENABLE_DEBUG_MODE) +# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" # endif // The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values: @@ -147,16 +183,53 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \ _LIBCPP_HARDENING_MODE_DEBUG # endif +// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts: +// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts +// `ignore` semantic which wouldn't evaluate the assertion at all); +// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution; +// - `quick-enforce` terminates the program as fast as possible (via trapping); +// - `enforce` logs an error and then terminates the program. +// +// Notes: +// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant +// to make adopting hardening easier but should not be used outside of this scenario; +// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts +// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for +// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened" +// implementation, unlike the other semantics above. +// clang-format off +# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1) +# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2) +# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3) +# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4) +// clang-format on + +// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics. +// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use +// `enforce` (i.e., log and abort). +# ifndef _LIBCPP_ASSERTION_SEMANTIC + +# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE +# else +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE +# endif + +# else +# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# error "Assertion semantics are an experimental feature." +# endif +# if defined(_LIBCPP_CXX03_LANG) +# error "Assertion semantics are not available in the C++03 mode." +# endif + +# endif // _LIBCPP_ASSERTION_SEMANTIC + // } HARDENING # define _LIBCPP_TOSTRING2(x) #x # define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) -// NOLINTNEXTLINE(libcpp-cpp-version-check) -# if __cplusplus < 201103L -# define _LIBCPP_CXX03_LANG -# endif - # ifndef __has_constexpr_builtin # define __has_constexpr_builtin(x) 0 # endif @@ -190,25 +263,6 @@ _LIBCPP_HARDENING_MODE_DEBUG # define _LIBCPP_ABI_VCRUNTIME # endif -# if __has_feature(experimental_library) -# ifndef _LIBCPP_ENABLE_EXPERIMENTAL -# define _LIBCPP_ENABLE_EXPERIMENTAL -# endif -# endif - -// Incomplete features get their own specific disabling flags. This makes it -// easier to grep for target specific flags once the feature is complete. -# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 -# else -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 -# endif - -# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY - # if defined(__MVS__) # include <features.h> // for __NATIVE_ASCII_F # endif diff --git a/libcxx/include/__cxx03/__config b/libcxx/include/__cxx03/__config index ef47327..9b88a49 100644 --- a/libcxx/include/__cxx03/__config +++ b/libcxx/include/__cxx03/__config @@ -152,6 +152,10 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \ _LIBCPP_HARDENING_MODE_DEBUG # endif +# ifdef _LIBCPP_ASSERTION_SEMANTIC +# error "Assertion semantics are not available in the C++03 mode." +# endif + // } HARDENING # define _LIBCPP_TOSTRING2(x) #x diff --git a/libcxx/include/__cxx03/__math/logarithms.h b/libcxx/include/__cxx03/__math/logarithms.h index 2547350..9b9e59a 100644 --- a/libcxx/include/__cxx03/__math/logarithms.h +++ b/libcxx/include/__cxx03/__math/logarithms.h @@ -58,7 +58,7 @@ inline _LIBCPP_HIDE_FROM_ABI double log10(_A1 __x) _NOEXCEPT { inline _LIBCPP_HIDE_FROM_ABI int ilogb(float __x) _NOEXCEPT { return __builtin_ilogbf(__x); } template <class = int> -_LIBCPP_HIDE_FROM_ABI double ilogb(double __x) _NOEXCEPT { +_LIBCPP_HIDE_FROM_ABI int ilogb(double __x) _NOEXCEPT { return __builtin_ilogb(__x); } diff --git a/libcxx/include/__format/concepts.h b/libcxx/include/__format/concepts.h index 28297c6..5b60370 100644 --- a/libcxx/include/__format/concepts.h +++ b/libcxx/include/__format/concepts.h @@ -15,12 +15,8 @@ #include <__config> #include <__format/format_parse_context.h> #include <__fwd/format.h> -#include <__fwd/tuple.h> -#include <__tuple/tuple_size.h> -#include <__type_traits/is_specialization.h> #include <__type_traits/remove_const.h> #include <__type_traits/remove_reference.h> -#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -65,16 +61,6 @@ concept __formattable = # if _LIBCPP_STD_VER >= 23 template <class _Tp, class _CharT> concept formattable = __formattable<_Tp, _CharT>; - -// [tuple.like] defines a tuple-like exposition only concept. This concept is -// not related to that. Therefore it uses a different name for the concept. -// -// TODO FMT Add a test to validate we fail when using that concept after P2165 -// has been implemented. -template <class _Tp> -concept __fmt_pair_like = - __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); - # endif // _LIBCPP_STD_VER >= 23 #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/fmt_pair_like.h b/libcxx/include/__format/fmt_pair_like.h new file mode 100644 index 0000000..d2f2f54 --- /dev/null +++ b/libcxx/include/__format/fmt_pair_like.h @@ -0,0 +1,42 @@ +// -*- 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___FORMAT_FMT_PAIR_LIKE_H +#define _LIBCPP___FORMAT_FMT_PAIR_LIKE_H + +#include <__config> +#include <__fwd/pair.h> +#include <__fwd/tuple.h> +#include <__tuple/tuple_size.h> +#include <__type_traits/is_specialization.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +// [tuple.like] defines a tuple-like exposition only concept. This concept is not related to that. Therefore it uses a +// different name for the concept. +// +// TODO FMT Add a test to validate we fail when using that concept after P2165 has been implemented. + +// [format.range.fmtkind]/2.2.1 and [tab:formatter.range.type]: +// "U is either a specialization of pair or a specialization of tuple such that tuple_size_v<U> is 2." +template <class _Tp> +concept __fmt_pair_like = + __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FMT_PAIR_LIKE_H diff --git a/libcxx/include/__format/range_default_formatter.h b/libcxx/include/__format/range_default_formatter.h index 2769647..2d21906 100644 --- a/libcxx/include/__format/range_default_formatter.h +++ b/libcxx/include/__format/range_default_formatter.h @@ -18,6 +18,7 @@ #include <__chrono/statically_widen.h> #include <__config> #include <__format/concepts.h> +#include <__format/fmt_pair_like.h> #include <__format/formatter.h> #include <__format/range_format.h> #include <__format/range_formatter.h> diff --git a/libcxx/include/__format/range_format.h b/libcxx/include/__format/range_format.h index 139cfd9..fe43923 100644 --- a/libcxx/include/__format/range_format.h +++ b/libcxx/include/__format/range_format.h @@ -16,7 +16,7 @@ #include <__concepts/same_as.h> #include <__config> -#include <__format/concepts.h> +#include <__format/fmt_pair_like.h> #include <__ranges/concepts.h> #include <__type_traits/remove_cvref.h> diff --git a/libcxx/include/__format/range_formatter.h b/libcxx/include/__format/range_formatter.h index 0d7fe99..06d2b4c 100644 --- a/libcxx/include/__format/range_formatter.h +++ b/libcxx/include/__format/range_formatter.h @@ -20,6 +20,7 @@ #include <__config> #include <__format/buffer.h> #include <__format/concepts.h> +#include <__format/fmt_pair_like.h> #include <__format/format_context.h> #include <__format/format_error.h> #include <__format/formatter.h> diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 03f50d9..dacc152 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -1709,41 +1709,45 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_D template <class _Tp, class _Hash, class _Equal, class _Alloc> template <bool _UniqueKeys> -void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) { - __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); - __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); - __bucket_list_.get_deleter().size() = __nbc; - if (__nbc > 0) { - for (size_type __i = 0; __i < __nbc; ++__i) - __bucket_list_[__i] = nullptr; - __next_pointer __pp = __first_node_.__ptr(); - __next_pointer __cp = __pp->__next_; - if (__cp != nullptr) { - size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); - __bucket_list_[__chash] = __pp; - size_type __phash = __chash; - for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { - __chash = std::__constrain_hash(__cp->__hash(), __nbc); - if (__chash == __phash) - __pp = __cp; - else { - if (__bucket_list_[__chash] == nullptr) { - __bucket_list_[__chash] = __pp; - __pp = __cp; - __phash = __chash; - } else { - __next_pointer __np = __cp; - if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) { - for (; __np->__next_ != nullptr && - key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value()); - __np = __np->__next_) - ; - } - __pp->__next_ = __np->__next_; - __np->__next_ = __bucket_list_[__chash]->__next_; - __bucket_list_[__chash]->__next_ = __cp; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __bucket_count) { + __pointer_allocator& __ptr_alloc = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__bucket_count > 0 ? __pointer_alloc_traits::allocate(__ptr_alloc, __bucket_count) : nullptr); + __bucket_list_.get_deleter().size() = __bucket_count; + + if (__bucket_count == 0) + return; + + for (size_type __i = 0; __i < __bucket_count; ++__i) + __bucket_list_[__i] = nullptr; + __next_pointer __pp = __first_node_.__ptr(); + __next_pointer __cp = __pp->__next_; + + if (!__cp) + return; + + size_type __chash = std::__constrain_hash(__cp->__hash(), __bucket_count); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { + __chash = std::__constrain_hash(__cp->__hash(), __bucket_count); + if (__chash == __phash) + __pp = __cp; + else { + if (__bucket_list_[__chash] == nullptr) { + __bucket_list_[__chash] = __pp; + __pp = __cp; + __phash = __chash; + } else { + __next_pointer __np = __cp; + if _LIBCPP_CONSTEXPR (!_UniqueKeys) { + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value()); + __np = __np->__next_) + ; } + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; } } } diff --git a/libcxx/include/__iterator/segmented_iterator.h b/libcxx/include/__iterator/segmented_iterator.h index af27a7b..5df9737 100644 --- a/libcxx/include/__iterator/segmented_iterator.h +++ b/libcxx/include/__iterator/segmented_iterator.h @@ -67,13 +67,13 @@ struct __segmented_iterator_traits; */ template <class _Tp, size_t = 0> -struct __has_specialization : false_type {}; +inline const bool __has_specialization_v = false; template <class _Tp> -struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {}; +inline const bool __has_specialization_v<_Tp, sizeof(_Tp) * 0> = true; template <class _Iterator> -using __is_segmented_iterator _LIBCPP_NODEBUG = __has_specialization<__segmented_iterator_traits<_Iterator> >; +inline const bool __is_segmented_iterator_v = __has_specialization_v<__segmented_iterator_traits<_Iterator> >; template <class _SegmentedIterator> struct __has_random_access_local_iterator diff --git a/libcxx/include/__math/logarithms.h b/libcxx/include/__math/logarithms.h index 5f5f943..7343d6a 100644 --- a/libcxx/include/__math/logarithms.h +++ b/libcxx/include/__math/logarithms.h @@ -58,7 +58,7 @@ inline _LIBCPP_HIDE_FROM_ABI double log10(_A1 __x) _NOEXCEPT { inline _LIBCPP_HIDE_FROM_ABI int ilogb(float __x) _NOEXCEPT { return __builtin_ilogbf(__x); } template <class = int> -_LIBCPP_HIDE_FROM_ABI double ilogb(double __x) _NOEXCEPT { +_LIBCPP_HIDE_FROM_ABI int ilogb(double __x) _NOEXCEPT { return __builtin_ilogb(__x); } diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 4e0d76f..4307e78 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -341,59 +341,67 @@ public: } #endif - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return this->__alloc_; } // // Iterators // - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __make_iter(__add_alignment_assumption(this->__begin_)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __make_iter(__add_alignment_assumption(this->__begin_)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __make_iter(__add_alignment_assumption(this->__end_)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __make_iter(__add_alignment_assumption(this->__end_)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } // // [vector.capacity], capacity // - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return static_cast<size_type>(this->__end_ - this->__begin_); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT { return static_cast<size_type>(this->__cap_ - this->__begin_); } [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return this->__begin_ == this->__end_; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return std::min<size_type>(__alloc_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max()); } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n); @@ -402,38 +410,39 @@ public: // // element access // - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference + operator[](size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) { if (__n >= size()) this->__throw_out_of_range(); return this->__begin_[__n]; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const { if (__n >= size()) this->__throw_out_of_range(); return this->__begin_[__n]; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector"); return *this->__begin_; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector"); return *this->__begin_; } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector"); return *(this->__end_ - 1); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector"); return *(this->__end_ - 1); } @@ -441,11 +450,11 @@ public: // // [vector.data], data access // - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT { return std::__to_address(this->__begin_); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT { return std::__to_address(this->__begin_); } diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index e921e65..bd7b28e 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -234,74 +234,89 @@ public: } #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { return allocator_type(this->__alloc_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { return __internal_cap_to_external(__cap_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { return __size_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { + return __size_; + } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool empty() const _NOEXCEPT { return __size_ == 0; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __n); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { return __make_iter(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { return __make_iter(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { return __make_iter(__size_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { + return __make_iter(0); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { + return __make_iter(0); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { + return __make_iter(__size_); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { return __make_iter(__size_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return __make_iter(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { + return __make_iter(0); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return __make_iter(__size_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); return __make_ref(__n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference + operator[](size_type __n) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); return __make_ref(__n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); return __make_ref(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); return __make_ref(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); return __make_ref(__size_ - 1); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); return __make_ref(__size_ - 1); } diff --git a/libcxx/include/deque b/libcxx/include/deque index e33e7d3..395a107 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -461,9 +461,8 @@ private: __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; public: - using __is_segmented_iterator _LIBCPP_NODEBUG = true_type; - using __segment_iterator _LIBCPP_NODEBUG = _MapPointer; - using __local_iterator _LIBCPP_NODEBUG = _Pointer; + using __segment_iterator _LIBCPP_NODEBUG = _MapPointer; + using __local_iterator _LIBCPP_NODEBUG = _Pointer; static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 117556e..5857a83 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1338,6 +1338,7 @@ module std [system] { module enable_insertable { header "__format/enable_insertable.h" } module escaped_output_table { header "__format/escaped_output_table.h" } module extended_grapheme_cluster_table { header "__format/extended_grapheme_cluster_table.h" } + module fmt_pair_like { header "__format/fmt_pair_like.h" } module format_arg { header "__format/format_arg.h" } module format_arg_store { header "__format/format_arg_store.h" } module format_args { header "__format/format_args.h" } diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 1623702..23a391d 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -106,6 +106,11 @@ public: void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20 constexpr void swap(const tuple&) const noexcept(see-below); // C++23 + + template<tuple-like UTuple> + friend constexpr bool operator==(const tuple& t, const UTuple& u); // C++23 + template<tuple-like UTuple> + friend constexpr auto operator<=>(const tuple& t, const UTuple& u); // C++23 }; @@ -220,6 +225,7 @@ template <class... Types> # include <__config> # include <__cstddef/size_t.h> # include <__fwd/array.h> +# include <__fwd/get.h> # include <__fwd/pair.h> # include <__fwd/tuple.h> # include <__memory/allocator_arg_t.h> @@ -229,6 +235,7 @@ template <class... Types> # include <__tuple/make_tuple_types.h> # include <__tuple/sfinae_helpers.h> # include <__tuple/tuple_element.h> +# include <__tuple/tuple_like.h> # include <__tuple/tuple_like_ext.h> # include <__tuple/tuple_size.h> # include <__tuple/tuple_types.h> @@ -287,6 +294,68 @@ _LIBCPP_BEGIN_NAMESPACE_STD # ifndef _LIBCPP_CXX03_LANG +template <size_t _Ip, class _Tp, class _Up> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __tuple_compare_equal(const _Tp& __x, const _Up& __y) { + if constexpr (_Ip == 0) + return true; + else + return std::__tuple_compare_equal<_Ip - 1>(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y); +} + +# if _LIBCPP_STD_VER >= 26 +template <class _Tp, class _Up, class _IndexSeq = make_index_sequence<tuple_size_v<_Tp>>> +inline constexpr bool __can_tuple_compare_equal = false; + +// TODO(LLVM 22): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends +// because the resolution of CWG2369 landed in LLVM-21. +template <class _Tp, class _Up, size_t... _Is> + requires(tuple_size_v<_Tp> == tuple_size_v<_Up>) +inline constexpr bool __can_tuple_compare_equal<_Tp, _Up, index_sequence<_Is...>> = + __all<requires(const tuple_element_t<_Is, _Tp>& __t, const tuple_element_t<_Is, _Up>& __u) { + { __t == __u } -> __boolean_testable; + }...>::value; +# endif // _LIBCPP_STD_VER >= 26 + +# if _LIBCPP_STD_VER >= 20 +template <class _Ret, class _Tp, class _Up, size_t... _Is> +_LIBCPP_HIDE_FROM_ABI constexpr _Ret __tuple_compare_three_way(const _Tp& __x, const _Up& __y, index_sequence<_Is...>) { + _Ret __result = strong_ordering::equal; + static_cast<void>( + ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...)); + return __result; +} +# endif // _LIBCPP_STD_VER >= 20 + +# if _LIBCPP_STD_VER >= 23 +template <class> +inline constexpr bool __is_tuple_v = false; + +template <class... _Tp> +inline constexpr bool __is_tuple_v<tuple<_Tp...>> = true; + +template <class _Tp> +concept __tuple_like_no_tuple = __tuple_like<_Tp> && !__is_tuple_v<_Tp>; + +template <class _Tp, class _Up, class _IndexSeq> +struct __tuple_common_comparison_category_impl {}; + +// TODO(LLVM 22): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends +// because the resolution of CWG2369 landed in LLVM-21. +template <class _Tp, class _Up, size_t... _Is> + requires(tuple_size_v<_Tp> == tuple_size_v<_Up>) && requires { + typename common_comparison_category_t< + __synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>; + } +struct __tuple_common_comparison_category_impl<_Tp, _Up, index_sequence<_Is...>> { + using type _LIBCPP_NODEBUG = + common_comparison_category_t<__synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>; +}; + +template <__tuple_like _Tp, __tuple_like _Up> +using __tuple_common_comparison_category _LIBCPP_NODEBUG = + __tuple_common_comparison_category_impl<_Tp, _Up, make_index_sequence<tuple_size_v<_Tp>>>::type; +# endif // _LIBCPP_STD_VER >= 23 + // __tuple_leaf template <size_t _Ip, class _Hp, bool = is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value > @@ -448,33 +517,28 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swallow(_Tp&&...) _NO template <class _Indx, class... _Tp> struct __tuple_impl; +struct __forward_args {}; +struct __value_init {}; + template <size_t... _Indx, class... _Tp> struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__index_sequence<_Indx...>, _Tp...> : public __tuple_leaf<_Indx, _Tp>... { _LIBCPP_HIDE_FROM_ABI constexpr __tuple_impl() noexcept( __all<is_nothrow_default_constructible<_Tp>::value...>::value) {} - template <size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl( - __index_sequence<_Uf...>, - __tuple_types<_Tf...>, - __index_sequence<_Ul...>, - __tuple_types<_Tl...>, - _Up&&... __u) noexcept(__all<is_nothrow_constructible<_Tf, _Up>::value...>::value && - __all<is_nothrow_default_constructible<_Tl>::value...>::value) - : __tuple_leaf<_Uf, _Tf>(std::forward<_Up>(__u))..., __tuple_leaf<_Ul, _Tl>()... {} - - template <class _Alloc, size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up> + template <class... _Args> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(__forward_args, _Args&&... __args) + : __tuple_leaf<_Indx, _Tp>(std::forward<_Args>(__args))... {} + + template <class _Alloc> + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(allocator_arg_t, const _Alloc& __alloc, __value_init) + : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc>(), __alloc)... {} + + template <class _Alloc, class... _Args> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl( - allocator_arg_t, - const _Alloc& __a, - __index_sequence<_Uf...>, - __tuple_types<_Tf...>, - __index_sequence<_Ul...>, - __tuple_types<_Tl...>, - _Up&&... __u) - : __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, std::forward<_Up>(__u))..., - __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... {} + allocator_arg_t, const _Alloc& __alloc, __forward_args, _Args&&... __args) + : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, _Args>(), __alloc, std::forward<_Args>(__args))... {} template <class _Tuple, __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(_Tuple&& __t) noexcept( @@ -559,12 +623,7 @@ public: __enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value) tuple(allocator_arg_t, _Alloc const& __a) - : __base_(allocator_arg_t(), - __a, - __index_sequence<>(), - __tuple_types<>(), - __make_index_sequence<sizeof...(_Tp)>(), - __tuple_types<_Tp...>()) {} + : __base_(allocator_arg_t(), __a, __value_init{}) {} // tuple(const T&...) constructors (including allocator_arg_t variants) template <template <class...> class _And = _And, @@ -572,11 +631,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) tuple(const _Tp&... __t) noexcept(_And<is_nothrow_copy_constructible<_Tp>...>::value) - : __base_(__make_index_sequence<sizeof...(_Tp)>(), - __tuple_types<_Tp...>(), - __index_sequence<>(), - __tuple_types<>(), - __t...) {} + : __base_(__forward_args{}, __t...) {} template <class _Alloc, template <class...> class _And = _And, @@ -584,13 +639,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, const _Tp&... __t) - : __base_(allocator_arg_t(), - __a, - __make_index_sequence<sizeof...(_Tp)>(), - __tuple_types<_Tp...>(), - __index_sequence<>(), - __tuple_types<>(), - __t...) {} + : __base_(allocator_arg_t(), __a, __forward_args{}, __t...) {} // tuple(U&& ...) constructors (including allocator_arg_t variants) template <class... _Up> @@ -609,11 +658,7 @@ public: int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(_Up&&... __u) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value) - : __base_(__make_index_sequence<sizeof...(_Up)>(), - __tuple_types<_Tp...>(), - __index_sequence<>(), - __tuple_types<>(), - std::forward<_Up>(__u)...) {} + : __base_(__forward_args{}, std::forward<_Up>(__u)...) {} template <class _Alloc, class... _Up, @@ -621,13 +666,7 @@ public: int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) - : __base_(allocator_arg_t(), - __a, - __make_index_sequence<sizeof...(_Up)>(), - __tuple_types<_Tp...>(), - __index_sequence<>(), - __tuple_types<>(), - std::forward<_Up>(__u)...) {} + : __base_(allocator_arg_t(), __a, __forward_args{}, std::forward<_Up>(__u)...) {} // Copy and move constructors (including the allocator_arg_t variants) tuple(const tuple&) = default; @@ -986,7 +1025,24 @@ public: noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) { __base_.swap(__t.__base_); } -# endif // _LIBCPP_STD_VER >= 23 + + template <__tuple_like_no_tuple _UTuple> +# if _LIBCPP_STD_VER >= 26 + requires __can_tuple_compare_equal<tuple, _UTuple> && (sizeof...(_Tp) == tuple_size_v<_UTuple>) +# endif // _LIBCPP_STD_VER >= 26 + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple& __x, const _UTuple& __y) { + static_assert(sizeof...(_Tp) == tuple_size_v<_UTuple>, "Can't compare tuple-like values of different sizes"); + return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y); + } + + template <__tuple_like_no_tuple _UTuple> + requires(sizeof...(_Tp) == tuple_size_v<_UTuple>) + _LIBCPP_HIDE_FROM_ABI friend constexpr __tuple_common_comparison_category<tuple, _UTuple> + operator<=>(const tuple& __x, const _UTuple& __y) { + return std::__tuple_compare_three_way<__tuple_common_comparison_category<tuple, _UTuple>>( + __x, __y, index_sequence_for<_Tp...>{}); + } +# endif // _LIBCPP_STD_VER >= 23 }; _LIBCPP_DIAGNOSTIC_PUSH @@ -1008,6 +1064,21 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple&) _NOEXCEPT {} # if _LIBCPP_STD_VER >= 23 _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {} + + template <__tuple_like_no_tuple _UTuple> +# if _LIBCPP_STD_VER >= 26 + requires(tuple_size_v<_UTuple> == 0) +# endif // _LIBCPP_STD_VER >= 26 + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple&, const _UTuple&) { + static_assert(tuple_size_v<_UTuple> == 0, "Can't compare tuple-like values of different sizes"); + return true; + } + + template <__tuple_like_no_tuple _UTuple> + requires(tuple_size_v<_UTuple> == 0) + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>(const tuple&, const _UTuple&) { + return strong_ordering::equal; + } # endif }; _LIBCPP_DIAGNOSTIC_POP @@ -1126,22 +1197,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...> forwa return tuple<_Tp&&...>(std::forward<_Tp>(__t)...); } -template <size_t _Ip> -struct __tuple_equal { - template <class _Tp, class _Up> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) { - return __tuple_equal<_Ip - 1>()(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y); - } -}; - -template <> -struct __tuple_equal<0> { - template <class _Tp, class _Up> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp&, const _Up&) { - return true; - } -}; - template <class... _Tp, class... _Up> # if _LIBCPP_STD_VER >= 26 requires(__all<requires(const _Tp& __t, const _Up& __u) { @@ -1151,27 +1206,19 @@ template <class... _Tp, class... _Up> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes"); - return __tuple_equal<sizeof...(_Tp)>()(__x, __y); + return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y); } # if _LIBCPP_STD_VER >= 20 // operator<=> -template <class... _Tp, class... _Up, size_t... _Is> -_LIBCPP_HIDE_FROM_ABI constexpr auto -__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) { - common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal; - static_cast<void>( - ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...)); - return __result; -} - template <class... _Tp, class... _Up> requires(sizeof...(_Tp) == sizeof...(_Up)) _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { - return std::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{}); + return std::__tuple_compare_three_way<common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>>( + __x, __y, index_sequence_for<_Tp...>{}); } # else // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/version b/libcxx/include/version index d98049b..aae9277 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -555,7 +555,7 @@ __cpp_lib_void_t 201411L <type_traits> # define __cpp_lib_constexpr_new 202406L # endif # define __cpp_lib_constexpr_queue 202502L -// # define __cpp_lib_constrained_equality 202411L +# define __cpp_lib_constrained_equality 202411L // # define __cpp_lib_copyable_function 202306L // # define __cpp_lib_debugging 202311L // # define __cpp_lib_default_template_type_for_algorithm_values 202403L |