`<tuple>`: Becomes a core header (#2730)

This commit is contained in:
A. Jiang 2022-06-02 08:24:43 +08:00 коммит произвёл GitHub
Родитель ae710e7b07
Коммит 87b1f5d134
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 552 добавлений и 509 удалений

Просмотреть файл

@ -6,6 +6,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_chrono.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_format_ucd_tables.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_int128.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_iter_core.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_system_error_abi.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_tzdb.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_xlocinfo_types.hpp

Просмотреть файл

@ -49,6 +49,7 @@
#include <numbers>
#include <ratio>
#include <source_location>
#include <tuple>
#include <type_traits>
#include <utility>
#include <version>
@ -128,7 +129,6 @@
#include <strstream>
#include <syncstream>
#include <system_error>
#include <tuple>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>

Просмотреть файл

@ -0,0 +1,525 @@
// __msvc_iter_core.hpp internal header (core)
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#pragma once
#ifndef __MSVC_ITER_CORE_HPP
#define __MSVC_ITER_CORE_HPP
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <utility>
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
_STD_BEGIN
// from <iterator>
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : input_iterator_tag {};
struct bidirectional_iterator_tag : forward_iterator_tag {};
struct random_access_iterator_tag : bidirectional_iterator_tag {};
#ifdef __cpp_lib_concepts
struct contiguous_iterator_tag : random_access_iterator_tag {};
template <class _Ty>
using _With_reference = _Ty&;
template <class _Ty>
concept _Can_reference = requires {
typename _With_reference<_Ty>;
};
template <class _Ty>
concept _Dereferenceable = requires(_Ty& __t) {
{ *__t } -> _Can_reference;
};
template <class _Ty>
concept _Has_member_iterator_concept = requires {
typename _Ty::iterator_concept;
};
template <class _Ty>
concept _Has_member_iterator_category = requires {
typename _Ty::iterator_category;
};
template <class _Ty>
concept _Has_member_value_type = requires {
typename _Ty::value_type;
};
template <class _Ty>
concept _Has_member_element_type = requires {
typename _Ty::element_type;
};
template <class _Ty>
concept _Has_member_difference_type = requires {
typename _Ty::difference_type;
};
template <class _Ty>
concept _Has_member_pointer = requires {
typename _Ty::pointer;
};
template <class _Ty>
concept _Has_member_reference = requires {
typename _Ty::reference;
};
template <class>
struct incrementable_traits {};
template <class _Ty>
requires is_object_v<_Ty>
struct incrementable_traits<_Ty*> {
using difference_type = ptrdiff_t;
};
template <class _Ty>
struct incrementable_traits<const _Ty> : incrementable_traits<_Ty> {};
template <_Has_member_difference_type _Ty>
struct incrementable_traits<_Ty> {
using difference_type = typename _Ty::difference_type;
};
template <class _Ty>
concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) {
{ __a - __b } -> integral;
};
// clang-format off
template <class _Ty>
requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>)
struct incrementable_traits<_Ty> {
using difference_type = make_signed_t<decltype(_STD declval<_Ty>() - _STD declval<_Ty>())>;
};
// clang-format on
template <class _Ty>
concept _Is_from_primary = _Same_impl<typename _Ty::_From_primary, _Ty>;
template <class>
struct iterator_traits;
template <class _Ty>
using iter_difference_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
incrementable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::difference_type;
template <class>
struct _Cond_value_type {};
template <class _Ty>
requires is_object_v<_Ty>
struct _Cond_value_type<_Ty> {
using value_type = remove_cv_t<_Ty>;
};
template <class>
struct indirectly_readable_traits {};
template <class _Ty>
struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {};
template <class _Ty>
requires is_array_v<_Ty>
struct indirectly_readable_traits<_Ty> {
using value_type = remove_cv_t<remove_extent_t<_Ty>>;
};
template <class _Ty>
struct indirectly_readable_traits<const _Ty> : indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
template <_Has_member_element_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::element_type> {};
// clang-format off
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
struct indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
&& same_as<remove_cv_t<typename _Ty::value_type>, remove_cv_t<typename _Ty::element_type>>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
// clang-format on
template <class _Ty>
using iter_value_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
indirectly_readable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::value_type;
template <_Dereferenceable _Ty>
using iter_reference_t = decltype(*_STD declval<_Ty&>());
template <class>
struct _Iterator_traits_base {};
template <class _It>
concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> //
&& _Has_member_reference<_It> && _Has_member_iterator_category<_It>;
template <bool _Has_member_typedef>
struct _Old_iter_traits_pointer {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Old_iter_traits_pointer<false> {
template <class>
using _Apply = void;
};
template <_Has_iter_types _It>
struct _Iterator_traits_base<_It> {
using iterator_category = typename _It::iterator_category;
using value_type = typename _It::value_type;
using difference_type = typename _It::difference_type;
using pointer = typename _Old_iter_traits_pointer<_Has_member_pointer<_It>>::template _Apply<_It>;
using reference = typename _It::reference;
};
template <bool _Has_member_typedef>
struct _Iter_traits_difference {
template <class _It>
using _Apply = typename incrementable_traits<_It>::difference_type;
};
template <>
struct _Iter_traits_difference<false> {
template <class>
using _Apply = void;
};
// clang-format off
template <class _It>
concept _Cpp17_iterator =
requires(_It __i) {
{ *__i } -> _Can_reference;
{ ++__i } -> same_as<_It&>;
{ *__i++ } -> _Can_reference;
}
&& copyable<_It>;
template <class _It>
concept _Cpp17_input_iterator = _Cpp17_iterator<_It>
&& equality_comparable<_It>
&& _Has_member_difference_type<incrementable_traits<_It>>
&& _Has_member_value_type<indirectly_readable_traits<_It>>
&& requires(_It __i) {
typename common_reference_t<iter_reference_t<_It>&&, typename indirectly_readable_traits<_It>::value_type&>;
typename common_reference_t<decltype(*__i++)&&, typename indirectly_readable_traits<_It>::value_type&>;
requires signed_integral<typename incrementable_traits<_It>::difference_type>;
};
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_iterator<_It> && !_Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type =
typename _Iter_traits_difference<_Has_member_difference_type<incrementable_traits<_It>>>::template _Apply<_It>;
using pointer = void;
using reference = void;
};
// clang-format on
enum class _Itraits_pointer_strategy { _Use_void, _Use_member, _Use_decltype };
template <_Itraits_pointer_strategy>
struct _Iter_traits_pointer;
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_void> {
template <class>
using _Apply = void;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> {
template <class _It>
using _Apply = decltype(_STD declval<_It&>().operator->());
};
template <class _Ty>
concept _Has_member_arrow = requires(_Ty&& __t) {
static_cast<_Ty&&>(__t).operator->();
};
template <bool _Has_member_typedef>
struct _Iter_traits_reference {
template <class _It>
using _Apply = typename _It::reference;
};
template <>
struct _Iter_traits_reference<false> {
template <class _It>
using _Apply = iter_reference_t<_It>;
};
template <bool _Is_random>
struct _Iter_traits_category4 {
using type = random_access_iterator_tag;
};
template <>
struct _Iter_traits_category4<false> {
using type = bidirectional_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_random_delta = totally_ordered<_It>
&& requires(_It __i, typename incrementable_traits<_It>::difference_type __n) {
{ __i += __n } -> same_as<_It&>;
{ __i -= __n } -> same_as<_It&>;
{ __i + __n } -> same_as<_It>;
{ __n + __i } -> same_as<_It>;
{ __i - __n } -> same_as<_It>;
{ __i - __i } -> same_as<decltype(__n)>;
{ __i[__n] } -> convertible_to<iter_reference_t<_It>>;
};
// clang-format on
template <bool _Is_bidi>
struct _Iter_traits_category3 {
template <class _It>
using _Apply = typename _Iter_traits_category4<_Cpp17_random_delta<_It>>::type;
};
template <>
struct _Iter_traits_category3<false> {
template <class>
using _Apply = forward_iterator_tag;
};
template <class _It>
concept _Cpp17_bidi_delta = requires(_It __i) {
{ --__i } -> same_as<_It&>;
{ __i-- } -> convertible_to<const _It&>;
requires same_as<decltype(*__i--), iter_reference_t<_It>>;
};
template <bool _Is_forward>
struct _Iter_traits_category2 {
template <class _It>
using _Apply = typename _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>;
};
template <>
struct _Iter_traits_category2<false> {
template <class>
using _Apply = input_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_forward_delta = constructible_from<_It> && is_lvalue_reference_v<iter_reference_t<_It>>
&& same_as<remove_cvref_t<iter_reference_t<_It>>, typename indirectly_readable_traits<_It>::value_type>
&& requires(_It __i) {
{ __i++ } -> convertible_to<const _It&>;
requires same_as<decltype(*__i++), iter_reference_t<_It>>;
};
// clang-format on
template <bool _Has_member_typedef>
struct _Iter_traits_category {
template <class _It>
using _Apply = typename _It::iterator_category;
};
template <>
struct _Iter_traits_category<false> {
template <class _It>
using _Apply = typename _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>;
};
// clang-format off
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = typename _Iter_traits_category<_Has_member_iterator_category<_It>>::template _Apply<_It>;
using value_type = typename indirectly_readable_traits<_It>::value_type;
using difference_type = typename incrementable_traits<_It>::difference_type;
using pointer = typename _Iter_traits_pointer<(
_Has_member_pointer<_It> ? _Itraits_pointer_strategy::_Use_member
: _Has_member_arrow<_It&> ? _Itraits_pointer_strategy::_Use_decltype
: _Itraits_pointer_strategy::_Use_void)>::template _Apply<_It>;
using reference = typename _Iter_traits_reference<_Has_member_reference<_It>>::template _Apply<_It>;
};
// clang-format on
template <class _Ty>
struct iterator_traits : _Iterator_traits_base<_Ty> {
using _From_primary = iterator_traits;
};
template <class _Ty>
requires is_object_v<_Ty>
struct iterator_traits<_Ty*> {
using iterator_concept = contiguous_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
template <class _Ty>
inline constexpr bool _Integer_class = requires {
typename _Ty::_Signed_type;
typename _Ty::_Unsigned_type;
};
template <class _Ty>
concept _Integer_like = _Is_nonbool_integral<remove_cv_t<_Ty>> || _Integer_class<_Ty>;
template <class _Ty>
concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0);
// clang-format off
template <class _Ty>
concept weakly_incrementable = movable<_Ty>
&& requires(_Ty __i) {
typename iter_difference_t<_Ty>;
requires _Signed_integer_like<iter_difference_t<_Ty>>;
{ ++__i } -> same_as<_Ty&>;
__i++;
}
#ifdef __clang__ // TRANSITION, LLVM-48173
&& !same_as<_Ty, bool>
#endif // TRANSITION, LLVM-48173
;
template <class _It>
concept input_or_output_iterator = requires(_It __i) { { *__i } -> _Can_reference; }
&& weakly_incrementable<_It>;
template <class _Se, class _It>
concept sentinel_for = semiregular<_Se>
&& input_or_output_iterator<_It>
&& _Weakly_equality_comparable_with<_Se, _It>;
// clang-format on
template <class _Se, class _It>
inline constexpr bool disable_sized_sentinel_for = false;
// clang-format off
template <class _Se, class _It>
concept sized_sentinel_for = sentinel_for<_Se, _It>
&& !disable_sized_sentinel_for<remove_cv_t<_Se>, remove_cv_t<_It>>
&& requires(const _It& __i, const _Se& __s) {
{ __s - __i } -> same_as<iter_difference_t<_It>>;
{ __i - __s } -> same_as<iter_difference_t<_It>>;
};
// clang-format on
namespace ranges {
// clang-format off
enum class subrange_kind : bool { unsized, sized };
template <input_or_output_iterator _It, sentinel_for<_It> _Se = _It,
subrange_kind _Ki = sized_sentinel_for<_Se, _It> ? subrange_kind::sized : subrange_kind::unsized>
requires (_Ki == subrange_kind::sized || !sized_sentinel_for<_Se, _It>)
class subrange;
template <size_t _Idx, class _It, class _Se, subrange_kind _Ki>
requires ((_Idx == 0 && copyable<_It>) || _Idx == 1)
_NODISCARD constexpr auto get(const subrange<_It, _Se, _Ki>& _Val);
template <size_t _Idx, class _It, class _Se, subrange_kind _Ki>
requires (_Idx < 2)
_NODISCARD constexpr auto get(subrange<_It, _Se, _Ki>&& _Val);
// clang-format on
} // namespace ranges
using ranges::get;
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_size<ranges::subrange<_It, _Se, _Ki>> : integral_constant<size_t, 2> {};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, const ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
template <class, class = void>
struct _Iterator_traits_base {}; // empty for non-iterators
template <class _Iter>
struct _Iterator_traits_base<_Iter,
void_t<typename _Iter::iterator_category, typename _Iter::value_type, typename _Iter::difference_type,
typename _Iter::pointer, typename _Iter::reference>> {
// defined if _Iter::* types exist
using iterator_category = typename _Iter::iterator_category;
using value_type = typename _Iter::value_type;
using difference_type = typename _Iter::difference_type;
using pointer = typename _Iter::pointer;
using reference = typename _Iter::reference;
};
template <class _Ty, bool = is_object_v<_Ty>>
struct _Iterator_traits_pointer_base { // iterator properties for pointers to object
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
template <class _Ty>
struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object
template <class _Iter>
struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible
template <class _Ty>
struct iterator_traits<_Ty*> : _Iterator_traits_pointer_base<_Ty> {}; // get traits from pointer, if possible
#endif // __cpp_lib_concepts
_STD_END
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // __MSVC_ITER_CORE_HPP

Просмотреть файл

@ -8,6 +8,7 @@
"__msvc_chrono.hpp",
"__msvc_format_ucd_tables.hpp",
"__msvc_int128.hpp",
"__msvc_iter_core.hpp",
"__msvc_system_error_abi.hpp",
"__msvc_tzdb.hpp",
"__msvc_xlocinfo_types.hpp",

Просмотреть файл

@ -1,4 +1,4 @@
// tuple standard header
// tuple standard header (core)
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@ -11,8 +11,8 @@
#ifdef __cpp_lib_concepts
#include <compare>
#endif // __cpp_lib_concepts
#include <__msvc_iter_core.hpp>
#include <type_traits>
#include <xutility>
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)

Просмотреть файл

@ -113,6 +113,27 @@ struct piecewise_construct_t { // tag type for pair tuple arguments
_INLINE_VAR constexpr piecewise_construct_t piecewise_construct{};
template <class _Ty, class _Alloc, class = void>
struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type
template <class _Ty, class _Alloc>
struct _Has_allocator_type<_Ty, _Alloc, void_t<typename _Ty::allocator_type>>
: is_convertible<_Alloc, typename _Ty::allocator_type>::type {}; // tests for suitable _Ty::allocator_type
struct allocator_arg_t { // tag type for added allocator argument
explicit allocator_arg_t() = default;
};
_INLINE_VAR constexpr allocator_arg_t allocator_arg{};
template <class _Ty, class _Alloc>
struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {
// determine whether _Ty has an allocator_type member type
};
template <class _Ty, class _Alloc>
_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value;
template <class...>
class tuple;

Просмотреть файл

@ -9,10 +9,10 @@
#include <yvals.h>
#if _STL_COMPILER_PREPROCESSOR
#include <__msvc_iter_core.hpp>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <utility>
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
@ -358,380 +358,10 @@ using _Any_tag = _Unused_parameter; // generic fallback/default/"other" target f
template <class _Ty>
using _Algorithm_int_t = conditional_t<is_integral_v<_Ty>, _Ty, ptrdiff_t>;
// from <iterator>
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : input_iterator_tag {};
struct bidirectional_iterator_tag : forward_iterator_tag {};
struct random_access_iterator_tag : bidirectional_iterator_tag {};
#ifdef __cpp_lib_concepts
struct contiguous_iterator_tag : random_access_iterator_tag {};
template <class _Ty>
using _With_reference = _Ty&;
template <class _Ty>
concept _Can_reference = requires {
typename _With_reference<_Ty>;
};
template <class _Ty>
concept _Dereferenceable = requires(_Ty& __t) {
{ *__t } -> _Can_reference;
};
template <class _Ty>
concept _Has_member_iterator_concept = requires {
typename _Ty::iterator_concept;
};
template <class _Ty>
concept _Has_member_iterator_category = requires {
typename _Ty::iterator_category;
};
template <class _Ty>
concept _Has_member_value_type = requires {
typename _Ty::value_type;
};
template <class _Ty>
concept _Has_member_element_type = requires {
typename _Ty::element_type;
};
template <class _Ty>
concept _Has_member_difference_type = requires {
typename _Ty::difference_type;
};
template <class _Ty>
concept _Has_member_pointer = requires {
typename _Ty::pointer;
};
template <class _Ty>
concept _Has_member_reference = requires {
typename _Ty::reference;
};
template <class _Ty>
concept _Destructible_object = is_object_v<_Ty> && destructible<_Ty>;
template <class>
struct incrementable_traits {};
template <class _Ty>
requires is_object_v<_Ty>
struct incrementable_traits<_Ty*> {
using difference_type = ptrdiff_t;
};
template <class _Ty>
struct incrementable_traits<const _Ty> : incrementable_traits<_Ty> {};
template <_Has_member_difference_type _Ty>
struct incrementable_traits<_Ty> {
using difference_type = typename _Ty::difference_type;
};
template <class _Ty>
concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) {
{ __a - __b } -> integral;
};
// clang-format off
template <class _Ty>
requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>)
struct incrementable_traits<_Ty> {
using difference_type = make_signed_t<decltype(_STD declval<_Ty>() - _STD declval<_Ty>())>;
};
// clang-format on
template <class _Ty>
concept _Is_from_primary = _Same_impl<typename _Ty::_From_primary, _Ty>;
template <class>
struct iterator_traits;
template <class _Ty>
using iter_difference_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
incrementable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::difference_type;
template <class>
struct _Cond_value_type {};
template <class _Ty>
requires is_object_v<_Ty>
struct _Cond_value_type<_Ty> {
using value_type = remove_cv_t<_Ty>;
};
template <class>
struct indirectly_readable_traits {};
template <class _Ty>
struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {};
template <class _Ty>
requires is_array_v<_Ty>
struct indirectly_readable_traits<_Ty> {
using value_type = remove_cv_t<remove_extent_t<_Ty>>;
};
template <class _Ty>
struct indirectly_readable_traits<const _Ty> : indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
template <_Has_member_element_type _Ty>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::element_type> {};
// clang-format off
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
struct indirectly_readable_traits<_Ty> {};
template <_Has_member_value_type _Ty>
requires _Has_member_element_type<_Ty>
&& same_as<remove_cv_t<typename _Ty::value_type>, remove_cv_t<typename _Ty::element_type>>
struct indirectly_readable_traits<_Ty> : _Cond_value_type<typename _Ty::value_type> {};
// clang-format on
template <class _Ty>
using iter_value_t = typename conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
indirectly_readable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::value_type;
template <_Dereferenceable _Ty>
using iter_reference_t = decltype(*_STD declval<_Ty&>());
template <class>
struct _Iterator_traits_base {};
template <class _It>
concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> //
&& _Has_member_reference<_It> && _Has_member_iterator_category<_It>;
template <bool _Has_member_typedef>
struct _Old_iter_traits_pointer {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Old_iter_traits_pointer<false> {
template <class>
using _Apply = void;
};
template <_Has_iter_types _It>
struct _Iterator_traits_base<_It> {
using iterator_category = typename _It::iterator_category;
using value_type = typename _It::value_type;
using difference_type = typename _It::difference_type;
using pointer = typename _Old_iter_traits_pointer<_Has_member_pointer<_It>>::template _Apply<_It>;
using reference = typename _It::reference;
};
template <bool _Has_member_typedef>
struct _Iter_traits_difference {
template <class _It>
using _Apply = typename incrementable_traits<_It>::difference_type;
};
template <>
struct _Iter_traits_difference<false> {
template <class>
using _Apply = void;
};
// clang-format off
template <class _It>
concept _Cpp17_iterator =
requires(_It __i) {
{ *__i } -> _Can_reference;
{ ++__i } -> same_as<_It&>;
{ *__i++ } -> _Can_reference;
}
&& copyable<_It>;
template <class _It>
concept _Cpp17_input_iterator = _Cpp17_iterator<_It>
&& equality_comparable<_It>
&& _Has_member_difference_type<incrementable_traits<_It>>
&& _Has_member_value_type<indirectly_readable_traits<_It>>
&& requires(_It __i) {
typename common_reference_t<iter_reference_t<_It>&&, typename indirectly_readable_traits<_It>::value_type&>;
typename common_reference_t<decltype(*__i++)&&, typename indirectly_readable_traits<_It>::value_type&>;
requires signed_integral<typename incrementable_traits<_It>::difference_type>;
};
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_iterator<_It> && !_Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type =
typename _Iter_traits_difference<_Has_member_difference_type<incrementable_traits<_It>>>::template _Apply<_It>;
using pointer = void;
using reference = void;
};
// clang-format on
enum class _Itraits_pointer_strategy { _Use_void, _Use_member, _Use_decltype };
template <_Itraits_pointer_strategy>
struct _Iter_traits_pointer;
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_void> {
template <class>
using _Apply = void;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> {
template <class _It>
using _Apply = typename _It::pointer;
};
template <>
struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> {
template <class _It>
using _Apply = decltype(_STD declval<_It&>().operator->());
};
template <class _Ty>
concept _Has_member_arrow = requires(_Ty&& __t) {
static_cast<_Ty&&>(__t).operator->();
};
template <bool _Has_member_typedef>
struct _Iter_traits_reference {
template <class _It>
using _Apply = typename _It::reference;
};
template <>
struct _Iter_traits_reference<false> {
template <class _It>
using _Apply = iter_reference_t<_It>;
};
template <bool _Is_random>
struct _Iter_traits_category4 {
using type = random_access_iterator_tag;
};
template <>
struct _Iter_traits_category4<false> {
using type = bidirectional_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_random_delta = totally_ordered<_It>
&& requires(_It __i, typename incrementable_traits<_It>::difference_type __n) {
{ __i += __n } -> same_as<_It&>;
{ __i -= __n } -> same_as<_It&>;
{ __i + __n } -> same_as<_It>;
{ __n + __i } -> same_as<_It>;
{ __i - __n } -> same_as<_It>;
{ __i - __i } -> same_as<decltype(__n)>;
{ __i[__n] } -> convertible_to<iter_reference_t<_It>>;
};
// clang-format on
template <bool _Is_bidi>
struct _Iter_traits_category3 {
template <class _It>
using _Apply = typename _Iter_traits_category4<_Cpp17_random_delta<_It>>::type;
};
template <>
struct _Iter_traits_category3<false> {
template <class>
using _Apply = forward_iterator_tag;
};
template <class _It>
concept _Cpp17_bidi_delta = requires(_It __i) {
{ --__i } -> same_as<_It&>;
{ __i-- } -> convertible_to<const _It&>;
requires same_as<decltype(*__i--), iter_reference_t<_It>>;
};
template <bool _Is_forward>
struct _Iter_traits_category2 {
template <class _It>
using _Apply = typename _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>;
};
template <>
struct _Iter_traits_category2<false> {
template <class>
using _Apply = input_iterator_tag;
};
// clang-format off
template <class _It>
concept _Cpp17_forward_delta = constructible_from<_It> && is_lvalue_reference_v<iter_reference_t<_It>>
&& same_as<remove_cvref_t<iter_reference_t<_It>>, typename indirectly_readable_traits<_It>::value_type>
&& requires(_It __i) {
{ __i++ } -> convertible_to<const _It&>;
requires same_as<decltype(*__i++), iter_reference_t<_It>>;
};
// clang-format on
template <bool _Has_member_typedef>
struct _Iter_traits_category {
template <class _It>
using _Apply = typename _It::iterator_category;
};
template <>
struct _Iter_traits_category<false> {
template <class _It>
using _Apply = typename _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>;
};
// clang-format off
template <class _It>
requires (!_Has_iter_types<_It> && _Cpp17_input_iterator<_It>)
struct _Iterator_traits_base<_It> {
using iterator_category = typename _Iter_traits_category<_Has_member_iterator_category<_It>>::template _Apply<_It>;
using value_type = typename indirectly_readable_traits<_It>::value_type;
using difference_type = typename incrementable_traits<_It>::difference_type;
using pointer = typename _Iter_traits_pointer<(
_Has_member_pointer<_It> ? _Itraits_pointer_strategy::_Use_member
: _Has_member_arrow<_It&> ? _Itraits_pointer_strategy::_Use_decltype
: _Itraits_pointer_strategy::_Use_void)>::template _Apply<_It>;
using reference = typename _Iter_traits_reference<_Has_member_reference<_It>>::template _Apply<_It>;
};
// clang-format on
template <class _Ty>
struct iterator_traits : _Iterator_traits_base<_Ty> {
using _From_primary = iterator_traits;
};
template <class _Ty>
requires is_object_v<_Ty>
struct iterator_traits<_Ty*> {
using iterator_concept = contiguous_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
namespace ranges {
namespace _Iter_move {
void iter_move(); // Block unqualified name lookup
@ -828,18 +458,6 @@ concept indirectly_writable = requires(_It&& __i, _Ty&& __t) {
const_cast<const iter_reference_t<_It>&&>(*static_cast<_It&&>(__i)) = static_cast<_Ty&&>(__t);
};
template <class _Ty>
inline constexpr bool _Integer_class = requires {
typename _Ty::_Signed_type;
typename _Ty::_Unsigned_type;
};
template <class _Ty>
concept _Integer_like = _Is_nonbool_integral<remove_cv_t<_Ty>> || _Integer_class<_Ty>;
template <class _Ty>
concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0);
template <bool _Is_integer_class>
struct _Make_unsigned_like_impl {
template <class _Ty>
@ -878,48 +496,11 @@ _NODISCARD constexpr auto _To_signed_like(const _Ty _Value) noexcept {
return static_cast<_Make_signed_like_t<_Ty>>(_Value);
}
// clang-format off
template <class _Ty>
concept weakly_incrementable = movable<_Ty>
&& requires(_Ty __i) {
typename iter_difference_t<_Ty>;
requires _Signed_integer_like<iter_difference_t<_Ty>>;
{ ++__i } -> same_as<_Ty&>;
__i++;
}
#ifdef __clang__ // TRANSITION, LLVM-48173
&& !same_as<_Ty, bool>
#endif // TRANSITION, LLVM-48173
;
template <class _Ty>
concept incrementable = regular<_Ty> && weakly_incrementable<_Ty> && requires(_Ty __t) {
{ __t++ } -> same_as<_Ty>;
};
template <class _It>
concept input_or_output_iterator = requires(_It __i) { { *__i } -> _Can_reference; }
&& weakly_incrementable<_It>;
template <class _Se, class _It>
concept sentinel_for = semiregular<_Se>
&& input_or_output_iterator<_It>
&& _Weakly_equality_comparable_with<_Se, _It>;
// clang-format on
template <class _Se, class _It>
inline constexpr bool disable_sized_sentinel_for = false;
// clang-format off
template <class _Se, class _It>
concept sized_sentinel_for = sentinel_for<_Se, _It>
&& !disable_sized_sentinel_for<remove_cv_t<_Se>, remove_cv_t<_It>>
&& requires(const _It& __i, const _Se& __s) {
{ __s - __i } -> same_as<iter_difference_t<_It>>;
{ __i - __s } -> same_as<iter_difference_t<_It>>;
};
// clang-format on
template <bool _Iterator_category_present>
struct _Iter_concept_impl2 {
template <class _It, class _Traits>
@ -1231,39 +812,6 @@ template <class _Iter>
using _Iter_diff_t = iter_difference_t<_Iter>;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
template <class, class = void>
struct _Iterator_traits_base {}; // empty for non-iterators
template <class _Iter>
struct _Iterator_traits_base<_Iter,
void_t<typename _Iter::iterator_category, typename _Iter::value_type, typename _Iter::difference_type,
typename _Iter::pointer, typename _Iter::reference>> {
// defined if _Iter::* types exist
using iterator_category = typename _Iter::iterator_category;
using value_type = typename _Iter::value_type;
using difference_type = typename _Iter::difference_type;
using pointer = typename _Iter::pointer;
using reference = typename _Iter::reference;
};
template <class _Ty, bool = is_object_v<_Ty>>
struct _Iterator_traits_pointer_base { // iterator properties for pointers to object
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Ty>;
using difference_type = ptrdiff_t;
using pointer = _Ty*;
using reference = _Ty&;
};
template <class _Ty>
struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object
template <class _Iter>
struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible
template <class _Ty>
struct iterator_traits<_Ty*> : _Iterator_traits_pointer_base<_Ty> {}; // get traits from pointer, if possible
template <class _Iter>
using _Iter_ref_t = typename iterator_traits<_Iter>::reference;
@ -3340,8 +2888,6 @@ namespace ranges {
return _RANGES begin(_Self)[_Idx];
}
};
enum class subrange_kind : bool { unsized, sized };
// clang-format on
} // namespace ranges
@ -3382,11 +2928,6 @@ namespace ranges {
&& constructible_from<_Ty, _First, _Second>
&& _Convertible_to_non_slicing<_First, tuple_element_t<0, _Ty>>
&& convertible_to<_Second, tuple_element_t<1, _Ty>>;
template <input_or_output_iterator _It, sentinel_for<_It> _Se = _It,
subrange_kind _Ki = sized_sentinel_for<_Se, _It> ? subrange_kind::sized : subrange_kind::unsized>
requires (_Ki == subrange_kind::sized || !sized_sentinel_for<_Se, _It>)
class subrange;
// clang-format on
template <class _It, class _Se, subrange_kind _Ki,
@ -3611,31 +3152,6 @@ namespace ranges {
// clang-format on
} // namespace ranges
using ranges::get;
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_size<ranges::subrange<_It, _Se, _Ki>> : integral_constant<size_t, 2> {};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> {
using type = _It;
};
template <class _It, class _Se, ranges::subrange_kind _Ki>
struct tuple_element<1, const ranges::subrange<_It, _Se, _Ki>> {
using type = _Se;
};
namespace ranges {
struct dangling {
constexpr dangling() noexcept = default;
@ -6217,19 +5733,6 @@ private:
_Udiff _Bmask; // 2^_Bits - 1
};
template <class _Ty, class _Alloc, class = void>
struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type
template <class _Ty, class _Alloc>
struct _Has_allocator_type<_Ty, _Alloc, void_t<typename _Ty::allocator_type>>
: is_convertible<_Alloc, typename _Ty::allocator_type>::type {}; // tests for suitable _Ty::allocator_type
struct allocator_arg_t { // tag type for added allocator argument
explicit allocator_arg_t() = default;
};
_INLINE_VAR constexpr allocator_arg_t allocator_arg{};
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Xbad_alloc();
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Xinvalid_argument(_In_z_ const char*);
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Xlength_error(_In_z_ const char*);
@ -6238,14 +5741,6 @@ _INLINE_VAR constexpr allocator_arg_t allocator_arg{};
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Xruntime_error(_In_z_ const char*);
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _XGetLastError();
template <class _Ty, class _Alloc>
struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {
// determine whether _Ty has an allocator_type member type
};
template <class _Ty, class _Alloc>
_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value;
template <class _Category, class _Ty, class _Diff = ptrdiff_t, class _Pointer = _Ty*, class _Reference = _Ty&>
struct _CXX17_DEPRECATE_ITERATOR_BASE_CLASS iterator { // base type for iterator classes
using iterator_category = _Category;