From 753969e321f6055fde1cb82e2b3ae95a01382576 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 22 Nov 2022 00:30:50 +0800 Subject: [PATCH 1/3] Implement LWG-3545 --- stl/inc/xutility | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index b8a210a37a..8923cce06b 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -210,16 +210,6 @@ struct _Replace_first_parameter<_Newfirst, _Ty<_First, _Rest...>> { // given _Ty using type = _Ty<_Newfirst, _Rest...>; }; -template -struct _Get_element_type { - using type = typename _Get_first_parameter<_Ty>::type; -}; - -template -struct _Get_element_type<_Ty, void_t> { - using type = typename _Ty::element_type; -}; - template struct _Get_ptr_difference_type { using type = ptrdiff_t; @@ -281,16 +271,16 @@ void _Default_construct_in_place(_Ty& _Obj) noexcept(is_nothrow_default_construc ::new (_Voidify_iter(_STD addressof(_Obj))) _Ty; } -_EXPORT_STD template -struct pointer_traits { +template +struct _Ptr_traits_base { using pointer = _Ty; - using element_type = typename _Get_element_type<_Ty>::type; + using element_type = _Elem; using difference_type = typename _Get_ptr_difference_type<_Ty>::type; template using rebind = typename _Get_rebind_alias<_Ty, _Other>::type; - using _Reftype = conditional_t, char, element_type>&; + using _Reftype = conditional_t, char, _Elem>&; _NODISCARD static _CONSTEXPR20 pointer pointer_to(_Reftype _Val) noexcept( noexcept(_Ty::pointer_to(_Val))) /* strengthened */ { // Per LWG-3454 @@ -298,6 +288,20 @@ struct pointer_traits { } }; +template +struct _Ptr_traits_sfinae_layer {}; + +template +struct _Ptr_traits_sfinae_layer<_Ty, _Uty, void_t::type>> + : _Ptr_traits_base<_Ty, typename _Get_first_parameter<_Ty>::type> {}; + +template +struct _Ptr_traits_sfinae_layer<_Ty, void_t, void> + : _Ptr_traits_base<_Ty, typename _Ty::element_type> {}; + +_EXPORT_STD template +struct pointer_traits : _Ptr_traits_sfinae_layer<_Ty> {}; + template struct pointer_traits<_Ty*> { using pointer = _Ty*; From d5e325a65573ff8dee93488fbe6e514a95dfcdfa Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 22 Nov 2022 00:32:32 +0800 Subject: [PATCH 2/3] Add test files for LWG-3545 --- .../LWG3545_pointer_traits_sfinae/env.lst | 4 + .../test.compile.pass.cpp | 92 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 tests/std/tests/LWG3545_pointer_traits_sfinae/env.lst create mode 100644 tests/std/tests/LWG3545_pointer_traits_sfinae/test.compile.pass.cpp diff --git a/tests/std/tests/LWG3545_pointer_traits_sfinae/env.lst b/tests/std/tests/LWG3545_pointer_traits_sfinae/env.lst new file mode 100644 index 0000000000..19f025bd0e --- /dev/null +++ b/tests/std/tests/LWG3545_pointer_traits_sfinae/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/LWG3545_pointer_traits_sfinae/test.compile.pass.cpp b/tests/std/tests/LWG3545_pointer_traits_sfinae/test.compile.pass.cpp new file mode 100644 index 0000000000..256007544a --- /dev/null +++ b/tests/std/tests/LWG3545_pointer_traits_sfinae/test.compile.pass.cpp @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +using namespace std; + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__); + +template +constexpr bool has_memtype_element_type = false; + +template +constexpr bool has_memtype_element_type> = true; + +template +constexpr bool has_memtype_pointer = false; + +template +constexpr bool has_memtype_pointer> = true; + +template +constexpr bool has_memtype_difference_type = false; + +template +constexpr bool has_memtype_difference_type> = true; + +STATIC_ASSERT(!has_memtype_element_type>); +STATIC_ASSERT(!has_memtype_pointer>); +STATIC_ASSERT(!has_memtype_difference_type>); + +struct LackElementType { + using pointer = int; + using difference_type = int; + template + using rebind = int; +}; + +STATIC_ASSERT(!has_memtype_element_type>); +STATIC_ASSERT(!has_memtype_pointer>); +STATIC_ASSERT(!has_memtype_difference_type>); + +struct OnlyElementType { + using element_type = void; +}; + +STATIC_ASSERT(has_memtype_element_type>); +STATIC_ASSERT(has_memtype_pointer>); +STATIC_ASSERT(has_memtype_difference_type>); + +STATIC_ASSERT(is_same_v::element_type, void>); +STATIC_ASSERT(is_same_v::pointer, OnlyElementType>); +STATIC_ASSERT(is_same_v::difference_type, ptrdiff_t>); + +template +struct Templated { + using difference_type = I; +}; + +STATIC_ASSERT(has_memtype_element_type>>); +STATIC_ASSERT(has_memtype_pointer>>); +STATIC_ASSERT(has_memtype_difference_type>>); + +STATIC_ASSERT(is_same_v>::element_type, char>); +STATIC_ASSERT(is_same_v>::pointer, Templated>); +STATIC_ASSERT(is_same_v>::difference_type, char>); + +template +struct BadTemplated { + using difference_type = I; +}; + +STATIC_ASSERT(!has_memtype_element_type>>); +STATIC_ASSERT(!has_memtype_pointer>>); +STATIC_ASSERT(!has_memtype_difference_type>>); + +template +struct CheckPriority { + using element_type = T[42]; +}; + +STATIC_ASSERT(has_memtype_element_type>>); +STATIC_ASSERT(has_memtype_pointer>>); +STATIC_ASSERT(has_memtype_difference_type>>); + +STATIC_ASSERT(is_same_v>::element_type, char[42]>); +STATIC_ASSERT(is_same_v>::pointer, CheckPriority>); +STATIC_ASSERT(is_same_v>::difference_type, ptrdiff_t>); + +int main() {} // COMPILE-ONLY From fb04d3fe646a0050f70ea825efd1ac520b9fe466 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 22 Nov 2022 00:33:29 +0800 Subject: [PATCH 3/3] Add `LWG3545_pointer_traits_sfinae` to list --- tests/std/test.lst | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/test.lst b/tests/std/test.lst index 9af561348b..f656c5d20b 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -224,6 +224,7 @@ tests\LWG3146_excessive_unwrapping_ref_cref tests\LWG3234_math_special_overloads tests\LWG3422_seed_seq_ctors tests\LWG3480_directory_iterator_range +tests\LWG3545_pointer_traits_sfinae tests\LWG3610_iota_view_size_and_integer_class tests\P0019R8_atomic_ref tests\P0024R2_parallel_algorithms_adjacent_difference