Skip to content

Commit 7364b42

Browse files
Implement P3016R6 Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists (#5847)
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
1 parent 641410d commit 7364b42

File tree

10 files changed

+146
-84
lines changed

10 files changed

+146
-84
lines changed

stl/inc/initializer_list

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,19 @@ public:
5151
return static_cast<size_t>(_Last - _First);
5252
}
5353

54+
_NODISCARD constexpr bool empty() const noexcept {
55+
return _First == _Last;
56+
}
57+
58+
_NODISCARD constexpr const _Elem* data() const noexcept {
59+
return _First;
60+
}
61+
5462
private:
5563
const _Elem* _First;
5664
const _Elem* _Last;
5765
};
5866

59-
_EXPORT_STD template <class _Elem>
60-
_NODISCARD constexpr const _Elem* begin(initializer_list<_Elem> _Ilist) noexcept {
61-
return _Ilist.begin();
62-
}
63-
64-
_EXPORT_STD template <class _Elem>
65-
_NODISCARD constexpr const _Elem* end(initializer_list<_Elem> _Ilist) noexcept {
66-
return _Ilist.end();
67-
}
6867
_STD_END
6968

7069
// TRANSITION, non-_Ugly attribute tokens

stl/inc/valarray

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,9 @@ class valarray { // store array with various indexing options
5959
public:
6060
friend _Tidy_deallocate_guard<valarray>;
6161

62-
template <class _Ty2>
63-
friend _Ty2* begin(valarray<_Ty2>& _Array) noexcept /* strengthened */;
64-
65-
template <class _Ty2>
66-
friend const _Ty2* begin(const valarray<_Ty2>& _Array) noexcept /* strengthened */;
67-
68-
template <class _Ty2>
69-
friend _Ty2* end(valarray<_Ty2>& _Array) noexcept /* strengthened */;
70-
71-
template <class _Ty2>
72-
friend const _Ty2* end(const valarray<_Ty2>& _Array) noexcept /* strengthened */;
73-
74-
using value_type = _Ty;
62+
using value_type = _Ty;
63+
using iterator = _Ty*;
64+
using const_iterator = const _Ty*;
7565

7666
valarray() = default; // construct empty valarray
7767

@@ -411,6 +401,22 @@ public:
411401
return _Mysize;
412402
}
413403

404+
_NODISCARD iterator begin() noexcept /* strengthened */ {
405+
return _Myptr;
406+
}
407+
408+
_NODISCARD const_iterator begin() const noexcept /* strengthened */ {
409+
return _Myptr;
410+
}
411+
412+
_NODISCARD iterator end() noexcept /* strengthened */ {
413+
return _Myptr + _Mysize;
414+
}
415+
416+
_NODISCARD const_iterator end() const noexcept /* strengthened */ {
417+
return _Myptr + _Mysize;
418+
}
419+
414420
_NODISCARD const _Ty& operator[](size_t _Off) const noexcept /* strengthened */ {
415421
#if _MSVC_STL_HARDENING_VALARRAY || _ITERATOR_DEBUG_LEVEL != 0
416422
_STL_VERIFY(_Off < _Mysize, "valarray subscript out of range");
@@ -612,26 +618,6 @@ void swap(valarray<_Ty>& _Left, valarray<_Ty>& _Right) noexcept {
612618
_Left.swap(_Right);
613619
}
614620

615-
_EXPORT_STD template <class _Ty>
616-
_NODISCARD _Ty* begin(valarray<_Ty>& _Array) noexcept /* strengthened */ {
617-
return _Array._Myptr;
618-
}
619-
620-
_EXPORT_STD template <class _Ty>
621-
_NODISCARD const _Ty* begin(const valarray<_Ty>& _Array) noexcept /* strengthened */ {
622-
return _Array._Myptr;
623-
}
624-
625-
_EXPORT_STD template <class _Ty>
626-
_NODISCARD _Ty* end(valarray<_Ty>& _Array) noexcept /* strengthened */ {
627-
return _Array._Myptr + _Array.size();
628-
}
629-
630-
_EXPORT_STD template <class _Ty>
631-
_NODISCARD const _Ty* end(const valarray<_Ty>& _Array) noexcept /* strengthened */ {
632-
return _Array._Myptr + _Array.size();
633-
}
634-
635621
_EXPORT_STD template <class _Ty>
636622
_NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) {
637623
const size_t _Size = _Left.size();

stl/inc/xutility

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,26 +2142,23 @@ constexpr bool disable_sized_sentinel_for<reverse_iterator<_BidIt1>, reverse_ite
21422142
#endif // _HAS_CXX20
21432143

21442144
_EXPORT_STD template <class _Container>
2145-
_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */
2146-
-> decltype(_Cont.begin()) {
2145+
_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) -> decltype(_Cont.begin()) {
21472146
return _Cont.begin();
21482147
}
21492148

21502149
_EXPORT_STD template <class _Container>
2151-
_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */
2150+
_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) noexcept(noexcept(_Cont.begin()))
21522151
-> decltype(_Cont.begin()) {
21532152
return _Cont.begin();
21542153
}
21552154

21562155
_EXPORT_STD template <class _Container>
2157-
_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */
2158-
-> decltype(_Cont.end()) {
2156+
_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) {
21592157
return _Cont.end();
21602158
}
21612159

21622160
_EXPORT_STD template <class _Container>
2163-
_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */
2164-
-> decltype(_Cont.end()) {
2161+
_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) {
21652162
return _Cont.end();
21662163
}
21672164

@@ -2188,66 +2185,60 @@ _NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD e
21882185
}
21892186

21902187
_EXPORT_STD template <class _Container>
2191-
_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */
2192-
-> decltype(_Cont.rbegin()) {
2188+
_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) noexcept(noexcept(_Cont.rbegin())) -> decltype(_Cont.rbegin()) {
21932189
return _Cont.rbegin();
21942190
}
21952191

21962192
_EXPORT_STD template <class _Container>
2197-
_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */
2193+
_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) noexcept(noexcept(_Cont.rbegin()))
21982194
-> decltype(_Cont.rbegin()) {
21992195
return _Cont.rbegin();
22002196
}
22012197

22022198
_EXPORT_STD template <class _Container>
2203-
_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */
2204-
-> decltype(_Cont.rend()) {
2199+
_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) noexcept(noexcept(_Cont.rend())) -> decltype(_Cont.rend()) {
22052200
return _Cont.rend();
22062201
}
22072202

22082203
_EXPORT_STD template <class _Container>
2209-
_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */
2210-
-> decltype(_Cont.rend()) {
2204+
_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) noexcept(noexcept(_Cont.rend())) -> decltype(_Cont.rend()) {
22112205
return _Cont.rend();
22122206
}
22132207

22142208
_EXPORT_STD template <class _Ty, size_t _Size>
2215-
_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) noexcept /* strengthened */ {
2209+
_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) noexcept {
22162210
return reverse_iterator<_Ty*>(_Array + _Size);
22172211
}
22182212

22192213
_EXPORT_STD template <class _Ty, size_t _Size>
2220-
_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) noexcept /* strengthened */ {
2214+
_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) noexcept {
22212215
return reverse_iterator<_Ty*>(_Array);
22222216
}
22232217

22242218
_EXPORT_STD template <class _Elem>
2225-
_NODISCARD _CONSTEXPR17 reverse_iterator<const _Elem*> rbegin(initializer_list<_Elem> _Ilist) noexcept
2226-
/* strengthened */ {
2219+
_NODISCARD _CONSTEXPR17 reverse_iterator<const _Elem*> rbegin(initializer_list<_Elem> _Ilist) noexcept {
22272220
return reverse_iterator<const _Elem*>(_Ilist.end());
22282221
}
22292222

22302223
_EXPORT_STD template <class _Elem>
2231-
_NODISCARD _CONSTEXPR17 reverse_iterator<const _Elem*> rend(initializer_list<_Elem> _Ilist) noexcept
2232-
/* strengthened */ {
2224+
_NODISCARD _CONSTEXPR17 reverse_iterator<const _Elem*> rend(initializer_list<_Elem> _Ilist) noexcept {
22332225
return reverse_iterator<const _Elem*>(_Ilist.begin());
22342226
}
22352227

22362228
_EXPORT_STD template <class _Container>
2237-
_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(_STD rbegin(_Cont))) /* strengthened */
2229+
_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(_STD rbegin(_Cont)))
22382230
-> decltype(_STD rbegin(_Cont)) {
22392231
return _STD rbegin(_Cont);
22402232
}
22412233

22422234
_EXPORT_STD template <class _Container>
2243-
_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(_STD rend(_Cont))) /* strengthened */
2235+
_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(_STD rend(_Cont)))
22442236
-> decltype(_STD rend(_Cont)) {
22452237
return _STD rend(_Cont);
22462238
}
22472239

22482240
_EXPORT_STD template <class _Container>
2249-
_NODISCARD constexpr auto size(const _Container& _Cont) noexcept(noexcept(_Cont.size())) /* strengthened */
2250-
-> decltype(_Cont.size()) {
2241+
_NODISCARD constexpr auto size(const _Container& _Cont) noexcept(noexcept(_Cont.size())) -> decltype(_Cont.size()) {
22512242
return _Cont.size();
22522243
}
22532244

@@ -2258,8 +2249,7 @@ _NODISCARD constexpr size_t size(const _Ty (&)[_Size]) noexcept {
22582249

22592250
#if _HAS_CXX20
22602251
_EXPORT_STD template <class _Container>
2261-
_NODISCARD constexpr auto ssize(const _Container& _Cont) noexcept(noexcept(
2262-
static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(_Cont.size())>>>(_Cont.size()))) /* strengthened */
2252+
_NODISCARD constexpr auto ssize(const _Container& _Cont) noexcept(noexcept(_Cont.size()))
22632253
-> common_type_t<ptrdiff_t, make_signed_t<decltype(_Cont.size())>> {
22642254
using _Common = common_type_t<ptrdiff_t, make_signed_t<decltype(_Cont.size())>>;
22652255
return static_cast<_Common>(_Cont.size());
@@ -2272,8 +2262,7 @@ _NODISCARD constexpr ptrdiff_t ssize(const _Ty (&)[_Size]) noexcept {
22722262
#endif // _HAS_CXX20
22732263

22742264
_EXPORT_STD template <class _Container>
2275-
_NODISCARD_EMPTY_NON_MEMBER constexpr auto empty(const _Container& _Cont)
2276-
noexcept(noexcept(_Cont.empty())) /* strengthened */
2265+
_NODISCARD_EMPTY_NON_MEMBER constexpr auto empty(const _Container& _Cont) noexcept(noexcept(_Cont.empty()))
22772266
-> decltype(_Cont.empty()) {
22782267
return _Cont.empty();
22792268
}
@@ -2283,20 +2272,13 @@ _NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(const _Ty (&)[_Size]) noexcept
22832272
return false;
22842273
}
22852274

2286-
_EXPORT_STD template <class _Elem>
2287-
_NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept {
2288-
return _Ilist.size() == 0;
2289-
}
2290-
22912275
_EXPORT_STD template <class _Container>
2292-
_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */
2293-
-> decltype(_Cont.data()) {
2276+
_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) -> decltype(_Cont.data()) {
22942277
return _Cont.data();
22952278
}
22962279

22972280
_EXPORT_STD template <class _Container>
2298-
_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */
2299-
-> decltype(_Cont.data()) {
2281+
_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) -> decltype(_Cont.data()) {
23002282
return _Cont.data();
23012283
}
23022284

@@ -2305,11 +2287,6 @@ _NODISCARD constexpr _Ty* data(_Ty (&_Array)[_Size]) noexcept {
23052287
return _Array;
23062288
}
23072289

2308-
_EXPORT_STD template <class _Elem>
2309-
_NODISCARD constexpr const _Elem* data(initializer_list<_Elem> _Ilist) noexcept {
2310-
return _Ilist.begin();
2311-
}
2312-
23132290
#if _HAS_CXX20
23142291
#if _HAS_CXX23
23152292
_EXPORT_STD template <indirectly_readable _Ty>

stl/inc/yvals_core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
// (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only)
8181
// P2937R0 Freestanding Library: Remove strtok
8282
// P2968R2 Make std::ignore A First-Class Object
83+
// P3016R6 Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists
8384
// P3223R2 Making istream::ignore() Less Surprising
8485
// P3323R1 Forbid atomic<cv T>, Specify atomic_ref<cv T>
8586
// (for atomic<cv T>)
@@ -1578,6 +1579,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
15781579
#define __cpp_lib_freestanding_tuple 202306L
15791580
#define __cpp_lib_freestanding_utility 202306L
15801581
#define __cpp_lib_generic_associative_lookup 201304L
1582+
#define __cpp_lib_initializer_list 202511L
15811583
#define __cpp_lib_integer_sequence 201304L
15821584
#define __cpp_lib_integral_constant_callable 201304L
15831585
#define __cpp_lib_is_final 201402L
@@ -1595,6 +1597,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
15951597
#define __cpp_lib_transformation_trait_aliases 201304L
15961598
#define __cpp_lib_tuple_element_t 201402L
15971599
#define __cpp_lib_tuples_by_type 201304L
1600+
#define __cpp_lib_valarray 202511L
15981601

15991602
// C++17
16001603
#define __cpp_lib_addressof_constexpr 201603L

tests/libcxx/expected_results.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil
136136
# libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok"
137137
std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL
138138

139+
# libc++ has not implemented P3016R6: "Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists"
140+
std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp FAIL
141+
139142
# libc++ has not implemented P3323R1: "Forbid atomic<cv T>, Specify atomic_ref<cv T>"
140143
std/atomics/atomics.ref/member_types.compile.pass.cpp FAIL
141144

tests/std/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ tests\P2693R1_text_formatting_header_stacktrace
725725
tests\P2693R1_text_formatting_header_thread
726726
tests\P2693R1_text_formatting_stacktrace
727727
tests\P2693R1_text_formatting_thread_id
728+
tests\P3016R6_inconsistent_begin_end
728729
tests\P3107R5_enabled_specializations
729730
tests\P3349R1_contiguous_iterators_to_pointers
730731
tests\P3503R3_packaged_task_promise_with_allocator

tests/std/tests/Dev11_1074023_constexpr/test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ constexpr auto int64_max = numeric_limits<int64_t>::max();
5353
constexpr initializer_list<int> il;
5454
STATIC_ASSERT(il.size() == 0);
5555
STATIC_ASSERT(il.begin() == il.end());
56+
#if _HAS_CXX17
5657
STATIC_ASSERT(begin(il) == end(il));
58+
#endif // _HAS_CXX17
5759

5860
// TRANSITION,
5961
// constexpr error_category() noexcept;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
RUNALL_INCLUDE ..\usual_matrix.lst

0 commit comments

Comments
 (0)