diff --git a/stl/inc/initializer_list b/stl/inc/initializer_list index b5d6ae7370e..852c8c32149 100644 --- a/stl/inc/initializer_list +++ b/stl/inc/initializer_list @@ -51,20 +51,19 @@ public: return static_cast(_Last - _First); } + _NODISCARD constexpr bool empty() const noexcept { + return size() == 0; + } + + _NODISCARD constexpr const _Elem* data() const noexcept { + return begin(); + } + private: const _Elem* _First; const _Elem* _Last; }; -_EXPORT_STD template -_NODISCARD constexpr const _Elem* begin(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.begin(); -} - -_EXPORT_STD template -_NODISCARD constexpr const _Elem* end(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.end(); -} _STD_END // TRANSITION, non-_Ugly attribute tokens diff --git a/stl/inc/valarray b/stl/inc/valarray index a6a0909d9a8..73a6a0e8fa8 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -59,19 +59,9 @@ class valarray { // store array with various indexing options public: friend _Tidy_deallocate_guard; - template - friend _Ty2* begin(valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend const _Ty2* begin(const valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend _Ty2* end(valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend const _Ty2* end(const valarray<_Ty2>& _Array) noexcept /* strengthened */; - - using value_type = _Ty; + using value_type = _Ty; + using iterator = _Ty*; + using const_iterator = const _Ty*; valarray() = default; // construct empty valarray @@ -411,6 +401,22 @@ public: return _Mysize; } + _NODISCARD iterator begin() noexcept /* strengthened */ { + return _Myptr; + } + + _NODISCARD const_iterator begin() const noexcept /* strengthened */ { + return _Myptr; + } + + _NODISCARD iterator end() noexcept /* strengthened */ { + return _Myptr + _Mysize; + } + + _NODISCARD const_iterator end() const noexcept /* strengthened */ { + return _Myptr + _Mysize; + } + _NODISCARD const _Ty& operator[](size_t _Off) const noexcept /* strengthened */ { #if _MSVC_STL_HARDENING_VALARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "valarray subscript out of range"); @@ -612,26 +618,6 @@ void swap(valarray<_Ty>& _Left, valarray<_Ty>& _Right) noexcept { _Left.swap(_Right); } -_EXPORT_STD template -_NODISCARD _Ty* begin(valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr; -} - -_EXPORT_STD template -_NODISCARD const _Ty* begin(const valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr; -} - -_EXPORT_STD template -_NODISCARD _Ty* end(valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr + _Array.size(); -} - -_EXPORT_STD template -_NODISCARD const _Ty* end(const valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr + _Array.size(); -} - _EXPORT_STD template _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { const size_t _Size = _Left.size(); diff --git a/stl/inc/xutility b/stl/inc/xutility index bbaf4357d91..7815db74d9b 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2283,11 +2283,6 @@ _NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(const _Ty (&)[_Size]) noexcept return false; } -_EXPORT_STD template -_NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.size() == 0; -} - _EXPORT_STD template _NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ -> decltype(_Cont.data()) { @@ -2305,11 +2300,6 @@ _NODISCARD constexpr _Ty* data(_Ty (&_Array)[_Size]) noexcept { return _Array; } -_EXPORT_STD template -_NODISCARD constexpr const _Elem* data(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.begin(); -} - #if _HAS_CXX20 #if _HAS_CXX23 _EXPORT_STD template diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 0ccf71729ed..97dc0808a70 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -80,6 +80,7 @@ // (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only) // P2937R0 Freestanding Library: Remove strtok // P2968R2 Make std::ignore A First-Class Object +// P3016R6 Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists // P3223R2 Making istream::ignore() Less Surprising // P3323R1 Forbid atomic, Specify atomic_ref // (for atomic) @@ -1608,6 +1609,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_freestanding_tuple 202306L #define __cpp_lib_freestanding_utility 202306L #define __cpp_lib_generic_associative_lookup 201304L +#define __cpp_lib_initializer_list 202511L #define __cpp_lib_integer_sequence 201304L #define __cpp_lib_integral_constant_callable 201304L #define __cpp_lib_is_final 201402L @@ -1625,6 +1627,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_transformation_trait_aliases 201304L #define __cpp_lib_tuple_element_t 201402L #define __cpp_lib_tuples_by_type 201304L +#define __cpp_lib_valarray 202511L // C++17 #define __cpp_lib_addressof_constexpr 201603L diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 343abccc27a..156412a9bc1 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -142,6 +142,9 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil # libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok" std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL +# libc++ has not implemented P3016R6: "Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists" +std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp FAIL + # libc++ has not implemented P3323R1: "Forbid atomic, Specify atomic_ref" std/atomics/atomics.ref/member_types.compile.pass.cpp FAIL diff --git a/tests/std/test.lst b/tests/std/test.lst index c502981b96d..41a9aa8da45 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -720,6 +720,7 @@ tests\P2693R1_text_formatting_header_stacktrace tests\P2693R1_text_formatting_header_thread tests\P2693R1_text_formatting_stacktrace tests\P2693R1_text_formatting_thread_id +tests\P3016R6_inconsistent_begin_end tests\P3107R5_enabled_specializations tests\P3349R1_contiguous_iterators_to_pointers tests\P3503R3_packaged_task_promise_with_allocator diff --git a/tests/std/tests/Dev11_1074023_constexpr/test.cpp b/tests/std/tests/Dev11_1074023_constexpr/test.cpp index d9b87f87247..47092a0a47e 100644 --- a/tests/std/tests/Dev11_1074023_constexpr/test.cpp +++ b/tests/std/tests/Dev11_1074023_constexpr/test.cpp @@ -53,7 +53,9 @@ constexpr auto int64_max = numeric_limits::max(); constexpr initializer_list il; STATIC_ASSERT(il.size() == 0); STATIC_ASSERT(il.begin() == il.end()); +#if _HAS_CXX17 STATIC_ASSERT(begin(il) == end(il)); +#endif // _HAS_CXX17 // TRANSITION, // constexpr error_category() noexcept; diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst b/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/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/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp new file mode 100644 index 00000000000..ab63fa58fe5 --- /dev/null +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +namespace my { + + template + void begin(std::initializer_list); + + template + void end(std::initializer_list); + + template + void empty(std::initializer_list); + + template + void data(std::initializer_list); +} // namespace my + +_CONSTEXPR17 bool test_initializer_list() { + // Check that free functions in std still can be invoked on std::initializer_list + std::initializer_list il = {1, 2, 3}; + + using namespace std; + (void) begin(il); + (void) cbegin(il); + (void) end(il); + (void) cend(il); + (void) size(il); + (void) empty(il); + (void) data(il); + + return true; +} + +bool test_valarray() { + // Check that free functions in std can be invoked on std::valarray + std::valarray v{1}; + + using namespace std; + (void) begin(v); + (void) cbegin(v); // Did not compile before P3016R6 + (void) end(v); + (void) cend(v); // Did not compile before P3016R6 + (void) size(v); + // There are no members 'empty' and 'data' of valarray + // (void) empty(il); + // (void) data(il); + + return true; +} + +constexpr bool test_braced_init_list_iteration() { + int sum = 0; + for (int n : {1, 2, 3, 4}) { + sum += n; + } + return sum == 10; +} + + +int main() { + // Check that free functions in std can't be invoked with braced-initializer-list. + // If they could be invoked, the following expressions would be ambiguous between std:: and my:: + using namespace std; + using namespace my; + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + + test_initializer_list(); + test_valarray(); + test_braced_init_list_iteration(); + +#if _HAS_CXX17 + STATIC_ASSERT(test_initializer_list()); +#endif // _HAS_CXX17 + // STATIC_ASSERT(test_valarray()); // valarray is not literal + STATIC_ASSERT(test_braced_init_list_iteration()); +} diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index fe5fbd82a9a..67578b87396 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -1048,3 +1048,7 @@ STATIC_ASSERT(__cpp_lib_variant == 202102L); #endif STATIC_ASSERT(__cpp_lib_void_t == 201411L); + +STATIC_ASSERT(__cpp_lib_initializer_list == 202511L); + +STATIC_ASSERT(__cpp_lib_valarray == 202511L);