From c4422eba4ea8843a069224072fef0deabb359107 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 11:21:16 +0800 Subject: [PATCH 01/13] Move allocator_arg, uses_allocator etc. to --- stl/inc/utility | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/stl/inc/utility b/stl/inc/utility index b3e3ab9814b..180db6b712e 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; From 01a7e0d7af6e54fb75043a05a81a17b2b88eebe8 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 11:22:25 +0800 Subject: [PATCH 02/13] Move allocator_arg, uses_allocator etc. to --- stl/inc/xutility | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index dc5f37a0c80..33682be16e4 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -6217,19 +6217,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 +6225,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; From 379946ce6018b1550d3fa631d444ab0a033b66a6 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 11:24:07 +0800 Subject: [PATCH 03/13] Make a core header --- stl/inc/tuple | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/tuple b/stl/inc/tuple index bc2948eb03d..7e09d32e516 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 @@ -12,7 +12,7 @@ #include #endif // __cpp_lib_concepts #include -#include +#include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) From cad65f174f8129f5da4dd0dd155c7b36e8a6696d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 11:27:17 +0800 Subject: [PATCH 04/13] Make a core header --- stl/inc/__msvc_all_public_headers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/__msvc_all_public_headers.hpp b/stl/inc/__msvc_all_public_headers.hpp index 3d7a53d4724..7c4748ec075 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 @@ -127,7 +128,6 @@ #include #include #include -#include #include #include #include From 3592ccac1d368b0670224c73b7f7582911d0b5e3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:25:48 +0800 Subject: [PATCH 05/13] Separate into <__msvc_iter_core.hpp> --- stl/inc/__msvc_iter_core.hpp | 500 +++++++++++++++++++++++++++++++++++ 1 file changed, 500 insertions(+) create mode 100644 stl/inc/__msvc_iter_core.hpp diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp new file mode 100644 index 00000000000..3fb8cbdf7d0 --- /dev/null +++ b/stl/inc/__msvc_iter_core.hpp @@ -0,0 +1,500 @@ +// __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 +} +#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 From 6ab051b057affcb688a05bd894612575512bf326 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:29:20 +0800 Subject: [PATCH 06/13] Keeping apply etc. correctly handing subrange --- stl/inc/tuple | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/tuple b/stl/inc/tuple index 7e09d32e516..a94a95f567b 100644 --- a/stl/inc/tuple +++ b/stl/inc/tuple @@ -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) From b5af1cad46e19cb934f00db874a408e565caabd9 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:30:34 +0800 Subject: [PATCH 07/13] Separate into <__msvc_iter_core.hpp> --- stl/inc/xutility | 461 +---------------------------------------------- 1 file changed, 1 insertion(+), 460 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 33682be16e4..f3bc2e0c702 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -9,10 +9,10 @@ #include #if _STL_COMPILER_PREPROCESSOR +#include <__msvc_iter_subrange.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 Date: Thu, 19 May 2022 23:33:31 +0800 Subject: [PATCH 08/13] Fix ruined format --- stl/inc/__msvc_iter_core.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp index 3fb8cbdf7d0..460352d1635 100644 --- a/stl/inc/__msvc_iter_core.hpp +++ b/stl/inc/__msvc_iter_core.hpp @@ -455,7 +455,7 @@ namespace ranges { requires (_Idx < 2) _NODISCARD constexpr auto get(subrange<_It, _Se, _Ki>&& _Val); // clang-format on -} +} // namespace ranges #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv template struct _Iterator_traits_base {}; // empty for non-iterators @@ -466,19 +466,19 @@ struct _Iterator_traits_base<_Iter, 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; + 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&; + using value_type = remove_cv_t<_Ty>; + using difference_type = ptrdiff_t; + using pointer = _Ty*; + using reference = _Ty&; }; template From 2ce8265fdf5235cf9297f77940eef6031bff6932 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:37:01 +0800 Subject: [PATCH 09/13] Add <__msvc_iter_core.hpp> --- stl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/CMakeLists.txt b/stl/CMakeLists.txt index 318279f3fb1..06b5a023cad 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 From c634bd787040d827071896ca2c98b30247f34f9f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:38:01 +0800 Subject: [PATCH 10/13] Add <__msvc_iter_core.hpp> --- stl/inc/header-units.json | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/header-units.json b/stl/inc/header-units.json index 476bff26a51..15fbae77c95 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", From cb5793d3084fe3b4db093b973d8c6daf13b0c4ea Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 May 2022 23:42:03 +0800 Subject: [PATCH 11/13] Fix the wrong file name --- stl/inc/xutility | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index f3bc2e0c702..c0c77621738 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -9,7 +9,7 @@ #include #if _STL_COMPILER_PREPROCESSOR -#include <__msvc_iter_subrange.hpp> +#include <__msvc_iter_core.hpp> #include #include #include From 861632f09485c29559c5aa4bcd7519047dc6b85b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 20 May 2022 10:57:20 +0800 Subject: [PATCH 12/13] Move tuple_size/tuple_element for subrange to <__msvc_iter_core.hpp> --- stl/inc/__msvc_iter_core.hpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp index 460352d1635..697da4cf280 100644 --- a/stl/inc/__msvc_iter_core.hpp +++ b/stl/inc/__msvc_iter_core.hpp @@ -456,6 +456,31 @@ namespace ranges { _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 From 24309e5b2c74952fcd3d1d150a823026f68938c2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 20 May 2022 10:57:26 +0800 Subject: [PATCH 13/13] Move tuple_size/tuple_element for subrange to <__msvc_iter_core.hpp> --- stl/inc/xutility | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index c0c77621738..132dddb48be 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -3152,31 +3152,6 @@ namespace ranges { // 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; -}; - namespace ranges { struct dangling { constexpr dangling() noexcept = default;