From 9d6717146afe810bfeab88ecf3571bc57321a0d3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 21 Jun 2023 02:06:30 +0800 Subject: [PATCH 01/10] Conversion --- stl/inc/iterator | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stl/inc/iterator b/stl/inc/iterator index 180abaa4c2f..0794589a879 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1488,6 +1488,11 @@ public: _STL_VERIFY(_Index <= _Size, "checked_array_iterator construction index out of range"); } + template , int> = 0> + constexpr operator checked_array_iterator() const noexcept { + return checked_array_iterator{_Myarray, _Mysize, _Myindex}; + } + _NODISCARD constexpr _Ptr base() const noexcept { return _Myarray + _Myindex; } @@ -1684,6 +1689,11 @@ public: constexpr explicit unchecked_array_iterator(const _Ptr _Src) noexcept : _Myptr(_Src) {} + template , int> = 0> + constexpr operator unchecked_array_iterator() const noexcept { + return unchecked_array_iterator{_Myptr}; + } + _NODISCARD constexpr _Ptr base() const noexcept { return _Myptr; } From b4fe05d22c61fd908d558155dedb45ffebd388a3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 21 Jun 2023 02:07:04 +0800 Subject: [PATCH 02/10] Modernization --- stl/inc/iterator | 50 ++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 0794589a879..46a1660d865 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1472,16 +1472,22 @@ using _STD size_t; template class checked_array_iterator { // wrap a pointer with checking - static_assert(_STD is_pointer_v<_Ptr>, "checked_array_iterator requires pointers"); +private: + using _Pointee_type = _STD remove_pointer_t<_Ptr>; + static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, + "checked_array_iterator requires pointers to objects"); public: - using iterator_category = typename iterator_traits<_Ptr>::iterator_category; - using value_type = typename iterator_traits<_Ptr>::value_type; - using difference_type = typename iterator_traits<_Ptr>::difference_type; - using pointer = typename iterator_traits<_Ptr>::pointer; - using reference = typename iterator_traits<_Ptr>::reference; + using iterator_category = _STD random_access_iterator_tag; + using value_type = _STD remove_cv_t<_Pointee_type>; + using difference_type = _STD ptrdiff_t; + using pointer = _Ptr; + using reference = _Pointee_type&; +#ifdef __cpp_lib_concepts + using iterator_concept = _STD contiguous_iterator_tag; +#endif // __cpp_lib_concepts - constexpr checked_array_iterator() noexcept : _Myarray(nullptr), _Mysize(0), _Myindex(0) {} + constexpr checked_array_iterator() = default; constexpr checked_array_iterator(const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept : _Myarray(_Array), _Mysize(_Size), _Myindex(_Index) { @@ -1663,29 +1669,35 @@ public: } private: - _Ptr _Myarray; // beginning of array - size_t _Mysize; // size of array - size_t _Myindex; // offset into array + _Ptr _Myarray = nullptr; // beginning of array + size_t _Mysize = 0; // size of array + size_t _Myindex = 0; // offset into array }; template _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( - const _Ptr _Array, const size_t _Size, const size_t _Index = 0) { + const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept { return checked_array_iterator<_Ptr>(_Array, _Size, _Index); } template class unchecked_array_iterator { // wrap a pointer without checking, to silence warnings - static_assert(_STD is_pointer_v<_Ptr>, "unchecked_array_iterator requires pointers"); +private: + using _Pointee_type = _STD remove_pointer_t<_Ptr>; + static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, + "unchecked_array_iterator requires pointers to objects"); public: - using iterator_category = typename iterator_traits<_Ptr>::iterator_category; - using value_type = typename iterator_traits<_Ptr>::value_type; - using difference_type = typename iterator_traits<_Ptr>::difference_type; - using pointer = typename iterator_traits<_Ptr>::pointer; - using reference = typename iterator_traits<_Ptr>::reference; + using iterator_category = _STD random_access_iterator_tag; + using value_type = _STD remove_cv_t<_Pointee_type>; + using difference_type = _STD ptrdiff_t; + using pointer = _Ptr; + using reference = _Pointee_type&; +#ifdef __cpp_lib_concepts + using iterator_concept = _STD contiguous_iterator_tag; +#endif // __cpp_lib_concepts - constexpr unchecked_array_iterator() noexcept : _Myptr(nullptr) {} + constexpr unchecked_array_iterator() = default; constexpr explicit unchecked_array_iterator(const _Ptr _Src) noexcept : _Myptr(_Src) {} @@ -1812,7 +1824,7 @@ public: } private: - _Ptr _Myptr; // underlying pointer + _Ptr _Myptr = nullptr; // underlying pointer }; template From 144fa321fd60056c5382390bb5b7d34a2ea53c74 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 00:20:32 +0800 Subject: [PATCH 03/10] Deprecation --- stl/inc/iterator | 9 +++++---- stl/inc/yvals_core.h | 14 +++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 46a1660d865..00fc94625d6 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1471,7 +1471,7 @@ using _STD iterator_traits; using _STD size_t; template -class checked_array_iterator { // wrap a pointer with checking +class _CXX_DEPRECATE_EXT_ARR_ITERS checked_array_iterator { // wrap a pointer with checking private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1675,13 +1675,13 @@ private: }; template -_NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( +_CXX_DEPRECATE_EXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept { return checked_array_iterator<_Ptr>(_Array, _Size, _Index); } template -class unchecked_array_iterator { // wrap a pointer without checking, to silence warnings +class _CXX_DEPRECATE_EXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1828,7 +1828,8 @@ private: }; template -_NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator(const _Ptr _It) noexcept { +_CXX_DEPRECATE_EXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( + const _Ptr _It) noexcept { return unchecked_array_iterator<_Ptr>(_It); } _STDEXT_END diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ceb2fce5ed8..a6cfc747066 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1445,7 +1445,19 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define _CXX23_DEPRECATE_DENORM #endif // ^^^ warning disabled ^^^ -// next warning number: STL4043 +#if _HAS_CXX17 && !defined(_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING) \ + && !defined(_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) +#define _CXX_DEPRECATE_EXT_ARR_ITERS \ + [[deprecated( \ + "warning STL4043: stdext::checked_array_iterator, stdext::unchecked_array_iterator, and related factory " \ + "functions are non-Standard extensions and will be removed in future. std::span (since C++20) and gsl::span " \ + "can be used instead. You can define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING or " \ + "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to suppress this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _CXX_DEPRECATE_EXT_ARR_ITERS +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4044 // next error number: STL1006 From bf07345de862a5e74ac6d7b9e0ba7a3254166a75 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 00:24:07 +0800 Subject: [PATCH 04/10] Suppress deprecation in tests --- tests/std/tests/Dev10_500860_overloaded_address_of/test.cpp | 1 + .../Dev10_709166_checked_and_unchecked_array_iterator/test.cpp | 2 ++ .../test.compile.pass.cpp | 2 ++ tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp | 1 + .../tests/P0040R3_extending_memory_management_tools/test.cpp | 2 ++ tests/std/tests/P1614R2_spaceship/test.cpp | 2 ++ .../test.compile.pass.cpp | 1 + tests/std/tests/VSO_0299624_checked_array_iterator_idl/test.cpp | 2 ++ 8 files changed, 13 insertions(+) diff --git a/tests/std/tests/Dev10_500860_overloaded_address_of/test.cpp b/tests/std/tests/Dev10_500860_overloaded_address_of/test.cpp index 93b4ead540d..5718201bf03 100644 --- a/tests/std/tests/Dev10_500860_overloaded_address_of/test.cpp +++ b/tests/std/tests/Dev10_500860_overloaded_address_of/test.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING #define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS #include diff --git a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp index 5addf960bdc..2c8b4b5e198 100644 --- a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp +++ b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING + #include #include #include diff --git a/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.compile.pass.cpp b/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.compile.pass.cpp index 4e7f0833bce..754b6a632f2 100644 --- a/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.compile.pass.cpp +++ b/tests/std/tests/Dev10_709168_marking_iterators_as_checked/test.compile.pass.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING + #include #include #include diff --git a/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp b/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp index f9ea851fcc1..64e3e9d2cf4 100644 --- a/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp +++ b/tests/std/tests/Dev11_0000000_null_forward_iterators/test.cpp @@ -3,6 +3,7 @@ #define _SILENCE_CXX23_ALIGNED_UNION_DEPRECATION_WARNING #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING #include #include diff --git a/tests/std/tests/P0040R3_extending_memory_management_tools/test.cpp b/tests/std/tests/P0040R3_extending_memory_management_tools/test.cpp index 771425af7e0..dce64b84442 100644 --- a/tests/std/tests/P0040R3_extending_memory_management_tools/test.cpp +++ b/tests/std/tests/P0040R3_extending_memory_management_tools/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING + #include #include #include diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index aee2e256ee3..45b77573ce6 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING + #include #include #include diff --git a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp index 7ade4b41b17..690dd4be34a 100644 --- a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp @@ -18,6 +18,7 @@ #define _SILENCE_CXX20_REL_OPS_DEPRECATION_WARNING #define _SILENCE_CXX20_U8PATH_DEPRECATION_WARNING #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING #define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING #define _USE_NAMED_IDL_NAMESPACE 1 diff --git a/tests/std/tests/VSO_0299624_checked_array_iterator_idl/test.cpp b/tests/std/tests/VSO_0299624_checked_array_iterator_idl/test.cpp index 91aee8682f3..f5da03d2735 100644 --- a/tests/std/tests/VSO_0299624_checked_array_iterator_idl/test.cpp +++ b/tests/std/tests/VSO_0299624_checked_array_iterator_idl/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING + #include #include From 562bfd051f6c6cdc66dc787e4958225e3407359f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 00:44:28 +0800 Subject: [PATCH 05/10] Test for modernization --- .../test.cpp | 99 +++++++++++++------ 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp index 2c8b4b5e198..00e47d97a63 100644 --- a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp +++ b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp @@ -10,6 +10,69 @@ #include #include +template +void check_checked_array_iterator_category_and_convertibility() { + static_assert( + std::is_same_v::iterator_category, std::random_access_iterator_tag>, + "stdext::checked_array_iterator::iterator_category is wrong!"); + + static_assert(std::is_same_v::value_type, std::remove_cv_t>, + "stdext::checked_array_iterator::value_type is wrong!"); + + static_assert(std::is_same_v::difference_type, ptrdiff_t>, + "stdext::checked_array_iterator::difference_type is wrong!"); + + static_assert(std::is_same_v::pointer, T*>, + "stdext::checked_array_iterator::pointer is wrong!"); + + static_assert(std::is_same_v::reference, T&>, + "stdext::checked_array_iterator::reference is wrong!"); + + static_assert(std::is_convertible_v, stdext::checked_array_iterator>, + "stdext::checked_array_iterator should be convertible to stdext::checked_array_iterator"); + +#ifdef __cpp_lib_concepts + static_assert( + std::is_same_v::iterator_concept, std::contiguous_iterator_tag>, + "stdext::checked_array_iterator::iterator_concept is wrong!"); + + static_assert(std::contiguous_iterator>, + "stdext::checked_array_iterator is not a contiguous iterator type!"); +#endif // __cpp_lib_concepts +} + +template +void check_unchecked_array_iterator_category_and_convertibility() { + static_assert(std::is_same_v::iterator_category, + std::random_access_iterator_tag>, + "stdext::unchecked_array_iterator::iterator_category is wrong!"); + + static_assert(std::is_same_v::value_type, std::remove_cv_t>, + "stdext::unchecked_array_iterator::value_type is wrong!"); + + static_assert(std::is_same_v::difference_type, ptrdiff_t>, + "stdext::unchecked_array_iterator::difference_type is wrong!"); + + static_assert(std::is_same_v::pointer, T*>, + "stdext::unchecked_array_iterator::pointer is wrong!"); + + static_assert(std::is_same_v::reference, T&>, + "stdext::unchecked_array_iterator::reference is wrong!"); + + static_assert( + std::is_convertible_v, stdext::unchecked_array_iterator>, + "stdext::unchecked_array_iterator should be convertible to stdext::unchecked_array_iterator"); + +#ifdef __cpp_lib_concepts + static_assert( + std::is_same_v::iterator_concept, std::contiguous_iterator_tag>, + "stdext::unchecked_array_iterator::iterator_concept is wrong!"); + + static_assert(std::contiguous_iterator>, + "stdext::unchecked_array_iterator is not a contiguous iterator type!"); +#endif // __cpp_lib_concepts +} + int main() { { int* const p = new int[9]; @@ -31,21 +94,9 @@ int main() { "stdext::make_checked_array_iterator(p, 9, 3)'s return type is wrong!"); - static_assert( - std::is_same_v::iterator_category, std::random_access_iterator_tag>, - "stdext::checked_array_iterator::iterator_category is wrong!"); - - static_assert(std::is_same_v::value_type, int>, - "stdext::checked_array_iterator::value_type is wrong!"); - - static_assert(std::is_same_v::difference_type, ptrdiff_t>, - "stdext::checked_array_iterator::difference_type is wrong!"); - - static_assert(std::is_same_v::pointer, int*>, - "stdext::checked_array_iterator::pointer is wrong!"); - - static_assert(std::is_same_v::reference, int&>, - "stdext::checked_array_iterator::reference is wrong!"); + check_checked_array_iterator_category_and_convertibility(); + check_checked_array_iterator_category_and_convertibility(); + check_checked_array_iterator_category_and_convertibility>(); { @@ -205,21 +256,9 @@ int main() { "stdext::make_unchecked_array_iterator(p + 3)'s return type is wrong!"); - static_assert( - std::is_same_v::iterator_category, std::random_access_iterator_tag>, - "stdext::unchecked_array_iterator::iterator_category is wrong!"); - - static_assert(std::is_same_v::value_type, int>, - "stdext::unchecked_array_iterator::value_type is wrong!"); - - static_assert(std::is_same_v::difference_type, ptrdiff_t>, - "stdext::unchecked_array_iterator::difference_type is wrong!"); - - static_assert(std::is_same_v::pointer, int*>, - "stdext::unchecked_array_iterator::pointer is wrong!"); - - static_assert(std::is_same_v::reference, int&>, - "stdext::unchecked_array_iterator::reference is wrong!"); + check_unchecked_array_iterator_category_and_convertibility(); + check_unchecked_array_iterator_category_and_convertibility(); + check_unchecked_array_iterator_category_and_convertibility>(); { From 7644d5e1bf731c303ba3622faed7f8bbc41a0de0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 01:09:34 +0800 Subject: [PATCH 06/10] Consistently use `_CXX_DEPRECATE_STDEXT_ARR_ITERS` --- stl/inc/iterator | 8 ++++---- stl/inc/yvals_core.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 00fc94625d6..57f9a866821 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1471,7 +1471,7 @@ using _STD iterator_traits; using _STD size_t; template -class _CXX_DEPRECATE_EXT_ARR_ITERS checked_array_iterator { // wrap a pointer with checking +class _CXX_DEPRECATE_STDEXT_ARR_ITERS checked_array_iterator { // wrap a pointer with checking private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1675,13 +1675,13 @@ private: }; template -_CXX_DEPRECATE_EXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( +_CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept { return checked_array_iterator<_Ptr>(_Array, _Size, _Index); } template -class _CXX_DEPRECATE_EXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings +class _CXX_DEPRECATE_STDEXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1828,7 +1828,7 @@ private: }; template -_CXX_DEPRECATE_EXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( +_CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( const _Ptr _It) noexcept { return unchecked_array_iterator<_Ptr>(_It); } diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index a6cfc747066..6aef8d3280f 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1447,14 +1447,14 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX17 && !defined(_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING) \ && !defined(_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) -#define _CXX_DEPRECATE_EXT_ARR_ITERS \ +#define _CXX_DEPRECATE_STDEXT_ARR_ITERS \ [[deprecated( \ "warning STL4043: stdext::checked_array_iterator, stdext::unchecked_array_iterator, and related factory " \ "functions are non-Standard extensions and will be removed in future. std::span (since C++20) and gsl::span " \ "can be used instead. You can define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING or " \ "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to suppress this warning.")]] #else // ^^^ warning enabled / warning disabled vvv -#define _CXX_DEPRECATE_EXT_ARR_ITERS +#define _CXX_DEPRECATE_STDEXT_ARR_ITERS #endif // ^^^ warning disabled ^^^ // next warning number: STL4044 From 5e7ea6586f1c9df6a66369cbf5205df7ff9f6a44 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 01:26:48 +0800 Subject: [PATCH 07/10] Disable and restore deprecation warnings. --- stl/inc/iterator | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stl/inc/iterator b/stl/inc/iterator index 57f9a866821..244b35e965e 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1494,10 +1494,12 @@ public: _STL_VERIFY(_Index <= _Size, "checked_array_iterator construction index out of range"); } + _STL_DISABLE_DEPRECATED_WARNING template , int> = 0> constexpr operator checked_array_iterator() const noexcept { return checked_array_iterator{_Myarray, _Mysize, _Myindex}; } + _STL_RESTORE_DEPRECATED_WARNING _NODISCARD constexpr _Ptr base() const noexcept { return _Myarray + _Myindex; @@ -1674,11 +1676,13 @@ private: size_t _Myindex = 0; // offset into array }; +_STL_DISABLE_DEPRECATED_WARNING template _CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept { return checked_array_iterator<_Ptr>(_Array, _Size, _Index); } +_STL_RESTORE_DEPRECATED_WARNING template class _CXX_DEPRECATE_STDEXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings @@ -1701,10 +1705,12 @@ public: constexpr explicit unchecked_array_iterator(const _Ptr _Src) noexcept : _Myptr(_Src) {} + _STL_DISABLE_DEPRECATED_WARNING template , int> = 0> constexpr operator unchecked_array_iterator() const noexcept { return unchecked_array_iterator{_Myptr}; } + _STL_RESTORE_DEPRECATED_WARNING _NODISCARD constexpr _Ptr base() const noexcept { return _Myptr; @@ -1827,11 +1833,13 @@ private: _Ptr _Myptr = nullptr; // underlying pointer }; +_STL_DISABLE_DEPRECATED_WARNING template _CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( const _Ptr _It) noexcept { return unchecked_array_iterator<_Ptr>(_It); } +_STL_RESTORE_DEPRECATED_WARNING _STDEXT_END #pragma pop_macro("new") From df87436260be291e2b9c7c3f00df0c467e1857e2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 15:21:06 +0800 Subject: [PATCH 08/10] Address @CaseyCarter's review comments Completing the story of contiguous iterators. --- stl/inc/iterator | 17 +++ .../test.cpp | 108 ++++++++++-------- 2 files changed, 80 insertions(+), 45 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 244b35e965e..9038346bc49 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1842,6 +1842,23 @@ _CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_u _STL_RESTORE_DEPRECATED_WARNING _STDEXT_END +#if _HAS_CXX20 +_STD_BEGIN +_STL_DISABLE_DEPRECATED_WARNING +template +struct _CXX_DEPRECATE_STDEXT_ARR_ITERS pointer_traits<_STDEXT checked_array_iterator<_Ty*>> { + using pointer = _STDEXT checked_array_iterator<_Ty*>; + using element_type = _Ty; + using difference_type = ptrdiff_t; + + _NODISCARD static constexpr element_type* to_address(const pointer _Iter) noexcept { + return _Iter._Unwrapped(); + } +}; +_STL_RESTORE_DEPRECATED_WARNING +_STD_END +#endif // _HAS_CXX20 + #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) diff --git a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp index 00e47d97a63..94cf411ab70 100644 --- a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp +++ b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp @@ -10,71 +10,62 @@ #include #include +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + template void check_checked_array_iterator_category_and_convertibility() { - static_assert( - std::is_same_v::iterator_category, std::random_access_iterator_tag>, - "stdext::checked_array_iterator::iterator_category is wrong!"); + STATIC_ASSERT(std::is_same_v::iterator_category, + std::random_access_iterator_tag>); - static_assert(std::is_same_v::value_type, std::remove_cv_t>, - "stdext::checked_array_iterator::value_type is wrong!"); + STATIC_ASSERT(std::is_same_v::value_type, std::remove_cv_t>); - static_assert(std::is_same_v::difference_type, ptrdiff_t>, - "stdext::checked_array_iterator::difference_type is wrong!"); + STATIC_ASSERT(std::is_same_v::difference_type, std::ptrdiff_t>); - static_assert(std::is_same_v::pointer, T*>, - "stdext::checked_array_iterator::pointer is wrong!"); + STATIC_ASSERT(std::is_same_v::pointer, T*>); - static_assert(std::is_same_v::reference, T&>, - "stdext::checked_array_iterator::reference is wrong!"); + STATIC_ASSERT(std::is_same_v::reference, T&>); - static_assert(std::is_convertible_v, stdext::checked_array_iterator>, - "stdext::checked_array_iterator should be convertible to stdext::checked_array_iterator"); + STATIC_ASSERT(std::is_convertible_v, stdext::checked_array_iterator>); #ifdef __cpp_lib_concepts - static_assert( - std::is_same_v::iterator_concept, std::contiguous_iterator_tag>, - "stdext::checked_array_iterator::iterator_concept is wrong!"); + STATIC_ASSERT( + std::is_same_v::iterator_concept, std::contiguous_iterator_tag>); - static_assert(std::contiguous_iterator>, - "stdext::checked_array_iterator is not a contiguous iterator type!"); + STATIC_ASSERT(std::contiguous_iterator>); #endif // __cpp_lib_concepts } template void check_unchecked_array_iterator_category_and_convertibility() { - static_assert(std::is_same_v::iterator_category, - std::random_access_iterator_tag>, - "stdext::unchecked_array_iterator::iterator_category is wrong!"); + STATIC_ASSERT(std::is_same_v::iterator_category, + std::random_access_iterator_tag>); - static_assert(std::is_same_v::value_type, std::remove_cv_t>, - "stdext::unchecked_array_iterator::value_type is wrong!"); + STATIC_ASSERT(std::is_same_v::value_type, std::remove_cv_t>); - static_assert(std::is_same_v::difference_type, ptrdiff_t>, - "stdext::unchecked_array_iterator::difference_type is wrong!"); + STATIC_ASSERT(std::is_same_v::difference_type, std::ptrdiff_t>); - static_assert(std::is_same_v::pointer, T*>, - "stdext::unchecked_array_iterator::pointer is wrong!"); + STATIC_ASSERT(std::is_same_v::pointer, T*>); - static_assert(std::is_same_v::reference, T&>, - "stdext::unchecked_array_iterator::reference is wrong!"); + STATIC_ASSERT(std::is_same_v::reference, T&>); - static_assert( - std::is_convertible_v, stdext::unchecked_array_iterator>, - "stdext::unchecked_array_iterator should be convertible to stdext::unchecked_array_iterator"); + STATIC_ASSERT( + std::is_convertible_v, stdext::unchecked_array_iterator>); #ifdef __cpp_lib_concepts - static_assert( - std::is_same_v::iterator_concept, std::contiguous_iterator_tag>, - "stdext::unchecked_array_iterator::iterator_concept is wrong!"); + STATIC_ASSERT( + std::is_same_v::iterator_concept, std::contiguous_iterator_tag>); - static_assert(std::contiguous_iterator>, - "stdext::unchecked_array_iterator is not a contiguous iterator type!"); + STATIC_ASSERT(std::contiguous_iterator>); #endif // __cpp_lib_concepts } int main() { { + check_checked_array_iterator_category_and_convertibility(); + check_checked_array_iterator_category_and_convertibility(); + check_checked_array_iterator_category_and_convertibility>(); + + int* const p = new int[9]; for (int i = 0; i < 9; ++i) { @@ -87,16 +78,27 @@ int main() { static_assert(std::is_same_v>, "stdext::make_checked_array_iterator(p, 9)'s return type is wrong!"); +#if _HAS_CXX20 + assert(std::to_address(cat) == &*cat); + assert(std::to_address(cat + 8) == &*cat + 8); + assert(std::to_address(cat + 8) == std::to_address(cat) + 8); + assert(std::to_address(cat + 9) == std::to_address(cat) + 9); +#endif // _HAS_CXX20 + auto dog = stdext::make_checked_array_iterator(p, 9, 3); static_assert(std::is_same_v>, "stdext::make_checked_array_iterator(p, 9, 3)'s return type is wrong!"); - - check_checked_array_iterator_category_and_convertibility(); - check_checked_array_iterator_category_and_convertibility(); - check_checked_array_iterator_category_and_convertibility>(); +#if _HAS_CXX20 + assert(std::to_address(dog) == &*dog); + assert(std::to_address(dog + 5) == &*dog + 5); + assert(std::to_address(dog + 5) == std::to_address(dog) + 5); + assert(std::to_address(dog - 3) == &*dog - 3); + assert(std::to_address(dog - 3) == std::to_address(dog) - 3); + assert(std::to_address(dog + 6) == std::to_address(dog) + 6); +#endif // _HAS_CXX20 { @@ -237,6 +239,11 @@ int main() { } { + check_unchecked_array_iterator_category_and_convertibility(); + check_unchecked_array_iterator_category_and_convertibility(); + check_unchecked_array_iterator_category_and_convertibility>(); + + int* const p = new int[9]; for (int i = 0; i < 9; ++i) { @@ -249,16 +256,27 @@ int main() { static_assert(std::is_same_v>, "stdext::make_unchecked_array_iterator(p)'s return type is wrong!"); +#if _HAS_CXX20 + assert(std::to_address(cat) == &*cat); + assert(std::to_address(cat + 8) == &*cat + 8); + assert(std::to_address(cat + 8) == std::to_address(cat) + 8); + assert(std::to_address(cat + 9) == std::to_address(cat) + 9); +#endif // _HAS_CXX20 + auto dog = stdext::make_unchecked_array_iterator(p + 3); static_assert(std::is_same_v>, "stdext::make_unchecked_array_iterator(p + 3)'s return type is wrong!"); - - check_unchecked_array_iterator_category_and_convertibility(); - check_unchecked_array_iterator_category_and_convertibility(); - check_unchecked_array_iterator_category_and_convertibility>(); +#if _HAS_CXX20 + assert(std::to_address(dog) == &*dog); + assert(std::to_address(dog + 5) == &*dog + 5); + assert(std::to_address(dog + 5) == std::to_address(dog) + 5); + assert(std::to_address(dog - 3) == &*dog - 3); + assert(std::to_address(dog - 3) == std::to_address(dog) - 3); + assert(std::to_address(dog + 6) == std::to_address(dog) + 6); +#endif // _HAS_CXX20 { From 7dde1f9439ff1b3db4412f1b147be6c55c7bebb2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Jun 2023 16:03:27 +0800 Subject: [PATCH 09/10] Convert remaining `static_assert` to `STATIC_ASSERT` --- .../test.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp index 94cf411ab70..aae64d9a0ab 100644 --- a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp +++ b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp @@ -75,8 +75,7 @@ int main() { auto cat = stdext::make_checked_array_iterator(p, 9); - static_assert(std::is_same_v>, - "stdext::make_checked_array_iterator(p, 9)'s return type is wrong!"); + STATIC_ASSERT(std::is_same_v>); #if _HAS_CXX20 assert(std::to_address(cat) == &*cat); @@ -88,8 +87,7 @@ int main() { auto dog = stdext::make_checked_array_iterator(p, 9, 3); - static_assert(std::is_same_v>, - "stdext::make_checked_array_iterator(p, 9, 3)'s return type is wrong!"); + STATIC_ASSERT(std::is_same_v>); #if _HAS_CXX20 assert(std::to_address(dog) == &*dog); @@ -253,8 +251,7 @@ int main() { auto cat = stdext::make_unchecked_array_iterator(p); - static_assert(std::is_same_v>, - "stdext::make_unchecked_array_iterator(p)'s return type is wrong!"); + STATIC_ASSERT(std::is_same_v>); #if _HAS_CXX20 assert(std::to_address(cat) == &*cat); @@ -266,8 +263,7 @@ int main() { auto dog = stdext::make_unchecked_array_iterator(p + 3); - static_assert(std::is_same_v>, - "stdext::make_unchecked_array_iterator(p + 3)'s return type is wrong!"); + STATIC_ASSERT(std::is_same_v>); #if _HAS_CXX20 assert(std::to_address(dog) == &*dog); From 777bf8833c7145556e827383e905431ab84c4805 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 30 Jun 2023 18:17:56 -0700 Subject: [PATCH 10/10] Code review feedback. --- stl/inc/iterator | 11 +++++------ stl/inc/yvals_core.h | 12 ++++++------ .../test.cpp | 3 +++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 9038346bc49..48089f6d0a9 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1467,11 +1467,10 @@ struct iterator_traits> : iterator_traits<_Iter> { _STD_END _STDEXT_BEGIN -using _STD iterator_traits; using _STD size_t; template -class _CXX_DEPRECATE_STDEXT_ARR_ITERS checked_array_iterator { // wrap a pointer with checking +class _DEPRECATE_STDEXT_ARR_ITERS checked_array_iterator { // wrap a pointer with checking private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1678,14 +1677,14 @@ private: _STL_DISABLE_DEPRECATED_WARNING template -_CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( +_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD constexpr checked_array_iterator<_Ptr> make_checked_array_iterator( const _Ptr _Array, const size_t _Size, const size_t _Index = 0) noexcept { return checked_array_iterator<_Ptr>(_Array, _Size, _Index); } _STL_RESTORE_DEPRECATED_WARNING template -class _CXX_DEPRECATE_STDEXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings +class _DEPRECATE_STDEXT_ARR_ITERS unchecked_array_iterator { // wrap a pointer without checking, to silence warnings private: using _Pointee_type = _STD remove_pointer_t<_Ptr>; static_assert(_STD is_pointer_v<_Ptr> && _STD is_object_v<_Pointee_type>, @@ -1835,7 +1834,7 @@ private: _STL_DISABLE_DEPRECATED_WARNING template -_CXX_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( +_DEPRECATE_STDEXT_ARR_ITERS _NODISCARD unchecked_array_iterator<_Ptr> make_unchecked_array_iterator( const _Ptr _It) noexcept { return unchecked_array_iterator<_Ptr>(_It); } @@ -1846,7 +1845,7 @@ _STDEXT_END _STD_BEGIN _STL_DISABLE_DEPRECATED_WARNING template -struct _CXX_DEPRECATE_STDEXT_ARR_ITERS pointer_traits<_STDEXT checked_array_iterator<_Ty*>> { +struct pointer_traits<_STDEXT checked_array_iterator<_Ty*>> { using pointer = _STDEXT checked_array_iterator<_Ty*>; using element_type = _Ty; using difference_type = ptrdiff_t; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 6aef8d3280f..ea78d77138b 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1447,14 +1447,14 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX17 && !defined(_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING) \ && !defined(_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) -#define _CXX_DEPRECATE_STDEXT_ARR_ITERS \ - [[deprecated( \ - "warning STL4043: stdext::checked_array_iterator, stdext::unchecked_array_iterator, and related factory " \ - "functions are non-Standard extensions and will be removed in future. std::span (since C++20) and gsl::span " \ - "can be used instead. You can define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING or " \ +#define _DEPRECATE_STDEXT_ARR_ITERS \ + [[deprecated( \ + "warning STL4043: stdext::checked_array_iterator, stdext::unchecked_array_iterator, and related factory " \ + "functions are non-Standard extensions and will be removed in the future. std::span (since C++20) " \ + "and gsl::span can be used instead. You can define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING or " \ "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to suppress this warning.")]] #else // ^^^ warning enabled / warning disabled vvv -#define _CXX_DEPRECATE_STDEXT_ARR_ITERS +#define _DEPRECATE_STDEXT_ARR_ITERS #endif // ^^^ warning disabled ^^^ // next warning number: STL4044 diff --git a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp index aae64d9a0ab..a1f8f5b611f 100644 --- a/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp +++ b/tests/std/tests/Dev10_709166_checked_and_unchecked_array_iterator/test.cpp @@ -5,7 +5,10 @@ #include #include +#include #include +#include +#include #include #include #include