diff --git a/stl/CMakeLists.txt b/stl/CMakeLists.txt index b50c571ce..580ee7f76 100644 --- a/stl/CMakeLists.txt +++ b/stl/CMakeLists.txt @@ -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 diff --git a/stl/inc/__msvc_all_public_headers.hpp b/stl/inc/__msvc_all_public_headers.hpp index 71c878219..21b84a613 100644 --- a/stl/inc/__msvc_all_public_headers.hpp +++ b/stl/inc/__msvc_all_public_headers.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -128,7 +129,6 @@ #include #include #include -#include #include #include #include diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp new file mode 100644 index 000000000..697da4cf2 --- /dev/null +++ b/stl/inc/__msvc_iter_core.hpp @@ -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 +#if _STL_COMPILER_PREPROCESSOR +#include + +#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 +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 +using _With_reference = _Ty&; + +template +concept _Can_reference = requires { + typename _With_reference<_Ty>; +}; + +template +concept _Dereferenceable = requires(_Ty& __t) { + { *__t } -> _Can_reference; +}; + +template +concept _Has_member_iterator_concept = requires { + typename _Ty::iterator_concept; +}; + +template +concept _Has_member_iterator_category = requires { + typename _Ty::iterator_category; +}; + +template +concept _Has_member_value_type = requires { + typename _Ty::value_type; +}; + +template +concept _Has_member_element_type = requires { + typename _Ty::element_type; +}; + +template +concept _Has_member_difference_type = requires { + typename _Ty::difference_type; +}; + +template +concept _Has_member_pointer = requires { + typename _Ty::pointer; +}; + +template +concept _Has_member_reference = requires { + typename _Ty::reference; +}; + +template +struct incrementable_traits {}; + +template + requires is_object_v<_Ty> +struct incrementable_traits<_Ty*> { + using difference_type = ptrdiff_t; +}; + +template +struct incrementable_traits : incrementable_traits<_Ty> {}; + +template <_Has_member_difference_type _Ty> +struct incrementable_traits<_Ty> { + using difference_type = typename _Ty::difference_type; +}; + +template +concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) { + { __a - __b } -> integral; +}; + +// clang-format off +template + requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>) +struct incrementable_traits<_Ty> { + using difference_type = make_signed_t() - _STD declval<_Ty>())>; +}; +// clang-format on + +template +concept _Is_from_primary = _Same_impl; + +template +struct iterator_traits; + +template +using iter_difference_t = typename conditional_t<_Is_from_primary>>, + incrementable_traits>, iterator_traits>>::difference_type; + +template +struct _Cond_value_type {}; + +template + requires is_object_v<_Ty> +struct _Cond_value_type<_Ty> { + using value_type = remove_cv_t<_Ty>; +}; + +template +struct indirectly_readable_traits {}; + +template +struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {}; + +template + requires is_array_v<_Ty> +struct indirectly_readable_traits<_Ty> { + using value_type = remove_cv_t>; +}; + +template +struct indirectly_readable_traits : indirectly_readable_traits<_Ty> {}; + +template <_Has_member_value_type _Ty> +struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; + +template <_Has_member_element_type _Ty> +struct indirectly_readable_traits<_Ty> : _Cond_value_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> +struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; +// clang-format on + +template +using iter_value_t = typename conditional_t<_Is_from_primary>>, + indirectly_readable_traits>, iterator_traits>>::value_type; + +template <_Dereferenceable _Ty> +using iter_reference_t = decltype(*_STD declval<_Ty&>()); + +template +struct _Iterator_traits_base {}; + +template +concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> // + && _Has_member_reference<_It> && _Has_member_iterator_category<_It>; + +template +struct _Old_iter_traits_pointer { + template + using _Apply = typename _It::pointer; +}; + +template <> +struct _Old_iter_traits_pointer { + template + 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 +struct _Iter_traits_difference { + template + using _Apply = typename incrementable_traits<_It>::difference_type; +}; + +template <> +struct _Iter_traits_difference { + template + using _Apply = void; +}; + +// clang-format off +template +concept _Cpp17_iterator = + requires(_It __i) { + { *__i } -> _Can_reference; + { ++__i } -> same_as<_It&>; + { *__i++ } -> _Can_reference; + } + && copyable<_It>; + +template +concept _Cpp17_input_iterator = _Cpp17_iterator<_It> + && equality_comparable<_It> + && _Has_member_difference_type> + && _Has_member_value_type> + && requires(_It __i) { + typename common_reference_t&&, typename indirectly_readable_traits<_It>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; + }; + +template + 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>>::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 + using _Apply = void; +}; + +template <> +struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> { + template + using _Apply = typename _It::pointer; +}; + +template <> +struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> { + template + using _Apply = decltype(_STD declval<_It&>().operator->()); +}; + +template +concept _Has_member_arrow = requires(_Ty&& __t) { + static_cast<_Ty&&>(__t).operator->(); +}; + +template +struct _Iter_traits_reference { + template + using _Apply = typename _It::reference; +}; + +template <> +struct _Iter_traits_reference { + template + using _Apply = iter_reference_t<_It>; +}; + +template +struct _Iter_traits_category4 { + using type = random_access_iterator_tag; +}; + +template <> +struct _Iter_traits_category4 { + using type = bidirectional_iterator_tag; +}; + +// clang-format off +template +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; + { __i[__n] } -> convertible_to>; + }; +// clang-format on + +template +struct _Iter_traits_category3 { + template + using _Apply = typename _Iter_traits_category4<_Cpp17_random_delta<_It>>::type; +}; + +template <> +struct _Iter_traits_category3 { + template + using _Apply = forward_iterator_tag; +}; + +template +concept _Cpp17_bidi_delta = requires(_It __i) { + { --__i } -> same_as<_It&>; + { __i-- } -> convertible_to; + requires same_as>; +}; + +template +struct _Iter_traits_category2 { + template + using _Apply = typename _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>; +}; + +template <> +struct _Iter_traits_category2 { + template + using _Apply = input_iterator_tag; +}; + +// clang-format off +template +concept _Cpp17_forward_delta = constructible_from<_It> && is_lvalue_reference_v> + && same_as>, typename indirectly_readable_traits<_It>::value_type> + && requires(_It __i) { + { __i++ } -> convertible_to; + requires same_as>; + }; +// clang-format on + +template +struct _Iter_traits_category { + template + using _Apply = typename _It::iterator_category; +}; + +template <> +struct _Iter_traits_category { + template + using _Apply = typename _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>; +}; + +// clang-format off +template + 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 +struct iterator_traits : _Iterator_traits_base<_Ty> { + using _From_primary = iterator_traits; +}; + +template + 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 +inline constexpr bool _Integer_class = requires { + typename _Ty::_Signed_type; + typename _Ty::_Unsigned_type; +}; + +template +concept _Integer_like = _Is_nonbool_integral> || _Integer_class<_Ty>; + +template +concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0); + +// clang-format off +template +concept weakly_incrementable = movable<_Ty> + && requires(_Ty __i) { + typename iter_difference_t<_Ty>; + requires _Signed_integer_like>; + { ++__i } -> same_as<_Ty&>; + __i++; + } +#ifdef __clang__ // TRANSITION, LLVM-48173 + && !same_as<_Ty, bool> +#endif // TRANSITION, LLVM-48173 + ; + +template +concept input_or_output_iterator = requires(_It __i) { { *__i } -> _Can_reference; } + && weakly_incrementable<_It>; + +template +concept sentinel_for = semiregular<_Se> + && input_or_output_iterator<_It> + && _Weakly_equality_comparable_with<_Se, _It>; +// clang-format on + +template +inline constexpr bool disable_sized_sentinel_for = false; + +// clang-format off +template +concept sized_sentinel_for = sentinel_for<_Se, _It> + && !disable_sized_sentinel_for, remove_cv_t<_It>> + && requires(const _It& __i, const _Se& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; +// clang-format on + +namespace ranges { + // clang-format off + enum class subrange_kind : bool { unsized, sized }; + + template _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 + requires ((_Idx == 0 && copyable<_It>) || _Idx == 1) + _NODISCARD constexpr auto get(const subrange<_It, _Se, _Ki>& _Val); + + template + requires (_Idx < 2) + _NODISCARD constexpr auto get(subrange<_It, _Se, _Ki>&& _Val); + // clang-format on +} // namespace ranges + +using ranges::get; + +template +struct tuple_size> : integral_constant {}; + +template +struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> { + using type = _It; +}; + +template +struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> { + using type = _Se; +}; + +template +struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> { + using type = _It; +}; + +template +struct tuple_element<1, const ranges::subrange<_It, _Se, _Ki>> { + using type = _Se; +}; +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv +template +struct _Iterator_traits_base {}; // empty for non-iterators + +template +struct _Iterator_traits_base<_Iter, + void_t> { + // 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 > +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 +struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object + +template +struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible + +template +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 diff --git a/stl/inc/header-units.json b/stl/inc/header-units.json index f63097a68..72cd63edf 100644 --- a/stl/inc/header-units.json +++ b/stl/inc/header-units.json @@ -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", diff --git a/stl/inc/tuple b/stl/inc/tuple index bc2948eb0..a94a95f56 100644 --- a/stl/inc/tuple +++ b/stl/inc/tuple @@ -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 #endif // __cpp_lib_concepts +#include <__msvc_iter_core.hpp> #include -#include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) diff --git a/stl/inc/utility b/stl/inc/utility index b3e3ab981..180db6b71 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -113,6 +113,27 @@ struct piecewise_construct_t { // tag type for pair tuple arguments _INLINE_VAR constexpr piecewise_construct_t piecewise_construct{}; +template +struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type + +template +struct _Has_allocator_type<_Ty, _Alloc, void_t> + : 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 +struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type { + // determine whether _Ty has an allocator_type member type +}; + +template +_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; + template class tuple; diff --git a/stl/inc/xutility b/stl/inc/xutility index dc5f37a0c..132dddb48 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -9,10 +9,10 @@ #include #if _STL_COMPILER_PREPROCESSOR +#include <__msvc_iter_core.hpp> #include #include #include -#include #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 using _Algorithm_int_t = conditional_t, _Ty, ptrdiff_t>; -// from -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 -using _With_reference = _Ty&; - -template -concept _Can_reference = requires { - typename _With_reference<_Ty>; -}; - -template -concept _Dereferenceable = requires(_Ty& __t) { - { *__t } -> _Can_reference; -}; - -template -concept _Has_member_iterator_concept = requires { - typename _Ty::iterator_concept; -}; - -template -concept _Has_member_iterator_category = requires { - typename _Ty::iterator_category; -}; - -template -concept _Has_member_value_type = requires { - typename _Ty::value_type; -}; - -template -concept _Has_member_element_type = requires { - typename _Ty::element_type; -}; - -template -concept _Has_member_difference_type = requires { - typename _Ty::difference_type; -}; - -template -concept _Has_member_pointer = requires { - typename _Ty::pointer; -}; - -template -concept _Has_member_reference = requires { - typename _Ty::reference; -}; - template concept _Destructible_object = is_object_v<_Ty> && destructible<_Ty>; -template -struct incrementable_traits {}; - -template - requires is_object_v<_Ty> -struct incrementable_traits<_Ty*> { - using difference_type = ptrdiff_t; -}; - -template -struct incrementable_traits : incrementable_traits<_Ty> {}; - -template <_Has_member_difference_type _Ty> -struct incrementable_traits<_Ty> { - using difference_type = typename _Ty::difference_type; -}; - -template -concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) { - { __a - __b } -> integral; -}; - -// clang-format off -template - requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>) -struct incrementable_traits<_Ty> { - using difference_type = make_signed_t() - _STD declval<_Ty>())>; -}; -// clang-format on - -template -concept _Is_from_primary = _Same_impl; - -template -struct iterator_traits; - -template -using iter_difference_t = typename conditional_t<_Is_from_primary>>, - incrementable_traits>, iterator_traits>>::difference_type; - -template -struct _Cond_value_type {}; - -template - requires is_object_v<_Ty> -struct _Cond_value_type<_Ty> { - using value_type = remove_cv_t<_Ty>; -}; - -template -struct indirectly_readable_traits {}; - -template -struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {}; - -template - requires is_array_v<_Ty> -struct indirectly_readable_traits<_Ty> { - using value_type = remove_cv_t>; -}; - -template -struct indirectly_readable_traits : indirectly_readable_traits<_Ty> {}; - -template <_Has_member_value_type _Ty> -struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; - -template <_Has_member_element_type _Ty> -struct indirectly_readable_traits<_Ty> : _Cond_value_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> -struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; -// clang-format on - -template -using iter_value_t = typename conditional_t<_Is_from_primary>>, - indirectly_readable_traits>, iterator_traits>>::value_type; - -template <_Dereferenceable _Ty> -using iter_reference_t = decltype(*_STD declval<_Ty&>()); - -template -struct _Iterator_traits_base {}; - -template -concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> // - && _Has_member_reference<_It> && _Has_member_iterator_category<_It>; - -template -struct _Old_iter_traits_pointer { - template - using _Apply = typename _It::pointer; -}; - -template <> -struct _Old_iter_traits_pointer { - template - 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 -struct _Iter_traits_difference { - template - using _Apply = typename incrementable_traits<_It>::difference_type; -}; - -template <> -struct _Iter_traits_difference { - template - using _Apply = void; -}; - -// clang-format off -template -concept _Cpp17_iterator = - requires(_It __i) { - { *__i } -> _Can_reference; - { ++__i } -> same_as<_It&>; - { *__i++ } -> _Can_reference; - } - && copyable<_It>; - -template -concept _Cpp17_input_iterator = _Cpp17_iterator<_It> - && equality_comparable<_It> - && _Has_member_difference_type> - && _Has_member_value_type> - && requires(_It __i) { - typename common_reference_t&&, typename indirectly_readable_traits<_It>::value_type&>; - typename common_reference_t::value_type&>; - requires signed_integral::difference_type>; - }; - -template - 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>>::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 - using _Apply = void; -}; - -template <> -struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> { - template - using _Apply = typename _It::pointer; -}; - -template <> -struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> { - template - using _Apply = decltype(_STD declval<_It&>().operator->()); -}; - -template -concept _Has_member_arrow = requires(_Ty&& __t) { - static_cast<_Ty&&>(__t).operator->(); -}; - -template -struct _Iter_traits_reference { - template - using _Apply = typename _It::reference; -}; - -template <> -struct _Iter_traits_reference { - template - using _Apply = iter_reference_t<_It>; -}; - -template -struct _Iter_traits_category4 { - using type = random_access_iterator_tag; -}; - -template <> -struct _Iter_traits_category4 { - using type = bidirectional_iterator_tag; -}; - -// clang-format off -template -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; - { __i[__n] } -> convertible_to>; - }; -// clang-format on - -template -struct _Iter_traits_category3 { - template - using _Apply = typename _Iter_traits_category4<_Cpp17_random_delta<_It>>::type; -}; - -template <> -struct _Iter_traits_category3 { - template - using _Apply = forward_iterator_tag; -}; - -template -concept _Cpp17_bidi_delta = requires(_It __i) { - { --__i } -> same_as<_It&>; - { __i-- } -> convertible_to; - requires same_as>; -}; - -template -struct _Iter_traits_category2 { - template - using _Apply = typename _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>; -}; - -template <> -struct _Iter_traits_category2 { - template - using _Apply = input_iterator_tag; -}; - -// clang-format off -template -concept _Cpp17_forward_delta = constructible_from<_It> && is_lvalue_reference_v> - && same_as>, typename indirectly_readable_traits<_It>::value_type> - && requires(_It __i) { - { __i++ } -> convertible_to; - requires same_as>; - }; -// clang-format on - -template -struct _Iter_traits_category { - template - using _Apply = typename _It::iterator_category; -}; - -template <> -struct _Iter_traits_category { - template - using _Apply = typename _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>; -}; - -// clang-format off -template - 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 -struct iterator_traits : _Iterator_traits_base<_Ty> { - using _From_primary = iterator_traits; -}; - -template - 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&&>(*static_cast<_It&&>(__i)) = static_cast<_Ty&&>(__t); }; -template -inline constexpr bool _Integer_class = requires { - typename _Ty::_Signed_type; - typename _Ty::_Unsigned_type; -}; - -template -concept _Integer_like = _Is_nonbool_integral> || _Integer_class<_Ty>; - -template -concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0); - template struct _Make_unsigned_like_impl { template @@ -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 -concept weakly_incrementable = movable<_Ty> - && requires(_Ty __i) { - typename iter_difference_t<_Ty>; - requires _Signed_integer_like>; - { ++__i } -> same_as<_Ty&>; - __i++; - } -#ifdef __clang__ // TRANSITION, LLVM-48173 - && !same_as<_Ty, bool> -#endif // TRANSITION, LLVM-48173 - ; - template concept incrementable = regular<_Ty> && weakly_incrementable<_Ty> && requires(_Ty __t) { { __t++ } -> same_as<_Ty>; }; -template -concept input_or_output_iterator = requires(_It __i) { { *__i } -> _Can_reference; } - && weakly_incrementable<_It>; - -template -concept sentinel_for = semiregular<_Se> - && input_or_output_iterator<_It> - && _Weakly_equality_comparable_with<_Se, _It>; -// clang-format on - -template -inline constexpr bool disable_sized_sentinel_for = false; - -// clang-format off -template -concept sized_sentinel_for = sentinel_for<_Se, _It> - && !disable_sized_sentinel_for, remove_cv_t<_It>> - && requires(const _It& __i, const _Se& __s) { - { __s - __i } -> same_as>; - { __i - __s } -> same_as>; - }; -// clang-format on - template struct _Iter_concept_impl2 { template @@ -1231,39 +812,6 @@ template using _Iter_diff_t = iter_difference_t<_Iter>; #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv -template -struct _Iterator_traits_base {}; // empty for non-iterators - -template -struct _Iterator_traits_base<_Iter, - void_t> { - // 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 > -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 -struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object - -template -struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible - -template -struct iterator_traits<_Ty*> : _Iterator_traits_pointer_base<_Ty> {}; // get traits from pointer, if possible - template 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 _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 -struct tuple_size> : integral_constant {}; - -template -struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> { - using type = _It; -}; - -template -struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> { - using type = _Se; -}; - -template -struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> { - using type = _It; -}; - -template -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 -struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type - -template -struct _Has_allocator_type<_Ty, _Alloc, void_t> - : 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 -struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type { - // determine whether _Ty has an allocator_type member type -}; - -template -_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; - template struct _CXX17_DEPRECATE_ITERATOR_BASE_CLASS iterator { // base type for iterator classes using iterator_category = _Category;