diff options
Diffstat (limited to 'libcxx/include')
215 files changed, 5936 insertions, 4359 deletions
diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h index 621ef5f20f82..29ad83f96810 100644 --- a/libcxx/include/__algorithm/adjacent_find.h +++ b/libcxx/include/__algorithm/adjacent_find.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H #define _LIBCPP___ALGORITHM_ADJACENT_FIND_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h index 8fc55b9becb1..2558dd0b27b9 100644 --- a/libcxx/include/__algorithm/binary_search.h +++ b/libcxx/include/__algorithm/binary_search.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H #define _LIBCPP___ALGORITHM_BINARY_SEARCH_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/lower_bound.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/clamp.h b/libcxx/include/__algorithm/clamp.h index db28735e97a3..a51c1015be3f 100644 --- a/libcxx/include/__algorithm/clamp.h +++ b/libcxx/include/__algorithm/clamp.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_CLAMP_H #define _LIBCPP___ALGORITHM_CLAMP_H +#include <__algorithm/comp.h> #include <__config> #include <__debug> -#include <__algorithm/comp.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h index e7e8b9e51a3e..65f0e0b0ef7d 100644 --- a/libcxx/include/__algorithm/copy.h +++ b/libcxx/include/__algorithm/copy.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_COPY_H #define _LIBCPP___ALGORITHM_COPY_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <cstring> #include <type_traits> diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h index 4a2f8c0c49cd..ac733290abe4 100644 --- a/libcxx/include/__algorithm/copy_backward.h +++ b/libcxx/include/__algorithm/copy_backward.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H #define _LIBCPP___ALGORITHM_COPY_BACKWARD_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <cstring> #include <type_traits> diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h index 230826f63af4..d32514d999b5 100644 --- a/libcxx/include/__algorithm/copy_if.h +++ b/libcxx/include/__algorithm/copy_if.h @@ -10,10 +10,6 @@ #define _LIBCPP___ALGORITHM_COPY_IF_H #include <__config> -#include <__algorithm/unwrap_iter.h> -#include <__iterator/iterator_traits.h> -#include <cstring> -#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h index 38a84a4105a4..cdcc0d50dbf1 100644 --- a/libcxx/include/__algorithm/copy_n.h +++ b/libcxx/include/__algorithm/copy_n.h @@ -9,11 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_COPY_N_H #define _LIBCPP___ALGORITHM_COPY_N_H -#include <__config> #include <__algorithm/copy.h> -#include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <cstring> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h index 0fe1a21fe526..4c9ad05ad6b8 100644 --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_H #define _LIBCPP___ALGORITHM_EQUAL_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h index 679456e27b43..e13f0bdd9695 100644 --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H #define _LIBCPP___ALGORITHM_EQUAL_RANGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/half_positive.h> #include <__algorithm/lower_bound.h> #include <__algorithm/upper_bound.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h index 1fad1de993bf..0cb36b02c831 100644 --- a/libcxx/include/__algorithm/fill.h +++ b/libcxx/include/__algorithm/fill.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_FILL_H #define _LIBCPP___ALGORITHM_FILL_H -#include <__config> #include <__algorithm/fill_n.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h index 5d971c57a4e0..dd0f7d7ac03d 100644 --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H #define _LIBCPP___ALGORITHM_FIND_END_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h index 79a00acb9ee6..69354f61769f 100644 --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H #define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/in_in_result.h b/libcxx/include/__algorithm/in_in_result.h new file mode 100644 index 000000000000..fbe53ae4f57e --- /dev/null +++ b/libcxx/include/__algorithm/in_in_result.h @@ -0,0 +1,45 @@ +// -*- 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___ALGORITHM_IN_IN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_RANGES + +namespace ranges { +template <class _I1, class _I2> +struct in_in_result { + [[no_unique_address]] _I1 in1; + [[no_unique_address]] _I2 in2; + + template <class _II1, class _II2> + requires convertible_to<const _I1&, _II1> && convertible_to<const _I2&, _II2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() const & { + return {in1, in2}; + } + + template <class _II1, class _II2> + requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() && { return {_VSTD::move(in1), _VSTD::move(in2)}; } +}; +} // namespace ranges + +#endif // _LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git a/libcxx/include/__algorithm/in_out_result.h b/libcxx/include/__algorithm/in_out_result.h new file mode 100644 index 000000000000..9d971157200f --- /dev/null +++ b/libcxx/include/__algorithm/in_out_result.h @@ -0,0 +1,52 @@ +// -*- 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___ALGORITHM_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.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 !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +template<class _InputIterator, class _OutputIterator> +struct in_out_result { + [[no_unique_address]] _InputIterator in; + [[no_unique_address]] _OutputIterator out; + + template <class _InputIterator2, class _OutputIterator2> + requires convertible_to<const _InputIterator&, _InputIterator2> && convertible_to<const _OutputIterator&, + _OutputIterator2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() const & { + return {in, out}; + } + + template <class _InputIterator2, class _OutputIterator2> + requires convertible_to<_InputIterator, _InputIterator2> && convertible_to<_OutputIterator, _OutputIterator2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() && { + return {_VSTD::move(in), _VSTD::move(out)}; + } +}; + +} // namespace ranges +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h index 9cc54d938dcf..9d0bc694c0d3 100644 --- a/libcxx/include/__algorithm/includes.h +++ b/libcxx/include/__algorithm/includes.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_INCLUDES_H #define _LIBCPP___ALGORITHM_INCLUDES_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index c74633a74cf3..e6f1efc011b1 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -9,14 +9,14 @@ #ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H #define _LIBCPP___ALGORITHM_INPLACE_MERGE_H -#include <__config> -#include <__algorithm/comp_ref_type.h> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/lower_bound.h> #include <__algorithm/min.h> #include <__algorithm/move.h> #include <__algorithm/rotate.h> #include <__algorithm/upper_bound.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h index 22c27a66d129..925ba8bfb8bd 100644 --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_H #define _LIBCPP___ALGORITHM_IS_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/is_heap_until.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h index dd8a62f07fd3..aa23b6d039d3 100644 --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H #define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h index 9a7f275c5400..57cad47761d9 100644 --- a/libcxx/include/__algorithm/is_sorted_until.h +++ b/libcxx/include/__algorithm/is_sorted_until.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H #define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h index a110a58c01c1..55a1da620125 100644 --- a/libcxx/include/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__algorithm/lexicographical_compare.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H #define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h index ddaecb045b3e..663a0b16228e 100644 --- a/libcxx/include/__algorithm/lower_bound.h +++ b/libcxx/include/__algorithm/lower_bound.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H #define _LIBCPP___ALGORITHM_LOWER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h index b3defd4de072..f489addaf5cc 100644 --- a/libcxx/include/__algorithm/make_heap.h +++ b/libcxx/include/__algorithm/make_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H #define _LIBCPP___ALGORITHM_MAKE_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sift_down.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -32,7 +32,7 @@ __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar // start from the first parent, there is no need to consider children for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); + _VSTD::__sift_down<_Compare>(__first, __comp, __n, __first + __start); } } } diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h index 79cbd2be86b6..0bbc971e0a9c 100644 --- a/libcxx/include/__algorithm/max.h +++ b/libcxx/include/__algorithm/max.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MAX_H #define _LIBCPP___ALGORITHM_MAX_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/max_element.h> +#include <__config> #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h index f932ca7049fa..db2937260582 100644 --- a/libcxx/include/__algorithm/max_element.h +++ b/libcxx/include/__algorithm/max_element.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/merge.h b/libcxx/include/__algorithm/merge.h index 480380db6caa..91826493771a 100644 --- a/libcxx/include/__algorithm/merge.h +++ b/libcxx/include/__algorithm/merge.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MERGE_H #define _LIBCPP___ALGORITHM_MERGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h index 5cacb2f28e7e..ed2d3b87828a 100644 --- a/libcxx/include/__algorithm/min.h +++ b/libcxx/include/__algorithm/min.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MIN_H #define _LIBCPP___ALGORITHM_MIN_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/min_element.h> +#include <__config> #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h index 3aebebca91ab..407c7f93336d 100644 --- a/libcxx/include/__algorithm/min_element.h +++ b/libcxx/include/__algorithm/min_element.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H #define _LIBCPP___ALGORITHM_MIN_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h index a96a5b252c09..0bf88a70b8aa 100644 --- a/libcxx/include/__algorithm/minmax.h +++ b/libcxx/include/__algorithm/minmax.h @@ -9,12 +9,11 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_H #define _LIBCPP___ALGORITHM_MINMAX_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <initializer_list> #include <utility> - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h index d21ff6f8dc5a..5d768603843b 100644 --- a/libcxx/include/__algorithm/minmax_element.h +++ b/libcxx/include/__algorithm/minmax_element.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h index 7a01a985934a..230ade03df19 100644 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_MISMATCH_H #define _LIBCPP___ALGORITHM_MISMATCH_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h index 7430bf087438..fa118f471669 100644 --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_H #define _LIBCPP___ALGORITHM_MOVE_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__utility/move.h> #include <cstring> -#include <utility> #include <type_traits> +#include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h index ee72d39764ca..a4e3828b6069 100644 --- a/libcxx/include/__algorithm/move_backward.h +++ b/libcxx/include/__algorithm/move_backward.h @@ -9,11 +9,11 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H #define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <cstring> -#include <utility> #include <type_traits> +#include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h index 1d71354eb375..eb81cceb7bbc 100644 --- a/libcxx/include/__algorithm/next_permutation.h +++ b/libcxx/include/__algorithm/next_permutation.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H #define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h index 63feba1ea616..3afbd6c61846 100644 --- a/libcxx/include/__algorithm/nth_element.h +++ b/libcxx/include/__algorithm/nth_element.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H #define _LIBCPP___ALGORITHM_NTH_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sort.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h index 622624ec4f42..a92a7e56610a 100644 --- a/libcxx/include/__algorithm/partial_sort.h +++ b/libcxx/include/__algorithm/partial_sort.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/make_heap.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> @@ -31,8 +31,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX17 void __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) + _Compare __comp) { + if (__first == __middle) + return; _VSTD::__make_heap<_Compare>(__first, __middle, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) @@ -40,7 +42,7 @@ __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _R if (__comp(*__i, *__first)) { swap(*__i, *__first); - _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first); + _VSTD::__sift_down<_Compare>(__first, __comp, __len, __first); } } _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); @@ -64,7 +66,7 @@ void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { _VSTD::partial_sort(__first, __middle, __last, - __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); + __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h index 4c0c9f5ad04a..67a62bae1f5a 100644 --- a/libcxx/include/__algorithm/partial_sort_copy.h +++ b/libcxx/include/__algorithm/partial_sort_copy.h @@ -9,14 +9,13 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/make_heap.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -40,7 +39,7 @@ __partial_sort_copy(_InputIterator __first, _InputIterator __last, if (__comp(*__first, *__result_first)) { *__result_first = *__first; - _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); + _VSTD::__sift_down<_Compare>(__result_first, __comp, __len, __result_first); } _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); } diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h index 2614520ccbcf..131c5d3735d5 100644 --- a/libcxx/include/__algorithm/partition.h +++ b/libcxx/include/__algorithm/partition.h @@ -12,7 +12,6 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> -#include <utility> // pair #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/partition_point.h b/libcxx/include/__algorithm/partition_point.h index 33aaf33d938c..18e6e6f6812f 100644 --- a/libcxx/include/__algorithm/partition_point.h +++ b/libcxx/include/__algorithm/partition_point.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H #define _LIBCPP___ALGORITHM_PARTITION_POINT_H -#include <__config> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h index e8c801a5c81f..c1cc8016ac91 100644 --- a/libcxx/include/__algorithm/pop_heap.h +++ b/libcxx/include/__algorithm/pop_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_POP_HEAP_H #define _LIBCPP___ALGORITHM_POP_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sift_down.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> @@ -31,7 +31,7 @@ __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare if (__len > 1) { swap(*__first, *--__last); - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); + _VSTD::__sift_down<_Compare>(__first, __comp, __len - 1, __first); } } diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h index 12c1816da37e..457c2695b324 100644 --- a/libcxx/include/__algorithm/prev_permutation.h +++ b/libcxx/include/__algorithm/prev_permutation.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H #define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h index 9327fe05b51d..864d419fa203 100644 --- a/libcxx/include/__algorithm/push_heap.h +++ b/libcxx/include/__algorithm/push_heap.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H #define _LIBCPP___ALGORITHM_PUSH_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h index 171d83284a2e..681b9cc768d9 100644 --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_H #define _LIBCPP___ALGORITHM_REMOVE_H -#include <__config> #include <__algorithm/find.h> #include <__algorithm/find_if.h> +#include <__config> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h index 4df36896afd5..36f817cfa6e1 100644 --- a/libcxx/include/__algorithm/remove_if.h +++ b/libcxx/include/__algorithm/remove_if.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H #define _LIBCPP___ALGORITHM_REMOVE_IF_H -#include <__config> #include <__algorithm/find_if.h> +#include <__config> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/reverse.h b/libcxx/include/__algorithm/reverse.h index 28bd2e84c8ae..1198aeaf41f4 100644 --- a/libcxx/include/__algorithm/reverse.h +++ b/libcxx/include/__algorithm/reverse.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_REVERSE_H #define _LIBCPP___ALGORITHM_REVERSE_H -#include <__config> #include <__algorithm/iter_swap.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/rotate_copy.h b/libcxx/include/__algorithm/rotate_copy.h index 4c682ef93d5a..f9e644c88d0e 100644 --- a/libcxx/include/__algorithm/rotate_copy.h +++ b/libcxx/include/__algorithm/rotate_copy.h @@ -9,10 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H #define _LIBCPP___ALGORITHM_ROTATE_COPY_H -#include <__config> #include <__algorithm/copy.h> -#include <iterator> -#include <type_traits> +#include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h index 67d066aa43d5..e4576cc76ac4 100644 --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_SEARCH_N_H #define _LIBCPP___ALGORITHM_SEARCH_N_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> // __convert_to_integral diff --git a/libcxx/include/__algorithm/set_difference.h b/libcxx/include/__algorithm/set_difference.h index d4a9750d6dd7..00f61e070b4b 100644 --- a/libcxx/include/__algorithm/set_difference.h +++ b/libcxx/include/__algorithm/set_difference.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h index 518e5e68b39d..f6aa38217d95 100644 --- a/libcxx/include/__algorithm/set_intersection.h +++ b/libcxx/include/__algorithm/set_intersection.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H #define _LIBCPP___ALGORITHM_SET_INTERSECTION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/set_symmetric_difference.h b/libcxx/include/__algorithm/set_symmetric_difference.h index efdf62725709..5b5c2acff773 100644 --- a/libcxx/include/__algorithm/set_symmetric_difference.h +++ b/libcxx/include/__algorithm/set_symmetric_difference.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/set_union.h b/libcxx/include/__algorithm/set_union.h index 388f037a73a4..5b3e3af79b4f 100644 --- a/libcxx/include/__algorithm/set_union.h +++ b/libcxx/include/__algorithm/set_union.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_UNION_H #define _LIBCPP___ALGORITHM_SET_UNION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/shift_left.h b/libcxx/include/__algorithm/shift_left.h index 8d9bc07d2e48..0466a3188a75 100644 --- a/libcxx/include/__algorithm/shift_left.h +++ b/libcxx/include/__algorithm/shift_left.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H #define _LIBCPP___ALGORITHM_SHIFT_LEFT_H -#include <__config> #include <__algorithm/move.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h index cee17733a6a2..121712e85532 100644 --- a/libcxx/include/__algorithm/shift_right.h +++ b/libcxx/include/__algorithm/shift_right.h @@ -9,12 +9,13 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H #define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H -#include <__config> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap +#include <__utility/swap.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/sift_down.h b/libcxx/include/__algorithm/sift_down.h index 4d99ff237c96..bf5447698cd6 100644 --- a/libcxx/include/__algorithm/sift_down.h +++ b/libcxx/include/__algorithm/sift_down.h @@ -21,8 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 void -__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, - _Compare __comp, +__sift_down(_RandomAccessIterator __first, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, _RandomAccessIterator __start) { @@ -46,7 +45,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, // check if we are in heap-order if (__comp(*__child_i, *__start)) - // we are, __start is larger than it's largest child + // we are, __start is larger than its largest child return; value_type __top(_VSTD::move(*__start)); diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h index bc127689a674..5e09b280080a 100644 --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_SORT_H #define _LIBCPP___ALGORITHM_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/min_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__utility/swap.h> #include <memory> diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h index bf6200c2a08d..64291ff2e8c9 100644 --- a/libcxx/include/__algorithm/sort_heap.h +++ b/libcxx/include/__algorithm/sort_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H #define _LIBCPP___ALGORITHM_SORT_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/pop_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> // swap diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 323b323c53dd..331f0fde77dc 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H #define _LIBCPP___ALGORITHM_STABLE_PARTITION_H -#include <__config> #include <__algorithm/rotate.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 41e17bde99ef..4ae17e0e4d94 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -9,15 +9,15 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H #define _LIBCPP___ALGORITHM_STABLE_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/inplace_merge.h> #include <__algorithm/sort.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> -#include <type_traits> // swap +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h index 62f0490b6d63..e17ff1567fa9 100644 --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_H #define _LIBCPP___ALGORITHM_UNIQUE_H -#include <__config> -#include <__algorithm/comp.h> #include <__algorithm/adjacent_find.h> +#include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> diff --git a/libcxx/include/__algorithm/unique_copy.h b/libcxx/include/__algorithm/unique_copy.h index 4c916dc3ada2..4833ae9b59f5 100644 --- a/libcxx/include/__algorithm/unique_copy.h +++ b/libcxx/include/__algorithm/unique_copy.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git a/libcxx/include/__algorithm/unwrap_iter.h b/libcxx/include/__algorithm/unwrap_iter.h index f77ecca6eee6..35765330bb7f 100644 --- a/libcxx/include/__algorithm/unwrap_iter.h +++ b/libcxx/include/__algorithm/unwrap_iter.h @@ -10,8 +10,8 @@ #define _LIBCPP___ALGORITHM_UNWRAP_ITER_H #include <__config> -#include <iterator> #include <__memory/pointer_traits.h> +#include <iterator> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h index 4ae7b8f9be1f..c064f1e35b9a 100644 --- a/libcxx/include/__algorithm/upper_bound.h +++ b/libcxx/include/__algorithm/upper_bound.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H #define _LIBCPP___ALGORITHM_UPPER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference index a02492c077dd..a60a5c721907 100644 --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -10,8 +10,8 @@ #ifndef _LIBCPP___BIT_REFERENCE #define _LIBCPP___BIT_REFERENCE -#include <__config> #include <__bits> +#include <__config> #include <algorithm> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/calendar.h b/libcxx/include/__chrono/calendar.h new file mode 100644 index 000000000000..745f7f5cf529 --- /dev/null +++ b/libcxx/include/__chrono/calendar.h @@ -0,0 +1,1276 @@ +// -*- 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___CHRONO_CALENDAR_H +#define _LIBCPP___CHRONO_CALENDAR_H + +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include <limits> +#include <ratio> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +struct local_t {}; +template<class Duration> +using local_time = time_point<local_t, Duration>; +using local_seconds = local_time<seconds>; +using local_days = local_time<days>; + +struct last_spec { explicit last_spec() = default; }; + +class day { +private: + unsigned char __d; +public: + day() = default; + explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} + inline constexpr day& operator++() noexcept { ++__d; return *this; } + inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } + inline constexpr day& operator--() noexcept { --__d; return *this; } + inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } + constexpr day& operator+=(const days& __dd) noexcept; + constexpr day& operator-=(const days& __dd) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __d; } + inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } + }; + + +inline constexpr +bool operator==(const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const day& __lhs, const day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const day& __lhs, const day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +day operator+ (const day& __lhs, const days& __rhs) noexcept +{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); } + +inline constexpr +day operator+ (const days& __lhs, const day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +day operator- (const day& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +days operator-(const day& __lhs, const day& __rhs) noexcept +{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) - + static_cast<int>(static_cast<unsigned>(__rhs))); } + +inline constexpr day& day::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr day& day::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class month { +private: + unsigned char __m; +public: + month() = default; + explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} + inline constexpr month& operator++() noexcept { ++__m; return *this; } + inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } + inline constexpr month& operator--() noexcept { --__m; return *this; } + inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } + constexpr month& operator+=(const months& __m1) noexcept; + constexpr month& operator-=(const months& __m1) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } +}; + + +inline constexpr +bool operator==(const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const month& __lhs, const month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month& __lhs, const month& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month operator+ (const month& __lhs, const months& __rhs) noexcept +{ + auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; +} + +inline constexpr +month operator+ (const months& __lhs, const month& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +month operator- (const month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +months operator-(const month& __lhs, const month& __rhs) noexcept +{ + auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +inline constexpr month& month::operator+=(const months& __dm) noexcept +{ *this = *this + __dm; return *this; } + +inline constexpr month& month::operator-=(const months& __dm) noexcept +{ *this = *this - __dm; return *this; } + + +class year { +private: + short __y; +public: + year() = default; + explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} + + inline constexpr year& operator++() noexcept { ++__y; return *this; } + inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } + inline constexpr year& operator--() noexcept { --__y; return *this; } + inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } + constexpr year& operator+=(const years& __dy) noexcept; + constexpr year& operator-=(const years& __dy) noexcept; + inline constexpr year operator+() const noexcept { return *this; } + inline constexpr year operator-() const noexcept { return year{-__y}; } + + inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } + explicit inline constexpr operator int() const noexcept { return __y; } + constexpr bool ok() const noexcept; + static inline constexpr year min() noexcept { return year{-32767}; } + static inline constexpr year max() noexcept { return year{ 32767}; } +}; + + +inline constexpr +bool operator==(const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); } + +inline constexpr +bool operator!=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); } + +inline constexpr +bool operator> (const year& __lhs, const year& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year& __lhs, const year& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year operator+ (const year& __lhs, const years& __rhs) noexcept +{ return year(static_cast<int>(__lhs) + __rhs.count()); } + +inline constexpr +year operator+ (const years& __lhs, const year& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year operator- (const year& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +years operator-(const year& __lhs, const year& __rhs) noexcept +{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } + + +inline constexpr year& year::operator+=(const years& __dy) noexcept +{ *this = *this + __dy; return *this; } + +inline constexpr year& year::operator-=(const years& __dy) noexcept +{ *this = *this - __dy; return *this; } + +inline constexpr bool year::ok() const noexcept +{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } + +class weekday_indexed; +class weekday_last; + +class weekday { +private: + unsigned char __wd; + static constexpr unsigned char __weekday_from_days(int __days) noexcept; +public: + weekday() = default; + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} + inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} + inline explicit constexpr weekday(const local_days& __locd) noexcept + : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} + + inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } + inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } + inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } + inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } + constexpr weekday& operator+=(const days& __dd) noexcept; + constexpr weekday& operator-=(const days& __dd) noexcept; + inline constexpr unsigned c_encoding() const noexcept { return __wd; } + inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } + inline constexpr bool ok() const noexcept { return __wd <= 6; } + constexpr weekday_indexed operator[](unsigned __index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast<unsigned char>( + static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + +inline constexpr +bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() == __rhs.c_encoding(); } + +inline constexpr +bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() < __rhs.c_encoding(); } + +inline constexpr +bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs < __rhs); } + +constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept +{ + auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast<unsigned>(__mu - __yr * 7)}; +} + +constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept +{ + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; + return days{__wdu - __wk * 7}; +} + +inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class weekday_indexed { +private: + chrono::weekday __wd; + unsigned char __idx; +public: + weekday_indexed() = default; + inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd{__wdval}, __idx(__idxval) {} + inline constexpr chrono::weekday weekday() const noexcept { return __wd; } + inline constexpr unsigned index() const noexcept { return __idx; } + inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } +}; + +inline constexpr +bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } + +inline constexpr +bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +class weekday_last { +private: + chrono::weekday __wd; +public: + explicit constexpr weekday_last(const chrono::weekday& __val) noexcept + : __wd{__val} {} + constexpr chrono::weekday weekday() const noexcept { return __wd; } + constexpr bool ok() const noexcept { return __wd.ok(); } +}; + +inline constexpr +bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday(); } + +inline constexpr +bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } + +inline constexpr +weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } + + +inline constexpr last_spec last{}; +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; + +inline constexpr month January{1}; +inline constexpr month February{2}; +inline constexpr month March{3}; +inline constexpr month April{4}; +inline constexpr month May{5}; +inline constexpr month June{6}; +inline constexpr month July{7}; +inline constexpr month August{8}; +inline constexpr month September{9}; +inline constexpr month October{10}; +inline constexpr month November{11}; +inline constexpr month December{12}; + + +class month_day { +private: + chrono::month __m; + chrono::day __d; +public: + month_day() = default; + constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m{__mval}, __d{__dval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + constexpr bool ok() const noexcept; +}; + +inline constexpr +bool month_day::ok() const noexcept +{ + if (!__m.ok()) return false; + const unsigned __dval = static_cast<unsigned>(__d); + if (__dval < 1 || __dval > 31) return false; + if (__dval <= 29) return true; +// Now we've got either 30 or 31 + const unsigned __mval = static_cast<unsigned>(__m); + if (__mval == 2) return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; +} + +inline constexpr +bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_day operator/(const month& __lhs, const day& __rhs) noexcept +{ return month_day{__lhs, __rhs}; } + +constexpr +month_day operator/(const day& __lhs, const month& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +month_day operator/(const month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +constexpr +month_day operator/(int __lhs, const day& __rhs) noexcept +{ return month(__lhs) / __rhs; } + +constexpr +month_day operator/(const day& __lhs, int __rhs) noexcept +{ return month(__rhs) / __lhs; } + + +inline constexpr +bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } + +inline constexpr +bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + + + +class month_day_last { +private: + chrono::month __m; +public: + explicit constexpr month_day_last(const chrono::month& __val) noexcept + : __m{__val} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m.ok(); } +}; + +inline constexpr +bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month_day_last operator/(const month& __lhs, last_spec) noexcept +{ return month_day_last{__lhs}; } + +inline constexpr +month_day_last operator/(last_spec, const month& __rhs) noexcept +{ return month_day_last{__rhs}; } + +inline constexpr +month_day_last operator/(int __lhs, last_spec) noexcept +{ return month_day_last{month(__lhs)}; } + +inline constexpr +month_day_last operator/(last_spec, int __rhs) noexcept +{ return month_day_last{month(__rhs)}; } + + +class month_weekday { +private: + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __m{__mval}, __wdi{__wdival} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{__lhs, __rhs}; } + +inline constexpr +month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{month(__lhs), __rhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept +{ return month_weekday{__rhs, __lhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept +{ return month_weekday{month(__rhs), __lhs}; } + + +class month_weekday_last { + chrono::month __m; + chrono::weekday_last __wdl; + public: + constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __m{__mval}, __wdl{__wdlval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{__lhs, __rhs}; } + +inline constexpr +month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{month(__lhs), __rhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept +{ return month_weekday_last{__rhs, __lhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept +{ return month_weekday_last{month(__rhs), __lhs}; } + + +class year_month { + chrono::year __y; + chrono::month __m; +public: + year_month() = default; + constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y{__yval}, __m{__mval} {} + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } + inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } + inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } + inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } +}; + +inline constexpr +year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } + +inline constexpr +year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } + +inline constexpr +bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept +{ + int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); +} + +constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month(); } + +constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept +{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } + +constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +class year_month_day_last; + +class year_month_day { +private: + chrono::year __y; + chrono::month __m; + chrono::day __d; +public: + year_month_day() = default; + inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y{__yval}, __m{__mval}, __d{__dval} {} + constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + constexpr year_month_day& operator+=(const months& __dm) noexcept; + constexpr year_month_day& operator-=(const months& __dm) noexcept; + constexpr year_month_day& operator+=(const years& __dy) noexcept; + constexpr year_month_day& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + constexpr bool ok() const noexcept; + + static constexpr year_month_day __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +inline constexpr +year_month_day +year_month_day::__from_days(days __d) noexcept +{ + static_assert(numeric_limits<unsigned>::digits >= 18, ""); + static_assert(numeric_limits<int>::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast<int>(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +inline constexpr days year_month_day::__to_days() const noexcept +{ + static_assert(numeric_limits<unsigned>::digits >= 18, ""); + static_assert(numeric_limits<int>::digits >= 20 , ""); + + const int __yr = static_cast<int>(__y) - (__m <= February); + const unsigned __mth = static_cast<unsigned>(__m); + const unsigned __dy = static_cast<unsigned>(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast<int>(__doe) - 719468}; +} + +inline constexpr +bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + if (__lhs.month() < __rhs.month()) return true; + if (__lhs.month() > __rhs.month()) return false; + return __lhs.day() < __rhs.day(); +} + +inline constexpr +bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept +{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_day operator/(const year_month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +inline constexpr +year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept +{ return __lhs / __rhs.month() / __rhs.day(); } + +inline constexpr +year_month_day operator/(int __lhs, const month_day& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept +{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } + +inline constexpr +year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } + +inline constexpr +year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_day_last { +private: + chrono::year __y; + chrono::month_day_last __mdl; +public: + constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y{__yval}, __mdl{__mdlval} {} + + constexpr year_month_day_last& operator+=(const months& __m) noexcept; + constexpr year_month_day_last& operator-=(const months& __m) noexcept; + constexpr year_month_day_last& operator+=(const years& __y) noexcept; + constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __mdl.month(); } + inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } + constexpr chrono::day day() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } +}; + +inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return (month() != February || !__y.is_leap()) && month().ok() ? + __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; +} + +inline constexpr +bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } + +inline constexpr +bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + return __lhs.month_day_last() < __rhs.month_day_last(); +} + +inline constexpr +bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept +{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } + +inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{__lhs, __rhs}; } + +inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{year{__lhs}, __rhs}; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept +{ return year{__rhs} / __lhs; } + + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / last; } + +inline constexpr +year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } + +inline constexpr +year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} + +inline constexpr bool year_month_day::ok() const noexcept +{ + if (!__y.ok() || !__m.ok()) return false; + return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); +} + +class year_month_weekday { + chrono::year __y; + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + year_month_weekday() = default; + constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __y{__yval}, __m{__mval}, __wdi{__wdival} {} + constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + constexpr year_month_weekday& operator+=(const months& m) noexcept; + constexpr year_month_weekday& operator-=(const months& m) noexcept; + constexpr year_month_weekday& operator+=(const years& y) noexcept; + constexpr year_month_weekday& operator-=(const years& y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } + inline constexpr unsigned index() const noexcept { return __wdi.index(); } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept + { + if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; + if (__wdi.index() <= 4) return true; + auto __nth_weekday_day = + __wdi.weekday() - + chrono::weekday{static_cast<sys_days>(__y / __m / 1)} + + days{(__wdi.index() - 1) * 7 + 1}; + return static_cast<unsigned>(__nth_weekday_day.count()) <= + static_cast<unsigned>((__y / __m / last).day()); + } + + static constexpr year_month_weekday __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + +inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; +} + +inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y/__m/1); + return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) + .time_since_epoch(); +} + +inline constexpr +bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept +{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept +{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } + +inline constexpr +year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + + +inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_weekday_last { +private: + chrono::year __y; + chrono::month __m; + chrono::weekday_last __wdl; +public: + constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} + constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } + + constexpr days __to_days() const noexcept; + +}; + +inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y/__m/last}; + return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); + +} + +inline constexpr +bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } + +inline constexpr +year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + + +template <class _Duration> +class hh_mm_ss +{ +private: + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + static constexpr uint64_t __pow10(unsigned __exp) + { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) + { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w+1); + return 0; + } + +public: + static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? + __width(__CommonType::period::den) : 6u; + using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; + + constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + + constexpr explicit hh_mm_ss(_Duration __d) noexcept : + __is_neg(__d < _Duration(0)), + __h(duration_cast<chrono::hours> (abs(__d))), + __m(duration_cast<chrono::minutes>(abs(__d) - hours())), + __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), + __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds())) + {} + + constexpr bool is_negative() const noexcept { return __is_neg; } + constexpr chrono::hours hours() const noexcept { return __h; } + constexpr chrono::minutes minutes() const noexcept { return __m; } + constexpr chrono::seconds seconds() const noexcept { return __s; } + constexpr precision subseconds() const noexcept { return __f; } + + constexpr precision to_duration() const noexcept + { + auto __dur = __h + __m + __s + __f; + return __is_neg ? -__dur : __dur; + } + + constexpr explicit operator precision() const noexcept { return to_duration(); } + +private: + bool __is_neg; + chrono::hours __h; + chrono::minutes __m; + chrono::seconds __s; + precision __f; +}; + +constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } +constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } + +constexpr hours make12(const hours& __h) noexcept +{ + if (__h == hours( 0)) return hours(12); + else if (__h <= hours(12)) return __h; + else return __h - hours(12); +} + +constexpr hours make24(const hours& __h, bool __is_pm) noexcept +{ + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; +} + +} // namespace chrono + +inline namespace literals +{ + inline namespace chrono_literals + { + constexpr chrono::day operator ""d(unsigned long long __d) noexcept + { + return chrono::day(static_cast<unsigned>(__d)); + } + + constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast<int>(__y)); + } +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CALENDAR_H diff --git a/libcxx/include/__chrono/convert_to_timespec.h b/libcxx/include/__chrono/convert_to_timespec.h new file mode 100644 index 000000000000..0106e6dec3e1 --- /dev/null +++ b/libcxx/include/__chrono/convert_to_timespec.h @@ -0,0 +1,55 @@ +// -*- 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___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__chrono/duration.h> +#include <__config> +#include <limits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template <class _TimeSpec> +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast<seconds>(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h new file mode 100644 index 000000000000..24801772ec5d --- /dev/null +++ b/libcxx/include/__chrono/duration.h @@ -0,0 +1,615 @@ +// -*- 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___CHRONO_DURATION_H +#define _LIBCPP___CHRONO_DURATION_H + +#include <__config> +#include <limits> +#include <ratio> +#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 + +namespace chrono +{ + +template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration; + +template <class _Tp> +struct __is_duration : false_type {}; + +template <class _Rep, class _Period> +struct __is_duration<duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<const duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<volatile duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {}; + +} // namespace chrono + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template <class _FromDuration, class _ToDuration, + class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count())); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd); +} + +template <class _Rep> +struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; + +#if _LIBCPP_STD_VER > 14 +template <class _Rep> +inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; +#endif + +template <class _Rep> +struct _LIBCPP_TEMPLATE_VIS duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template <class _Rep, class _Period> +class _LIBCPP_TEMPLATE_VIS duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template <class _R1, class _R2> + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template <intmax_t _Xp, intmax_t _Yp, bool __overflow> + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template <intmax_t _Xp, intmax_t _Yp> + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_CXX03_LANG + duration() = default; +#else + duration() {} +#endif + + template <class _Rep2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible<_Rep2, rep>::value && + (treat_as_floating_point<rep>::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = nullptr) + : __rep_(__r) {} + + // conversions + template <class _Rep2, class _Period2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point<rep>::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = nullptr) + : __rep_(chrono::duration_cast<duration>(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());} +}; + +typedef duration<long long, nano> nanoseconds; +typedef duration<long long, micro> microseconds; +typedef duration<long long, milli> milliseconds; +typedef duration<long long > seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; +typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; +typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; +typedef duration< int, ratio_divide<years::period, ratio<12>>> months; +#endif +// Duration == + +template <class _LhsDuration, class _RhsDuration> +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template <class _LhsDuration> +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template <class _LhsDuration, class _RhsDuration> +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template <class _LhsDuration> +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +} // namespace chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + constexpr chrono::hours operator""h(unsigned long long __h) + { + return chrono::hours(static_cast<chrono::hours::rep>(__h)); + } + + constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h) + { + return chrono::duration<long double, ratio<3600,1>>(__h); + } + + + constexpr chrono::minutes operator""min(unsigned long long __m) + { + return chrono::minutes(static_cast<chrono::minutes::rep>(__m)); + } + + constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m) + { + return chrono::duration<long double, ratio<60,1>> (__m); + } + + + constexpr chrono::seconds operator""s(unsigned long long __s) + { + return chrono::seconds(static_cast<chrono::seconds::rep>(__s)); + } + + constexpr chrono::duration<long double> operator""s(long double __s) + { + return chrono::duration<long double> (__s); + } + + + constexpr chrono::milliseconds operator""ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms)); + } + + constexpr chrono::duration<long double, milli> operator""ms(long double __ms) + { + return chrono::duration<long double, milli>(__ms); + } + + + constexpr chrono::microseconds operator""us(unsigned long long __us) + { + return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us)); + } + + constexpr chrono::duration<long double, micro> operator""us(long double __us) + { + return chrono::duration<long double, micro> (__us); + } + + + constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns)); + } + + constexpr chrono::duration<long double, nano> operator""ns(long double __ns) + { + return chrono::duration<long double, nano> (__ns); + } + +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_DURATION_H diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h new file mode 100644 index 000000000000..cd8758f81908 --- /dev/null +++ b/libcxx/include/__chrono/file_clock.h @@ -0,0 +1,85 @@ +// -*- 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___CHRONO_FILE_CLOCK_H +#define _LIBCPP___CHRONO_FILE_CLOCK_H + +#include <__availability> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include <ratio> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template<class _Duration> +using file_time = time_point<file_clock, _Duration>; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration<rep, period> duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + _LIBCPP_EXPORTED_FROM_ABI + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + +#if _LIBCPP_STD_VER > 17 + template <class _Duration> + _LIBCPP_HIDE_FROM_ABI + static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + return chrono::sys_time<_Duration>(__t.time_since_epoch()); + } + + template <class _Duration> + _LIBCPP_HIDE_FROM_ABI + static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + return chrono::file_time<_Duration>(__t.time_since_epoch()); + } +#endif // _LIBCPP_STD_VER > 17 +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#endif // _LIBCPP___CHRONO_FILE_CLOCK_H diff --git a/libcxx/include/__chrono/high_resolution_clock.h b/libcxx/include/__chrono/high_resolution_clock.h new file mode 100644 index 000000000000..f5cde4acb979 --- /dev/null +++ b/libcxx/include/__chrono/high_resolution_clock.h @@ -0,0 +1,36 @@ +// -*- 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___CHRONO_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H + +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git a/libcxx/include/__chrono/steady_clock.h b/libcxx/include/__chrono/steady_clock.h new file mode 100644 index 000000000000..5ba911df843e --- /dev/null +++ b/libcxx/include/__chrono/steady_clock.h @@ -0,0 +1,44 @@ +// -*- 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___CHRONO_STEADY_CLOCK_H +#define _LIBCPP___CHRONO_STEADY_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<steady_clock, duration> time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H diff --git a/libcxx/include/__chrono/system_clock.h b/libcxx/include/__chrono/system_clock.h new file mode 100644 index 000000000000..9c977d369e1b --- /dev/null +++ b/libcxx/include/__chrono/system_clock.h @@ -0,0 +1,54 @@ +// -*- 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___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include <ctime> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<system_clock> time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 17 + +template <class _Duration> +using sys_time = time_point<system_clock, _Duration>; +using sys_seconds = sys_time<seconds>; +using sys_days = sys_time<days>; + +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h new file mode 100644 index 000000000000..c042e125145a --- /dev/null +++ b/libcxx/include/__chrono/time_point.h @@ -0,0 +1,249 @@ +// -*- 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___CHRONO_TIME_POINT_H +#define _LIBCPP___CHRONO_TIME_POINT_H + +#include <__chrono/duration.h> +#include <__config> +#include <limits> +#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 + +namespace chrono +{ + +template <class _Clock, class _Duration = typename _Clock::duration> +class _LIBCPP_TEMPLATE_VIS time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template <class _Duration2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + time_point(const time_point<clock, _Duration2>& t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = nullptr) + : __d_(t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} +}; + +} // namespace chrono + +template <class _Clock, class _Duration1, class _Duration2> +struct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? +__d : -__d; +} +#endif // _LIBCPP_STD_VER > 14 + +// time_point == + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template <class _Clock, class _Duration1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template <class _Rep1, class _Period1, class _Clock, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template <class _Clock, class _Duration1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); +} + +// duration operator-(time_point x, time_point y); + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_TIME_POINT_H diff --git a/libcxx/include/__compare/compare_three_way.h b/libcxx/include/__compare/compare_three_way.h index 3edddf1a1c94..d7f339eda992 100644 --- a/libcxx/include/__compare/compare_three_way.h +++ b/libcxx/include/__compare/compare_three_way.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_H #define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H -#include <__config> #include <__compare/three_way_comparable.h> +#include <__config> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__compare/synth_three_way.h b/libcxx/include/__compare/synth_three_way.h index 3d8e738816dd..0f302c0fa11f 100644 --- a/libcxx/include/__compare/synth_three_way.h +++ b/libcxx/include/__compare/synth_three_way.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___COMPARE_SYNTH_THREE_WAY_H #define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H -#include <__config> #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__concepts/boolean_testable.h> +#include <__config> #include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__concepts/class_or_enum.h b/libcxx/include/__concepts/class_or_enum.h index 43c7636d9c81..aa8606a21929 100644 --- a/libcxx/include/__concepts/class_or_enum.h +++ b/libcxx/include/__concepts/class_or_enum.h @@ -25,6 +25,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _Tp> concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; +// Work around Clang bug https://llvm.org/PR52970 +template<class _Tp> +concept __workaround_52970 = is_class_v<__uncvref_t<_Tp>> || is_union_v<__uncvref_t<_Tp>>; + #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__concepts/convertible_to.h b/libcxx/include/__concepts/convertible_to.h index ec68967106d5..795b0bd7494c 100644 --- a/libcxx/include/__concepts/convertible_to.h +++ b/libcxx/include/__concepts/convertible_to.h @@ -10,6 +10,7 @@ #define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H #include <__config> +#include <__utility/declval.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,8 +26,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _From, class _To> concept convertible_to = is_convertible_v<_From, _To> && - requires (add_rvalue_reference_t<_From> (&__f)()) { - static_cast<_To>(__f()); + requires { + static_cast<_To>(declval<_From>()); }; #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) diff --git a/libcxx/include/__config b/libcxx/include/__config index 720e12eac0dd..b99cdc38dc9f 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -107,6 +107,15 @@ # define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI // Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr # define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI +// std::random_device holds some state when it uses an implementation that gets +// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this +// implementation to another one on a platform that has already shipped +// std::random_device, one needs to retain the same object layout to remain ABI +// compatible. This switch removes these workarounds for platforms that don't care +// about ABI compatibility. +# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT +// Remove basic_string common base +# define _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -250,6 +259,10 @@ # endif // defined(__GLIBC_PREREQ) #endif // defined(__linux__) +#if defined(__MVS__) +# include <features.h> // for __NATIVE_ASCII_F +#endif + #ifdef __LITTLE_ENDIAN__ # if __LITTLE_ENDIAN__ # define _LIBCPP_LITTLE_ENDIAN @@ -354,6 +367,12 @@ // When this option is used, the token passed to `std::random_device`'s // constructor *must* be "/dev/urandom" -- anything else is an error. // +// _LIBCPP_USING_FUCHSIA_CPRNG +// Use Fuchsia's zx_cprng_draw() system call, which is specified to +// deliver high-quality entropy and cannot fail. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// // _LIBCPP_USING_NACL_RANDOM // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, // including accesses to the special files under `/dev`. This implementation @@ -365,10 +384,12 @@ // 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__) +#if defined(__OpenBSD__) || defined(__APPLE__) # define _LIBCPP_USING_ARC4_RANDOM -#elif defined(__Fuchsia__) || defined(__wasi__) +#elif defined(__wasi__) # define _LIBCPP_USING_GETENTROPY +#elif defined(__Fuchsia__) +# define _LIBCPP_USING_FUCHSIA_CPRNG #elif defined(__native_client__) # define _LIBCPP_USING_NACL_RANDOM #elif defined(_LIBCPP_WIN32API) @@ -1204,9 +1225,9 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( # define _LIBCPP_C_HAS_NO_GETS #endif -#if defined(__BIONIC__) || defined(__NuttX__) || \ - defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \ - defined(__MVS__) || defined(__OpenBSD__) +#if defined(__BIONIC__) || defined(__NuttX__) || \ + defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE #endif diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h index 9dbf21aac5e6..a29e202f4e4f 100644 --- a/libcxx/include/__coroutine/noop_coroutine_handle.h +++ b/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -20,7 +20,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__builtin_coro_noop) +#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + // [coroutine.noop] // [coroutine.promise.noop] struct noop_coroutine_promise {}; @@ -64,20 +65,45 @@ private: _LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept; +#if __has_builtin(__builtin_coro_noop) _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); } void* __handle_ = nullptr; + +#elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() { } + + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; + + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + + void* __handle_ = &__noop_coroutine_frame_; + + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + +#endif // __has_builtin(__builtin_coro_noop) }; using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; +#if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ + noop_coroutine_handle::__noop_coroutine_frame_{}; +#endif + // [coroutine.noop.coroutine] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } -#endif // __has_builtin(__builtin_coro_noop) +#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__debug b/libcxx/include/__debug index 42f6cef4c07f..a1e21a703224 100644 --- a/libcxx/include/__debug +++ b/libcxx/include/__debug @@ -12,6 +12,7 @@ #include <__config> #include <iosfwd> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -22,9 +23,9 @@ #endif #if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) -# include <cstdlib> -# include <cstdio> # include <cstddef> +# include <cstdio> +# include <cstdlib> #endif #if _LIBCPP_DEBUG_LEVEL == 0 @@ -268,6 +269,26 @@ _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); #endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) +template <class _Tp> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_c(_Tp* __c) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_c(__c); +#else + (void)(__c); +#endif +} + +template <class _Tp> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_i(_Tp* __i) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_i(__i); +#else + (void)(__i); +#endif +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_DEBUG_H diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h index 9efe19465428..91dd1a214588 100644 --- a/libcxx/include/__filesystem/directory_entry.h +++ b/libcxx/include/__filesystem/directory_entry.h @@ -12,17 +12,18 @@ #include <__availability> #include <__config> -#include <__filesystem/path.h> -#include <__filesystem/file_time_type.h> -#include <__filesystem/filesystem_error.h> +#include <__errc> #include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> #include <__filesystem/file_type.h> +#include <__filesystem/filesystem_error.h> #include <__filesystem/operations.h> +#include <__filesystem/path.h> #include <__filesystem/perms.h> -#include <__errc> #include <chrono> #include <cstdint> #include <cstdlib> +#include <iosfwd> #include <system_error> _LIBCPP_PUSH_MACROS @@ -239,6 +240,12 @@ public: return __p_ >= __rhs.__p_; } + template <class _CharT, class _Traits> + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + private: friend class directory_iterator; friend class recursive_directory_iterator; diff --git a/libcxx/include/__filesystem/directory_iterator.h b/libcxx/include/__filesystem/directory_iterator.h index be958e0eb8de..7ea66bbc7ff0 100644 --- a/libcxx/include/__filesystem/directory_iterator.h +++ b/libcxx/include/__filesystem/directory_iterator.h @@ -12,12 +12,12 @@ #include <__availability> #include <__config> +#include <__debug> #include <__filesystem/directory_entry.h> #include <__filesystem/directory_options.h> #include <__filesystem/path.h> #include <__iterator/iterator_traits.h> #include <__memory/shared_ptr.h> -#include <__debug> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <cstddef> diff --git a/libcxx/include/__filesystem/filesystem_error.h b/libcxx/include/__filesystem/filesystem_error.h index a8c6977b48e9..0b1874b0e50e 100644 --- a/libcxx/include/__filesystem/filesystem_error.h +++ b/libcxx/include/__filesystem/filesystem_error.h @@ -14,9 +14,9 @@ #include <__config> #include <__filesystem/path.h> #include <__memory/shared_ptr.h> -#include <system_error> #include <iosfwd> #include <new> +#include <system_error> #include <type_traits> #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__filesystem/operations.h b/libcxx/include/__filesystem/operations.h index 19d6c2d437f9..918b4f9362e6 100644 --- a/libcxx/include/__filesystem/operations.h +++ b/libcxx/include/__filesystem/operations.h @@ -30,430 +30,118 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH -_LIBCPP_FUNC_VIS -path __absolute(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __canonical(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __copy_file(const path& __from, const path& __to, copy_options __opt, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __copy(const path& __from, const path& __to, copy_options __opt, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directories(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_directory_symlink(const path& __to, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, const path& attributes, - error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_hard_link(const path& __to, const path& __new_hard_link, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_symlink(const path& __to, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __current_path(error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __current_path(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __equivalent(const path&, const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_status __status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __file_size(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_status __symlink_status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_time_type __last_write_time(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __last_write_time(const path& p, file_time_type new_time, - error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -path __weakly_canonical(path const& __p, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __read_symlink(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __remove_all(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -bool __remove(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __rename(const path& from, const path& to, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -path __temp_directory_path(error_code* __ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { - return __absolute(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, - error_code& __ec) { - return __absolute(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { - return __canonical(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, - error_code& __ec) { - return __canonical(__p, &__ec); -} - - -inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, - const path& __to) { - return __copy_file(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -copy_file(const path& __from, const path& __to, error_code& __ec) { - return __copy_file(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -copy_file(const path& __from, const path& __to, copy_options __opt) { - return __copy_file(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, - const path& __to, - copy_options __opt, - error_code& __ec) { - return __copy_file(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, - const path& __new) { - __copy_symlink(__existing, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { - __copy_symlink(__ext, __new, &__ec); -} - - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, - const path& __to) { - __copy(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - error_code& __ec) { - __copy(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - copy_options __opt) { - __copy(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - copy_options __opt, - error_code& __ec) { - __copy(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { - return __create_directories(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, - error_code& __ec) { - return __create_directories(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_directory_symlink(const path& __to, const path& __new) { - __create_directory_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_directory_symlink(const path& __to, const path& __new, - error_code& __ec) noexcept { - __create_directory_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { - return __create_directory(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -create_directory(const path& __p, error_code& __ec) noexcept { - return __create_directory(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, - const path& __attrs) { - return __create_directory(__p, __attrs); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -create_directory(const path& __p, const path& __attrs, - error_code& __ec) noexcept { - return __create_directory(__p, __attrs, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, - const path& __new) { - __create_hard_link(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_hard_link(const path& __to, const path& __new, - error_code& __ec) noexcept { - __create_hard_link(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, - const path& __new) { - __create_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { - return __create_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path current_path() { - return __current_path(); -} - -inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { - return __current_path(&__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { - __current_path(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, - error_code& __ec) noexcept { - __current_path(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, - const path& __p2) { - return __equivalent(__p1, __p2); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { - return __equivalent(__p1, __p2, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { - return __s.type() != file_type::none; -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { - return status_known(__s) && __s.type() != file_type::not_found; -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { - return exists(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, - error_code& __ec) noexcept { +_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directories(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, const path& attributes, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __last_write_time(const path& p, file_time_type new_time, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __read_symlink(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __remove(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __rename(const path& from, const path& to, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); + +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { return __absolute(__p); } +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { return __create_directories(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { return __create_directory(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path current_path() { return __current_path(); } +inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { return __current_path(&__ec); } +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { __current_path(__p); } +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } +inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { return exists(__status(__p)); } + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { auto __s = __status(__p, &__ec); if (status_known(__s)) __ec.clear(); return exists(__s); } -inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { - return __file_size(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t -file_size(const path& __p, error_code& __ec) noexcept { - return __file_size(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { - return __hard_link_count(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t -hard_link_count(const path& __p, error_code& __ec) noexcept { - return __hard_link_count(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { - return __s.type() == file_type::block; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { - return is_block_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, - error_code& __ec) noexcept { - return is_block_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_character_file(file_status __s) noexcept { - return __s.type() == file_type::character; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { - return is_character_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_character_file(const path& __p, error_code& __ec) noexcept { - return is_character_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { - return __s.type() == file_type::directory; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { - return is_directory(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, - error_code& __ec) noexcept { - return is_directory(__status(__p, &__ec)); -} - -_LIBCPP_FUNC_VIS -bool __fs_is_empty(const path& p, error_code* ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { - return __fs_is_empty(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, - error_code& __ec) { - return __fs_is_empty(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { - return __s.type() == file_type::fifo; -} -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { - return is_fifo(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, - error_code& __ec) noexcept { - return is_fifo(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_regular_file(file_status __s) noexcept { - return __s.type() == file_type::regular; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { - return is_regular_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_regular_file(const path& __p, error_code& __ec) noexcept { - return is_regular_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { - return __s.type() == file_type::symlink; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { - return is_symlink(__symlink_status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, - error_code& __ec) noexcept { - return is_symlink(__symlink_status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { - return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && - !is_symlink(__s); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { - return is_other(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, - error_code& __ec) noexcept { - return is_other(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { - return __s.type() == file_type::socket; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { - return is_socket(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, - error_code& __ec) noexcept { - return is_socket(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY file_time_type -last_write_time(const path& __p) { - return __last_write_time(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_time_type -last_write_time(const path& __p, error_code& __ec) noexcept { - return __last_write_time(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, - file_time_type __t) { - __last_write_time(__p, __t); -} - -inline _LIBCPP_INLINE_VISIBILITY void -last_write_time(const path& __p, file_time_type __t, - error_code& __ec) noexcept { - __last_write_time(__p, __t, &__ec); -} - -_LIBCPP_FUNC_VIS -void __permissions(const path&, perms, perm_options, error_code* = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY void -permissions(const path& __p, perms __prms, - perm_options __opts = perm_options::replace) { - __permissions(__p, __prms, __opts); -} - -inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, - error_code& __ec) noexcept { - __permissions(__p, __prms, perm_options::replace, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, - perm_options __opts, - error_code& __ec) { - __permissions(__p, __prms, __opts, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, - const path& __base, - error_code& __ec) { +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { return __file_size(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { return is_directory(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } +_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& p, error_code* ec = nullptr); +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { return __fs_is_empty(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { return is_other(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { return is_socket(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } +_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return {}; @@ -463,29 +151,12 @@ inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, return __tmp.lexically_proximate(__tmp_base); } -inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, - error_code& __ec) { - return proximate(__p, current_path(), __ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path -proximate(const path& __p, const path& __base = current_path()) { - return __weakly_canonical(__p).lexically_proximate( - __weakly_canonical(__base)); -} - -inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { - return __read_symlink(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, - error_code& __ec) { - return __read_symlink(__p, &__ec); -} +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { return __read_symlink(__p); } +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } -inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, - const path& __base, - error_code& __ec) { +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return path(); @@ -495,100 +166,27 @@ inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, return __tmp.lexically_relative(__tmpbase); } -inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, - error_code& __ec) { - return relative(__p, current_path(), __ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path -relative(const path& __p, const path& __base = current_path()) { - return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { - return __remove_all(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, - error_code& __ec) { - return __remove_all(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { - return __remove(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, - error_code& __ec) noexcept { - return __remove(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, - const path& __to) { - return __rename(__from, __to); -} - -inline _LIBCPP_INLINE_VISIBILITY void -rename(const path& __from, const path& __to, error_code& __ec) noexcept { - return __rename(__from, __to, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, - uintmax_t __ns) { - return __resize_file(__p, __ns); -} - -inline _LIBCPP_INLINE_VISIBILITY void -resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { - return __resize_file(__p, __ns, &__ec); -} - -_LIBCPP_FUNC_VIS -space_info __space(const path&, error_code* __ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { - return __space(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, - error_code& __ec) noexcept { - return __space(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { - return __status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, - error_code& __ec) noexcept { - return __status(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { - return __symlink_status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status -symlink_status(const path& __p, error_code& __ec) noexcept { - return __symlink_status(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { - return __temp_directory_path(); -} - -inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { - return __temp_directory_path(&__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { - return __weakly_canonical(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, - error_code& __ec) { - return __weakly_canonical(__p, &__ec); -} +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { return __remove_all(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { return __remove(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to) { return __rename(__from, __to); } +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } +_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { return __space(__p); } +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { return __status(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { return __symlink_status(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { return __temp_directory_path(); } +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } _LIBCPP_AVAILABILITY_FILESYSTEM_POP diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index a6d1ee997d91..77547cbacb7d 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -12,16 +12,16 @@ #include <__availability> #include <__config> -#include <string> -#include <type_traits> #include <__iterator/back_insert_iterator.h> #include <__iterator/iterator_traits.h> #include <cstddef> +#include <string> #include <string_view> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include <locale> # include <iomanip> // for quoted +# include <locale> #endif #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__filesystem/path_iterator.h b/libcxx/include/__filesystem/path_iterator.h index 62f8dc6fd357..08039e4c8a36 100644 --- a/libcxx/include/__filesystem/path_iterator.h +++ b/libcxx/include/__filesystem/path_iterator.h @@ -12,9 +12,9 @@ #include <__availability> #include <__config> +#include <__debug> #include <__filesystem/path.h> #include <__iterator/iterator_traits.h> -#include <__debug> #include <cstddef> #include <string> #include <string_view> @@ -38,15 +38,13 @@ public: }; public: - typedef bidirectional_iterator_tag iterator_category; + typedef input_iterator_tag iterator_category; + typedef bidirectional_iterator_tag iterator_concept; typedef path value_type; typedef ptrdiff_t difference_type; typedef const path* pointer; - typedef const path& reference; - - typedef void - __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator + typedef path reference; public: _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h index 59429c13d415..da829d52fbfe 100644 --- a/libcxx/include/__format/format_arg.h +++ b/libcxx/include/__format/format_arg.h @@ -14,7 +14,9 @@ #include <__config> #include <__format/format_error.h> #include <__format/format_fwd.h> +#include <__format/format_parse_context.h> #include <__functional_base> +#include <__memory/addressof.h> #include <__variant/monostate.h> #include <string> #include <string_view> @@ -56,7 +58,8 @@ enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { __long_double, __const_char_type_ptr, __string_view, - __ptr + __ptr, + __handle }; } // namespace __format @@ -104,6 +107,8 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__string_view); case __format::__arg_t::__ptr: return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__ptr); + case __format::__arg_t::__handle: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__handle); } _LIBCPP_UNREACHABLE(); } @@ -111,8 +116,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { template <class _Context> class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { public: - // TODO FMT Define the handle class. - class handle; + class _LIBCPP_TEMPLATE_VIS handle; _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept : __type_{__format::__arg_t::__none} {} @@ -161,7 +165,7 @@ private: const char_type* __const_char_type_ptr; basic_string_view<char_type> __string_view; const void* __ptr; - // TODO FMT Add the handle. + handle __handle; }; __format::__arg_t __type_; @@ -245,7 +249,37 @@ private: explicit basic_format_arg(nullptr_t) noexcept : __ptr(nullptr), __type_(__format::__arg_t::__ptr) {} - // TODO FMT Implement the _Tp* constructor. + template <class _Tp> + requires is_void_v<_Tp> _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp* __p) noexcept + : __ptr(__p), __type_(__format::__arg_t::__ptr) {} + + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept + : __handle(__v), __type_(__format::__arg_t::__handle) {} +}; + +template <class _Context> +class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { + friend class basic_format_arg<_Context>; + +public: + _LIBCPP_HIDE_FROM_ABI + void format(basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx) const { + __format_(__parse_ctx, __ctx, __ptr_); + } + +private: + const void* __ptr_; + void (*__format_)(basic_format_parse_context<char_type>&, _Context&, const void*); + + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI explicit handle(const _Tp& __v) noexcept + : __ptr_(_VSTD::addressof(__v)), + __format_([](basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx, const void* __ptr) { + typename _Context::template formatter_type<_Tp> __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + __ctx.advance_to(__f.format(*static_cast<const _Tp*>(__ptr), __ctx)); + }) {} }; #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) diff --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h index 1adce75a8611..38b73bba32f3 100644 --- a/libcxx/include/__format/formatter.h +++ b/libcxx/include/__format/formatter.h @@ -38,26 +38,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD // to support compilers with partial C++20 support. #if !defined(_LIBCPP_HAS_NO_CONCEPTS) -// Currently not implemented specializations throw an exception when used. This -// does not conform to the Standard. However not all Standard defined formatters -// have been implemented yet. Until that time the current behavior is intended. -// TODO FMT Disable the default template. +/// The default formatter template. +/// +/// [format.formatter.spec]/5 +/// If F is a disabled specialization of formatter, these values are false: +/// - is_default_constructible_v<F>, +/// - is_copy_constructible_v<F>, +/// - is_move_constructible_v<F>, +/// - is_copy_assignable<F>, and +/// - is_move_assignable<F>. template <class _Tp, class _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI auto parse(auto& __parse_ctx) - -> decltype(__parse_ctx.begin()) { - __throw(); - } - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI auto format(_Tp, auto& __ctx) - -> decltype(__ctx.out()) { - __throw(); - } - -private: - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw() { - __throw_format_error("Argument type not implemented yet"); - } + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; }; namespace __format_spec { @@ -193,6 +187,34 @@ __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first, /** * @overload * + * Writes additional zero's for the precision before the exponent. + * This is used when the precision requested in the format string is larger + * than the maximum precision of the floating-point type. These precision + * digits are always 0. + * + * @param __exponent The location of the exponent character. + * @param __num_trailing_zeros The number of 0's to write before the exponent + * character. + */ +template <class _CharT, class _Fill> +_LIBCPP_HIDE_FROM_ABI auto __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first, + const _CharT* __last, size_t __size, size_t __width, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it)); + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +/** + * @overload + * * Uses a transformation operation before writing an element. * * TODO FMT Fill will probably change to support Unicode grapheme cluster. diff --git a/libcxx/include/__format/formatter_bool.h b/libcxx/include/__format/formatter_bool.h index fdd1d75355d2..1e40bc0a435a 100644 --- a/libcxx/include/__format/formatter_bool.h +++ b/libcxx/include/__format/formatter_bool.h @@ -102,7 +102,7 @@ using __formatter_bool = __formatter_integral<__parser_bool<_CharT>>; // For each charT, for each cv-unqualified arithmetic type ArithmeticT other // than char, wchar_t, char8_t, char16_t, or char32_t, a specialization -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> : public __format_spec::__formatter_bool<_CharT> { using _Base = __format_spec::__formatter_bool<_CharT>; diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h new file mode 100644 index 000000000000..2e710b409deb --- /dev/null +++ b/libcxx/include/__format/formatter_floating_point.h @@ -0,0 +1,717 @@ +// -*- 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_FORMATTER_FLOATING_POINT_H +#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H + +#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/find.h> +#include <__algorithm/min.h> +#include <__algorithm/rotate.h> +#include <__algorithm/transform.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__debug> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_string.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/move.h> +#include <charconv> +#include <cmath> + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include <locale> +#endif + +#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 > 17 + +// TODO FMT Remove this once we require compilers with proper C++20 support. +// If the compiler has no concepts support, the format header will be disabled. +// Without concepts support enable_if needs to be used and that too much effort +// to support compilers with partial C++20 support. +# if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +namespace __format_spec { + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +// https://en.cppreference.com/w/cpp/language/types#cite_note-1 +// float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38 +// double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308 +// long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932 +// +// The maximum number of digits required for the integral part is based on the +// maximum's value power of 10. Every power of 10 requires one additional +// decimal digit. +// The maximum number of digits required for the fractional part is based on +// the minimal subnormal hexadecimal output's power of 10. Every division of a +// fraction's binary 1 by 2, requires one additional decimal digit. +// +// The maximum size of a formatted value depends on the selected output format. +// Ignoring the fact the format string can request a precision larger than the +// values maximum required, these values are: +// +// sign 1 code unit +// __max_integral +// radix point 1 code unit +// __max_fractional +// exponent character 1 code unit +// sign 1 code unit +// __max_fractional_value +// ----------------------------------- +// total 4 code units extra required. +// +// TODO FMT Optimize the storage to avoid storing digits that are known to be zero. +// https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/ + +// TODO FMT Add long double specialization when to_chars has proper long double support. +template <class _Tp> +struct __traits; + +template <floating_point _Fp> +static constexpr size_t __float_buffer_size(int __precision) { + using _Traits = __traits<_Fp>; + return 4 + _Traits::__max_integral + __precision + _Traits::__max_fractional_value; +} + +template <> +struct __traits<float> { + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; + static constexpr int __max_fractional_value = 3; + static constexpr size_t __stack_buffer_size = 256; + + static constexpr int __hex_precision_digits = 3; +}; + +template <> +struct __traits<double> { + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; + static constexpr int __max_fractional_value = 4; + static constexpr size_t __stack_buffer_size = 1024; + + static constexpr int __hex_precision_digits = 4; +}; + +/// Helper class to store the conversion buffer. +/// +/// Depending on the maxium size required for a value, the buffer is allocated +/// on the stack or the heap. +template <floating_point _Fp> +class _LIBCPP_TEMPLATE_VIS __float_buffer { + using _Traits = __traits<_Fp>; + +public: + // TODO FMT Improve this constructor to do a better estimate. + // When using a scientific formatting with a precision of 6 a stack buffer + // will always suffice. At the moment that isn't important since floats and + // doubles use a stack buffer, unless the precision used in the format string + // is large. + // When supporting long doubles the __max_integral part becomes 4932 which + // may be too much for some platforms. For these cases a better estimate is + // required. + explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) + : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { + + // When the precision is larger than _Traits::__max_fractional the digits in + // the range (_Traits::__max_fractional, precision] will contain the value + // zero. There's no need to request to_chars to write these zeros: + // - When the value is large a temporary heap buffer needs to be allocated. + // - When to_chars writes the values they need to be "copied" to the output: + // - char: std::fill on the output iterator is faster than std::copy. + // - wchar_t: same argument as char, but additional std::copy won't work. + // The input is always a char buffer, so every char in the buffer needs + // to be converted from a char to a wchar_t. + if (__precision_ > _Traits::__max_fractional) { + __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; + } + + __size_ = __format_spec::__float_buffer_size<_Fp>(__precision_); + if (__size_ > _Traits::__stack_buffer_size) + // The allocated buffer's contents don't need initialization. + __begin_ = allocator<char>{}.allocate(__size_); + else + __begin_ = __buffer_; + } + + _LIBCPP_HIDE_FROM_ABI ~__float_buffer() { + if (__size_ > _Traits::__stack_buffer_size) + allocator<char>{}.deallocate(__begin_, __size_); + } + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; + + _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } + _LIBCPP_HIDE_FROM_ABI char* end() const { return __begin_ + __size_; } + + _LIBCPP_HIDE_FROM_ABI int __precision() const { return __precision_; } + _LIBCPP_HIDE_FROM_ABI int __num_trailing_zeros() const { return __num_trailing_zeros_; } + _LIBCPP_HIDE_FROM_ABI void __remove_trailing_zeros() { __num_trailing_zeros_ = 0; } + +private: + int __precision_; + int __num_trailing_zeros_{0}; + size_t __size_; + char* __begin_; + char __buffer_[_Traits::__stack_buffer_size]; +}; + +struct __float_result { + /// Points at the beginning of the integral part in the buffer. + /// + /// When there's no sign character this points at the start of the buffer. + char* __integral; + + /// Points at the radix point, when not present it's the same as \ref __last. + char* __radix_point; + + /// Points at the exponent character, when not present it's the same as \ref __last. + char* __exponent; + + /// Points beyond the last written element in the buffer. + char* __last; +}; + +/// Finds the position of the exponent character 'e' at the end of the buffer. +/// +/// Assuming there is an exponent the input will terminate with +/// eSdd and eSdddd (S = sign, d = digit) +/// +/// \returns a pointer to the exponent or __last when not found. +constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { + ptrdiff_t __size = __last - __first; + if (__size > 4) { + __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + for (; __first != __last - 3; ++__first) { + if (*__first == 'e') + return __first; + } + } + return __last; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value); + + __result.__exponent = __format_spec::__find_exponent(__result.__integral, __result.__last); + + // Constrains: + // - There's at least one decimal digit before the radix point. + // - The radix point, when present, is placed before the exponent. + __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + + // When the radix point isn't found its position is the exponent instead of + // __result.__last. + if (__result.__radix_point == __result.__exponent) + __result.__radix_point = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + if (__precision == -1) + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex); + else + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision); + + // H = one or more hex-digits + // S = sign + // D = one or more decimal-digits + // When the fractional part is zero and no precision the output is 0p+0 + // else the output is 0.HpSD + // So testing the second position can differentiate between these two cases. + char* __first = __integral + 1; + if (*__first == '.') { + __result.__radix_point = __first; + // One digit is the minimum + // 0.hpSd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456 + // + // Four digits is the maximum + // 0.hpSdddd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456789 + static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); + + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = _VSTD::find(__first, __last, 'p'); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); + _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + *__result.__exponent = 'P'; + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = + __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); + + char* __first = __integral + 1; + _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + if (*__first == '.') { + __result.__radix_point = __first; + __result.__exponent = __format_spec::__find_exponent(__first + 1, __result.__last); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); + *__result.__exponent = 'E'; + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); + + // When there's no precision there's no radix point. + // Else the radix point is placed at __precision + 1 from the end. + // By converting __precision to a bool the subtraction can be done + // unconditionally. + __result.__radix_point = __result.__last - (__precision + bool(__precision)); + __result.__exponent = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); + // clang-format on + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + + __buffer.__remove_trailing_zeros(); + + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision); + + char* __first = __integral + 1; + if (__first == __result.__last) { + __result.__radix_point = __result.__last; + __result.__exponent = __result.__last; + } else { + __result.__exponent = __format_spec::__find_exponent(__first, __result.__last); + if (__result.__exponent != __result.__last) + // In scientific mode if there's a radix point it will always be after + // the first digit. (This is the position __first points at). + __result.__radix_point = *__first == '.' ? __first : __result.__last; + else { + // In fixed mode the algorithm truncates trailing spaces and possibly the + // radix point. There's no good guess for the position of the radix point + // therefore scan the output after the first digit. + __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + } + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result = + __format_spec::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); + if (__result.__exponent != __result.__last) + *__result.__exponent = 'E'; + return __result; +} + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION +template <class _OutIt, class _Fp, class _CharT> +_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, const __float_buffer<_Fp>& __buffer, + const __float_result& __result, _VSTD::locale __loc, + size_t __width, _Flags::_Alignment __alignment, + _CharT __fill) { + const auto& __np = use_facet<numpunct<_CharT>>(__loc); + string __grouping = __np.grouping(); + char* __first = __result.__integral; + // When no radix point or exponent are present __last will be __result.__last. + char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + + ptrdiff_t __digits = __last - __first; + if (!__grouping.empty()) { + if (__digits <= __grouping[0]) + __grouping.clear(); + else + __grouping = __determine_grouping(__digits, __grouping); + } + + size_t __size = __result.__last - __buffer.begin() + // Formatted string + __buffer.__num_trailing_zeros() + // Not yet rendered zeros + __grouping.size() - // Grouping contains one + !__grouping.empty(); // additional character + + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __alignment == _Flags::_Alignment::__default; + if (__size < __width) { + if (__zero_padding) { + __alignment = _Flags::_Alignment::__right; + __fill = _CharT('0'); + } + + __padding = __formatter::__padding_size(__size, __width, __alignment); + } + + // sign and (zero padding or alignment) + if (__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + if (!__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + + // integral part + if (__grouping.empty()) { + __out_it = _VSTD::copy_n(__first, __digits, _VSTD::move(__out_it)); + } else { + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _CharT __sep = __np.thousands_sep(); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + while (true) { + __out_it = _VSTD::copy_n(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + } + + // fractional part + if (__result.__radix_point != __result.__last) { + *__out_it++ = __np.decimal_point(); + __out_it = _VSTD::copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + } + + // exponent + if (__result.__exponent != __result.__last) + __out_it = _VSTD::copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + + // alignment + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +# endif // _LIBCPP_HAS_NO_LOCALIZATION + +template <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_floating_point : public __parser_floating_point<_CharT> { +public: + template <floating_point _Tp> + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) { + if (this->__width_needs_substitution()) + this->__substitute_width_arg_id(__ctx.arg(this->__width)); + + bool __negative = _VSTD::signbit(__value); + + if (!_VSTD::isfinite(__value)) [[unlikely]] + return __format_non_finite(__ctx.out(), __negative, _VSTD::isnan(__value)); + + bool __has_precision = this->__has_precision_field(); + if (this->__precision_needs_substitution()) + this->__substitute_precision_arg_id(__ctx.arg(this->__precision)); + + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a non negative value. + // The function @ref __insert_sign will insert a '-' when the value was + // negative. + + if (__negative) + __value = _VSTD::copysign(__value, +1.0); + + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + using _Fp = conditional_t<same_as<_Tp, long double>, double, _Tp>; + // Force the type of the precision to avoid -1 to become an unsigned value. + __float_buffer<_Fp> __buffer(__has_precision ? int(this->__precision) : -1); + __float_result __result = __format_buffer(__buffer, __value, __negative, __has_precision); + + if (this->__alternate_form && __result.__radix_point == __result.__last) { + *__result.__last++ = '.'; + + // When there is an exponent the point needs to be moved before the + // exponent. When there's no exponent the rotate does nothing. Since + // rotate tests whether the operation is a nop, call it unconditionally. + _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + __result.__radix_point = __result.__exponent; + + // The radix point is always placed before the exponent. + // - No exponent needs to point to the new last. + // - An exponent needs to move one position to the right. + // So it's safe to increment the value unconditionally. + ++__result.__exponent; + } + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (this->__locale_specific_form) + return __format_spec::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), + this->__width, this->__alignment, this->__fill); +# endif + + ptrdiff_t __size = __result.__last - __buffer.begin(); + int __num_trailing_zeros = __buffer.__num_trailing_zeros(); + if (__size + __num_trailing_zeros >= this->__width) { + if (__num_trailing_zeros && __result.__exponent != __result.__last) + // Insert trailing zeros before exponent character. + return _VSTD::copy(__result.__exponent, __result.__last, + _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__exponent, __ctx.out()), + __num_trailing_zeros, _CharT('0'))); + + return _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, + _CharT('0')); + } + + auto __out_it = __ctx.out(); + char* __first = __buffer.begin(); + if (this->__alignment == _Flags::_Alignment::__default) { + // When there is a sign output it before the padding. Note the __size + // doesn't need any adjustment, regardless whether the sign is written + // here or in __formatter::__write. + if (__first != __result.__integral) + *__out_it++ = *__first++; + // After the sign is written, zero padding is the same a right alignment + // with '0'. + this->__alignment = _Flags::_Alignment::__right; + this->__fill = _CharT('0'); + } + + if (__num_trailing_zeros) + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment, __result.__exponent, __num_trailing_zeros); + + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment); + } + +private: + template <class _OutIt> + _LIBCPP_HIDE_FROM_ABI _OutIt __format_non_finite(_OutIt __out_it, bool __negative, bool __isnan) { + char __buffer[4]; + char* __last = __insert_sign(__buffer, __negative, this->__sign); + + // to_char can return inf, infinity, nan, and nan(n-char-sequence). + // The format library requires inf and nan. + // All in one expression to avoid dangling references. + __last = _VSTD::copy_n(&("infnanINFNAN"[6 * (this->__type == _Flags::_Type::__float_hexadecimal_upper_case || + this->__type == _Flags::_Type::__scientific_upper_case || + this->__type == _Flags::_Type::__fixed_upper_case || + this->__type == _Flags::_Type::__general_upper_case) + + 3 * __isnan]), + 3, __last); + + // [format.string.std]/13 + // A zero (0) character preceding the width field pads the field with + // leading zeros (following any indication of sign or base) to the field + // width, except when applied to an infinity or NaN. + if (this->__alignment == _Flags::_Alignment::__default) + this->__alignment = _Flags::_Alignment::__right; + + ptrdiff_t __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy_n(__buffer, __size, _VSTD::move(__out_it)); + + return __formatter::__write(_VSTD::move(__out_it), __buffer, __last, __size, this->__width, this->__fill, + this->__alignment); + } + + /// Fills the buffer with the data based on the requested formatting. + /// + /// This function, when needed, turns the characters to upper case and + /// determines the "interesting" locations which are returned to the caller. + /// + /// This means the caller never has to convert the contents of the buffer to + /// upper case or search for radix points and the location of the exponent. + /// This gives a bit of overhead. The original code didn't do that, but due + /// to the number of possible additional work needed to turn this number to + /// the proper output the code was littered with tests for upper cases and + /// searches for radix points and exponents. + /// - When a precision larger than the type's precision is selected + /// additional zero characters need to be written before the exponent. + /// - alternate form needs to add a radix point when not present. + /// - localization needs to do grouping in the integral part. + template <class _Fp, class _Tp> + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(__float_buffer<_Fp>& __buffer, _Tp __value, bool __negative, + bool __has_precision) { + char* __first = __insert_sign(__buffer.begin(), __negative, this->__sign); + switch (this->__type) { + case _Flags::_Type::__default: + return __format_spec::__format_buffer_default(__buffer, __value, __first); + + case _Flags::_Type::__float_hexadecimal_lower_case: + return __format_spec::__format_buffer_hexadecimal_lower_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__float_hexadecimal_upper_case: + return __format_spec::__format_buffer_hexadecimal_upper_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__scientific_lower_case: + return __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__scientific_upper_case: + return __format_spec::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + return __format_spec::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_lower_case: + return __format_spec::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_upper_case: + return __format_spec::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); + + default: + _LIBCPP_ASSERT(false, "The parser should have validated the type"); + _LIBCPP_UNREACHABLE(); + } + } +}; + +} //namespace __format_spec + +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h index 767df36e61eb..e1f3d4e34897 100644 --- a/libcxx/include/__format/formatter_integer.h +++ b/libcxx/include/__format/formatter_integer.h @@ -81,25 +81,25 @@ using __formatter_integer = __formatter_integral<__parser_integer<_CharT>>; // than char, wchar_t, char8_t, char16_t, or char32_t, a specialization // Signed integral types. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; #ifndef _LIBCPP_HAS_NO_INT128 -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> : public __format_spec::__formatter_integer<_CharT> { @@ -119,28 +119,28 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT #endif // Unsigned integral types. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; #ifndef _LIBCPP_HAS_NO_INT128 -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> : public __format_spec::__formatter_integer<_CharT> { diff --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h index 5f1353effd77..f164ee610974 100644 --- a/libcxx/include/__format/formatter_integral.h +++ b/libcxx/include/__format/formatter_integral.h @@ -10,15 +10,15 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H #define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H +#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/transform.h> #include <__config> #include <__format/format_error.h> #include <__format/format_fwd.h> #include <__format/formatter.h> #include <__format/parser_std_format_spec.h> -#include <__algorithm/copy.h> -#include <__algorithm/copy_n.h> -#include <__algorithm/fill_n.h> -#include <__algorithm/transform.h> #include <array> #include <charconv> #include <concepts> @@ -82,7 +82,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __format_spec { /** Wrapper around @ref to_chars, returning the output pointer. */ -template <class _Tp> +template <integral _Tp> _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { // TODO FMT Evaluate code overhead due to not calling the internal function diff --git a/libcxx/include/__format/formatter_pointer.h b/libcxx/include/__format/formatter_pointer.h new file mode 100644 index 000000000000..aa2eb641c6c6 --- /dev/null +++ b/libcxx/include/__format/formatter_pointer.h @@ -0,0 +1,91 @@ +// -*- 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_FORMATTER_POINTER_H +#define _LIBCPP___FORMAT_FORMATTER_POINTER_H + +#include <__algorithm/copy.h> +#include <__availability> +#include <__config> +#include <__debug> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/access.h> +#include <__nullptr> +#include <cstdint> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Remove this once we require compilers with proper C++20 support. +// If the compiler has no concepts support, the format header will be disabled. +// Without concepts support enable_if needs to be used and that too much effort +// to support compilers with partial C++20 support. +# if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +namespace __format_spec { + +template <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_pointer : public __parser_pointer<_CharT> { +public: + _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) -> decltype(__ctx.out()) { + _LIBCPP_ASSERT(this->__alignment != _Flags::_Alignment::__default, + "The call to parse should have updated the alignment"); + if (this->__width_needs_substitution()) + this->__substitute_width_arg_id(__ctx.arg(this->__width)); + + // This code looks a lot like the code to format a hexadecimal integral, + // but that code isn't public. Making that code public requires some + // refactoring. + // TODO FMT Remove code duplication. + char __buffer[2 + 2 * sizeof(uintptr_t)]; + __buffer[0] = '0'; + __buffer[1] = 'x'; + char* __last = __to_buffer(__buffer + 2, _VSTD::end(__buffer), reinterpret_cast<uintptr_t>(__ptr), 16); + + unsigned __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy(__buffer, __last, __ctx.out()); + + return __formatter::__write(__ctx.out(), __buffer, __last, __size, this->__width, this->__fill, this->__alignment); + } +}; + +} // namespace __format_spec + +// [format.formatter.spec]/2.4 +// For each charT, the pointer type specializations template<> +// - struct formatter<nullptr_t, charT>; +// - template<> struct formatter<void*, charT>; +// - template<> struct formatter<const void*, charT>; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h index 75a81f5184a0..04950faa4a21 100644 --- a/libcxx/include/__format/formatter_string.h +++ b/libcxx/include/__format/formatter_string.h @@ -64,7 +64,7 @@ public: // [format.formatter.spec]/2.2 For each charT, the string type specializations // Formatter const char*. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -98,7 +98,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter char*. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT> : public formatter<const _CharT*, _CharT> { using _Base = formatter<const _CharT*, _CharT>; @@ -110,7 +110,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter const char[]. -template <class _CharT, size_t _Size> +template <__formatter::__char_type _CharT, size_t _Size> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -123,7 +123,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter std::string. -template <class _CharT, class _Traits, class _Allocator> +template <__formatter::__char_type _CharT, class _Traits, class _Allocator> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -138,7 +138,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter std::string_view. -template <class _CharT, class _Traits> +template <__formatter::__char_type _CharT, class _Traits> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT> : public __format_spec::__formatter_string<_CharT> { using _Base = __format_spec::__formatter_string<_CharT>; diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h index 9b713b811484..9d893e9ced27 100644 --- a/libcxx/include/__format/parser_std_format_spec.h +++ b/libcxx/include/__format/parser_std_format_spec.h @@ -214,7 +214,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { __format::__parse_arg_id(__begin, __end, __parse_ctx); if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) - __throw_format_error("A format-spec arg-id should terminate at a '}'"); + __throw_format_error("Invalid arg-id"); ++__r.__ptr; return __r; @@ -363,17 +363,6 @@ protected: if (__begin == __end) __throw_format_error("End of input while parsing format-spec precision"); - if (*__begin == _CharT('0')) { - ++__begin; - if (__begin != __end && *__begin >= '0' && *__begin <= '9') - __throw_format_error( - "A format-spec precision field shouldn't have a leading zero"); - - __precision = 0; - __precision_as_arg = 0; - return __begin; - } - if (*__begin == _CharT('{')) { __format::__parse_number_result __arg_id = __parse_arg_id(++__begin, __end, __parse_ctx); @@ -487,6 +476,21 @@ __parse_type(const _CharT* __begin, _Flags& __flags) { } /** + * Process the parsed alignment and zero-padding state of arithmetic types. + * + * [format.string.std]/13 + * If the 0 character and an align option both appear, the 0 character is + * ignored. + * + * For the formatter a @ref __default alignment means zero-padding. + */ +_LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) { + __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default; + if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default) + __flags.__alignment = _Flags::_Alignment::__right; +} + +/** * The parser for the std-format-spec. * * [format.string.std]/1 specifies the std-format-spec: @@ -659,23 +663,9 @@ protected: return __begin; } - /** - * Handles the post-parsing updates for the integer types. - * - * Updates the zero-padding and alignment for integer types. - * - * [format.string.std]/13 - * If the 0 character and an align option both appear, the 0 character is - * ignored. - * - * For the formatter a @ref __default alignment means zero-padding. Update - * the alignment based on parsed format string. - */ + /** Handles the post-parsing updates for the integer types. */ _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept { - this->__zero_padding &= this->__alignment == _Flags::_Alignment::__default; - if (!this->__zero_padding && - this->__alignment == _Flags::_Alignment::__default) - this->__alignment = _Flags::_Alignment::__right; + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); } /** @@ -712,8 +702,232 @@ protected: } }; -// TODO FMT Add a parser for floating-point values. -// TODO FMT Add a parser for pointer values. +/** + * The parser for the std-format-spec. + * + * This implements the parser for the floating-point types. + * + * See @ref __parser_string. + */ +template <class _CharT> +class _LIBCPP_TEMPLATE_VIS __parser_floating_point + : public __parser_width, // provides __width(|as_arg) + public __parser_precision, // provides __precision(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); + __process_display_type(); + return __it; + } +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, + static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_sign(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parser_precision::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = + __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error( + "The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + // When no precision specified then it keeps default since that + // formatting differs from the other types. + if (this->__has_precision_field()) + this->__type = _Flags::_Type::__general_lower_case; + break; + case _Flags::_Type::__float_hexadecimal_lower_case: + case _Flags::_Type::__float_hexadecimal_upper_case: + // Precision specific behavior will be handled later. + break; + case _Flags::_Type::__scientific_lower_case: + case _Flags::_Type::__scientific_upper_case: + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + case _Flags::_Type::__general_lower_case: + case _Flags::_Type::__general_upper_case: + if (!this->__has_precision_field()) { + // Set the default precision for the call to to_chars. + this->__precision = 6; + this->__precision_as_arg = false; + } + break; + + default: + __throw_format_error("The format-spec type has a type not supported for " + "a floating-point argument"); + } + } +}; + +/** + * The parser for the std-format-spec. + * + * This implements the parser for the pointer types. + * + * See @ref __parser_string. + */ +template <class _CharT> +class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width, // provides __width(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() { + // Implements LWG3612 Inconsistent pointer alignment in std::format. + // The issue's current status is "Tentatively Ready" and libc++ status is + // still experimental. + // + // TODO FMT Validate this with the final resolution of LWG3612. + this->__alignment = _Flags::_Alignment::__right; + } + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_display_type(); + return __it; + } + +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + // An integer presentation type isn't defined in the Standard. + // Since a pointer is formatted as an integer it can be argued it's an + // integer presentation type. However there are two LWG-issues asserting it + // isn't an integer presentation type: + // - LWG3612 Inconsistent pointer alignment in std::format + // - LWG3644 std::format does not define "integer presentation type" + // + // There's a paper to make additional clarifications on the status of + // formatting pointers and proposes additional fields to be valid. That + // paper hasn't been reviewed by the Committee yet. + // - P2510 Formatting pointers + // + // The current implementation assumes formatting pointers isn't covered by + // "integer presentation type". + // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee. + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + this->__type = _Flags::_Type::__pointer; + break; + case _Flags::_Type::__pointer: + break; + default: + __throw_format_error("The format-spec type has a type not supported for a pointer argument"); + } + } +}; /** Helper struct returned from @ref __get_string_alignment. */ template <class _CharT> diff --git a/libcxx/include/__function_like.h b/libcxx/include/__function_like.h deleted file mode 100644 index 4075355174d9..000000000000 --- a/libcxx/include/__function_like.h +++ /dev/null @@ -1,51 +0,0 @@ -// -*- 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___ITERATOR_FUNCTION_LIKE_H -#define _LIBCPP___ITERATOR_FUNCTION_LIKE_H - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_RANGES) - -namespace ranges { -// Per [range.iter.ops.general] and [algorithms.requirements], functions in namespace std::ranges -// can't be found by ADL and inhibit ADL when found by unqualified lookup. The easiest way to -// facilitate this is to use function objects. -// -// Since these are still standard library functions, we use `__function_like` to eliminate most of -// the properties that function objects get by default (e.g. semiregularity, addressability), to -// limit the surface area of the unintended public interface, so as to curb the effect of Hyrum's -// law. -struct __function_like { - __function_like() = delete; - __function_like(__function_like const&) = delete; - __function_like& operator=(__function_like const&) = delete; - - void operator&() const = delete; - - struct __tag { }; - -protected: - constexpr explicit __function_like(__tag) noexcept {} - ~__function_like() = default; -}; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___ITERATOR_FUNCTION_LIKE_H diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h index 0eb95c824664..11a51e5957ee 100644 --- a/libcxx/include/__functional/bind.h +++ b/libcxx/include/__functional/bind.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_BIND_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/invoke.h> +#include <__functional/weak_result_type.h> #include <cstddef> #include <tuple> #include <type_traits> @@ -23,18 +23,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template<class _Tp> struct __is_bind_expression : public false_type {}; -template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression - : public __is_bind_expression<typename remove_cv<_Tp>::type> {}; +template<class _Tp> +struct is_bind_expression : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + false_type, + is_bind_expression<typename __uncvref<_Tp>::type> +> {}; #if _LIBCPP_STD_VER > 14 template <class _Tp> inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; #endif -template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {}; -template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder - : public __is_placeholder<typename remove_cv<_Tp>::type> {}; +template<class _Tp> +struct is_placeholder : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + integral_constant<int, 0>, + is_placeholder<typename __uncvref<_Tp>::type> +> {}; #if _LIBCPP_STD_VER > 14 template <class _Tp> @@ -73,7 +79,7 @@ _LIBCPP_FUNC_VIS extern const __ph<10> _10; } // namespace placeholders template<int _Np> -struct __is_placeholder<placeholders::__ph<_Np> > +struct is_placeholder<placeholders::__ph<_Np> > : public integral_constant<int, _Np> {}; @@ -304,7 +310,7 @@ public: }; template<class _Fp, class ..._BoundArgs> -struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; template<class _Rp, class _Fp, class ..._BoundArgs> class __bind_r @@ -359,7 +365,7 @@ public: }; template<class _Rp, class _Fp, class ..._BoundArgs> -struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; template<class _Fp, class ..._BoundArgs> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h index 86d4594b6571..31397ec5400d 100644 --- a/libcxx/include/__functional/bind_front.h +++ b/libcxx/include/__functional/bind_front.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_BIND_FRONT_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> +#include <__functional/perfect_forward.h> #include <type_traits> #include <utility> diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index 8336d85adf2e..b6d383ce8459 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -16,6 +16,7 @@ #include <__functional/invoke.h> #include <__functional/unary_function.h> #include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/shared_ptr.h> @@ -360,7 +361,7 @@ const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) - return &__f_.__target(); + return _VSTD::addressof(__f_.__target()); return nullptr; } @@ -1392,7 +1393,7 @@ const void* __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) - return &__f_.first(); + return _VSTD::addressof(__f_.first()); return (const void*)0; } diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index b1a3ad94ae2d..de0c161f47ec 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -16,9 +16,9 @@ #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/swap.h> +#include <cstddef> #include <cstdint> #include <cstring> -#include <cstddef> #include <limits> #include <type_traits> diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h index 1fa070a42cc9..0ec84233439c 100644 --- a/libcxx/include/__functional/mem_fn.h +++ b/libcxx/include/__functional/mem_fn.h @@ -11,9 +11,9 @@ #define _LIBCPP___FUNCTIONAL_MEM_FN_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/binary_function.h> #include <__functional/invoke.h> +#include <__functional/weak_result_type.h> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__functional/mem_fun_ref.h b/libcxx/include/__functional/mem_fun_ref.h index 4616da0b0748..830936c1b0e5 100644 --- a/libcxx/include/__functional/mem_fun_ref.h +++ b/libcxx/include/__functional/mem_fun_ref.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H #include <__config> -#include <__functional/unary_function.h> #include <__functional/binary_function.h> +#include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__functional/not_fn.h b/libcxx/include/__functional/not_fn.h index 81fe112c88ba..36aab2eb7935 100644 --- a/libcxx/include/__functional/not_fn.h +++ b/libcxx/include/__functional/not_fn.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_NOT_FN_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> +#include <__functional/perfect_forward.h> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index e1e4abd80c23..d04d51568beb 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -34,25 +34,16 @@ public: private: type* __f_; -#ifndef _LIBCPP_CXX03_LANG static void __fun(_Tp&) _NOEXCEPT; static void __fun(_Tp&&) = delete; -#endif public: - // construct/copy/destroy -#ifdef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - reference_wrapper(type& __f) _NOEXCEPT - : __f_(_VSTD::addressof(__f)) {} -#else - template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) >> + template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { type& __f = static_cast<_Up&&>(__u); __f_ = _VSTD::addressof(__f); } -#endif // access _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -176,7 +167,7 @@ public: #endif // _LIBCPP_CXX03_LANG }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template <class _Tp> reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif @@ -194,7 +185,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::ref(__t.get()); + return __t; } template <class _Tp> @@ -210,13 +201,11 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::cref(__t.get()); + return __t; } -#ifndef _LIBCPP_CXX03_LANG template <class _Tp> void ref(const _Tp&&) = delete; template <class _Tp> void cref(const _Tp&&) = delete; -#endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 126e1884a664..adc732cffb01 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -288,9 +288,7 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -310,9 +308,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator=(const __hash_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; @@ -400,9 +398,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -410,7 +406,7 @@ public: : __node_(__x.__node_) { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } @@ -419,7 +415,7 @@ public: __hash_const_iterator(const __hash_const_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -431,9 +427,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator=(const __hash_const_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; @@ -517,9 +513,7 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -529,7 +523,7 @@ public: __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -541,9 +535,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator=(const __hash_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; @@ -651,9 +645,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -663,7 +655,7 @@ public: __bucket_count_(__x.__bucket_count_) { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } @@ -674,7 +666,7 @@ public: __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -686,9 +678,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; @@ -1623,7 +1615,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __u.size() = 0; } #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2029,11 +2021,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( const_iterator __p, __node_pointer __cp) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); if (__p != end() && key_eq()(*__p, __cp->__value_)) { __next_pointer __np = __p.__node_; @@ -2158,11 +2148,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -2484,12 +2472,12 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __next_pointer __np = __p.__node_; + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__p != end(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container erase(iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__p != end(), - "unordered container erase(iterator) called with a non-dereferenceable iterator"); iterator __r(__np, this); #else iterator __r(__np); @@ -2504,14 +2492,12 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); for (const_iterator __p = __first; __first != __last; __p = __first) { ++__first; @@ -2741,7 +2727,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = __u.__p1_.first().__ptr(); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h index 2236a57936cc..03418979ddbd 100644 --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -12,13 +12,12 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> -#include <cstdlib> #include <concepts> +#include <cstdlib> #include <limits> #include <type_traits> @@ -67,17 +66,13 @@ void advance(_InputIter& __i, _Distance __orig_n) { #if !defined(_LIBCPP_HAS_NO_RANGES) -namespace ranges { // [range.iter.op.advance] -// TODO(varconst): rename `__advance_fn` to `__fn`. -struct __advance_fn final : private __function_like { -private: - template <class _Tp> - _LIBCPP_HIDE_FROM_ABI - static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept { - return __a < 0 ? (__a <= __b) : (__a >= __b); - } +namespace ranges { +namespace __advance { + +struct __fn { +private: template <class _Ip> _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { @@ -97,8 +92,6 @@ private: } public: - constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {} - // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template <input_or_output_iterator _Ip> _LIBCPP_HIDE_FROM_ABI @@ -156,6 +149,12 @@ public: // If `S` and `I` model `sized_sentinel_for<S, I>`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`. + // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. + auto __magnitude_geq = [](auto __a, auto __b) { + return __a == 0 ? __b == 0 : + __a > 0 ? __a >= __b : + __a <= __b; + }; if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) { (*this)(__i, __bound); return __n - __M; @@ -186,7 +185,11 @@ public: } }; -inline constexpr auto advance = __advance_fn(__function_like::__tag()); +} // namespace __advance + +inline namespace __cpo { + inline constexpr auto advance = __advance::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h index 9a142769e55a..605071d70928 100644 --- a/libcxx/include/__iterator/common_iterator.h +++ b/libcxx/include/__iterator/common_iterator.h @@ -29,6 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_RANGES) +template<class _Iter> +concept __can_use_postfix_proxy = + constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> && + move_constructible<iter_value_t<_Iter>>; + template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> requires (!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { @@ -41,7 +46,7 @@ class common_iterator { : __value(_VSTD::move(__x)) {} public: - const iter_value_t<_Iter>* operator->() const { + constexpr const iter_value_t<_Iter>* operator->() const noexcept { return _VSTD::addressof(__value); } }; @@ -54,11 +59,7 @@ class common_iterator { : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {} public: - constexpr static bool __valid_for_iter = - constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> && - move_constructible<iter_value_t<_Iter>>; - - const iter_value_t<_Iter>& operator*() const { + constexpr const iter_value_t<_Iter>& operator*() const noexcept { return __value; } }; @@ -75,7 +76,7 @@ public: requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> constexpr common_iterator(const common_iterator<_I2, _S2>& __other) : __hold_([&]() -> variant<_Iter, _Sent> { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Constructed from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); if (__other.__hold_.index() == 0) return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; @@ -85,7 +86,7 @@ public: requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> && assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Assigned from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); auto __idx = __hold_.index(); auto __other_idx = __other.__hold_.index(); @@ -105,18 +106,16 @@ public: return *this; } - decltype(auto) operator*() + constexpr decltype(auto) operator*() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } - decltype(auto) operator*() const + constexpr decltype(auto) operator*() const requires __dereferenceable<const _Iter> { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } @@ -127,9 +126,7 @@ public: is_reference_v<iter_reference_t<_I2>> || constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { return _VSTD::__unchecked_get<_Iter>(__hold_); } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) { @@ -141,21 +138,18 @@ public: } common_iterator& operator++() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; } decltype(auto) operator++(int) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); if constexpr (forward_iterator<_Iter>) { auto __tmp = *this; ++*this; return __tmp; } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } || - !__postfix_proxy::__valid_for_iter) { + !__can_use_postfix_proxy<_Iter>) { return _VSTD::__unchecked_get<_Iter>(__hold_)++; } else { __postfix_proxy __p(**this); @@ -166,10 +160,9 @@ public: template<class _I2, sentinel_for<_Iter> _S2> requires sentinel_for<_Sent, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -185,10 +178,9 @@ public: template<class _I2, sentinel_for<_Iter> _S2> requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -207,10 +199,9 @@ public: template<sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2> requires sized_sentinel_for<_Sent, _I2> - friend iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot subtract valueless iterators.)"); + friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -227,24 +218,21 @@ public: return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); } - friend iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) + friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) noexcept(noexcept(ranges::iter_move(declval<const _Iter&>()))) requires input_iterator<_Iter> { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), - "Cannot iter_move a sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); } template<indirectly_swappable<_Iter> _I2, class _S2> - friend void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) + friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) noexcept(noexcept(ranges::iter_swap(declval<const _Iter&>(), declval<const _I2&>()))) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), - "Cannot swap __y with a sentinel. Common iterator (__x) not holding an iterator."); - _LIBCPP_ASSERT(holds_alternative<_Iter>(__y.__hold_), - "Cannot swap __x with a sentinel. Common iterator (__y) not holding an iterator."); - return ranges::iter_swap( _VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_Iter>(__y.__hold_)); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT(holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); } }; @@ -271,10 +259,10 @@ struct __arrow_type_or_void { template<class _Iter, class _Sent> requires __common_iter_has_ptr_op<_Iter, _Sent> struct __arrow_type_or_void<_Iter, _Sent> { - using type = decltype(declval<const common_iterator<_Iter, _Sent>>().operator->()); + using type = decltype(declval<const common_iterator<_Iter, _Sent>&>().operator->()); }; -template<class _Iter, class _Sent> +template<input_iterator _Iter, class _Sent> struct iterator_traits<common_iterator<_Iter, _Sent>> { using iterator_concept = _If<forward_iterator<_Iter>, forward_iterator_tag, @@ -288,7 +276,6 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> { using reference = iter_reference_t<_Iter>; }; - #endif // !defined(_LIBCPP_HAS_NO_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h index 55979fe5571e..82d7adcfb02e 100644 --- a/libcxx/include/__iterator/counted_iterator.h +++ b/libcxx/include/__iterator/counted_iterator.h @@ -13,9 +13,9 @@ #include <__debug> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> -#include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/pointer_traits.h> @@ -96,7 +96,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& { return __current_; } + constexpr const _Iter& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return _VSTD::move(__current_); } diff --git a/libcxx/include/__iterator/indirectly_comparable.h b/libcxx/include/__iterator/indirectly_comparable.h new file mode 100644 index 000000000000..3129b2dcf65e --- /dev/null +++ b/libcxx/include/__iterator/indirectly_comparable.h @@ -0,0 +1,30 @@ +// -*- 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___ITERATOR_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_RANGES + +template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity> +concept indirectly_comparable = + indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; + +#endif // _LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h index eac9264df30a..29bac864c275 100644 --- a/libcxx/include/__iterator/move_iterator.h +++ b/libcxx/include/__iterator/move_iterator.h @@ -12,6 +12,7 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,19 +24,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Iter> class _LIBCPP_TEMPLATE_VIS move_iterator { -private: - _Iter __i; public: - typedef _Iter iterator_type; +#if _LIBCPP_STD_VER > 17 + typedef input_iterator_tag iterator_concept; +#endif + + 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; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; typedef iterator_type pointer; - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category> iterator_category; -#if _LIBCPP_STD_VER > 17 - typedef input_iterator_tag iterator_concept; -#endif #ifndef _LIBCPP_CXX03_LANG typedef typename iterator_traits<iterator_type>::reference __reference; @@ -48,114 +50,113 @@ public: typedef typename iterator_traits<iterator_type>::reference reference; #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator() : __i() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator() : __current_() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit move_iterator(_Iter __x) : __i(__x) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {} template <class _Up, class = __enable_if_t< - !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value + !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value + is_convertible<const _Up&, _Iter>::value && + is_assignable<_Iter&, const _Up&>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator=(const move_iterator<_Up>& __u) { - __i = __u.base(); + __current_ = __u.base(); return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator*() const { return static_cast<reference>(*__i); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const { return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator++() {++__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator--() {--__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator+=(difference_type __n) {__i += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + _Iter base() const { return __current_; } + + _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; } + _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; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + +private: + _Iter __current_; }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); + return __x.base() != __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); + return __x.base() < __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); + return __x.base() <= __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +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(); + return __x.base() >= __y.base(); } #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -auto -operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) --> decltype(__x.base() - __y.base()) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> decltype(__x.base() - __y.base()) { return __x.base() - __y.base(); } #else template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -164,7 +165,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { @@ -172,11 +173,11 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato } template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> make_move_iterator(_Iter __i) { - return move_iterator<_Iter>(__i); + return move_iterator<_Iter>(_VSTD::move(__i)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h index d332abfa8e0e..b9bdd6b27e05 100644 --- a/libcxx/include/__iterator/next.h +++ b/libcxx/include/__iterator/next.h @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -38,12 +37,12 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 #if !defined(_LIBCPP_HAS_NO_RANGES) +// [range.iter.op.next] + namespace ranges { -// TODO(varconst): rename `__next_fn` to `__fn`. -struct __next_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __next { +struct __fn { template <input_or_output_iterator _Ip> _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -73,7 +72,11 @@ struct __next_fn final : private __function_like { } }; -inline constexpr auto next = __next_fn(__function_like::__tag()); +} // namespace __next + +inline namespace __cpo { + inline constexpr auto next = __next::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h index 57f2d04a1325..870cbe64eaee 100644 --- a/libcxx/include/__iterator/prev.h +++ b/libcxx/include/__iterator/prev.h @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -37,12 +36,12 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 #if !defined(_LIBCPP_HAS_NO_RANGES) +// [range.iter.op.prev] + namespace ranges { -// TODO(varconst): rename `__prev_fn` to `__fn`. -struct __prev_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __prev { +struct __fn { template <bidirectional_iterator _Ip> _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -65,7 +64,11 @@ struct __prev_fn final : private __function_like { } }; -inline constexpr auto prev = __prev_fn(__function_like::__tag()); +} // namespace __prev + +inline namespace __cpo { + inline constexpr auto prev = __prev::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/readable_traits.h b/libcxx/include/__iterator/readable_traits.h index 90121bea8073..13f323e295ba 100644 --- a/libcxx/include/__iterator/readable_traits.h +++ b/libcxx/include/__iterator/readable_traits.h @@ -57,14 +57,14 @@ template<__has_member_element_type _Tp> struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::element_type> {}; -// Pre-emptively applies LWG3541 template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> + requires __has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> {}; + template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> && - same_as<remove_cv_t<typename _Tp::element_type>, - remove_cv_t<typename _Tp::value_type>> + requires __has_member_element_type<_Tp> && + same_as<remove_cv_t<typename _Tp::element_type>, + remove_cv_t<typename _Tp::value_type>> struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::value_type> {}; diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index d06859ee5f39..449eb529aa98 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -10,9 +10,9 @@ #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H -#include <__config> #include <__compare/compare_three_way_result.h> #include <__compare/three_way_comparable.h> +#include <__config> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> @@ -24,13 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp, class = void> -struct __is_stashing_iterator : false_type {}; - -template <class _Tp> -struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type> - : true_type {}; - _LIBCPP_SUPPRESS_DEPRECATED_PUSH template <class _Iter> class _LIBCPP_TEMPLATE_VIS reverse_iterator @@ -48,10 +41,6 @@ private: _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break #endif - static_assert(!__is_stashing_iterator<_Iter>::value, - "The specified iterator type cannot be used with reverse_iterator; " - "Using stashing iterators with reverse_iterator causes undefined behavior"); - protected: _Iter current; public: @@ -88,7 +77,7 @@ public: template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter, _Up const&>::value + is_assignable<_Iter&, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { @@ -113,7 +102,7 @@ public: template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter, _Up const&>::value + is_assignable<_Iter&, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h index cfcc9857b3fc..d9dbee588896 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -43,10 +43,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter() _NOEXCEPT : __i() { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const __wrap_iter<_Up>& __u, @@ -69,9 +66,10 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator=(const __wrap_iter& __x) { - if (this != _VSTD::addressof(__x) && !__libcpp_is_constant_evaluated()) + if (this != _VSTD::addressof(__x)) { - __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); __i = __x.__i; } return *this; @@ -85,29 +83,20 @@ public: #endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); return *__i; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); return _VSTD::__to_address(__i); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator++() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable iterator"); ++__i; return *this; } @@ -116,11 +105,8 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator--() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable iterator"); --__i; return *this; } @@ -130,11 +116,8 @@ public: {__wrap_iter __w(*this); __w += __n; return __w;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), - "Attempted to add/subtract an iterator outside its valid range"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n), + "Attempted to add/subtract an iterator outside its valid range"); __i += __n; return *this; } @@ -144,11 +127,8 @@ public: {*this += -__n; return *this;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), - "Attempted to subscript an iterator outside its valid range"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n), + "Attempted to subscript an iterator outside its valid range"); return __i[__n]; } @@ -189,11 +169,8 @@ template <class _Iter1> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), - "Attempted to compare incomparable iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to compare incomparable iterators"); return __x.base() < __y.base(); } @@ -201,11 +178,8 @@ template <class _Iter1, class _Iter2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), - "Attempted to compare incomparable iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); return __x.base() < __y.base(); } @@ -275,11 +249,8 @@ typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT #endif // C++03 { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), - "Attempted to subtract incompatible iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to subtract incompatible iterators"); return __x.base() - __y.base(); } diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 2582a90bb578..98445bd2d8f4 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -12,13 +12,14 @@ #include <__availability> #include <__config> -#include <string> -#include <memory> -#include <utility> -#include <mutex> -#include <cstdint> #include <cctype> +#include <cstdint> #include <locale.h> +#include <memory> +#include <mutex> +#include <string> +#include <utility> + #if defined(_LIBCPP_MSVCRT_LIKE) # include <cstring> # include <__support/win32/locale_win32.h> @@ -510,6 +511,33 @@ public: # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#elif defined(__MVS__) +# if defined(__NATIVE_ASCII_F) + typedef unsigned int mask; + static const mask space = _ISSPACE_A; + static const mask print = _ISPRINT_A; + static const mask cntrl = _ISCNTRL_A; + static const mask upper = _ISUPPER_A; + static const mask lower = _ISLOWER_A; + static const mask alpha = _ISALPHA_A; + static const mask digit = _ISDIGIT_A; + static const mask punct = _ISPUNCT_A; + static const mask xdigit = _ISXDIGIT_A; + static const mask blank = _ISBLANK_A; +# else + typedef unsigned short mask; + static const mask space = __ISSPACE; + static const mask print = __ISPRINT; + static const mask cntrl = __ISCNTRL; + static const mask upper = __ISUPPER; + static const mask lower = __ISLOWER; + static const mask alpha = __ISALPHA; + static const mask digit = __ISDIGIT; + static const mask punct = __ISPUNCT; + static const mask xdigit = __ISXDIGIT; + static const mask blank = __ISBLANK; +# endif + static const mask __regex_word = 0x8000; #else # error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? #endif @@ -733,6 +761,10 @@ public: static const short* __classic_upper_table() _NOEXCEPT; static const short* __classic_lower_table() _NOEXCEPT; #endif +#if defined(__MVS__) + static const unsigned short* __classic_upper_table() _NOEXCEPT; + static const unsigned short* __classic_lower_table() _NOEXCEPT; +#endif protected: ~ctype(); diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h index 3b58451c5009..580ce781f482 100644 --- a/libcxx/include/__memory/construct_at.h +++ b/libcxx/include/__memory/construct_at.h @@ -14,6 +14,7 @@ #include <__debug> #include <__iterator/access.h> #include <__memory/addressof.h> +#include <__memory/voidify.h> #include <__utility/forward.h> #include <type_traits> #include <utility> @@ -31,10 +32,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _Tp, class ..._Args, class = decltype( ::new (declval<void*>()) _Tp(declval<_Args>()...) )> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) { _LIBCPP_ASSERT(__location, "null pointer given to construct_at"); - return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...); + return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...); } #endif @@ -46,7 +47,7 @@ constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 -void __destroy(_ForwardIterator, _ForwardIterator); +_ForwardIterator __destroy(_ForwardIterator, _ForwardIterator); template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -66,9 +67,10 @@ void __destroy_at(_Tp* __loc) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 -void __destroy(_ForwardIterator __first, _ForwardIterator __last) { +_ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) { for (; __first != __last; ++__first) _VSTD::__destroy_at(_VSTD::addressof(*__first)); + return __first; } #if _LIBCPP_STD_VER > 14 @@ -90,7 +92,7 @@ void destroy_at(_Tp* __loc) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void destroy(_ForwardIterator __first, _ForwardIterator __last) { - _VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); + (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); } template <class _ForwardIterator, class _Size> diff --git a/libcxx/include/__memory/ranges_construct_at.h b/libcxx/include/__memory/ranges_construct_at.h new file mode 100644 index 000000000000..1a72da739682 --- /dev/null +++ b/libcxx/include/__memory/ranges_construct_at.h @@ -0,0 +1,124 @@ +// -*- 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___MEMORY_RANGES_CONSTRUCT_AT_H +#define _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H + +#include <__concepts/destructible.h> +#include <__config> +#include <__iterator/incrementable_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/concepts.h> +#include <__memory/construct_at.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +// construct_at + +namespace __construct_at { + +struct __fn { + template<class _Tp, class... _Args, class = decltype( + ::new (declval<void*>()) _Tp(declval<_Args>()...) + )> + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp* operator()(_Tp* __location, _Args&& ...__args) const { + return _VSTD::construct_at(__location, _VSTD::forward<_Args>(__args)...); + } +}; + +} // namespace __construct_at + +inline namespace __cpo { + inline constexpr auto construct_at = __construct_at::__fn{}; +} // namespace __cpo + +// destroy_at + +namespace __destroy_at { + +struct __fn { + template <destructible _Tp> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_Tp* __location) const noexcept { + _VSTD::destroy_at(__location); + } +}; + +} // namespace __destroy_at + +inline namespace __cpo { + inline constexpr auto destroy_at = __destroy_at::__fn{}; +} // namespace __cpo + +// destroy + +namespace __destroy { + +struct __fn { + template <__nothrow_input_iterator _InputIterator, __nothrow_sentinel_for<_InputIterator> _Sentinel> + requires destructible<iter_value_t<_InputIterator>> + _LIBCPP_HIDE_FROM_ABI + constexpr _InputIterator operator()(_InputIterator __first, _Sentinel __last) const noexcept { + return _VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); + } + + template <__nothrow_input_range _InputRange> + requires destructible<range_value_t<_InputRange>> + _LIBCPP_HIDE_FROM_ABI + constexpr borrowed_iterator_t<_InputRange> operator()(_InputRange&& __range) const noexcept { + return (*this)(ranges::begin(__range), ranges::end(__range)); + } +}; + +} // namespace __destroy + +inline namespace __cpo { + inline constexpr auto destroy = __destroy::__fn{}; +} // namespace __cpo + +// destroy_n + +namespace __destroy_n { + +struct __fn { + template <__nothrow_input_iterator _InputIterator> + requires destructible<iter_value_t<_InputIterator>> + _LIBCPP_HIDE_FROM_ABI + constexpr _InputIterator operator()(_InputIterator __first, iter_difference_t<_InputIterator> __n) const noexcept { + return _VSTD::destroy_n(_VSTD::move(__first), __n); + } +}; + +} // namespace __destroy_n + +inline namespace __cpo { + inline constexpr auto destroy_n = __destroy_n::__fn{}; +} // namespace __cpo + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h index 6ec803806c05..6a8f9f070ed7 100644 --- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h +++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -10,10 +10,12 @@ #ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H #define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#include <__algorithm/in_out_result.h> #include <__concepts/constructible.h> #include <__config> -#include <__function_like.h> +#include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/concepts.h> @@ -37,10 +39,7 @@ namespace ranges { namespace __uninitialized_default_construct { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable<iter_value_t<_ForwardIterator>> @@ -55,25 +54,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __uninitialized_default_construct inline namespace __cpo { -inline constexpr auto uninitialized_default_construct = - __uninitialized_default_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{}; } // namespace __cpo // uninitialized_default_construct_n namespace __uninitialized_default_construct_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : - __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable<iter_value_t<_ForwardIterator>> _ForwardIterator operator()(_ForwardIterator __first, @@ -81,24 +74,19 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n); } - }; } // namespace __uninitialized_default_construct_n inline namespace __cpo { -inline constexpr auto uninitialized_default_construct_n = - __uninitialized_default_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{}; } // namespace __cpo // uninitialized_value_construct namespace __uninitialized_value_construct { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable<iter_value_t<_ForwardIterator>> @@ -113,24 +101,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __uninitialized_value_construct inline namespace __cpo { -inline constexpr auto uninitialized_value_construct = - __uninitialized_value_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{}; } // namespace __cpo // uninitialized_value_construct_n namespace __uninitialized_value_construct_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable<iter_value_t<_ForwardIterator>> _ForwardIterator operator()(_ForwardIterator __first, @@ -138,24 +121,19 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } - }; } // namespace __uninitialized_value_construct_n inline namespace __cpo { -inline constexpr auto uninitialized_value_construct_n = - __uninitialized_value_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{}; } // namespace __cpo // uninitialized_fill namespace __uninitialized_fill { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel, class _Tp> @@ -170,23 +148,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { return (*this)(ranges::begin(__range), ranges::end(__range), __x); } - }; -} // namespace __uninitialized_fil +} // namespace __uninitialized_fill inline namespace __cpo { -inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{}; } // namespace __cpo // uninitialized_fill_n namespace __uninitialized_fill_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, class _Tp> requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> _ForwardIterator operator()(_ForwardIterator __first, @@ -195,13 +169,143 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x); } - }; } // namespace __uninitialized_fill_n inline namespace __cpo { -inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{}; +} // namespace __cpo + +// uninitialized_copy + +template <class _InputIterator, class _OutputIterator> +using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_copy { + +struct __fn { + template <input_iterator _InputIterator, + sentinel_for<_InputIterator> _Sentinel1, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel2> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_copy_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + + auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), _VSTD::move(__olast)); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } + + template <input_range _InputRange, __nothrow_forward_range _OutputRange> + requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> + uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> + operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const { + return (*this)(ranges::begin(__in_range), ranges::end(__in_range), + ranges::begin(__out_range), ranges::end(__out_range)); + } +}; + +} // namespace __uninitialized_copy + +inline namespace __cpo { + inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{}; +} // namespace __cpo + +// uninitialized_copy_n + +template <class _InputIterator, class _OutputIterator> +using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_copy_n { + +struct __fn { + template <input_iterator _InputIterator, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_copy_n_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, + _OutputIterator __ofirst, _Sentinel __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, + _VSTD::move(__ofirst), _VSTD::move(__olast)); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } +}; + +} // namespace __uninitialized_copy_n + +inline namespace __cpo { + inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{}; +} // namespace __cpo + +// uninitialized_move + +template <class _InputIterator, class _OutputIterator> +using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_move { + +struct __fn { + template <input_iterator _InputIterator, + sentinel_for<_InputIterator> _Sentinel1, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel2> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_move_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; + auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } + + template <input_range _InputRange, __nothrow_forward_range _OutputRange> + requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> + uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> + operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { + return (*this)(ranges::begin(__in_range), ranges::end(__in_range), + ranges::begin(__out_range), ranges::end(__out_range)); + } +}; + +} // namespace __uninitialized_move + +inline namespace __cpo { + inline constexpr auto uninitialized_move = __uninitialized_move::__fn{}; +} // namespace __cpo + +// uninitialized_move_n + +template <class _InputIterator, class _OutputIterator> +using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_move_n { + +struct __fn { + template <input_iterator _InputIterator, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_move_n_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, + _OutputIterator __ofirst, _Sentinel __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; + auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, + _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } +}; + +} // namespace __uninitialized_move_n + +inline namespace __cpo { + inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 9c7df8845956..6a4ffc88c866 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -12,14 +12,14 @@ #include <__availability> #include <__config> -#include <__functional_base> #include <__functional/binary_function.h> #include <__functional/operations.h> #include <__functional/reference_wrapper.h> +#include <__functional_base> #include <__memory/addressof.h> #include <__memory/allocation_guard.h> -#include <__memory/allocator_traits.h> #include <__memory/allocator.h> +#include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/pointer_traits.h> #include <__memory/unique_ptr.h> @@ -28,8 +28,8 @@ #include <cstdlib> // abort #include <iosfwd> #include <stdexcept> -#include <typeinfo> #include <type_traits> +#include <typeinfo> #include <utility> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include <atomic> diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h index 69132633a48e..40e7c79a51e0 100644 --- a/libcxx/include/__memory/uninitialized_algorithms.h +++ b/libcxx/include/__memory/uninitialized_algorithms.h @@ -23,52 +23,75 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _InputIterator, class _ForwardIterator> -_ForwardIterator -uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +// This is a simplified version of C++20 `unreachable_sentinel` that doesn't use concepts and thus can be used in any +// language mode. +struct __unreachable_sentinel { + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool operator!=(const _Iter&, __unreachable_sentinel) _NOEXCEPT { + return true; + } +}; + +// uninitialized_copy + +template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast, + _ForwardIterator __ofirst, _Sentinel2 __olast) { + _ForwardIterator __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __f != __l; ++__f, (void) ++__r) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx) + ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif - return __r; + + return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); } -template <class _InputIterator, class _Size, class _ForwardIterator> -_ForwardIterator -uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +template <class _InputIterator, class _ForwardIterator> +_ForwardIterator uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, + _ForwardIterator __ofirst) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), __unreachable_sentinel()); + return _VSTD::move(__result.second); +} + +// uninitialized_copy_n + +template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_copy_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst, _Sentinel __olast) { + _ForwardIterator __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __n > 0; ++__f, (void) ++__r, (void) --__n) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n) + ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif - return __r; + + return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); +} + +template <class _InputIterator, class _Size, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_copy_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), + __unreachable_sentinel()); + return _VSTD::move(__result.second); } // uninitialized_fill @@ -253,43 +276,71 @@ _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size return __uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } -template <class _InputIt, class _ForwardIt> -inline _LIBCPP_INLINE_VISIBILITY -_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; - auto __idx = __first_res; +// uninitialized_move + +template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2, + class _IterMove> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast, + _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) { + auto __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + try { #endif - for (; __first != __last; ++__idx, (void) ++__first) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); - return __idx; -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first_res, __idx); - throw; + for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) { + ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); } +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif + + return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; +} + +template <class _InputIterator, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_move(_InputIterator __ifirst, _InputIterator __ilast, + _ForwardIterator __ofirst) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; + + auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), __unreachable_sentinel(), __iter_move); + return _VSTD::move(__result.second); } -template <class _InputIt, class _Size, class _ForwardIt> -inline _LIBCPP_INLINE_VISIBILITY -pair<_InputIt, _ForwardIt> -uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; - auto __idx = __first_res; +// uninitialized_move_n + +template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel, class _IterMove> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_move_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) { + auto __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + try { #endif - for (; __n > 0; ++__idx, (void) ++__first, --__n) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); - return {__first, __idx}; + for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n) + ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); #ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first_res, __idx); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif + + return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; +} + +template <class _InputIterator, class _Size, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; + + return _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), + __unreachable_sentinel(), __iter_move); } #endif // _LIBCPP_STD_VER > 14 diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h index 433120394269..e892f3287b93 100644 --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -11,9 +11,9 @@ #define _LIBCPP___MEMORY_UNIQUE_PTR_H #include <__config> -#include <__functional_base> #include <__functional/hash.h> #include <__functional/operations.h> +#include <__functional_base> #include <__memory/allocator_traits.h> // __pointer #include <__memory/compressed_pair.h> #include <__utility/forward.h> diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index 21e2075603b5..8d8c8af7070c 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -13,6 +13,7 @@ #include <__config> #include <__threading_support> #include <chrono> +#include <ratio> #include <system_error> #include <time.h> diff --git a/libcxx/include/__random/chi_squared_distribution.h b/libcxx/include/__random/chi_squared_distribution.h index 9cf38971bdde..2aa0762a520c 100644 --- a/libcxx/include/__random/chi_squared_distribution.h +++ b/libcxx/include/__random/chi_squared_distribution.h @@ -11,8 +11,8 @@ #include <__config> #include <__random/gamma_distribution.h> -#include <limits> #include <iosfwd> +#include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/__random/gamma_distribution.h b/libcxx/include/__random/gamma_distribution.h index 49d024eafea2..34167e463528 100644 --- a/libcxx/include/__random/gamma_distribution.h +++ b/libcxx/include/__random/gamma_distribution.h @@ -10,8 +10,8 @@ #define _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H #include <__config> -#include <__random/uniform_real_distribution.h> #include <__random/exponential_distribution.h> +#include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> diff --git a/libcxx/include/__random/lognormal_distribution.h b/libcxx/include/__random/lognormal_distribution.h index 752861c3de0c..8fadb5a1e66a 100644 --- a/libcxx/include/__random/lognormal_distribution.h +++ b/libcxx/include/__random/lognormal_distribution.h @@ -24,6 +24,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +#ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + template<class _RealType = double> class _LIBCPP_TEMPLATE_VIS lognormal_distribution { @@ -156,6 +158,140 @@ operator>>(basic_istream<_CharT, _Traits>& __is, return __is >> __x.__p_.__nd_; } +#else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + +template<class _RealType = double> +class _LIBCPP_TEMPLATE_VIS lognormal_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __m_; + result_type __s_; + public: + typedef lognormal_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __m = 0, result_type __s = 1) + : __m_(__m), __s_(__s) {} + + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __m_;} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __s_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__m_ == __y.__m_ && __x.__s_ == __y.__s_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + normal_distribution<result_type> __nd_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + lognormal_distribution() : lognormal_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m, result_type __s = 1) + : __nd_(__m, __s) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m = 0, + result_type __s = 1) + : __nd_(__m, __s) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(const param_type& __p) + : __nd_(__p.m(), __p.s()) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {__nd_.reset();} + + // generating functions + template<class _URNG> + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + { + return _VSTD::exp(__nd_(__g)); + } + + template<class _URNG> + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + { + typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s()); + return _VSTD::exp(__nd_(__g, __pn)); + } + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __nd_.mean();} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __nd_.stddev();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return param_type(__nd_.mean(), __nd_.stddev());} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) + { + typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s()); + __nd_.param(__pn); + } + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits<result_type>::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return __x.__nd_ == __y.__nd_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return !(__x == __y);} + + template <class _CharT, class _Traits, class _RT> + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x); + + template <class _CharT, class _Traits, class _RT> + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x); +}; + +template <class _CharT, class _Traits, class _RT> +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x) +{ + return __os << __x.__nd_; +} + +template <class _CharT, class _Traits, class _RT> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x) +{ + return __is >> __x.__nd_; +} + +#endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/libcxx/include/__random/random_device.h b/libcxx/include/__random/random_device.h index 835f726fdbcc..ef11977f9b77 100644 --- a/libcxx/include/__random/random_device.h +++ b/libcxx/include/__random/random_device.h @@ -27,7 +27,26 @@ class _LIBCPP_TYPE_VIS random_device { #ifdef _LIBCPP_USING_DEV_RANDOM int __f_; +#elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT) +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused-private-field" +# endif + + // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now + // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we + // retain the same layout as before. +# if defined(__APPLE__) + int __padding_; // padding to fake the `__f_` field above +# endif + + // ... vendors can add workarounds here if they switch to a different representation ... + +# if defined(__clang__) +# pragma clang diagnostic pop +# endif #endif + public: // types typedef unsigned result_type; diff --git a/libcxx/include/__random/seed_seq.h b/libcxx/include/__random/seed_seq.h index bf27af6627a5..1a0877995650 100644 --- a/libcxx/include/__random/seed_seq.h +++ b/libcxx/include/__random/seed_seq.h @@ -31,25 +31,24 @@ public: // types typedef uint32_t result_type; -private: - vector<result_type> __v_; - - template<class _InputIterator> - void init(_InputIterator __first, _InputIterator __last); -public: // constructors _LIBCPP_INLINE_VISIBILITY seed_seq() _NOEXCEPT {} #ifndef _LIBCPP_CXX03_LANG - template<class _Tp> - _LIBCPP_INLINE_VISIBILITY - seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());} + template<class _Tp, __enable_if_t<is_integral<_Tp>::value>* = nullptr> + _LIBCPP_INLINE_VISIBILITY + seed_seq(initializer_list<_Tp> __il) { + __init(__il.begin(), __il.end()); + } #endif // _LIBCPP_CXX03_LANG template<class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - seed_seq(_InputIterator __first, _InputIterator __last) - {init(__first, __last);} + _LIBCPP_INLINE_VISIBILITY + seed_seq(_InputIterator __first, _InputIterator __last) { + static_assert(is_integral<typename iterator_traits<_InputIterator>::value_type>::value, + "Mandates: iterator_traits<InputIterator>::value_type is an integer type"); + __init(__first, __last); + } // generating functions template<class _RandomAccessIterator> @@ -68,11 +67,17 @@ public: _LIBCPP_INLINE_VISIBILITY static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);} + +private: + template<class _InputIterator> + void __init(_InputIterator __first, _InputIterator __last); + + vector<result_type> __v_; }; template<class _InputIterator> void -seed_seq::init(_InputIterator __first, _InputIterator __last) +seed_seq::__init(_InputIterator __first, _InputIterator __last) { for (_InputIterator __s = __first; __s != __last; ++__s) __v_.push_back(*__s & 0xFFFFFFFF); diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h index 91dc3055c86d..0b9470fa4017 100644 --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_ACCESS_H #define _LIBCPP___RANGES_ACCESS_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/readable_traits.h> @@ -39,6 +40,7 @@ namespace __begin { template <class _Tp> concept __member_begin = __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator; }; @@ -102,6 +104,7 @@ namespace __end { template <class _Tp> concept __member_end = __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { typename iterator_t<_Tp>; { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>; @@ -160,20 +163,20 @@ namespace ranges { namespace __cbegin { struct __fn { template <class _Tp> - requires invocable<decltype(ranges::begin), _Tp const&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const - noexcept(noexcept(ranges::begin(_VSTD::as_const(__t)))) - { - return ranges::begin(_VSTD::as_const(__t)); - } + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); } template <class _Tp> - requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t)))) - { - return ranges::begin(static_cast<_Tp const&&>(__t)); - } + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::begin(static_cast<const _Tp&&>(__t))) + { return ranges::begin(static_cast<const _Tp&&>(__t)); } }; } @@ -188,20 +191,20 @@ namespace ranges { namespace __cend { struct __fn { template <class _Tp> - requires invocable<decltype(ranges::end), _Tp const&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const - noexcept(noexcept(ranges::end(_VSTD::as_const(__t)))) - { - return ranges::end(_VSTD::as_const(__t)); - } + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); } template <class _Tp> - requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t)))) - { - return ranges::end(static_cast<_Tp const&&>(__t)); - } + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::end(static_cast<const _Tp&&>(__t))) + { return ranges::end(static_cast<const _Tp&&>(__t)); } }; } diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h index ccc77258ba10..90327da81460 100644 --- a/libcxx/include/__ranges/all.h +++ b/libcxx/include/__ranges/all.h @@ -14,9 +14,9 @@ #include <__iterator/iterator_traits.h> #include <__ranges/access.h> #include <__ranges/concepts.h> +#include <__ranges/owning_view.h> #include <__ranges/range_adaptor.h> #include <__ranges/ref_view.h> -#include <__ranges/subrange.h> #include <__utility/auto_cast.h> #include <__utility/declval.h> #include <__utility/forward.h> @@ -56,12 +56,12 @@ namespace __all { template<class _Tp> requires (!ranges::view<decay_t<_Tp>> && !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } && - requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; }) + requires (_Tp&& __t) { ranges::owning_view{_VSTD::forward<_Tp>(__t)}; }) [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)})) + noexcept(noexcept(ranges::owning_view{_VSTD::forward<_Tp>(__t)})) { - return ranges::subrange{_VSTD::forward<_Tp>(__t)}; + return ranges::owning_view{_VSTD::forward<_Tp>(__t)}; } }; } diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h index bad23c8c4bfb..a9cb15f9f17c 100644 --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -9,6 +9,9 @@ #ifndef _LIBCPP___RANGES_CONCEPTS_H #define _LIBCPP___RANGES_CONCEPTS_H +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__concepts/same_as.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -20,7 +23,7 @@ #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/size.h> -#include <concepts> +#include <initializer_list> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -80,11 +83,11 @@ namespace ranges { movable<_Tp> && enable_view<_Tp>; - template<class _Range> + template <class _Range> concept __simple_view = view<_Range> && range<const _Range> && same_as<iterator_t<_Range>, iterator_t<const _Range>> && - same_as<sentinel_t<_Range>, iterator_t<const _Range>>; + same_as<sentinel_t<_Range>, sentinel_t<const _Range>>; // [range.refinements], other range refinements template <class _Rp, class _Tp> @@ -114,12 +117,20 @@ namespace ranges { template <class _Tp> concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; - template<class _Tp> + template <class _Tp> + inline constexpr bool __is_std_initializer_list = false; + + template <class _Ep> + inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true; + + template <class _Tp> concept viewable_range = - range<_Tp> && ( - (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || - (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>) - ); + range<_Tp> && + ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || + (!view<remove_cvref_t<_Tp>> && + (is_lvalue_reference_v<_Tp> || + (movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>)))); + } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h index cc151c59f3d7..69dfd479c011 100644 --- a/libcxx/include/__ranges/data.h +++ b/libcxx/include/__ranges/data.h @@ -9,13 +9,13 @@ #ifndef _LIBCPP___RANGES_DATA_H #define _LIBCPP___RANGES_DATA_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> #include <__ranges/access.h> -#include <__utility/forward.h> -#include <concepts> +#include <__utility/auto_cast.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -35,34 +35,33 @@ namespace __data { template <class _Tp> concept __member_data = + __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { - { _VSTD::forward<_Tp>(__t) } -> __can_borrow; - { __t.data() } -> __ptr_to_object; + { _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object; }; template <class _Tp> concept __ranges_begin_invocable = !__member_data<_Tp> && + __can_borrow<_Tp> && requires(_Tp&& __t) { - { _VSTD::forward<_Tp>(__t) } -> __can_borrow; - { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator; + { ranges::begin(__t) } -> contiguous_iterator; }; struct __fn { template <__member_data _Tp> - requires __can_borrow<_Tp> _LIBCPP_HIDE_FROM_ABI - constexpr __ptr_to_object auto operator()(_Tp&& __t) const + constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(__t.data())) { return __t.data(); } template<__ranges_begin_invocable _Tp> - requires __can_borrow<_Tp> _LIBCPP_HIDE_FROM_ABI - constexpr __ptr_to_object auto operator()(_Tp&& __t) const - noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) { - return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))); + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::to_address(ranges::begin(__t)))) { + return _VSTD::to_address(ranges::begin(__t)); } }; } @@ -72,6 +71,34 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges +// [range.prim.cdata] + +namespace ranges { +namespace __cdata { + struct __fn { + template <class _Tp> + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); } + + template <class _Tp> + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::data(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::data(static_cast<const _Tp&&>(__t))) + { return ranges::data(static_cast<const _Tp&&>(__t)); } + }; +} + +inline namespace __cpo { + inline constexpr auto cdata = __cdata::__fn{}; +} // namespace __cpo +} // namespace ranges + #endif // !defined(_LIBCPP_HAS_NO_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h index e8a8aabf4aed..8da0b120f182 100644 --- a/libcxx/include/__ranges/empty.h +++ b/libcxx/include/__ranges/empty.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_EMPTY_H #define _LIBCPP___RANGES_EMPTY_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__ranges/access.h> @@ -28,9 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __empty { template <class _Tp> - concept __member_empty = requires(_Tp&& __t) { - bool(__t.empty()); - }; + concept __member_empty = + __workaround_52970<_Tp> && + requires(_Tp&& __t) { + bool(__t.empty()); + }; template<class _Tp> concept __can_invoke_size = diff --git a/libcxx/include/__ranges/empty_view.h b/libcxx/include/__ranges/empty_view.h index 4a98a6f324e7..f744dcbe92f4 100644 --- a/libcxx/include/__ranges/empty_view.h +++ b/libcxx/include/__ranges/empty_view.h @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_EMPTY_VIEW_H #include <__config> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/view_interface.h> #include <type_traits> @@ -32,6 +33,9 @@ namespace ranges { _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; } _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; } }; + + template<class _Tp> + inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__ranges/enable_view.h b/libcxx/include/__ranges/enable_view.h index a09de11da81e..e1daec046fc0 100644 --- a/libcxx/include/__ranges/enable_view.h +++ b/libcxx/include/__ranges/enable_view.h @@ -12,6 +12,7 @@ #include <__config> #include <concepts> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -25,8 +26,17 @@ namespace ranges { struct view_base { }; +template<class _Derived> + requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> +class view_interface; + +template<class _Op, class _Yp> + requires is_convertible_v<_Op*, view_interface<_Yp>*> +void __is_derived_from_view_interface(const _Op*, const view_interface<_Yp>*); + template <class _Tp> -inline constexpr bool enable_view = derived_from<_Tp, view_base>; +inline constexpr bool enable_view = derived_from<_Tp, view_base> || + requires { ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr); }; } // end namespace ranges diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h new file mode 100644 index 000000000000..29182d2d8e46 --- /dev/null +++ b/libcxx/include/__ranges/owning_view.h @@ -0,0 +1,81 @@ +// -*- 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_OWNING_VIEW_H +#define _LIBCPP___RANGES_OWNING_VIEW_H + +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__config> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/data.h> +#include <__ranges/empty.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.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 !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template<range _Rp> + requires movable<_Rp> && (!__is_std_initializer_list<remove_cvref_t<_Rp>>) + class owning_view : public view_interface<owning_view<_Rp>> { + _Rp __r_ = _Rp(); + +public: + owning_view() requires default_initializable<_Rp> = default; + _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(_VSTD::move(__r)) {} + + owning_view(owning_view&&) = default; + owning_view& operator=(owning_view&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return _VSTD::move(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return _VSTD::move(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range<const _Rp> { return ranges::begin(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires range<const _Rp> { return ranges::end(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr bool empty() requires requires { ranges::empty(__r_); } + { return ranges::empty(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const requires requires { ranges::empty(__r_); } + { return ranges::empty(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_Rp> + { return ranges::size(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range<const _Rp> + { return ranges::size(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr auto data() requires contiguous_range<_Rp> + { return ranges::data(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp> + { return ranges::data(__r_); } + }; + + template<class _Tp> + inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_OWNING_VIEW_H diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h index 7567ac48f255..283fa2599bff 100644 --- a/libcxx/include/__ranges/ref_view.h +++ b/libcxx/include/__ranges/ref_view.h @@ -18,6 +18,7 @@ #include <__ranges/concepts.h> #include <__ranges/data.h> #include <__ranges/empty.h> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/size.h> #include <__ranges/view_interface.h> #include <__utility/forward.h> @@ -74,6 +75,8 @@ public: template<class _Range> ref_view(_Range&) -> ref_view<_Range>; + template<class _Tp> + inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h index 412fa9b64643..931ce78da7b9 100644 --- a/libcxx/include/__ranges/single_view.h +++ b/libcxx/include/__ranges/single_view.h @@ -10,8 +10,8 @@ #define _LIBCPP___RANGES_SINGLE_VIEW_H #include <__config> -#include <__ranges/view_interface.h> #include <__ranges/copyable_box.h> +#include <__ranges/view_interface.h> #include <__utility/forward.h> #include <__utility/in_place.h> #include <__utility/move.h> diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h index fc6641cf4887..f3de5a8b8410 100644 --- a/libcxx/include/__ranges/size.h +++ b/libcxx/include/__ranges/size.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_SIZE_H #define _LIBCPP___RANGES_SIZE_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> @@ -41,9 +42,12 @@ namespace __size { concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>; template <class _Tp> - concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) { - { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like; - }; + concept __member_size = + __size_enabled<_Tp> && + __workaround_52970<_Tp> && + requires(_Tp&& __t) { + { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like; + }; template <class _Tp> concept __unqualified_size = diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h index 8e984f2bf06c..14716d1fb0ff 100644 --- a/libcxx/include/__ranges/subrange.h +++ b/libcxx/include/__ranges/subrange.h @@ -40,12 +40,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template<class _From, class _To> + concept __uses_nonqualification_pointer_conversion = + is_pointer_v<_From> && is_pointer_v<_To> && + !convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>; + + template<class _From, class _To> concept __convertible_to_non_slicing = convertible_to<_From, _To> && - // If they're both pointers, they must have the same element type. - !(is_pointer_v<decay_t<_From>> && - is_pointer_v<decay_t<_To>> && - __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>); + !__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>; template<class _Tp> concept __pair_like = diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 0f53fbaa7e68..1506e8b2a7fe 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -195,9 +195,7 @@ public: : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {} _LIBCPP_HIDE_FROM_ABI - constexpr iterator_t<_Base> base() const& - requires copyable<iterator_t<_Base>> - { + constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h index 8a1f5d8c9251..c5215cbcb8e3 100644 --- a/libcxx/include/__ranges/view_interface.h +++ b/libcxx/include/__ranges/view_interface.h @@ -18,7 +18,6 @@ #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/empty.h> -#include <__ranges/enable_view.h> #include <concepts> #include <type_traits> @@ -40,7 +39,7 @@ void __implicitly_convert_to(type_identity_t<_Tp>) noexcept; template<class _Derived> requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> -class view_interface : public view_base { +class view_interface { _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept { static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); diff --git a/libcxx/include/__string b/libcxx/include/__string index 13ff7b35e47d..2249d3a8aec5 100644 --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -10,21 +10,21 @@ #ifndef _LIBCPP___STRING #define _LIBCPP___STRING -#include <__config> #include <__algorithm/copy.h> #include <__algorithm/copy_backward.h> #include <__algorithm/copy_n.h> #include <__algorithm/fill_n.h> -#include <__algorithm/find_first_of.h> #include <__algorithm/find_end.h> +#include <__algorithm/find_first_of.h> #include <__algorithm/min.h> +#include <__config> #include <__functional/hash.h> // for __murmur2_or_cityhash #include <__iterator/iterator_traits.h> -#include <cstdio> // for EOF #include <cstdint> // for uint_least16_t +#include <cstdio> // for EOF #include <cstring> // for memcpy -#include <type_traits> // for __libcpp_is_constant_evaluated #include <iosfwd> // for streampos & friends +#include <type_traits> // for __libcpp_is_constant_evaluated #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include <cwchar> // for wmemcpy diff --git a/libcxx/include/__thread/poll_with_backoff.h b/libcxx/include/__thread/poll_with_backoff.h index e1d8a9c90c56..3149a3862890 100644 --- a/libcxx/include/__thread/poll_with_backoff.h +++ b/libcxx/include/__thread/poll_with_backoff.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H #define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H +#include <__availability> #include <__config> #include <chrono> diff --git a/libcxx/include/__thread/timed_backoff_policy.h b/libcxx/include/__thread/timed_backoff_policy.h new file mode 100644 index 000000000000..d85a34071c6d --- /dev/null +++ b/libcxx/include/__thread/timed_backoff_policy.h @@ -0,0 +1,45 @@ +// -*- 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___THREAD_TIMED_BACKOFF_POLICY_H +#define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_THREADS + +#include <__threading_support> +#include <chrono> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __libcpp_timed_backoff_policy { + _LIBCPP_INLINE_VISIBILITY + bool operator()(chrono::nanoseconds __elapsed) const + { + if(__elapsed > chrono::milliseconds(128)) + __libcpp_thread_sleep_for(chrono::milliseconds(8)); + else if(__elapsed > chrono::microseconds(64)) + __libcpp_thread_sleep_for(__elapsed / 2); + else if(__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else + {} // poll + return false; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support index 68f381a62183..bf85d5f5d9f0 100644 --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -54,9 +54,6 @@ typedef ::timespec __libcpp_timespec_t; #endif // !defined(_LIBCPP_HAS_NO_THREADS) -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_THREADS) @@ -252,53 +249,9 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -struct __libcpp_timed_backoff_policy { - _LIBCPP_INLINE_VISIBILITY - bool operator()(chrono::nanoseconds __elapsed) const - { - if(__elapsed > chrono::milliseconds(128)) - __libcpp_thread_sleep_for(chrono::milliseconds(8)); - else if(__elapsed > chrono::microseconds(64)) - __libcpp_thread_sleep_for(__elapsed / 2); - else if(__elapsed > chrono::microseconds(4)) - __libcpp_thread_yield(); - else - {} // poll - return false; - } -}; - #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) - -namespace __thread_detail { - -_LIBCPP_HIDE_FROM_ABI inline -__libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) -{ - using namespace chrono; - seconds __s = duration_cast<seconds>(__ns); - __libcpp_timespec_t __ts; - typedef decltype(__ts.tv_sec) __ts_sec; - const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); - __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; - __ts.tv_nsec = 999999999; // (10^9 - 1) - } - - return __ts; -} - -} // namespace __thread_detail - #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) _LIBCPP_HIDE_FROM_ABI inline @@ -479,7 +432,7 @@ void __libcpp_thread_yield() _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); } @@ -664,7 +617,7 @@ void __libcpp_thread_yield() _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); thrd_sleep(&__ts, nullptr); } @@ -776,6 +729,4 @@ get_id() _NOEXCEPT _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP_THREADING_SUPPORT diff --git a/libcxx/include/__utility/swap.h b/libcxx/include/__utility/swap.h index 6c07511686f0..20ec1419fc97 100644 --- a/libcxx/include/__utility/swap.h +++ b/libcxx/include/__utility/swap.h @@ -12,8 +12,8 @@ #include <__config> #include <__utility/declval.h> #include <__utility/move.h> -#include <type_traits> #include <cstddef> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm index b28c8cd49890..03b4faaee284 100644 --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -18,6 +18,11 @@ namespace std { +namespace ranges { + template <class I1, class I2> + struct in_in_result; // since C++20 +} + template <class InputIterator, class Predicate> constexpr bool // constexpr in C++20 all_of(InputIterator first, InputIterator last, Predicate pred); @@ -641,19 +646,23 @@ template <class BidirectionalIterator, class Compare> constexpr bool // constexpr in C++20 prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); +namespace ranges { +// [algorithms.results], algorithm result types +template<class InputIterator, class OutputIterator> + struct in_out_result; +} + } // std */ +#include <__bits> // __libcpp_clz #include <__config> #include <__debug> -#include <__bits> // __libcpp_clz #include <cstddef> #include <cstring> #include <functional> #include <initializer_list> -#include <utility> // needed to provide swap_ranges. -#include <memory> #include <iterator> #include <memory> #include <type_traits> @@ -675,8 +684,8 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/count_if.h> #include <__algorithm/equal.h> #include <__algorithm/equal_range.h> -#include <__algorithm/fill_n.h> #include <__algorithm/fill.h> +#include <__algorithm/fill_n.h> #include <__algorithm/find.h> #include <__algorithm/find_end.h> #include <__algorithm/find_first_of.h> @@ -684,9 +693,11 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/find_if_not.h> #include <__algorithm/for_each.h> #include <__algorithm/for_each_n.h> -#include <__algorithm/generate_n.h> #include <__algorithm/generate.h> +#include <__algorithm/generate_n.h> #include <__algorithm/half_positive.h> +#include <__algorithm/in_in_result.h> +#include <__algorithm/in_out_result.h> #include <__algorithm/includes.h> #include <__algorithm/inplace_merge.h> #include <__algorithm/is_heap.h> @@ -749,8 +760,8 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/stable_sort.h> #include <__algorithm/swap_ranges.h> #include <__algorithm/transform.h> -#include <__algorithm/unique_copy.h> #include <__algorithm/unique.h> +#include <__algorithm/unique_copy.h> #include <__algorithm/unwrap_iter.h> #include <__algorithm/upper_bound.h> diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 4b60d4d6802b..02844642fa08 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -521,6 +521,7 @@ template <class T> #include <__availability> #include <__config> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include <cstddef> #include <cstdint> #include <cstring> diff --git a/libcxx/include/barrier b/libcxx/include/barrier index aef88556a011..c7af46271745 100644 --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -47,6 +47,7 @@ namespace std #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include <atomic> #ifndef _LIBCPP_HAS_NO_TREE_BARRIER # include <memory> diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 8f538e92e7ff..a5b93f90d40f 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -112,14 +112,15 @@ template <size_t N> struct hash<std::bitset<N>>; */ -#include <__config> #include <__bit_reference> +#include <__config> #include <__functional_base> #include <climits> #include <cstddef> #include <iosfwd> #include <stdexcept> #include <string> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/chrono b/libcxx/include/chrono index 90c9b0829a1f..eada2b8520e3 100644 --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -694,2145 +694,20 @@ constexpr chrono::year operator ""y(unsigned lo } // std */ -#include <__availability> +#include <__chrono/calendar.h> +#include <__chrono/convert_to_timespec.h> +#include <__chrono/duration.h> +#include <__chrono/file_clock.h> +#include <__chrono/high_resolution_clock.h> +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> #include <__config> #include <compare> -#include <ctime> -#include <limits> -#include <ratio> -#include <type_traits> #include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -#ifndef _LIBCPP_CXX03_LANG -_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock; -_LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // !_LIBCPP_CXX03_LANG - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace chrono -{ - -template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration; - -template <class _Tp> -struct __is_duration : false_type {}; - -template <class _Rep, class _Period> -struct __is_duration<duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<const duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<volatile duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {}; - -} // namespace chrono - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>, - chrono::duration<_Rep2, _Period2> > -{ - typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, - typename __ratio_gcd<_Period1, _Period2>::type> type; -}; - -namespace chrono { - -// duration_cast - -template <class _FromDuration, class _ToDuration, - class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type, - bool = _Period::num == 1, - bool = _Period::den == 1> -struct __duration_cast; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count())); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) - / static_cast<_Ct>(_Period::den))); - } -}; - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -duration_cast(const duration<_Rep, _Period>& __fd) -{ - return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd); -} - -template <class _Rep> -struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; - -#if _LIBCPP_STD_VER > 14 -template <class _Rep> -inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; -#endif - -template <class _Rep> -struct _LIBCPP_TEMPLATE_VIS duration_values -{ -public: - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} -}; - -#if _LIBCPP_STD_VER > 14 -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -floor(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = duration_cast<_ToDuration>(__d); - if (__t > __d) - __t = __t - _ToDuration{1}; - return __t; -} - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -ceil(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = duration_cast<_ToDuration>(__d); - if (__t < __d) - __t = __t + _ToDuration{1}; - return __t; -} - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -round(const duration<_Rep, _Period>& __d) -{ - _ToDuration __lower = floor<_ToDuration>(__d); - _ToDuration __upper = __lower + _ToDuration{1}; - auto __lowerDiff = __d - __lower; - auto __upperDiff = __upper - __d; - if (__lowerDiff < __upperDiff) - return __lower; - if (__lowerDiff > __upperDiff) - return __upper; - return __lower.count() & 1 ? __upper : __lower; -} -#endif - -// duration - -template <class _Rep, class _Period> -class _LIBCPP_TEMPLATE_VIS duration -{ - static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); - static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); - static_assert(_Period::num > 0, "duration period must be positive"); - - template <class _R1, class _R2> - struct __no_overflow - { - private: - static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; - static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; - static const intmax_t __n1 = _R1::num / __gcd_n1_n2; - static const intmax_t __d1 = _R1::den / __gcd_d1_d2; - static const intmax_t __n2 = _R2::num / __gcd_n1_n2; - static const intmax_t __d2 = _R2::den / __gcd_d1_d2; - static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); - - template <intmax_t _Xp, intmax_t _Yp, bool __overflow> - struct __mul // __overflow == false - { - static const intmax_t value = _Xp * _Yp; - }; - - template <intmax_t _Xp, intmax_t _Yp> - struct __mul<_Xp, _Yp, true> - { - static const intmax_t value = 1; - }; - - public: - static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); - typedef ratio<__mul<__n1, __d2, !value>::value, - __mul<__n2, __d1, !value>::value> type; - }; - -public: - typedef _Rep rep; - typedef typename _Period::type period; -private: - rep __rep_; -public: - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -#ifndef _LIBCPP_CXX03_LANG - duration() = default; -#else - duration() {} -#endif - - template <class _Rep2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - explicit duration(const _Rep2& __r, - typename enable_if - < - is_convertible<_Rep2, rep>::value && - (treat_as_floating_point<rep>::value || - !treat_as_floating_point<_Rep2>::value) - >::type* = nullptr) - : __rep_(__r) {} - - // conversions - template <class _Rep2, class _Period2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - duration(const duration<_Rep2, _Period2>& __d, - typename enable_if - < - __no_overflow<_Period2, period>::value && ( - treat_as_floating_point<rep>::value || - (__no_overflow<_Period2, period>::type::den == 1 && - !treat_as_floating_point<_Rep2>::value)) - >::type* = nullptr) - : __rep_(chrono::duration_cast<duration>(__d).count()) {} - - // observer - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} - - // arithmetic - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} - - // special values - - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());} -}; - -typedef duration<long long, nano> nanoseconds; -typedef duration<long long, micro> microseconds; -typedef duration<long long, milli> milliseconds; -typedef duration<long long > seconds; -typedef duration< long, ratio< 60> > minutes; -typedef duration< long, ratio<3600> > hours; -#if _LIBCPP_STD_VER > 17 -typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; -typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; -typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; -typedef duration< int, ratio_divide<years::period, ratio<12>>> months; -#endif -// Duration == - -template <class _LhsDuration, class _RhsDuration> -struct __duration_eq -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() == _Ct(__rhs).count(); - } -}; - -template <class _LhsDuration> -struct __duration_eq<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() == __rhs.count();} -}; - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); -} - -// Duration != - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs == __rhs); -} - -// Duration < - -template <class _LhsDuration, class _RhsDuration> -struct __duration_lt -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() < _Ct(__rhs).count(); - } -}; - -template <class _LhsDuration> -struct __duration_lt<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() < __rhs.count();} -}; - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); -} - -// Duration > - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __rhs < __lhs; -} - -// Duration <= - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__rhs < __lhs); -} - -// Duration >= - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs < __rhs); -} - -// Duration + - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); -} - -// Duration - - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); -} - -// Duration * - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) -{ - return __d * __s; -} - -// Duration / - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<_Rep1, _Rep2>::type -operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct; - return _Ct(__lhs).count() / _Ct(__rhs).count(); -} - -// Duration % - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); -} - -////////////////////////////////////////////////////////// -///////////////////// time_point ///////////////////////// -////////////////////////////////////////////////////////// - -template <class _Clock, class _Duration = typename _Clock::duration> -class _LIBCPP_TEMPLATE_VIS time_point -{ - static_assert(__is_duration<_Duration>::value, - "Second template parameter of time_point must be a std::chrono::duration"); -public: - typedef _Clock clock; - typedef _Duration duration; - typedef typename duration::rep rep; - typedef typename duration::period period; -private: - duration __d_; - -public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} - - // conversions - template <class _Duration2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - time_point(const time_point<clock, _Duration2>& t, - typename enable_if - < - is_convertible<_Duration2, duration>::value - >::type* = nullptr) - : __d_(t.time_since_epoch()) {} - - // observer - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} - - // arithmetic - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} - - // special values - - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} -}; - -} // namespace chrono - -template <class _Clock, class _Duration1, class _Duration2> -struct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>, - chrono::time_point<_Clock, _Duration2> > -{ - typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; -}; - -namespace chrono { - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, _ToDuration> -time_point_cast(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); -} - -#if _LIBCPP_STD_VER > 14 -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -floor(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -ceil(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -round(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - numeric_limits<_Rep>::is_signed, - duration<_Rep, _Period> ->::type -abs(duration<_Rep, _Period> __d) -{ - return __d >= __d.zero() ? +__d : -__d; -} -#endif - -// time_point == - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() == __rhs.time_since_epoch(); -} - -// time_point != - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs == __rhs); -} - -// time_point < - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() < __rhs.time_since_epoch(); -} - -// time_point > - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs < __lhs; -} - -// time_point <= - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__rhs < __lhs); -} - -// time_point >= - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs < __rhs); -} - -// time_point operator+(time_point x, duration y); - -template <class _Clock, class _Duration1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; - return _Tr (__lhs.time_since_epoch() + __rhs); -} - -// time_point operator+(duration x, time_point y); - -template <class _Rep1, class _Period1, class _Clock, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> -operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs + __lhs; -} - -// time_point operator-(time_point x, duration y); - -template <class _Clock, class _Duration1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; - return _Ret(__lhs.time_since_epoch() -__rhs); -} - -// duration operator-(time_point x, time_point y); - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename common_type<_Duration1, _Duration2>::type -operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() - __rhs.time_since_epoch(); -} - -////////////////////////////////////////////////////////// -/////////////////////// clocks /////////////////////////// -////////////////////////////////////////////////////////// - -class _LIBCPP_TYPE_VIS system_clock -{ -public: - typedef microseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point<system_clock> time_point; - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - static time_point now() _NOEXCEPT; - static time_t to_time_t (const time_point& __t) _NOEXCEPT; - static time_point from_time_t(time_t __t) _NOEXCEPT; -}; - -#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK -class _LIBCPP_TYPE_VIS steady_clock -{ -public: - typedef nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point<steady_clock, duration> time_point; - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; - - static time_point now() _NOEXCEPT; -}; - -typedef steady_clock high_resolution_clock; -#else -typedef system_clock high_resolution_clock; -#endif - -#if _LIBCPP_STD_VER > 17 -// [time.clock.file], type file_clock -using file_clock = _VSTD_FS::_FilesystemClock; - -template<class _Duration> -using file_time = time_point<file_clock, _Duration>; - - -template <class _Duration> -using sys_time = time_point<system_clock, _Duration>; -using sys_seconds = sys_time<seconds>; -using sys_days = sys_time<days>; - -struct local_t {}; -template<class Duration> -using local_time = time_point<local_t, Duration>; -using local_seconds = local_time<seconds>; -using local_days = local_time<days>; - - -struct last_spec { explicit last_spec() = default; }; - -class day { -private: - unsigned char __d; -public: - day() = default; - explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} - inline constexpr day& operator++() noexcept { ++__d; return *this; } - inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } - inline constexpr day& operator--() noexcept { --__d; return *this; } - inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } - constexpr day& operator+=(const days& __dd) noexcept; - constexpr day& operator-=(const days& __dd) noexcept; - explicit inline constexpr operator unsigned() const noexcept { return __d; } - inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } - }; - - -inline constexpr -bool operator==(const day& __lhs, const day& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator!=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const day& __lhs, const day& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator> (const day& __lhs, const day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const day& __lhs, const day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -day operator+ (const day& __lhs, const days& __rhs) noexcept -{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); } - -inline constexpr -day operator+ (const days& __lhs, const day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -day operator- (const day& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -days operator-(const day& __lhs, const day& __rhs) noexcept -{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) - - static_cast<int>(static_cast<unsigned>(__rhs))); } - -inline constexpr day& day::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } - -inline constexpr day& day::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } - - -class month { -private: - unsigned char __m; -public: - month() = default; - explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} - inline constexpr month& operator++() noexcept { ++__m; return *this; } - inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } - inline constexpr month& operator--() noexcept { --__m; return *this; } - inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } - constexpr month& operator+=(const months& __m1) noexcept; - constexpr month& operator-=(const months& __m1) noexcept; - explicit inline constexpr operator unsigned() const noexcept { return __m; } - inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } -}; - - -inline constexpr -bool operator==(const month& __lhs, const month& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator!=(const month& __lhs, const month& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const month& __lhs, const month& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator> (const month& __lhs, const month& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month& __lhs, const month& __rhs) noexcept -{ return !(__rhs < __lhs); } - -inline constexpr -bool operator>=(const month& __lhs, const month& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -month operator+ (const month& __lhs, const months& __rhs) noexcept -{ - auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); - auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; - return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; -} - -inline constexpr -month operator+ (const months& __lhs, const month& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -month operator- (const month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -months operator-(const month& __lhs, const month& __rhs) noexcept -{ - auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); - return months(__dm <= 11 ? __dm : __dm + 12); -} - -inline constexpr month& month::operator+=(const months& __dm) noexcept -{ *this = *this + __dm; return *this; } - -inline constexpr month& month::operator-=(const months& __dm) noexcept -{ *this = *this - __dm; return *this; } - - -class year { -private: - short __y; -public: - year() = default; - explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} - - inline constexpr year& operator++() noexcept { ++__y; return *this; } - inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } - inline constexpr year& operator--() noexcept { --__y; return *this; } - inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } - constexpr year& operator+=(const years& __dy) noexcept; - constexpr year& operator-=(const years& __dy) noexcept; - inline constexpr year operator+() const noexcept { return *this; } - inline constexpr year operator-() const noexcept { return year{-__y}; } - - inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } - explicit inline constexpr operator int() const noexcept { return __y; } - constexpr bool ok() const noexcept; - static inline constexpr year min() noexcept { return year{-32767}; } - static inline constexpr year max() noexcept { return year{ 32767}; } -}; - - -inline constexpr -bool operator==(const year& __lhs, const year& __rhs) noexcept -{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); } - -inline constexpr -bool operator!=(const year& __lhs, const year& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year& __lhs, const year& __rhs) noexcept -{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); } - -inline constexpr -bool operator> (const year& __lhs, const year& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year& __lhs, const year& __rhs) noexcept -{ return !(__rhs < __lhs); } - -inline constexpr -bool operator>=(const year& __lhs, const year& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -year operator+ (const year& __lhs, const years& __rhs) noexcept -{ return year(static_cast<int>(__lhs) + __rhs.count()); } - -inline constexpr -year operator+ (const years& __lhs, const year& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year operator- (const year& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -years operator-(const year& __lhs, const year& __rhs) noexcept -{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } - - -inline constexpr year& year::operator+=(const years& __dy) noexcept -{ *this = *this + __dy; return *this; } - -inline constexpr year& year::operator-=(const years& __dy) noexcept -{ *this = *this - __dy; return *this; } - -inline constexpr bool year::ok() const noexcept -{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } - -class weekday_indexed; -class weekday_last; - -class weekday { -private: - unsigned char __wd; - static constexpr unsigned char __weekday_from_days(int __days) noexcept; -public: - weekday() = default; - inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} - inline constexpr weekday(const sys_days& __sysd) noexcept - : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} - inline explicit constexpr weekday(const local_days& __locd) noexcept - : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} - - inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } - inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } - inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } - inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } - constexpr weekday& operator+=(const days& __dd) noexcept; - constexpr weekday& operator-=(const days& __dd) noexcept; - inline constexpr unsigned c_encoding() const noexcept { return __wd; } - inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } - inline constexpr bool ok() const noexcept { return __wd <= 6; } - constexpr weekday_indexed operator[](unsigned __index) const noexcept; - constexpr weekday_last operator[](last_spec) const noexcept; -}; - - -// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days -inline constexpr -unsigned char weekday::__weekday_from_days(int __days) noexcept -{ - return static_cast<unsigned char>( - static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) - ); -} - -inline constexpr -bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() == __rhs.c_encoding(); } - -inline constexpr -bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() < __rhs.c_encoding(); } - -inline constexpr -bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs < __rhs); } - -constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept -{ - auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); - auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; - return weekday{static_cast<unsigned>(__mu - __yr * 7)}; -} - -constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } - -constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept -{ - const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); - const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; - return days{__wdu - __wk * 7}; -} - -inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } - -inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } - - -class weekday_indexed { -private: - chrono::weekday __wd; - unsigned char __idx; -public: - weekday_indexed() = default; - inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept - : __wd{__wdval}, __idx(__idxval) {} - inline constexpr chrono::weekday weekday() const noexcept { return __wd; } - inline constexpr unsigned index() const noexcept { return __idx; } - inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } -}; - -inline constexpr -bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } - -inline constexpr -bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -class weekday_last { -private: - chrono::weekday __wd; -public: - explicit constexpr weekday_last(const chrono::weekday& __val) noexcept - : __wd{__val} {} - constexpr chrono::weekday weekday() const noexcept { return __wd; } - constexpr bool ok() const noexcept { return __wd.ok(); } -}; - -inline constexpr -bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday(); } - -inline constexpr -bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } - -inline constexpr -weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } - - -inline constexpr last_spec last{}; -inline constexpr weekday Sunday{0}; -inline constexpr weekday Monday{1}; -inline constexpr weekday Tuesday{2}; -inline constexpr weekday Wednesday{3}; -inline constexpr weekday Thursday{4}; -inline constexpr weekday Friday{5}; -inline constexpr weekday Saturday{6}; - -inline constexpr month January{1}; -inline constexpr month February{2}; -inline constexpr month March{3}; -inline constexpr month April{4}; -inline constexpr month May{5}; -inline constexpr month June{6}; -inline constexpr month July{7}; -inline constexpr month August{8}; -inline constexpr month September{9}; -inline constexpr month October{10}; -inline constexpr month November{11}; -inline constexpr month December{12}; - - -class month_day { -private: - chrono::month __m; - chrono::day __d; -public: - month_day() = default; - constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept - : __m{__mval}, __d{__dval} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::day day() const noexcept { return __d; } - constexpr bool ok() const noexcept; -}; - -inline constexpr -bool month_day::ok() const noexcept -{ - if (!__m.ok()) return false; - const unsigned __dval = static_cast<unsigned>(__d); - if (__dval < 1 || __dval > 31) return false; - if (__dval <= 29) return true; -// Now we've got either 30 or 31 - const unsigned __mval = static_cast<unsigned>(__m); - if (__mval == 2) return false; - if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) - return __dval == 30; - return true; -} - -inline constexpr -bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } - -inline constexpr -bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -month_day operator/(const month& __lhs, const day& __rhs) noexcept -{ return month_day{__lhs, __rhs}; } - -constexpr -month_day operator/(const day& __lhs, const month& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -month_day operator/(const month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } - -constexpr -month_day operator/(int __lhs, const day& __rhs) noexcept -{ return month(__lhs) / __rhs; } - -constexpr -month_day operator/(const day& __lhs, int __rhs) noexcept -{ return month(__rhs) / __lhs; } - - -inline constexpr -bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } - -inline constexpr -bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__lhs < __rhs); } - - - -class month_day_last { -private: - chrono::month __m; -public: - explicit constexpr month_day_last(const chrono::month& __val) noexcept - : __m{__val} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr bool ok() const noexcept { return __m.ok(); } -}; - -inline constexpr -bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month(); } - -inline constexpr -bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() < __rhs.month(); } - -inline constexpr -bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -month_day_last operator/(const month& __lhs, last_spec) noexcept -{ return month_day_last{__lhs}; } - -inline constexpr -month_day_last operator/(last_spec, const month& __rhs) noexcept -{ return month_day_last{__rhs}; } - -inline constexpr -month_day_last operator/(int __lhs, last_spec) noexcept -{ return month_day_last{month(__lhs)}; } - -inline constexpr -month_day_last operator/(last_spec, int __rhs) noexcept -{ return month_day_last{month(__rhs)}; } - - -class month_weekday { -private: - chrono::month __m; - chrono::weekday_indexed __wdi; -public: - month_weekday() = default; - constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept - : __m{__mval}, __wdi{__wdival} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } - inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } -}; - -inline constexpr -bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -inline constexpr -bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{__lhs, __rhs}; } - -inline constexpr -month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{month(__lhs), __rhs}; } - -inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept -{ return month_weekday{__rhs, __lhs}; } - -inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept -{ return month_weekday{month(__rhs), __lhs}; } - - -class month_weekday_last { - chrono::month __m; - chrono::weekday_last __wdl; - public: - constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept - : __m{__mval}, __wdl{__wdlval} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } - inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } -}; - -inline constexpr -bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } - -inline constexpr -bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -inline constexpr -month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{__lhs, __rhs}; } - -inline constexpr -month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{month(__lhs), __rhs}; } - -inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept -{ return month_weekday_last{__rhs, __lhs}; } - -inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept -{ return month_weekday_last{month(__rhs), __lhs}; } - - -class year_month { - chrono::year __y; - chrono::month __m; -public: - year_month() = default; - constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept - : __y{__yval}, __m{__mval} {} - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } - inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } - inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } - inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } - inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } -}; - -inline constexpr -year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } - -inline constexpr -year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } - -inline constexpr -bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } - -inline constexpr -bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } - -inline constexpr -bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__lhs < __rhs); } - -constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept -{ - int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); - const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; - __dmi = __dmi - __dy * 12 + 1; - return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); -} - -constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month(); } - -constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept -{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } - -constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -class year_month_day_last; - -class year_month_day { -private: - chrono::year __y; - chrono::month __m; - chrono::day __d; -public: - year_month_day() = default; - inline constexpr year_month_day( - const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept - : __y{__yval}, __m{__mval}, __d{__dval} {} - constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; - inline constexpr year_month_day(const sys_days& __sysd) noexcept - : year_month_day(__from_days(__sysd.time_since_epoch())) {} - inline explicit constexpr year_month_day(const local_days& __locd) noexcept - : year_month_day(__from_days(__locd.time_since_epoch())) {} - - constexpr year_month_day& operator+=(const months& __dm) noexcept; - constexpr year_month_day& operator-=(const months& __dm) noexcept; - constexpr year_month_day& operator+=(const years& __dy) noexcept; - constexpr year_month_day& operator-=(const years& __dy) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::day day() const noexcept { return __d; } - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - - constexpr bool ok() const noexcept; - - static constexpr year_month_day __from_days(days __d) noexcept; - constexpr days __to_days() const noexcept; -}; - - -// https://howardhinnant.github.io/date_algorithms.html#civil_from_days -inline constexpr -year_month_day -year_month_day::__from_days(days __d) noexcept -{ - static_assert(numeric_limits<unsigned>::digits >= 18, ""); - static_assert(numeric_limits<int>::digits >= 20 , ""); - const int __z = __d.count() + 719468; - const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; - const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] - const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] - const int __yr = static_cast<int>(__yoe) + __era * 400; - const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] - const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] - const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] - const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] - return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; -} - -// https://howardhinnant.github.io/date_algorithms.html#days_from_civil -inline constexpr days year_month_day::__to_days() const noexcept -{ - static_assert(numeric_limits<unsigned>::digits >= 18, ""); - static_assert(numeric_limits<int>::digits >= 20 , ""); - - const int __yr = static_cast<int>(__y) - (__m <= February); - const unsigned __mth = static_cast<unsigned>(__m); - const unsigned __dy = static_cast<unsigned>(__d); - - const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; - const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] - const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] - const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] - return days{__era * 146097 + static_cast<int>(__doe) - 719468}; -} - -inline constexpr -bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } - -inline constexpr -bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - if (__lhs.month() < __rhs.month()) return true; - if (__lhs.month() > __rhs.month()) return false; - return __lhs.day() < __rhs.day(); -} - -inline constexpr -bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept -{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_day operator/(const year_month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } - -inline constexpr -year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept -{ return __lhs / __rhs.month() / __rhs.day(); } - -inline constexpr -year_month_day operator/(int __lhs, const month_day& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_day operator/(const month_day& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept -{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } - -inline constexpr -year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } - -inline constexpr -year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -class year_month_day_last { -private: - chrono::year __y; - chrono::month_day_last __mdl; -public: - constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept - : __y{__yval}, __mdl{__mdlval} {} - - constexpr year_month_day_last& operator+=(const months& __m) noexcept; - constexpr year_month_day_last& operator-=(const months& __m) noexcept; - constexpr year_month_day_last& operator+=(const years& __y) noexcept; - constexpr year_month_day_last& operator-=(const years& __y) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __mdl.month(); } - inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } - constexpr chrono::day day() const noexcept; - inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } - inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } -}; - -inline constexpr -chrono::day year_month_day_last::day() const noexcept -{ - constexpr chrono::day __d[] = - { - chrono::day(31), chrono::day(28), chrono::day(31), - chrono::day(30), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(30), chrono::day(31) - }; - return (month() != February || !__y.is_leap()) && month().ok() ? - __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; -} - -inline constexpr -bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } - -inline constexpr -bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - return __lhs.month_day_last() < __rhs.month_day_last(); -} - -inline constexpr -bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept -{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } - -inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{__lhs, __rhs}; } - -inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{year{__lhs}, __rhs}; } - -inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept -{ return year{__rhs} / __lhs; } - - -inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / last; } - -inline constexpr -year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } - -inline constexpr -year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept - : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} - -inline constexpr bool year_month_day::ok() const noexcept -{ - if (!__y.ok() || !__m.ok()) return false; - return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); -} - -class year_month_weekday { - chrono::year __y; - chrono::month __m; - chrono::weekday_indexed __wdi; -public: - year_month_weekday() = default; - constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_indexed& __wdival) noexcept - : __y{__yval}, __m{__mval}, __wdi{__wdival} {} - constexpr year_month_weekday(const sys_days& __sysd) noexcept - : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} - inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept - : year_month_weekday(__from_days(__locd.time_since_epoch())) {} - constexpr year_month_weekday& operator+=(const months& m) noexcept; - constexpr year_month_weekday& operator-=(const months& m) noexcept; - constexpr year_month_weekday& operator+=(const years& y) noexcept; - constexpr year_month_weekday& operator-=(const years& y) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } - inline constexpr unsigned index() const noexcept { return __wdi.index(); } - inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } - - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - inline constexpr bool ok() const noexcept - { - if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; - if (__wdi.index() <= 4) return true; - auto __nth_weekday_day = - __wdi.weekday() - - chrono::weekday{static_cast<sys_days>(__y / __m / 1)} + - days{(__wdi.index() - 1) * 7 + 1}; - return static_cast<unsigned>(__nth_weekday_day.count()) <= - static_cast<unsigned>((__y / __m / last).day()); - } - - static constexpr year_month_weekday __from_days(days __d) noexcept; - constexpr days __to_days() const noexcept; -}; - -inline constexpr -year_month_weekday year_month_weekday::__from_days(days __d) noexcept -{ - const sys_days __sysd{__d}; - const chrono::weekday __wd = chrono::weekday(__sysd); - const year_month_day __ymd = year_month_day(__sysd); - return year_month_weekday{__ymd.year(), __ymd.month(), - __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; -} - -inline constexpr -days year_month_weekday::__to_days() const noexcept -{ - const sys_days __sysd = sys_days(__y/__m/1); - return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) - .time_since_epoch(); -} - -inline constexpr -bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -inline constexpr -bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept -{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept -{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } - -inline constexpr -year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } - -inline constexpr -year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } - -inline constexpr -year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - - -inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -class year_month_weekday_last { -private: - chrono::year __y; - chrono::month __m; - chrono::weekday_last __wdl; -public: - constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_last& __wdlval) noexcept - : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} - constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; - constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; - constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; - constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } - inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } - - constexpr days __to_days() const noexcept; - -}; - -inline constexpr -days year_month_weekday_last::__to_days() const noexcept -{ - const sys_days __last = sys_days{__y/__m/last}; - return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); - -} - -inline constexpr -bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } - -inline constexpr -bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -inline constexpr -year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } - -inline constexpr -year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } - -inline constexpr -year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } - -inline constexpr -year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - - -template <class _Duration> -class hh_mm_ss -{ -private: - static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); - using __CommonType = common_type_t<_Duration, chrono::seconds>; - - static constexpr uint64_t __pow10(unsigned __exp) - { - uint64_t __ret = 1; - for (unsigned __i = 0; __i < __exp; ++__i) - __ret *= 10U; - return __ret; - } - - static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) - { - if (__n >= 2 && __d != 0 && __w < 19) - return 1 + __width(__n, __d % __n * 10, __w+1); - return 0; - } - -public: - static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? - __width(__CommonType::period::den) : 6u; - using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; - - constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} - - constexpr explicit hh_mm_ss(_Duration __d) noexcept : - __is_neg(__d < _Duration(0)), - __h(duration_cast<chrono::hours> (abs(__d))), - __m(duration_cast<chrono::minutes>(abs(__d) - hours())), - __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), - __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds())) - {} - - constexpr bool is_negative() const noexcept { return __is_neg; } - constexpr chrono::hours hours() const noexcept { return __h; } - constexpr chrono::minutes minutes() const noexcept { return __m; } - constexpr chrono::seconds seconds() const noexcept { return __s; } - constexpr precision subseconds() const noexcept { return __f; } - - constexpr precision to_duration() const noexcept - { - auto __dur = __h + __m + __s + __f; - return __is_neg ? -__dur : __dur; - } - - constexpr explicit operator precision() const noexcept { return to_duration(); } - -private: - bool __is_neg; - chrono::hours __h; - chrono::minutes __m; - chrono::seconds __s; - precision __f; -}; - -constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } -constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } - -constexpr hours make12(const hours& __h) noexcept -{ - if (__h == hours( 0)) return hours(12); - else if (__h <= hours(12)) return __h; - else return __h - hours(12); -} - -constexpr hours make24(const hours& __h, bool __is_pm) noexcept -{ - if (__is_pm) - return __h == hours(12) ? __h : __h + hours(12); - else - return __h == hours(12) ? hours(0) : __h; -} - -#endif // _LIBCPP_STD_VER > 17 -} // namespace chrono - -#if _LIBCPP_STD_VER > 11 -// Suffixes for duration literals [time.duration.literals] -inline namespace literals -{ - inline namespace chrono_literals - { - - constexpr chrono::hours operator""h(unsigned long long __h) - { - return chrono::hours(static_cast<chrono::hours::rep>(__h)); - } - - constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h) - { - return chrono::duration<long double, ratio<3600,1>>(__h); - } - - - constexpr chrono::minutes operator""min(unsigned long long __m) - { - return chrono::minutes(static_cast<chrono::minutes::rep>(__m)); - } - - constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m) - { - return chrono::duration<long double, ratio<60,1>> (__m); - } - - - constexpr chrono::seconds operator""s(unsigned long long __s) - { - return chrono::seconds(static_cast<chrono::seconds::rep>(__s)); - } - - constexpr chrono::duration<long double> operator""s(long double __s) - { - return chrono::duration<long double> (__s); - } - - - constexpr chrono::milliseconds operator""ms(unsigned long long __ms) - { - return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms)); - } - - constexpr chrono::duration<long double, milli> operator""ms(long double __ms) - { - return chrono::duration<long double, milli>(__ms); - } - - - constexpr chrono::microseconds operator""us(unsigned long long __us) - { - return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us)); - } - - constexpr chrono::duration<long double, micro> operator""us(long double __us) - { - return chrono::duration<long double, micro> (__us); - } - - - constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) - { - return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns)); - } - - constexpr chrono::duration<long double, nano> operator""ns(long double __ns) - { - return chrono::duration<long double, nano> (__ns); - } - -#if _LIBCPP_STD_VER > 17 - constexpr chrono::day operator ""d(unsigned long long __d) noexcept - { - return chrono::day(static_cast<unsigned>(__d)); - } - - constexpr chrono::year operator ""y(unsigned long long __y) noexcept - { - return chrono::year(static_cast<int>(__y)); - } -#endif -} // namespace chrono_literals -} // namespace literals - -namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; -} // namespace chrono - -#endif - -_LIBCPP_END_NAMESPACE_STD - -#ifndef _LIBCPP_CXX03_LANG -_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) - typedef __int128_t rep; - typedef nano period; -#else - typedef long long rep; - typedef nano period; -#endif - - typedef chrono::duration<rep, period> duration; - typedef chrono::time_point<_FilesystemClock> time_point; - - _LIBCPP_EXPORTED_FROM_ABI - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; - -#if _LIBCPP_STD_VER > 17 - template <class _Duration> - _LIBCPP_HIDE_FROM_ABI - static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { - return chrono::sys_time<_Duration>(__t.time_since_epoch()); - } - - template <class _Duration> - _LIBCPP_HIDE_FROM_ABI - static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { - return chrono::file_time<_Duration>(__t.time_since_epoch()); - } -#endif // _LIBCPP_STD_VER > 17 -}; -_LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // !_LIBCPP_CXX03_LANG - -_LIBCPP_POP_MACROS - #endif // _LIBCPP_CHRONO diff --git a/libcxx/include/cmath b/libcxx/include/cmath index b5c332c81ad6..8bd55542ed92 100644 --- a/libcxx/include/cmath +++ b/libcxx/include/cmath @@ -306,8 +306,8 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept #include <__config> #include <math.h> -#include <version> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -636,6 +636,23 @@ lerp(double __a, double __b, double __t) _NOEXCEPT { return __ler constexpr long double lerp(long double __a, long double __b, long double __t) _NOEXCEPT { return __lerp(__a, __b, __t); } +template <class _A1, class _A2, class _A3> +inline _LIBCPP_HIDE_FROM_ABI +constexpr typename enable_if_t +< + is_arithmetic<_A1>::value && + is_arithmetic<_A2>::value && + is_arithmetic<_A3>::value, + __promote<_A1, _A2, _A3> +>::type +lerp(_A1 __a, _A2 __b, _A3 __t) noexcept +{ + typedef typename __promote<_A1, _A2, _A3>::type __result_type; + static_assert(!(_IsSame<_A1, __result_type>::value && + _IsSame<_A2, __result_type>::value && + _IsSame<_A3, __result_type>::value)); + return __lerp((__result_type)__a, (__result_type)__b, (__result_type)__t); +} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt index 60d3db882c03..74839d199686 100644 --- a/libcxx/include/codecvt +++ b/libcxx/include/codecvt @@ -56,6 +56,7 @@ class codecvt_utf8_utf16 #include <__config> #include <__locale> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/compare b/libcxx/include/compare index 5d07ebaf2fbd..d686b5a369f2 100644 --- a/libcxx/include/compare +++ b/libcxx/include/compare @@ -145,6 +145,7 @@ namespace std { #include <__compare/three_way_comparable.h> #include <__compare/weak_order.h> #include <__config> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable index 0569e2254d1d..ecec3ea8c017 100644 --- a/libcxx/include/condition_variable +++ b/libcxx/include/condition_variable @@ -109,6 +109,7 @@ public: #include <__config> #include <__mutex_base> #include <memory> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/coroutine b/libcxx/include/coroutine index 4e140ab3fed7..6e83fe285bc7 100644 --- a/libcxx/include/coroutine +++ b/libcxx/include/coroutine @@ -40,8 +40,8 @@ struct suspend_always; #include <__config> #include <__coroutine/coroutine_handle.h> -#include <__coroutine/noop_coroutine_handle.h> #include <__coroutine/coroutine_traits.h> +#include <__coroutine/noop_coroutine_handle.h> #include <__coroutine/trivial_awaitables.h> #include <version> diff --git a/libcxx/include/execution b/libcxx/include/execution index c1debcb72ff1..417b11b103a2 100644 --- a/libcxx/include/execution +++ b/libcxx/include/execution @@ -11,6 +11,7 @@ #define _LIBCPP_EXECUTION #include <__config> +#include <version> #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 # include <__pstl_execution> diff --git a/libcxx/include/experimental/__memory b/libcxx/include/experimental/__memory index bd9bf95e5933..33027793895d 100644 --- a/libcxx/include/experimental/__memory +++ b/libcxx/include/experimental/__memory @@ -10,11 +10,11 @@ #ifndef _LIBCPP_EXPERIMENTAL___MEMORY #define _LIBCPP_EXPERIMENTAL___MEMORY +#include <__functional_base> #include <__memory/allocator_arg_t.h> #include <__memory/uses_allocator.h> #include <experimental/__config> #include <experimental/utility> // for erased_type -#include <__functional_base> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/experimental/algorithm b/libcxx/include/experimental/algorithm index bcf372cafd7a..a7fa18ff5dde 100644 --- a/libcxx/include/experimental/algorithm +++ b/libcxx/include/experimental/algorithm @@ -31,12 +31,11 @@ ForwardIterator search(ForwardIterator first, ForwardIterator last, */ -#include <experimental/__config> +#include <__debug> #include <algorithm> +#include <experimental/__config> #include <type_traits> -#include <__debug> - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif diff --git a/libcxx/include/experimental/coroutine b/libcxx/include/experimental/coroutine index 16b4028765bc..4b53e4b62b40 100644 --- a/libcxx/include/experimental/coroutine +++ b/libcxx/include/experimental/coroutine @@ -45,13 +45,13 @@ template <class P> struct hash<coroutine_handle<P>>; */ +#include <__debug> +#include <cstddef> #include <experimental/__config> -#include <new> -#include <type_traits> #include <functional> #include <memory> // for hash<T*> -#include <cstddef> -#include <__debug> +#include <new> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/deque b/libcxx/include/experimental/deque index 594ddff22f98..41c25d95b9a0 100644 --- a/libcxx/include/experimental/deque +++ b/libcxx/include/experimental/deque @@ -28,8 +28,8 @@ namespace pmr { */ -#include <experimental/__config> #include <deque> +#include <experimental/__config> #include <experimental/memory_resource> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/experimental/forward_list b/libcxx/include/experimental/forward_list index 6781424cf2c6..590bef0283a2 100644 --- a/libcxx/include/experimental/forward_list +++ b/libcxx/include/experimental/forward_list @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <forward_list> #include <experimental/memory_resource> +#include <forward_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/functional b/libcxx/include/experimental/functional index bcff51e8056f..8977c6354355 100644 --- a/libcxx/include/experimental/functional +++ b/libcxx/include/experimental/functional @@ -86,16 +86,15 @@ inline namespace fundamentals_v1 { */ +#include <__debug> #include <__memory/uses_allocator.h> +#include <algorithm> +#include <array> #include <experimental/__config> #include <functional> -#include <algorithm> #include <type_traits> -#include <vector> -#include <array> #include <unordered_map> - -#include <__debug> +#include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -104,7 +103,6 @@ inline namespace fundamentals_v1 { _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_LFTS #if _LIBCPP_STD_VER > 11 diff --git a/libcxx/include/experimental/iterator b/libcxx/include/experimental/iterator index 9da08a0cff9d..ab1f54e35eb9 100644 --- a/libcxx/include/experimental/iterator +++ b/libcxx/include/experimental/iterator @@ -53,8 +53,8 @@ namespace std { */ #include <__memory/addressof.h> -#include <__utility/move.h> #include <__utility/forward.h> +#include <__utility/move.h> #include <experimental/__config> #include <iterator> diff --git a/libcxx/include/experimental/list b/libcxx/include/experimental/list index 099d80fd8db5..be43e60f49ad 100644 --- a/libcxx/include/experimental/list +++ b/libcxx/include/experimental/list @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <list> #include <experimental/memory_resource> +#include <list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/map b/libcxx/include/experimental/map index 27ff7e862e27..704626eed674 100644 --- a/libcxx/include/experimental/map +++ b/libcxx/include/experimental/map @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <map> #include <experimental/memory_resource> +#include <map> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/memory_resource b/libcxx/include/experimental/memory_resource index 71a4f51c50e5..47bb8c58c8de 100644 --- a/libcxx/include/experimental/memory_resource +++ b/libcxx/include/experimental/memory_resource @@ -64,18 +64,18 @@ namespace pmr { */ +#include <__debug> +#include <__tuple> +#include <cstddef> +#include <cstdlib> #include <experimental/__config> #include <experimental/__memory> #include <limits> #include <memory> #include <new> #include <stdexcept> -#include <__tuple> #include <type_traits> #include <utility> -#include <cstddef> -#include <cstdlib> -#include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/propagate_const b/libcxx/include/experimental/propagate_const index 12376dcec242..deb4ba98a7fa 100644 --- a/libcxx/include/experimental/propagate_const +++ b/libcxx/include/experimental/propagate_const @@ -107,19 +107,18 @@ */ #include <experimental/__config> +#include <functional> +#include <type_traits> +#include <utility> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif #if _LIBCPP_STD_VER > 11 -#include <type_traits> -#include <utility> -#include <functional> - _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 - template <class _Tp> class propagate_const; diff --git a/libcxx/include/experimental/regex b/libcxx/include/experimental/regex index ced0e950a127..5bb3dccf9387 100644 --- a/libcxx/include/experimental/regex +++ b/libcxx/include/experimental/regex @@ -36,9 +36,9 @@ namespace pmr { */ #include <experimental/__config> -#include <regex> -#include <experimental/string> #include <experimental/memory_resource> +#include <experimental/string> +#include <regex> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/set b/libcxx/include/experimental/set index 891510bbb8d9..12b2ac23b81a 100644 --- a/libcxx/include/experimental/set +++ b/libcxx/include/experimental/set @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <set> #include <experimental/memory_resource> +#include <set> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd index 1f17ee96f0b5..475155512d76 100644 --- a/libcxx/include/experimental/simd +++ b/libcxx/include/experimental/simd @@ -649,10 +649,10 @@ public: */ -#include <experimental/__config> #include <algorithm> #include <array> #include <cstddef> +#include <experimental/__config> #include <functional> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -689,7 +689,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; } @@ -706,7 +706,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }; + _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; } void __set(size_t __index, _Tp __val) noexcept { (&__storage_)[__index] = __val; } @@ -770,7 +770,7 @@ struct __vec_ext_traits { _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \ - _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32); + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32) _LIBCPP_SPECIALIZE_VEC_EXT_32(char); _LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t); @@ -808,7 +808,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; } diff --git a/libcxx/include/experimental/string b/libcxx/include/experimental/string index b881fcf3af1c..1643e84c5a0c 100644 --- a/libcxx/include/experimental/string +++ b/libcxx/include/experimental/string @@ -38,8 +38,8 @@ namespace pmr { */ #include <experimental/__config> -#include <string> #include <experimental/memory_resource> +#include <string> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/unordered_map b/libcxx/include/experimental/unordered_map index fc8cc7f77bf0..80905e68ef36 100644 --- a/libcxx/include/experimental/unordered_map +++ b/libcxx/include/experimental/unordered_map @@ -40,8 +40,8 @@ namespace pmr { */ #include <experimental/__config> -#include <unordered_map> #include <experimental/memory_resource> +#include <unordered_map> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/unordered_set b/libcxx/include/experimental/unordered_set index 39342da5f679..f09b0bd57d9f 100644 --- a/libcxx/include/experimental/unordered_set +++ b/libcxx/include/experimental/unordered_set @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <unordered_set> #include <experimental/memory_resource> +#include <unordered_set> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/experimental/vector b/libcxx/include/experimental/vector index a22698ef7ce4..4d31d1ccd85b 100644 --- a/libcxx/include/experimental/vector +++ b/libcxx/include/experimental/vector @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <vector> #include <experimental/memory_resource> +#include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/ext/__hash b/libcxx/include/ext/__hash index 2f998ee40a93..f6e7a486f6b6 100644 --- a/libcxx/include/ext/__hash +++ b/libcxx/include/ext/__hash @@ -13,8 +13,8 @@ #pragma GCC system_header #include <__string> -#include <string> #include <cstring> +#include <string> namespace __gnu_cxx { diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map index d6ea26c2cf86..a52c6a4066f7 100644 --- a/libcxx/include/ext/hash_map +++ b/libcxx/include/ext/hash_map @@ -203,10 +203,10 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> +#include <ext/__hash> #include <functional> #include <stdexcept> #include <type_traits> -#include <ext/__hash> #if defined(__DEPRECATED) && __DEPRECATED #if defined(_LIBCPP_WARNING) diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set index 7d19ccd006e2..bca008d172a2 100644 --- a/libcxx/include/ext/hash_set +++ b/libcxx/include/ext/hash_set @@ -194,8 +194,8 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> -#include <functional> #include <ext/__hash> +#include <functional> #if defined(__DEPRECATED) && __DEPRECATED #if defined(_LIBCPP_WARNING) diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index 9f5b42747b34..74f596599a1e 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -248,8 +248,8 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct #include <__filesystem/file_type.h> #include <__filesystem/filesystem_error.h> #include <__filesystem/operations.h> -#include <__filesystem/path_iterator.h> #include <__filesystem/path.h> +#include <__filesystem/path_iterator.h> #include <__filesystem/perm_options.h> #include <__filesystem/perms.h> #include <__filesystem/recursive_directory_iterator.h> diff --git a/libcxx/include/format b/libcxx/include/format index 788b9c299abc..4cf146ead17a 100644 --- a/libcxx/include/format +++ b/libcxx/include/format @@ -14,43 +14,15 @@ namespace std { // [format.context], class template basic_format_context - template<class Out, class charT> - class basic_format_context { - basic_format_args<basic_format_context> args_; // exposition only - Out out_; // exposition only - - public: - using iterator = Out; - using char_type = charT; - template<class T> using formatter_type = formatter<T, charT>; - - basic_format_arg<basic_format_context> arg(size_t id) const; - std::locale locale(); - - iterator out(); - void advance_to(iterator it); - }; + template<class Out, class charT> class basic_format_context; using format_context = basic_format_context<unspecified, char>; using wformat_context = basic_format_context<unspecified, wchar_t>; // [format.args], class template basic_format_args - template<class Context> - class basic_format_args { - size_t size_; // exposition only - const basic_format_arg<Context>* data_; // exposition only - - public: - basic_format_args() noexcept; - - template<class... Args> - basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; - - basic_format_arg<Context> get(size_t i) const noexcept; - }; + template<class Context> class basic_format_args; using format_args = basic_format_args<format_context>; using wformat_args = basic_format_args<wformat_context>; - // [format.functions], formatting functions template<class... Args> string format(string_view fmt, const Args&... args); @@ -90,8 +62,7 @@ namespace std { Out out; iter_difference_t<Out> size; }; - - template<class Out, class... Args> + template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args); template<class Out, class... Args> @@ -116,99 +87,22 @@ namespace std { size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); // [format.formatter], formatter - template<> struct formatter<char, char>; - template<> struct formatter<char, wchar_t>; - template<> struct formatter<wchar_t, wchar_t>; - - template<> struct formatter<charT*, charT>; - template<> struct formatter<const charT*, charT>; - template<size_t N> struct formatter<const charT[N], charT>; - template<class traits, class Allocator> - struct formatter<basic_string<charT, traits, Allocator>, charT>; - template<class traits> - struct formatter<basic_string_view<charT, traits>, charT>; + template<class T, class charT = char> struct formatter; // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; + template<class charT> class basic_format_parse_context; using format_parse_context = basic_format_parse_context<char>; using wformat_parse_context = basic_format_parse_context<wchar_t>; // [format.arguments], arguments // [format.arg], class template basic_format_arg - template<class Context> - class basic_format_arg { - public: - class handle; - - private: - using char_type = typename Context::char_type; // exposition only - - variant<monostate, bool, char_type, - int, unsigned int, long long int, unsigned long long int, - float, double, long double, - const char_type*, basic_string_view<char_type>, - const void*, handle> value; // exposition only - - template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only - explicit basic_format_arg(float n) noexcept; // exposition only - explicit basic_format_arg(double n) noexcept; // exposition only - explicit basic_format_arg(long double n) noexcept; // exposition only - explicit basic_format_arg(const char_type* s); // exposition only - - template<class traits> - explicit basic_format_arg( - basic_string_view<char_type, traits> s) noexcept; // exposition only - - template<class traits, class Allocator> - explicit basic_format_arg( - const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only - - explicit basic_format_arg(nullptr_t) noexcept; // exposition only - - template<class T> - explicit basic_format_arg(const T* p) noexcept; // exposition only - - public: - basic_format_arg() noexcept; - - explicit operator bool() const noexcept; - }; + template<class Context> class basic_format_arg; template<class Visitor, class Context> see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); // [format.arg.store], class template format-arg-store - template<class Context, class... Args> - struct format-arg-store { // exposition only - array<basic_format_arg<Context>, sizeof...(Args)> args; - }; + template<class Context, class... Args> struct format-arg-store; // exposition only template<class Context = format_context, class... Args> format-arg-store<Context, Args...> @@ -218,43 +112,7 @@ namespace std { make_wformat_args(const Args&... args); // [format.error], class format_error - class format_error : public runtime_error { - public: - explicit format_error(const string& what_arg); - explicit format_error(const char* what_arg); - }; - - // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; - using format_parse_context = basic_format_parse_context<char>; - using wformat_parse_context = basic_format_parse_context<wchar_t>; + class format_error; } */ @@ -277,7 +135,9 @@ namespace std { #include <__format/formatter.h> #include <__format/formatter_bool.h> #include <__format/formatter_char.h> +#include <__format/formatter_floating_point.h> #include <__format/formatter_integer.h> +#include <__format/formatter_pointer.h> #include <__format/formatter_string.h> #include <__format/parser_std_format_spec.h> #include <__variant/monostate.h> @@ -367,6 +227,8 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, [&](auto __arg) { if constexpr (same_as<decltype(__arg), monostate>) __throw_format_error("Argument index out of bounds"); + else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>) + __arg.format(__parse_ctx, __ctx); else { formatter<decltype(__arg), _CharT> __formatter; __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); diff --git a/libcxx/include/fstream b/libcxx/include/fstream index 3d64adcb23d1..fc0a9204ed60 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -187,6 +187,7 @@ typedef basic_fstream<wchar_t> wfstream; #include <cstdlib> #include <istream> #include <ostream> +#include <version> #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) # include <filesystem> diff --git a/libcxx/include/functional b/libcxx/include/functional index 53a5f2bc3770..3a24b975881c 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -496,9 +496,9 @@ POLICY: For non-variadic implementations, the number of arguments is limited #include <__debug> #include <__functional/binary_function.h> // TODO: deprecate #include <__functional/binary_negate.h> +#include <__functional/bind.h> #include <__functional/bind_back.h> #include <__functional/bind_front.h> -#include <__functional/bind.h> #include <__functional/binder1st.h> #include <__functional/binder2nd.h> #include <__functional/compose.h> diff --git a/libcxx/include/future b/libcxx/include/future index 6b666a70f48e..e35eedf35641 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -374,6 +374,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; #include <mutex> #include <system_error> #include <thread> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/ios b/libcxx/include/ios index 237d146dfb85..74c3c63bd347 100644 --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -214,6 +214,7 @@ storage-class-specifier const error_category& iostream_category() noexcept; #include <__locale> #include <iosfwd> #include <system_error> +#include <version> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) #include <atomic> // for __xindex_ diff --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd index 938d712cf36b..c2ba8ee9e652 100644 --- a/libcxx/include/iosfwd +++ b/libcxx/include/iosfwd @@ -96,6 +96,7 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>; #include <__config> #include <__mbstate_t.h> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/iostream b/libcxx/include/iostream index 7397acfc678b..793f08ab1330 100644 --- a/libcxx/include/iostream +++ b/libcxx/include/iostream @@ -38,6 +38,7 @@ extern wostream wclog; #include <istream> #include <ostream> #include <streambuf> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/iterator b/libcxx/include/iterator index 4dd9902d79a2..29097a9aa8bf 100644 --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -140,6 +140,11 @@ template<class In, class Out> template<class I1, class I2 = I1> concept indirectly_swappable = see below; // since C++20 +template<class I1, class I2, class R, class P1 = identity, + class P2 = identity> + concept indirectly_comparable = + indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // since C++20 + template<input_or_output_iterator I, sentinel_for<I> S> requires (!same_as<I, S> && copyable<I>) class common_iterator; // since C++20 @@ -593,17 +598,18 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; #include <__iterator/erase_if_container.h> #include <__iterator/front_insert_iterator.h> #include <__iterator/incrementable_traits.h> +#include <__iterator/indirectly_comparable.h> #include <__iterator/insert_iterator.h> -#include <__iterator/istreambuf_iterator.h> #include <__iterator/istream_iterator.h> -#include <__iterator/iterator.h> -#include <__iterator/iterator_traits.h> +#include <__iterator/istreambuf_iterator.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> #include <__iterator/move_iterator.h> #include <__iterator/next.h> -#include <__iterator/ostreambuf_iterator.h> #include <__iterator/ostream_iterator.h> +#include <__iterator/ostreambuf_iterator.h> #include <__iterator/prev.h> #include <__iterator/projected.h> #include <__iterator/readable_traits.h> diff --git a/libcxx/include/latch b/libcxx/include/latch index e65825991b59..2cc9222baadc 100644 --- a/libcxx/include/latch +++ b/libcxx/include/latch @@ -43,6 +43,7 @@ namespace std #include <__availability> #include <__config> #include <atomic> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/list b/libcxx/include/list index c9c050a4f1f0..258fe2cee727 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -319,9 +319,7 @@ public: _LIBCPP_INLINE_VISIBILITY __list_iterator() _NOEXCEPT : __ptr_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -355,29 +353,23 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); return __ptr_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); } _LIBCPP_INLINE_VISIBILITY __list_iterator& operator++() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable list::iterator"); __ptr_ = __ptr_->__next_; return *this; } @@ -387,10 +379,8 @@ public: _LIBCPP_INLINE_VISIBILITY __list_iterator& operator--() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable list::iterator"); __ptr_ = __ptr_->__prev_; return *this; } @@ -439,9 +429,7 @@ public: _LIBCPP_INLINE_VISIBILITY __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT @@ -482,29 +470,23 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); return __ptr_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); } _LIBCPP_INLINE_VISIBILITY __list_const_iterator& operator++() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable list::const_iterator"); __ptr_ = __ptr_->__next_; return *this; } @@ -514,10 +496,8 @@ public: _LIBCPP_INLINE_VISIBILITY __list_const_iterator& operator--() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable list::const_iterator"); __ptr_ = __ptr_->__prev_; return *this; } @@ -869,16 +849,12 @@ public: list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } _LIBCPP_INLINE_VISIBILITY explicit list(const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } explicit list(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -888,9 +864,7 @@ public: template <class = __enable_if_t<__is_allocator<_Alloc>::value> > list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) push_back(__x); } @@ -1217,9 +1191,7 @@ list<_Tp, _Alloc>::__iterator(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) #ifndef _LIBCPP_CXX03_LANG emplace_back(); @@ -1232,9 +1204,7 @@ list<_Tp, _Alloc>::list(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) emplace_back(); } @@ -1243,9 +1213,7 @@ list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) push_back(__x); } @@ -1255,9 +1223,7 @@ template <class _InpIter> list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __f != __l; ++__f) __emplace_back(*__f); } @@ -1268,9 +1234,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __f != __l; ++__f) __emplace_back(*__f); } @@ -1279,9 +1243,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c) : base(__node_alloc_traits::select_on_container_copy_construction( __c.__node_alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -1290,9 +1252,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -1303,9 +1263,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -1314,9 +1272,7 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -1324,11 +1280,9 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il) template <class _Tp, class _Alloc> inline list<_Tp, _Alloc>::list(list&& __c) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) - : base(_VSTD::move(__c.__node_alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) + : base(_VSTD::move(__c.__node_alloc())) { + _VSTD::__debug_db_insert_c(this); splice(end(), __c); } @@ -1337,9 +1291,7 @@ inline list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a == __c.get_allocator()) splice(end(), __c); else @@ -1448,11 +1400,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, x) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); @@ -1469,10 +1418,9 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, n, x) called with an iterator not referring to this list"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, n, x) called with an iterator not" - " referring to this list"); iterator __r(__p.__ptr_, this); #else iterator __r(__p.__ptr_); @@ -1535,10 +1483,9 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, range) called with an iterator not referring to this list"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, range) called with an iterator not" - " referring to this list"); iterator __r(__p.__ptr_, this); #else iterator __r(__p.__ptr_); @@ -1694,11 +1641,8 @@ template <class... _Args> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::emplace(iterator, args...) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::emplace(iterator, args...) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); @@ -1717,11 +1661,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, x) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); @@ -1800,11 +1741,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::erase(iterator) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::erase(iterator) called with an iterator not referring to this list"); _LIBCPP_ASSERT(__p != end(), "list::erase(iterator) called with a non-dereferenceable iterator"); __node_allocator& __na = base::__node_alloc(); @@ -1841,14 +1779,10 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, - "list::erase(iterator, iterator) called with an iterator not" - " referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, - "list::erase(iterator, iterator) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, + "list::erase(iterator, iterator) called with an iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, + "list::erase(iterator, iterator) called with an iterator not referring to this list"); if (__f != __l) { __node_allocator& __na = base::__node_alloc(); @@ -2006,11 +1940,8 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { _LIBCPP_ASSERT(this != _VSTD::addressof(__c), "list::splice(iterator, list) called with this == &list"); -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list) called with an iterator not referring to this list"); if (!__c.empty()) { __link_pointer __f = __c.__end_.__next_; @@ -2046,17 +1977,13 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator) called with the first iterator" - " not referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator) called with the second iterator" - " not referring to the list argument"); - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), - "list::splice(iterator, list, iterator) called with the second iterator" - " not dereferenceable"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list, iterator) called with the first iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), + "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable"); + if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) { __link_pointer __f = __i.__ptr_; @@ -2091,23 +2018,20 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument"); + #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator, iterator) called with first iterator not" - " referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with second iterator not" - " referring to the list argument"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with third iterator not" - " referring to the list argument"); if (this == _VSTD::addressof(__c)) { for (const_iterator __i = __f; __i != __l; ++__i) - _LIBCPP_ASSERT(__i != __p, - "list::splice(iterator, list, iterator, iterator)" - " called with the first iterator within the range" - " of the second and third iterators"); + _LIBCPP_DEBUG_ASSERT(__i != __p, + "list::splice(iterator, list, iterator, iterator)" + " called with the first iterator within the range of the second and third iterators"); } #endif if (__f != __l) diff --git a/libcxx/include/locale b/libcxx/include/locale index 86af26c3e35e..7c2d2361f751 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -416,11 +416,11 @@ struct __num_get unsigned& __dc, _CharT __thousands_sep, const string& __grouping, unsigned* __g, unsigned*& __g_end, const _CharT* __atoms); private: - template<typename T> - const T* __do_widen_p(ios_base& __iob, T* __atoms) const + template<typename _Tp> + const _Tp* __do_widen_p(ios_base& __iob, _Tp* __atoms) const { locale __loc = __iob.getloc(); - use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms); + use_facet<ctype<_Tp> >(__loc).widen(__src, __src + 26, __atoms); return __atoms; } diff --git a/libcxx/include/math.h b/libcxx/include/math.h index 850cdcfb32f6..e59ac6be11bf 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -305,9 +305,9 @@ long double truncl(long double x); // back to C++ linkage before including these C++ headers. extern "C++" { +#include <limits> #include <stdlib.h> #include <type_traits> -#include <limits> // signbit diff --git a/libcxx/include/memory b/libcxx/include/memory index 3ed1530f2a75..db59936707e4 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -181,82 +181,189 @@ template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2> + requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> +uninitialized_copy_result<InputIterator, OutputIterator> +uninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 + +template<input_range InputRange, nothrow-forward-range OutputRange> + requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>> +uninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> +uninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20 + +} + template <class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> + requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> +uninitialized_copy_n_result<InputIterator, OutputIterator> +uninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 + +} + template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T> requires constructible_from<iter_value_t<ForwardIterator>, const T&> -ForwardIterator ranges::uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20 +ForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20 template <nothrow-forward-range ForwardRange, class T> requires constructible_from<range_value_t<ForwardRange>, const T&> -borrowed_iterator_t<ForwardRange> ranges::uninitialized_fill(ForwardRange&& range, const T& x); // since C++20 +borrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20 + +} template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, class T> requires constructible_from<iter_value_t<ForwardIterator>, const T&> -ForwardIterator ranges::uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 +ForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class T, class ...Args> constexpr T* construct_at(T* location, Args&& ...args); // since C++20 +namespace ranges { + template<class T, class... Args> + constexpr T* construct_at(T* location, Args&&... args); // since C++20 +} + template <class T> void destroy_at(T* location); // constexpr in C++20 +namespace ranges { + template<destructible T> + constexpr void destroy_at(T* location) noexcept; // since C++20 +} + template <class ForwardIterator> void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 +namespace ranges { + template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel> + requires destructible<iter_value_t<InputIterator>> + constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20 + template<nothrow-input-range InputRange> + requires destructible<range_value_t<InputRange>> + constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20 +} + template <class ForwardIterator, class Size> ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 +namespace ranges { + template<nothrow-input-iterator InputIterator> + requires destructible<iter_value_t<InputIterator>> + constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20 +} + template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2> + requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> +uninitialized_move_result<InputIterator, OutputIterator> +uninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 + +template<input_range InputRange, nothrow-forward-range OutputRange> + requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>> +uninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> +uninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20 + +} + template <class InputIterator, class Size, class ForwardIterator> pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> + requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> +uninitialized_move_n_result<InputIterator, OutputIterator> +uninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 + +} + template <class ForwardIterator> void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20 + ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20 template <nothrow-forward-range ForwardRange> requires default_initializable<range_value_t<ForwardRange>> - borrowed_iterator_t<ForwardRange> ranges::uninitialized_value_construct(ForwardRange&& r); // since C++20 + borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20 + +} template <class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class ForwardIterator> void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20 + ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20 template <nothrow-forward-range ForwardRange> requires default_initializable<range_value_t<ForwardRange>> - borrowed_iterator_t<ForwardRange> ranges::uninitialized_default_construct(ForwardRange&& r); // since C++20 + borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20 + +} template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 @@ -708,6 +815,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <__memory/concepts.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__memory/ranges_construct_at.h> #include <__memory/ranges_uninitialized_algorithms.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 1dc6db406a74..90fae9bb8362 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -246,6 +246,8 @@ module std [system] { module generate { private header "__algorithm/generate.h" } module generate_n { private header "__algorithm/generate_n.h" } module half_positive { private header "__algorithm/half_positive.h" } + module in_in_result { private header "__algorithm/in_in_result.h" } + module in_out_result { private header "__algorithm/in_out_result.h" } module includes { private header "__algorithm/includes.h" } module inplace_merge { private header "__algorithm/inplace_merge.h" } module is_heap { private header "__algorithm/is_heap.h" } @@ -362,6 +364,17 @@ module std [system] { module chrono { header "chrono" export * + + module __chrono { + module calendar { private header "__chrono/calendar.h" } + module convert_to_timespec { private header "__chrono/convert_to_timespec.h" } + module duration { private header "__chrono/duration.h" } + module file_clock { private header "__chrono/file_clock.h" } + module high_resolution_clock { private header "__chrono/high_resolution_clock.h" } + module steady_clock { private header "__chrono/steady_clock.h" } + module system_clock { private header "__chrono/system_clock.h" } + module time_point { private header "__chrono/time_point.h" } + } } module codecvt { header "codecvt" @@ -430,8 +443,8 @@ module std [system] { module __coroutine { module coroutine_handle { private header "__coroutine/coroutine_handle.h" } module coroutine_traits { private header "__coroutine/coroutine_traits.h" } - module trivial_awaitables { private header "__coroutine/trivial_awaitables.h" } module noop_coroutine_handle { private header "__coroutine/noop_coroutine_handle.h" } + module trivial_awaitables { private header "__coroutine/trivial_awaitables.h" } } } module deque { @@ -461,8 +474,8 @@ module std [system] { module file_type { private header "__filesystem/file_type.h" } module filesystem_error { private header "__filesystem/filesystem_error.h" } module operations { private header "__filesystem/operations.h" } - module path_iterator { private header "__filesystem/path_iterator.h" } module path { private header "__filesystem/path.h" } + module path_iterator { private header "__filesystem/path_iterator.h" } module perm_options { private header "__filesystem/perm_options.h" } module perms { private header "__filesystem/perms.h" } module recursive_directory_iterator { private header "__filesystem/recursive_directory_iterator.h" } @@ -475,25 +488,27 @@ module std [system] { export * module __format { - module format_arg { private header "__format/format_arg.h" } - module format_args { private header "__format/format_args.h" } + module format_arg { private header "__format/format_arg.h" } + module format_args { private header "__format/format_args.h" } module format_context { private header "__format/format_context.h" export optional export locale } - module format_error { private header "__format/format_error.h" } - module format_fwd { private header "__format/format_fwd.h" } - module format_parse_context { private header "__format/format_parse_context.h" } - module format_string { private header "__format/format_string.h" } - module format_to_n_result { private header "__format/format_to_n_result.h" } - module formatter { private header "__format/formatter.h" } - module formatter_bool { private header "__format/formatter_bool.h" } - module formatter_char { private header "__format/formatter_char.h" } - module formatter_integer { private header "__format/formatter_integer.h" } - module formatter_integral { private header "__format/formatter_integral.h" } - module formatter_string { private header "__format/formatter_string.h" } - module parser_std_format_spec { private header "__format/parser_std_format_spec.h" } + module format_error { private header "__format/format_error.h" } + module format_fwd { private header "__format/format_fwd.h" } + module format_parse_context { private header "__format/format_parse_context.h" } + module format_string { private header "__format/format_string.h" } + module format_to_n_result { private header "__format/format_to_n_result.h" } + module formatter { private header "__format/formatter.h" } + module formatter_bool { private header "__format/formatter_bool.h" } + module formatter_char { private header "__format/formatter_char.h" } + module formatter_floating_point { private header "__format/formatter_floating_point.h" } + module formatter_integer { private header "__format/formatter_integer.h" } + module formatter_integral { private header "__format/formatter_integral.h" } + module formatter_pointer { private header "__format/formatter_pointer.h" } + module formatter_string { private header "__format/formatter_string.h" } + module parser_std_format_spec { private header "__format/parser_std_format_spec.h" } } } module forward_list { @@ -579,10 +594,7 @@ module std [system] { module __iterator { module access { private header "__iterator/access.h" } - module advance { - private header "__iterator/advance.h" - export __function_like - } + module advance { private header "__iterator/advance.h" } module back_insert_iterator { private header "__iterator/back_insert_iterator.h" } module common_iterator { private header "__iterator/common_iterator.h" } module concepts { private header "__iterator/concepts.h" } @@ -594,6 +606,7 @@ module std [system] { module erase_if_container { private header "__iterator/erase_if_container.h" } module front_insert_iterator { private header "__iterator/front_insert_iterator.h" } module incrementable_traits { private header "__iterator/incrementable_traits.h" } + module indirectly_comparable { private header "__iterator/indirectly_comparable.h" } module insert_iterator { private header "__iterator/insert_iterator.h" } module istream_iterator { private header "__iterator/istream_iterator.h" } module istreambuf_iterator { private header "__iterator/istreambuf_iterator.h" } @@ -602,16 +615,10 @@ module std [system] { module iterator { private header "__iterator/iterator.h" } module iterator_traits { private header "__iterator/iterator_traits.h" } module move_iterator { private header "__iterator/move_iterator.h" } - module next { - private header "__iterator/next.h" - export __function_like - } + module next { private header "__iterator/next.h" } module ostream_iterator { private header "__iterator/ostream_iterator.h" } module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" } - module prev { - private header "__iterator/prev.h" - export __function_like - } + module prev { private header "__iterator/prev.h" } module projected { private header "__iterator/projected.h" } module readable_traits { private header "__iterator/readable_traits.h" } module reverse_access { private header "__iterator/reverse_access.h" } @@ -659,10 +666,8 @@ module std [system] { module concepts { private header "__memory/concepts.h" } module construct_at { private header "__memory/construct_at.h" } module pointer_traits { private header "__memory/pointer_traits.h" } - module ranges_uninitialized_algorithms { - private header "__memory/ranges_uninitialized_algorithms.h" - export __function_like - } + module ranges_construct_at { private header "__memory/ranges_construct_at.h" } + module ranges_uninitialized_algorithms { private header "__memory/ranges_uninitialized_algorithms.h" } module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } module shared_ptr { private header "__memory/shared_ptr.h" } module temporary_buffer { private header "__memory/temporary_buffer.h" } @@ -793,11 +798,12 @@ module std [system] { module iota_view { private header "__ranges/iota_view.h" } module join_view { private header "__ranges/join_view.h" } module non_propagating_cache { private header "__ranges/non_propagating_cache.h" } + module owning_view { private header "__ranges/owning_view.h" } module range_adaptor { private header "__ranges/range_adaptor.h" } module ref_view { private header "__ranges/ref_view.h" } module reverse_view { private header "__ranges/reverse_view.h" } - module size { private header "__ranges/size.h" } module single_view { private header "__ranges/single_view.h" } + module size { private header "__ranges/size.h" } module subrange { private header "__ranges/subrange.h" } module take_view { private header "__ranges/take_view.h" } module transform_view { @@ -884,7 +890,8 @@ module std [system] { export * module __thread { - module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module timed_backoff_policy { private header "__thread/timed_backoff_policy.h" } } } module tuple { @@ -968,10 +975,9 @@ module std [system] { module __bits { private header "__bits" export * } module __debug { header "__debug" export * } module __errc { private header "__errc" export * } - module __function_like { private header "__function_like.h" export * } module __hash_table { header "__hash_table" export * } module __locale { private header "__locale" export * } - module __mbstate { private header "__mbstate_t.h" export * } + module __mbstate_t { private header "__mbstate_t.h" export * } module __mutex_base { private header "__mutex_base" export * } module __node_handle { private header "__node_handle" export * } module __nullptr { header "__nullptr" export * } diff --git a/libcxx/include/numbers b/libcxx/include/numbers index ede4e33c7a88..2ac36695b888 100644 --- a/libcxx/include/numbers +++ b/libcxx/include/numbers @@ -73,42 +73,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace numbers { -template <class T> +template <class _Tp> inline constexpr bool __false = false; -template <class T> +template <class _Tp> struct __illformed { - static_assert(__false<T>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); + static_assert(__false<_Tp>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); }; -template <class T> inline constexpr T e_v = __illformed<T>{}; -template <class T> inline constexpr T log2e_v = __illformed<T>{}; -template <class T> inline constexpr T log10e_v = __illformed<T>{}; -template <class T> inline constexpr T pi_v = __illformed<T>{}; -template <class T> inline constexpr T inv_pi_v = __illformed<T>{}; -template <class T> inline constexpr T inv_sqrtpi_v = __illformed<T>{}; -template <class T> inline constexpr T ln2_v = __illformed<T>{}; -template <class T> inline constexpr T ln10_v = __illformed<T>{}; -template <class T> inline constexpr T sqrt2_v = __illformed<T>{}; -template <class T> inline constexpr T sqrt3_v = __illformed<T>{}; -template <class T> inline constexpr T inv_sqrt3_v = __illformed<T>{}; -template <class T> inline constexpr T egamma_v = __illformed<T>{}; -template <class T> inline constexpr T phi_v = __illformed<T>{}; - -template <floating_point T> inline constexpr T e_v<T> = 2.718281828459045235360287471352662; -template <floating_point T> inline constexpr T log2e_v<T> = 1.442695040888963407359924681001892; -template <floating_point T> inline constexpr T log10e_v<T> = 0.434294481903251827651128918916605; -template <floating_point T> inline constexpr T pi_v<T> = 3.141592653589793238462643383279502; -template <floating_point T> inline constexpr T inv_pi_v<T> = 0.318309886183790671537767526745028; -template <floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772; -template <floating_point T> inline constexpr T ln2_v<T> = 0.693147180559945309417232121458176; -template <floating_point T> inline constexpr T ln10_v<T> = 2.302585092994045684017991454684364; -template <floating_point T> inline constexpr T sqrt2_v<T> = 1.414213562373095048801688724209698; -template <floating_point T> inline constexpr T sqrt3_v<T> = 1.732050807568877293527446341505872; -template <floating_point T> inline constexpr T inv_sqrt3_v<T> = 0.577350269189625764509148780501957; -template <floating_point T> inline constexpr T egamma_v<T> = 0.577215664901532860606512090082402; -template <floating_point T> inline constexpr T phi_v<T> = 1.618033988749894848204586834365638; +template <class _Tp> inline constexpr _Tp e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp log2e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp log10e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp pi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_pi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_sqrtpi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp ln2_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp ln10_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp sqrt2_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp sqrt3_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_sqrt3_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp egamma_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp phi_v = __illformed<_Tp>{}; + +template <floating_point _Tp> inline constexpr _Tp e_v<_Tp> = 2.718281828459045235360287471352662; +template <floating_point _Tp> inline constexpr _Tp log2e_v<_Tp> = 1.442695040888963407359924681001892; +template <floating_point _Tp> inline constexpr _Tp log10e_v<_Tp> = 0.434294481903251827651128918916605; +template <floating_point _Tp> inline constexpr _Tp pi_v<_Tp> = 3.141592653589793238462643383279502; +template <floating_point _Tp> inline constexpr _Tp inv_pi_v<_Tp> = 0.318309886183790671537767526745028; +template <floating_point _Tp> inline constexpr _Tp inv_sqrtpi_v<_Tp> = 0.564189583547756286948079451560772; +template <floating_point _Tp> inline constexpr _Tp ln2_v<_Tp> = 0.693147180559945309417232121458176; +template <floating_point _Tp> inline constexpr _Tp ln10_v<_Tp> = 2.302585092994045684017991454684364; +template <floating_point _Tp> inline constexpr _Tp sqrt2_v<_Tp> = 1.414213562373095048801688724209698; +template <floating_point _Tp> inline constexpr _Tp sqrt3_v<_Tp> = 1.732050807568877293527446341505872; +template <floating_point _Tp> inline constexpr _Tp inv_sqrt3_v<_Tp> = 0.577350269189625764509148780501957; +template <floating_point _Tp> inline constexpr _Tp egamma_v<_Tp> = 0.577215664901532860606512090082402; +template <floating_point _Tp> inline constexpr _Tp phi_v<_Tp> = 1.618033988749894848204586834365638; inline constexpr double e = e_v<double>; inline constexpr double log2e = log2e_v<double>; diff --git a/libcxx/include/optional b/libcxx/include/optional index 63753d9f9f03..917e9b5cdb57 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -1167,8 +1167,8 @@ public: }; #if _LIBCPP_STD_VER >= 17 -template<class T> - optional(T) -> optional<T>; +template<class _Tp> + optional(_Tp) -> optional<_Tp>; #endif // Comparisons between optionals diff --git a/libcxx/include/queue b/libcxx/include/queue index 03081eb844ba..9e1257b25e0e 100644 --- a/libcxx/include/queue +++ b/libcxx/include/queue @@ -41,6 +41,8 @@ public: explicit queue(const container_type& c); explicit queue(container_type&& c) + template<class InputIterator> + queue(InputIterator first, InputIterator last); // since C++23 template <class Alloc> explicit queue(const Alloc& a); template <class Alloc> @@ -51,6 +53,8 @@ public: queue(const queue& q, const Alloc& a); template <class Alloc> queue(queue&& q, const Alloc& a); + template <class InputIterator, class Alloc> + queue(InputIterator first, InputIterator last, const Alloc&); // since C++23 bool empty() const; size_type size() const; @@ -71,9 +75,17 @@ public: template<class Container> queue(Container) -> queue<typename Container::value_type, Container>; // C++17 +template<class InputIterator> + queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23 + template<class Container, class Allocator> queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17 +template<class InputIterator, class Allocator> + queue(InputIterator, InputIterator, Allocator) + -> queue<iter-value-type<InputIterator>, + deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 + template <class T, class Container> bool operator==(const queue<T, Container>& x,const queue<T, Container>& y); @@ -206,13 +218,16 @@ template <class T, class Container, class Compare> */ #include <__config> +#include <__iterator/iterator_traits.h> #include <__memory/uses_allocator.h> #include <__utility/forward.h> #include <algorithm> #include <compare> #include <deque> #include <functional> +#include <type_traits> #include <vector> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -255,6 +270,20 @@ public: _LIBCPP_INLINE_VISIBILITY queue(const queue& __q) : c(__q.c) {} +#if _LIBCPP_STD_VER > 20 + template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> + _LIBCPP_HIDE_FROM_ABI + queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} + + template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> + _LIBCPP_HIDE_FROM_ABI + queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {} +#endif + _LIBCPP_INLINE_VISIBILITY queue& operator=(const queue& __q) {c = __q.c; return *this;} @@ -358,7 +387,7 @@ public: operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template<class _Container, class = enable_if_t<!__is_allocator<_Container>::value> > @@ -374,6 +403,20 @@ queue(_Container, _Alloc) -> queue<typename _Container::value_type, _Container>; #endif +#if _LIBCPP_STD_VER > 20 +template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> +queue(_InputIterator, _InputIterator) + -> queue<__iter_value_type<_InputIterator>>; + +template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<__is_allocator<_Alloc>::value>> +queue(_InputIterator, _InputIterator, _Alloc) + -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; +#endif + template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY bool diff --git a/libcxx/include/random b/libcxx/include/random index c88bfce03b19..2e271cec46ad 100644 --- a/libcxx/include/random +++ b/libcxx/include/random @@ -1715,6 +1715,7 @@ class piecewise_linear_distribution #include <__random/uniform_real_distribution.h> #include <__random/weibull_distribution.h> #include <initializer_list> +#include <version> #include <algorithm> // for backward compatibility; TODO remove it #include <cmath> // for backward compatibility; TODO remove it diff --git a/libcxx/include/ranges b/libcxx/include/ranges index dd7decf66fa8..eb4492376c5c 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -135,6 +135,13 @@ namespace std::ranges { template<class T> inline constexpr bool enable_borrowed_range<ref_view<T>> = true; + template<range R> + requires see below + class owning_view; + + template<class T> + inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>; + // [range.drop], drop view template<view V> class drop_view; @@ -207,8 +214,8 @@ namespace std::ranges { #include <__ranges/dangling.h> #include <__ranges/data.h> #include <__ranges/drop_view.h> -#include <__ranges/empty_view.h> #include <__ranges/empty.h> +#include <__ranges/empty_view.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/iota_view.h> diff --git a/libcxx/include/ratio b/libcxx/include/ratio index 16b45a28ed8b..8859261208d0 100644 --- a/libcxx/include/ratio +++ b/libcxx/include/ratio @@ -81,6 +81,7 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported #include <climits> #include <cstdint> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/regex b/libcxx/include/regex index 8203c81659c8..59b2c9a23399 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -1310,19 +1310,51 @@ regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const return (__c == '_' && (__m & __regex_word)); } +inline _LIBCPP_INLINE_VISIBILITY +bool __is_07(unsigned char c) +{ + return (c & 0xF8u) == +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + 0xF0; +#else + 0x30; +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +bool __is_89(unsigned char c) +{ + return (c & 0xFEu) == +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + 0xF8; +#else + 0x38; +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned char __to_lower(unsigned char c) +{ +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + return c & 0xBF; +#else + return c | 0x20; +#endif +} + template <class _CharT> int regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix) { - if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7' + if (__is_07(__ch)) // '0' <= __ch && __ch <= '7' return __ch - '0'; if (__radix != 8) { - if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9' + if (__is_89(__ch)) // '8' <= __ch && __ch <= '9' return __ch - '0'; if (__radix == 16) { - __ch |= 0x20; // tolower + __ch = __to_lower(__ch); // tolower if ('a' <= __ch && __ch <= 'f') return __ch - ('a' - 10); } diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore index 2c2518bce46a..7dffc94b13ba 100644 --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -47,8 +47,10 @@ using binary_semaphore = counting_semaphore<1>; #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include <atomic> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/sstream b/libcxx/include/sstream index e63d1434ac76..6ad624a93a65 100644 --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -184,6 +184,7 @@ typedef basic_stringstream<wchar_t> wstringstream; #include <istream> #include <ostream> #include <string> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/stack b/libcxx/include/stack index 5d959c33c742..ad65d7b29b4f 100644 --- a/libcxx/include/stack +++ b/libcxx/include/stack @@ -41,11 +41,14 @@ public: explicit stack(const container_type& c); explicit stack(container_type&& c); + template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23 template <class Alloc> explicit stack(const Alloc& a); template <class Alloc> stack(const container_type& c, const Alloc& a); template <class Alloc> stack(container_type&& c, const Alloc& a); template <class Alloc> stack(const stack& c, const Alloc& a); template <class Alloc> stack(stack&& c, const Alloc& a); + template<class InputIterator, class Alloc> + stack(InputIterator first, InputIterator last, const Alloc&); // since C++23 bool empty() const; size_type size() const; @@ -63,9 +66,17 @@ public: template<class Container> stack(Container) -> stack<typename Container::value_type, Container>; // C++17 +template<class InputIterator> + stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23 + template<class Container, class Allocator> stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17 +template<class InputIterator, class Allocator> + stack(InputIterator, InputIterator, Allocator) + -> stack<iter-value-type<InputIterator>, + deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 + template <class T, class Container> bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); template <class T, class Container> @@ -88,9 +99,12 @@ template <class T, class Container> */ #include <__config> +#include <__iterator/iterator_traits.h> #include <__memory/uses_allocator.h> #include <__utility/forward.h> #include <deque> +#include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -183,6 +197,20 @@ public: : c(_VSTD::move(__s.c), __a) {} #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 20 + template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> + _LIBCPP_HIDE_FROM_ABI + stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} + + template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> + _LIBCPP_HIDE_FROM_ABI + stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {} +#endif + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool empty() const {return c.empty();} _LIBCPP_INLINE_VISIBILITY @@ -231,7 +259,7 @@ public: operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template<class _Container, class = enable_if_t<!__is_allocator<_Container>::value> > @@ -247,6 +275,20 @@ stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>; #endif +#if _LIBCPP_STD_VER > 20 +template<class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> +stack(_InputIterator, _InputIterator) + -> stack<__iter_value_type<_InputIterator>>; + +template<class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<__is_allocator<_Alloc>::value>> +stack(_InputIterator, _InputIterator, _Alloc) + -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; +#endif + template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY bool diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept index c1dc05669bb9..5df2050ee4ec 100644 --- a/libcxx/include/stdexcept +++ b/libcxx/include/stdexcept @@ -42,9 +42,9 @@ public: */ #include <__config> +#include <cstdlib> #include <exception> #include <iosfwd> // for string forward decl -#include <cstdlib> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf index db3078d809a5..9874ec2ce499 100644 --- a/libcxx/include/streambuf +++ b/libcxx/include/streambuf @@ -108,8 +108,10 @@ protected: */ #include <__config> +#include <cstdint> #include <ios> #include <iosfwd> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/string b/libcxx/include/string index 9049d7acbb9b..3616de8a214d 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -158,6 +158,9 @@ public: void resize(size_type n, value_type c); void resize(size_type n); + template<class Operation> + constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 + void reserve(size_type res_arg); void reserve(); // deprecated in C++20 void shrink_to_fit(); @@ -615,6 +618,7 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) +#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS template <bool> struct __basic_string_common; @@ -624,6 +628,7 @@ struct __basic_string_common<true> { _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; }; +#endif template <class _Iter> struct __string_is_trivial_iterator : public false_type {}; @@ -677,7 +682,9 @@ class _LIBCPP_PREFERRED_NAME(u32string) #endif basic_string +#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS : private __basic_string_common<true> // This base class is historical, but it needs to remain for ABI compatibility +#endif { public: typedef basic_string __self; @@ -826,10 +833,7 @@ public: 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)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > @@ -973,6 +977,16 @@ public: _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} 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))); + } +#endif + _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY @@ -1455,6 +1469,11 @@ public: #endif // _LIBCPP_DEBUG_LEVEL == 2 private: + _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); + } + _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() _NOEXCEPT {return __r_.second();} @@ -1714,20 +1733,12 @@ private: _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_length_error(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_length_error("basic_string"); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_out_of_range(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_out_of_range("basic_string"); } friend basic_string operator+<>(const basic_string&, const basic_string&); @@ -1827,10 +1838,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) : __r_(__default_init_tag(), __default_init_tag()) { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1844,10 +1852,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #endif : __r_(__default_init_tag(), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1857,9 +1862,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __reserve) { if (__reserve > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__reserve < __min_cap) + if (__fits_in_sso(__reserve)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1881,9 +1886,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1907,10 +1912,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1918,12 +1920,9 @@ inline 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); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); + __init(__s, __n); + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1933,10 +1932,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1948,11 +1944,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1965,22 +1957,19 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { pointer __p; - if (__sz < __min_cap) { + if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); __set_short_size(__sz); } else { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); size_t __cap = __recommend(__sz); __p = __alloc_traits::allocate(__alloc(), __cap + 1); __set_long_pointer(__p); @@ -2003,12 +1992,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) : __r_(_VSTD::move(__str.__r_)) { __str.__zero(); + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) { - __get_db()->__insert_c(this); - if (__is_long()) - __get_db()->swap(this, &__str); - } + if (!__libcpp_is_constant_evaluated() && __is_long()) + __get_db()->swap(this, &__str); #endif } @@ -2024,12 +2011,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, co __r_.first().__r = __str.__r_.first().__r; __str.__zero(); } + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) { - __get_db()->__insert_c(this); - if (__is_long()) - __get_db()->swap(this, &__str); - } + if (!__libcpp_is_constant_evaluated() && __is_long()) + __get_db()->swap(this, &__str); #endif } @@ -2040,9 +2025,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { if (__n > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__n < __min_cap) + if (__fits_in_sso(__n)) { __set_short_size(__n); __p = __get_short_pointer(); @@ -2065,10 +2050,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2077,10 +2059,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __a) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2091,12 +2070,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2107,12 +2083,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, __str_sz - __pos); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2124,10 +2097,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2137,10 +2107,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2150,10 +2117,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _ { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2192,9 +2156,9 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For { size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -2233,10 +2197,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2247,10 +2208,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __a) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #ifndef _LIBCPP_CXX03_LANG @@ -2262,10 +2220,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2276,10 +2231,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #endif // _LIBCPP_CXX03_LANG @@ -2303,7 +2255,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) - this->__throw_length_error(); + __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)) : @@ -2335,7 +2287,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap) - this->__throw_length_error(); + __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)) : @@ -2398,7 +2350,7 @@ basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); - return (__builtin_constant_p(__n) && __n < __min_cap) + return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); } @@ -2567,7 +2519,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2584,7 +2536,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2601,7 +2553,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); return __builtin_constant_p(*__s) - ? (traits_type::length(__s) < __min_cap + ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) : __assign_external(__s, traits_type::length(__s))) : __assign_external(__s); @@ -2753,7 +2705,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2769,7 +2721,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2790,7 +2742,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __cap = capacity(); if (__cap - __sz >= __n) { @@ -2821,7 +2773,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); if (__n) { size_type __cap = capacity(); @@ -2927,7 +2879,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } @@ -2944,7 +2896,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } @@ -3005,7 +2957,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) @@ -3052,7 +3004,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); value_type* __p; @@ -3086,7 +3038,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it _InputIterator __j1, _InputIterator __j2) { const basic_string __temp(__j1, __j2, __alloc()); - return this->replace(__i1, __i2, __temp); + return replace(__i1, __i2, __temp); } template <class _CharT, class _Traits, class _Allocator> @@ -3104,7 +3056,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } @@ -3121,7 +3073,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } @@ -3191,7 +3143,8 @@ template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { - if (__pos > size()) this->__throw_out_of_range(); + if (__pos > size()) + __throw_out_of_range(); if (__n == npos) { __erase_to_end(__pos); } else { @@ -3307,12 +3260,13 @@ void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { if (__requested_capacity > max_size()) - this->__throw_length_error(); + __throw_length_error(); -#if _LIBCPP_STD_VER > 17 - // Reserve never shrinks as of C++20. - if (__requested_capacity <= capacity()) return; -#endif + // Make sure reserve(n) never shrinks. This is technically only required in C++20 + // and later (since P0966R1), however we provide consistent behavior in all Standard + // modes because this function is instantiated in the shared library. + if (__requested_capacity <= capacity()) + return; size_type __target_capacity = _VSTD::max(__requested_capacity, size()); __target_capacity = __recommend(__target_capacity); @@ -3413,7 +3367,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3422,7 +3376,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3468,7 +3422,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n, __sz - __pos); traits_type::copy(__s, data() + __pos, __rlen); return __rlen; @@ -3912,7 +3866,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); size_type __sz = size(); if (__pos1 > __sz || __n2 == npos) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n1, __sz - __pos1); int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); if (__r == 0) @@ -3976,7 +3930,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __pos2, size_type __n2) const { - return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); + return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } template <class _CharT, class _Traits, class _Allocator> @@ -4490,16 +4444,16 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return this->data() <= _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) < this->data() + this->size(); + return data() <= _VSTD::__to_address(__i->base()) && + _VSTD::__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 this->data() < _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) <= this->data() + this->size(); + return data() < _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4507,7 +4461,7 @@ 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; - return this->data() <= __p && __p <= this->data() + this->size(); + return data() <= __p && __p <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4515,7 +4469,7 @@ 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; - return this->data() <= __p && __p < this->data() + this->size(); + return data() <= __p && __p < data() + size(); } #endif // _LIBCPP_DEBUG_LEVEL == 2 diff --git a/libcxx/include/strstream b/libcxx/include/strstream index a5f17a9dc319..c34a5628b634 100644 --- a/libcxx/include/strstream +++ b/libcxx/include/strstream @@ -132,6 +132,7 @@ private: #include <__config> #include <istream> #include <ostream> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/system_error b/libcxx/include/system_error index 059fa0e2d511..6d3a6ca65038 100644 --- a/libcxx/include/system_error +++ b/libcxx/include/system_error @@ -150,6 +150,7 @@ template <> struct hash<std::error_condition>; #include <stdexcept> #include <string> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/thread b/libcxx/include/thread index a4632f6fe524..27756e42cdcb 100644 --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -87,6 +87,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <__functional_base> #include <__mutex_base> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include <__utility/forward.h> #include <chrono> @@ -97,6 +98,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <system_error> #include <tuple> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 8ee5c2eef51d..5cf120fec359 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -73,6 +73,19 @@ public: void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20 }; + +template<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23 + requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; } +struct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> { + using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; +}; + +template<class... TTypes, class... UTypes> // since C++23 + requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; } +struct common_type<tuple<TTypes...>, tuple<UTypes...>> { + using type = tuple<common_type_t<TTypes, UTypes>...>; +}; + template <class ...T> tuple(T...) -> tuple<T...>; // since C++17 template <class T1, class T2> @@ -1103,7 +1116,21 @@ public: void swap(tuple&) _NOEXCEPT {} }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 20 +template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual> + requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } +struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> { + using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; +}; + +template <class... _TTypes, class... _UTypes> + requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; } +struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> { + using type = tuple<common_type_t<_TTypes, _UTypes>...>; +}; +#endif + +#if _LIBCPP_STD_VER > 14 template <class ..._Tp> tuple(_Tp...) -> tuple<_Tp...>; template <class _Tp1, class _Tp2> diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 155b775e4929..b4010851f133 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -2318,7 +2318,7 @@ struct __common_type_impl {}; // Clang provides variadic templates in C++03 as an extension. #if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__) # define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__ -template <class... Tp> +template <class... _Tp> struct __common_types; template <class... _Tp> struct _LIBCPP_TEMPLATE_VIS common_type; diff --git a/libcxx/include/typeindex b/libcxx/include/typeindex index 790aea4d4763..ede0c7fb25c2 100644 --- a/libcxx/include/typeindex +++ b/libcxx/include/typeindex @@ -49,6 +49,7 @@ struct hash<type_index> #include <__functional_base> #include <compare> #include <typeinfo> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index 53ddb95663d1..361db707d246 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -517,8 +517,9 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__config> #include <__debug> #include <__functional/is_transparent.h> -#include <__iterator/iterator_traits.h> #include <__hash_table> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> #include <__node_handle> #include <__utility/forward.h> #include <compare> @@ -1068,11 +1069,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_map(size_type __n, const hasher& __hf, @@ -1188,13 +1187,10 @@ public: {return __table_.__insert_unique(__x);} iterator insert(const_iterator __p, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not " + "referring to this unordered_map"); ((void)__p); -#endif return insert(__x).first; } @@ -1212,13 +1208,10 @@ public: {return __table_.__insert_unique(_VSTD::move(__x));} iterator insert(const_iterator __p, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return __table_.__insert_unique(_VSTD::move(__x)).first; } @@ -1233,13 +1226,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, _Pp&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return insert(_VSTD::forward<_Pp>(__x)).first; } @@ -1252,13 +1242,10 @@ public: template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } @@ -1287,13 +1274,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__h); -#endif return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } @@ -1301,13 +1285,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__h); -#endif return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } @@ -1625,9 +1606,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1637,9 +1616,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1649,9 +1626,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1659,9 +1634,7 @@ template <class _InputIterator> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -1672,9 +1645,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1686,9 +1657,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1698,9 +1667,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1710,9 +1677,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1726,9 +1691,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1737,9 +1702,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1750,7 +1713,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1758,9 +1721,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1770,9 +1731,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1783,9 +1742,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -2003,11 +1960,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multimap(size_type __n, const hasher& __hf, @@ -2427,9 +2382,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -2439,9 +2392,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -2450,9 +2401,7 @@ template <class _InputIterator> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -2463,9 +2412,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -2477,9 +2424,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -2490,9 +2435,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -2500,9 +2443,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2512,9 +2453,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2528,9 +2467,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2539,9 +2478,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -2553,7 +2490,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2561,9 +2498,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -2573,9 +2508,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -2586,9 +2519,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index 1b62e31bb918..29a19f2f0cb5 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -463,6 +463,7 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__debug> #include <__functional/is_transparent.h> #include <__hash_table> +#include <__memory/addressof.h> #include <__node_handle> #include <__utility/forward.h> #include <compare> @@ -524,11 +525,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); #if _LIBCPP_STD_VER > 11 @@ -642,7 +641,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_set"); return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; @@ -659,7 +658,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_set"); return insert(_VSTD::move(__x)).first; @@ -680,7 +679,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_set"); return insert(__x).first; @@ -935,9 +934,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -946,9 +943,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -957,9 +952,7 @@ template <class _InputIterator> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -970,9 +963,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -984,9 +975,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -997,9 +986,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1007,9 +994,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1019,9 +1004,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1035,9 +1018,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1046,9 +1029,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( unordered_set&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1057,7 +1038,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1065,9 +1046,7 @@ template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1077,9 +1056,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1090,9 +1067,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1223,11 +1198,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multiset(size_type __n, const hasher& __hf, @@ -1601,9 +1574,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1613,9 +1584,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1624,9 +1593,7 @@ template <class _InputIterator> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -1637,9 +1604,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1651,9 +1616,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1664,9 +1627,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1674,9 +1635,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1686,9 +1645,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1702,9 +1659,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1713,9 +1670,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( unordered_multiset&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1724,7 +1679,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1732,9 +1687,7 @@ template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1744,9 +1697,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1757,9 +1708,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } diff --git a/libcxx/include/valarray b/libcxx/include/valarray index 909e0422c476..a55d921872ba 100644 --- a/libcxx/include/valarray +++ b/libcxx/include/valarray @@ -348,6 +348,7 @@ template <class T> unspecified2 end(const valarray<T>& v); #include <functional> #include <initializer_list> #include <new> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/vector b/libcxx/include/vector index 9b0092cfdbd9..fd0fb0db2756 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -271,8 +271,8 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20 */ -#include <__config> #include <__bit_reference> +#include <__config> #include <__debug> #include <__functional_base> #include <__iterator/iterator_traits.h> @@ -373,11 +373,9 @@ public: _LIBCPP_INLINE_VISIBILITY vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) @@ -386,9 +384,7 @@ public: #endif : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } explicit vector(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -400,9 +396,7 @@ public: vector(size_type __n, const value_type& __x, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1101,9 +1095,7 @@ vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1116,9 +1108,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1130,9 +1120,7 @@ vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1150,9 +1138,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, typename iterator_traits<_InputIterator>::reference>::value, _InputIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1167,9 +1153,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c typename iterator_traits<_InputIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1183,9 +1167,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, typename iterator_traits<_ForwardIterator>::reference>::value, _ForwardIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1203,9 +1185,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las typename iterator_traits<_ForwardIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1218,9 +1198,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(const vector& __x) : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = __x.size(); if (__n > 0) { @@ -1233,9 +1211,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = __x.size(); if (__n > 0) { @@ -1256,8 +1232,8 @@ vector<_Tp, _Allocator>::vector(vector&& __x) #endif : __base(_VSTD::move(__x.__alloc())) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); __get_db()->swap(this, _VSTD::addressof(__x)); #endif this->__begin_ = __x.__begin_; @@ -1271,9 +1247,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a == __x.__alloc()) { this->__begin_ = __x.__begin_; @@ -1295,9 +1269,7 @@ template <class _Tp, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__il.size() > 0) { __vallocate(__il.size()); @@ -1310,9 +1282,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__il.size() > 0) { __vallocate(__il.size()); @@ -1677,11 +1647,8 @@ inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::erase(iterator) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::erase(iterator) called with an iterator not referring to this vector"); _LIBCPP_ASSERT(__position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); @@ -1696,14 +1663,11 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, - "vector::erase(iterator, iterator) called with an iterator not" - " referring to this vector"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, - "vector::erase(iterator, iterator) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); + _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); if (__first != __last) { @@ -1737,11 +1701,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1774,11 +1735,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1807,11 +1765,8 @@ template <class... _Args> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::emplace(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::emplace(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1842,11 +1797,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, n, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, n, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (__n > 0) { @@ -1893,11 +1845,8 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, range) called with an iterator not referring to this vector"); difference_type __off = __position - begin(); pointer __p = this->__begin_ + __off; allocator_type& __a = this->__alloc(); @@ -1946,11 +1895,8 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, range) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); difference_type __n = _VSTD::distance(__first, __last); if (__n > 0) diff --git a/libcxx/include/version b/libcxx/include/version index 574dfe47b58f..0c2365612853 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -14,7 +14,9 @@ version synopsis Macro name Value Headers +__cpp_lib_adaptor_iterator_pair_constructor 202106L <queue> <stack> __cpp_lib_addressof_constexpr 201603L <memory> +__cpp_lib_allocate_at_least 202106L <memory> __cpp_lib_allocator_traits_is_always_equal 201411L <deque> <forward_list> <list> <map> <memory> <scoped_allocator> <set> <string> <unordered_map> @@ -24,6 +26,8 @@ __cpp_lib_apply 201603L <tuple> __cpp_lib_array_constexpr 201811L <array> <iterator> 201603L // C++17 __cpp_lib_as_const 201510L <utility> +__cpp_lib_associative_heterogeneous_erasure 202110L <map> <set> <unordered_map> + <unordered_set> __cpp_lib_assume_aligned 201811L <memory> __cpp_lib_atomic_flag_test 201907L <atomic> __cpp_lib_atomic_float 201711L <atomic> @@ -60,6 +64,7 @@ __cpp_lib_constexpr_numeric 201911L <numeric> __cpp_lib_constexpr_string 201811L <string> __cpp_lib_constexpr_string_view 201811L <string_view> __cpp_lib_constexpr_tuple 201811L <tuple> +__cpp_lib_constexpr_typeinfo 202106L <typeinfo> __cpp_lib_constexpr_utility 201811L <utility> __cpp_lib_constexpr_vector 201907L <vector> __cpp_lib_coroutine 201902L <coroutine> @@ -87,6 +92,7 @@ __cpp_lib_integer_sequence 201304L <utility> __cpp_lib_integral_constant_callable 201304L <type_traits> __cpp_lib_interpolate 201902L <cmath> <numeric> __cpp_lib_invoke 201411L <functional> +__cpp_lib_invoke_r 202106L <functional> __cpp_lib_is_aggregate 201703L <type_traits> __cpp_lib_is_constant_evaluated 201811L <type_traits> __cpp_lib_is_final 201402L <type_traits> @@ -110,6 +116,7 @@ __cpp_lib_math_constants 201907L <numbers> __cpp_lib_math_special_functions 201603L <cmath> __cpp_lib_memory_resource 201603L <memory_resource> __cpp_lib_monadic_optional 202110L <optional> +__cpp_lib_move_only_function 202110L <functional> __cpp_lib_node_extract 201606L <map> <set> <unordered_map> <unordered_set> __cpp_lib_nonmember_container_access 201411L <array> <deque> <forward_list> @@ -119,11 +126,14 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque> __cpp_lib_not_fn 201603L <functional> __cpp_lib_null_iterators 201304L <iterator> __cpp_lib_optional 201606L <optional> +__cpp_lib_out_ptr 202106L <memory> __cpp_lib_parallel_algorithm 201603L <algorithm> <numeric> -__cpp_lib_polymorphic_allocator 201902L <memory> +__cpp_lib_polymorphic_allocator 201902L <memory_resource> __cpp_lib_quoted_string_io 201304L <iomanip> __cpp_lib_ranges 201811L <algorithm> <functional> <iterator> <memory> <ranges> +__cpp_lib_ranges_starts_ends_with 202106L <algorithm> +__cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility> __cpp_lib_raw_memory_algorithms 201606L <memory> __cpp_lib_remove_cvref 201711L <type_traits> __cpp_lib_result_of_sfinae 201210L <functional> <type_traits> @@ -139,11 +149,13 @@ __cpp_lib_shift 201806L <algorithm> __cpp_lib_smart_ptr_for_overwrite 202002L <memory> __cpp_lib_source_location 201907L <source_location> __cpp_lib_span 202002L <span> +__cpp_lib_spanstream 202106L <spanstream> __cpp_lib_ssize 201902L <iterator> __cpp_lib_stacktrace 202011L <stacktrace> __cpp_lib_starts_ends_with 201711L <string> <string_view> __cpp_lib_stdatomic_h 202011L <stdatomic.h> __cpp_lib_string_contains 202011L <string> <string_view> +__cpp_lib_string_resize_and_overwrite 202110L <string> __cpp_lib_string_udls 201304L <string> __cpp_lib_string_view 201803L <string> <string_view> 201606L // C++17 @@ -158,6 +170,7 @@ __cpp_lib_transparent_operators 201510L <functional> <me 201210L // C++14 __cpp_lib_tuple_element_t 201402L <tuple> __cpp_lib_tuples_by_type 201304L <tuple> <utility> +__cpp_lib_type_identity 201806L <type_traits> __cpp_lib_type_trait_variable_templates 201510L <type_traits> __cpp_lib_uncaught_exceptions 201411L <exception> __cpp_lib_unordered_map_try_emplace 201411L <unordered_map> @@ -342,16 +355,28 @@ __cpp_lib_void_t 201411L <type_traits> // # define __cpp_lib_three_way_comparison 201907L # define __cpp_lib_to_address 201711L # define __cpp_lib_to_array 201907L +# define __cpp_lib_type_identity 201806L # define __cpp_lib_unwrap_ref 201811L #endif #if _LIBCPP_STD_VER > 20 +# define __cpp_lib_adaptor_iterator_pair_constructor 202106L +// # define __cpp_lib_allocate_at_least 202106L +// # define __cpp_lib_associative_heterogeneous_erasure 202110L # define __cpp_lib_byteswap 202110L +// # define __cpp_lib_constexpr_typeinfo 202106L +// # define __cpp_lib_invoke_r 202106L # define __cpp_lib_is_scoped_enum 202011L # define __cpp_lib_monadic_optional 202110L +// # define __cpp_lib_move_only_function 202110L +// # define __cpp_lib_out_ptr 202106L +// # define __cpp_lib_ranges_starts_ends_with 202106L +// # define __cpp_lib_ranges_zip 202110L +// # define __cpp_lib_spanstream 202106L // # define __cpp_lib_stacktrace 202011L // # define __cpp_lib_stdatomic_h 202011L # define __cpp_lib_string_contains 202011L +# define __cpp_lib_string_resize_and_overwrite 202110L # define __cpp_lib_to_underlying 202102L #endif |