Skip to content

Commit ce41ce1

Browse files
committed
Merge branch 'master' into string_constexpr
2 parents e346257 + c2ab522 commit ce41ce1

File tree

38 files changed

+334
-229
lines changed

38 files changed

+334
-229
lines changed

stl/inc/atomic

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ inline void _Atomic_lock_release(_Smtx_t* _Spinlock) noexcept {
445445
}
446446

447447
template <class _Spinlock_t>
448-
class _Atomic_lock_guard {
448+
class _NODISCARD _Atomic_lock_guard {
449449
public:
450450
explicit _Atomic_lock_guard(_Spinlock_t& _Spinlock_) noexcept : _Spinlock(_Spinlock_) {
451451
_Atomic_lock_acquire(_Spinlock);

stl/inc/compare

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ struct compare_three_way_result<_Ty1, _Ty2> {
333333
struct compare_three_way {
334334
template <class _Ty1, class _Ty2>
335335
requires three_way_comparable_with<_Ty1, _Ty2> // TRANSITION, GH-489
336-
constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
336+
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
337337
noexcept(noexcept(_STD forward<_Ty1>(_Left) <=> _STD forward<_Ty2>(_Right))) /* strengthened */ {
338338
return _STD forward<_Ty1>(_Left) <=> _STD forward<_Ty2>(_Right);
339339
}
@@ -396,35 +396,37 @@ namespace _Strong_order {
396396
using _Floating_type = decay_t<_Ty1>;
397397
using _Traits = _Floating_type_traits<_Floating_type>;
398398
using _Uint_type = typename _Traits::_Uint_type;
399+
using _Sint_type = make_signed_t<_Uint_type>;
399400

400-
auto _Left_uint = _STD bit_cast<_Uint_type>(_Left);
401-
auto _Right_uint = _STD bit_cast<_Uint_type>(_Right);
401+
const auto _Left_uint = _STD bit_cast<_Uint_type>(_Left);
402+
const auto _Right_uint = _STD bit_cast<_Uint_type>(_Right);
402403

403404
// 1. Ultra-fast path: equal representations are equal.
404405
if (_Left_uint == _Right_uint) {
405406
return strong_ordering::equal;
406407
}
407408

408409
// 2. Examine the sign bits.
409-
const bool _Left_negative = (_Left_uint & _Traits::_Shifted_sign_mask) != 0;
410-
const bool _Right_negative = (_Right_uint & _Traits::_Shifted_sign_mask) != 0;
410+
const _Uint_type _Left_shifted_sign = _Left_uint & _Traits::_Shifted_sign_mask;
411+
const _Uint_type _Right_shifted_sign = _Right_uint & _Traits::_Shifted_sign_mask;
411412

412-
// 3. Fast path: any negative value is less than any positive value.
413-
if (_Left_negative != _Right_negative) {
414-
return _Left_negative ? strong_ordering::less : strong_ordering::greater;
415-
}
413+
// 3. Interpret floating-point bit patterns as sign magnitude representations of integers,
414+
// and then transform them into ones' complement representation.
415+
// (Ones' complement representations of positive zero and negative zero are different.)
416+
const _Uint_type _Left_sign = _Left_shifted_sign >> _Traits::_Sign_shift;
417+
const _Uint_type _Right_sign = _Right_shifted_sign >> _Traits::_Sign_shift;
416418

417-
// 4. Clear the (identical) sign bits. We've already stored them for use at the end.
418-
_Left_uint &= ~_Traits::_Shifted_sign_mask;
419-
_Right_uint &= ~_Traits::_Shifted_sign_mask;
419+
const _Uint_type _Left_xor = _Left_shifted_sign - _Left_sign;
420+
const _Uint_type _Right_xor = _Right_shifted_sign - _Right_sign;
420421

421-
// 5. Perform the final comparison, reversed for negative values.
422-
// (For example, 1.5 is less than 2.5, but -1.5 is greater than -2.5.)
423-
if (_Left_negative) {
424-
return _Right_uint <=> _Left_uint;
425-
} else {
426-
return _Left_uint <=> _Right_uint;
427-
}
422+
const _Uint_type _Left_ones_complement_uint = _Left_uint ^ _Left_xor;
423+
const _Uint_type _Right_ones_complement_uint = _Right_uint ^ _Right_xor;
424+
425+
const auto _Left_ones_complement = static_cast<_Sint_type>(_Left_ones_complement_uint);
426+
const auto _Right_ones_complement = static_cast<_Sint_type>(_Right_ones_complement_uint);
427+
428+
// 4. Perform the final comparison.
429+
return _Left_ones_complement <=> _Right_ones_complement;
428430
} else if constexpr (_Strat == _St::_Three) {
429431
return static_cast<strong_ordering>(compare_three_way{}(_Left, _Right));
430432
} else {
@@ -498,6 +500,7 @@ namespace _Weak_order {
498500
using _Floating_type = decay_t<_Ty1>;
499501
using _Traits = _Floating_type_traits<_Floating_type>;
500502
using _Uint_type = typename _Traits::_Uint_type;
503+
using _Sint_type = make_signed_t<_Uint_type>;
501504

502505
auto _Left_uint = _STD bit_cast<_Uint_type>(_Left);
503506
auto _Right_uint = _STD bit_cast<_Uint_type>(_Right);
@@ -507,47 +510,42 @@ namespace _Weak_order {
507510
return weak_ordering::equivalent;
508511
}
509512

510-
// 2. Fold negative zero into positive zero.
511-
constexpr _Uint_type _Negative_zero = _Traits::_Shifted_sign_mask;
513+
// 2. Examine the sign bits.
514+
const _Uint_type _Left_shifted_sign = _Left_uint & _Traits::_Shifted_sign_mask;
515+
const _Uint_type _Right_shifted_sign = _Right_uint & _Traits::_Shifted_sign_mask;
512516

513-
if (_Left_uint == _Negative_zero) {
514-
_Left_uint = 0;
515-
} else if (_Right_uint == _Negative_zero) { // The representations are known to be non-equal here.
516-
_Right_uint = 0;
517-
}
517+
// 3. Fold all NaN values together.
518+
// (The fact that _Infinity_plus_one represents a signaling NaN is irrelevant here.)
519+
constexpr _Uint_type _Infinity_plus_one = _Traits::_Shifted_exponent_mask + 1;
518520

519-
// 3. Examine the sign bits.
520-
const bool _Left_negative = (_Left_uint & _Traits::_Shifted_sign_mask) != 0;
521-
const bool _Right_negative = (_Right_uint & _Traits::_Shifted_sign_mask) != 0;
521+
const _Uint_type _Left_magnitude = _Left_uint & ~_Traits::_Shifted_sign_mask;
522+
const _Uint_type _Right_magnitude = _Right_uint & ~_Traits::_Shifted_sign_mask;
522523

523-
// 4. Fast path: after folding negative zero, any negative value is less than any positive value.
524-
if (_Left_negative != _Right_negative) {
525-
return _Left_negative ? weak_ordering::less : weak_ordering::greater;
524+
if (_Left_magnitude > _Infinity_plus_one) {
525+
_Left_uint = _Left_shifted_sign | _Infinity_plus_one;
526526
}
527527

528-
// 5. Clear the (identical) sign bits. We've already stored them for use at the end.
529-
_Left_uint &= ~_Traits::_Shifted_sign_mask;
530-
_Right_uint &= ~_Traits::_Shifted_sign_mask;
528+
if (_Right_magnitude > _Infinity_plus_one) {
529+
_Right_uint = _Right_shifted_sign | _Infinity_plus_one;
530+
}
531531

532-
// 6. Fold all NaN values together.
533-
// (The fact that _Infinity_plus_one represents a signaling NaN is irrelevant here.)
534-
constexpr _Uint_type _Infinity_plus_one = _Traits::_Shifted_exponent_mask + 1;
532+
// 4. Interpret floating-point bit patterns as sign magnitude representations of integers,
533+
// and then transform them into two's complement representation.
534+
// (Two's complement representations of positive zero and negative zero are the same.)
535+
const _Uint_type _Left_sign = _Left_shifted_sign >> _Traits::_Sign_shift;
536+
const _Uint_type _Right_sign = _Right_shifted_sign >> _Traits::_Sign_shift;
535537

536-
if (_Left_uint > _Infinity_plus_one) {
537-
_Left_uint = _Infinity_plus_one;
538-
}
538+
const _Uint_type _Left_xor = _Left_shifted_sign - _Left_sign;
539+
const _Uint_type _Right_xor = _Right_shifted_sign - _Right_sign;
539540

540-
if (_Right_uint > _Infinity_plus_one) {
541-
_Right_uint = _Infinity_plus_one;
542-
}
541+
const _Uint_type _Left_twos_complement_uint = (_Left_uint ^ _Left_xor) + _Left_sign;
542+
const _Uint_type _Right_twos_complement_uint = (_Right_uint ^ _Right_xor) + _Right_sign;
543543

544-
// 7. Perform the final comparison, reversed for negative values.
545-
// (For example, 1.5 is less than 2.5, but -1.5 is greater than -2.5.)
546-
if (_Left_negative) {
547-
return static_cast<weak_ordering>(_Right_uint <=> _Left_uint);
548-
} else {
549-
return static_cast<weak_ordering>(_Left_uint <=> _Right_uint);
550-
}
544+
const auto _Left_twos_complement = static_cast<_Sint_type>(_Left_twos_complement_uint);
545+
const auto _Right_twos_complement = static_cast<_Sint_type>(_Right_twos_complement_uint);
546+
547+
// 5. Perform the final comparison.
548+
return static_cast<weak_ordering>(_Left_twos_complement <=> _Right_twos_complement);
551549
} else if constexpr (_Strat == _St::_Three) {
552550
return static_cast<weak_ordering>(compare_three_way{}(_Left, _Right));
553551
} else if constexpr (_Strat == _St::_Strong) {

stl/inc/complex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ struct _C_ldouble_complex {
6060

6161
_STD_BEGIN
6262

63-
// implements multi-precision floating point arithmetic for numerical algorithms
63+
// implements multi-precision floating-point arithmetic for numerical algorithms
6464
#pragma float_control(precise, on, push)
6565
namespace _Float_multi_prec {
66-
// multi-precision floating point types
66+
// multi-precision floating-point types
6767
template <class _Ty, int _Prec>
6868
struct _Fmp_t;
6969

@@ -1877,7 +1877,7 @@ _Ty _Fabs(const complex<_Ty>& _Left, int* _Pexp) { // Used by sqrt(), return mag
18771877
_Bv = _Bv * static_cast<_Ty>(0.0625);
18781878
} else {
18791879
constexpr _Ty _Flt_eps = _Ctraits<_Ty>::_Flt_eps();
1880-
// TRANSITION, workaround for non floating point _Ty
1880+
// TRANSITION, workaround for non-floating-point _Ty
18811881
constexpr _Ty _Leg_tiny = _Flt_eps == 0 ? _Ty{0} : 2 * _Ctraits<_Ty>::_Flt_norm_min() / _Flt_eps;
18821882

18831883
if (_Av < _Leg_tiny) {
@@ -1914,7 +1914,7 @@ _Ty _Fabs(const complex<_Ty>& _Left, int* _Pexp) { // Used by sqrt(), return mag
19141914

19151915
// FUNCTION TEMPLATE log
19161916
template <class _Ty>
1917-
_NODISCARD _Ty _Log_abs(const complex<_Ty>& _Left) noexcept { // for double, long double, and non floating point types
1917+
_NODISCARD _Ty _Log_abs(const complex<_Ty>& _Left) noexcept { // for double, long double, and non-floating-point types
19181918
return static_cast<_Ty>(
19191919
_Math_algorithms::_Log_hypot(static_cast<double>(_STD real(_Left)), static_cast<double>(_STD imag(_Left))));
19201920
}

stl/inc/condition_variable

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ _STL_DISABLE_CLANG_WARNINGS
2929

3030
_STD_BEGIN
3131
template <class _Lock>
32-
struct _Unlock_guard {
32+
struct _NODISCARD _Unlock_guard {
3333
explicit _Unlock_guard(_Lock& _Mtx_) : _Mtx(_Mtx_) {
3434
_Mtx.unlock();
3535
}

stl/inc/coroutine

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,14 @@ struct coroutine_handle<void> {
8888
__builtin_coro_destroy(_Ptr);
8989
}
9090

91-
protected:
91+
private:
9292
void* _Ptr = nullptr;
9393
};
9494

9595
template <class _Promise>
96-
struct coroutine_handle : coroutine_handle<> {
97-
using coroutine_handle<>::coroutine_handle;
96+
struct coroutine_handle {
97+
constexpr coroutine_handle() noexcept = default;
98+
constexpr coroutine_handle(nullptr_t) noexcept {}
9899

99100
_NODISCARD static coroutine_handle from_promise(_Promise& _Prom) noexcept { // strengthened
100101
const auto _Prom_ptr = const_cast<void*>(static_cast<const volatile void*>(_STD addressof(_Prom)));
@@ -109,15 +110,46 @@ struct coroutine_handle : coroutine_handle<> {
109110
return *this;
110111
}
111112

113+
_NODISCARD constexpr void* address() const noexcept {
114+
return _Ptr;
115+
}
116+
112117
_NODISCARD static constexpr coroutine_handle from_address(void* const _Addr) noexcept { // strengthened
113118
coroutine_handle _Result;
114119
_Result._Ptr = _Addr;
115120
return _Result;
116121
}
117122

123+
constexpr operator coroutine_handle<>() const noexcept {
124+
return coroutine_handle<>::from_address(_Ptr);
125+
}
126+
127+
constexpr explicit operator bool() const noexcept {
128+
return _Ptr != nullptr;
129+
}
130+
131+
_NODISCARD bool done() const noexcept { // strengthened
132+
return __builtin_coro_done(_Ptr);
133+
}
134+
135+
void operator()() const {
136+
__builtin_coro_resume(_Ptr);
137+
}
138+
139+
void resume() const {
140+
__builtin_coro_resume(_Ptr);
141+
}
142+
143+
void destroy() const noexcept { // strengthened
144+
__builtin_coro_destroy(_Ptr);
145+
}
146+
118147
_NODISCARD _Promise& promise() const noexcept { // strengthened
119148
return *reinterpret_cast<_Promise*>(__builtin_coro_promise(_Ptr, 0, false));
120149
}
150+
151+
private:
152+
void* _Ptr = nullptr;
121153
};
122154

123155
_NODISCARD constexpr bool operator==(const coroutine_handle<> _Left, const coroutine_handle<> _Right) noexcept {
@@ -145,9 +177,13 @@ struct noop_coroutine_promise {};
145177

146178
// STRUCT coroutine_handle<noop_coroutine_promise>
147179
template <>
148-
struct coroutine_handle<noop_coroutine_promise> : coroutine_handle<> {
180+
struct coroutine_handle<noop_coroutine_promise> {
149181
friend coroutine_handle noop_coroutine() noexcept;
150182

183+
constexpr operator coroutine_handle<>() const noexcept {
184+
return coroutine_handle<>::from_address(_Ptr);
185+
}
186+
151187
constexpr explicit operator bool() const noexcept {
152188
return true;
153189
}
@@ -159,17 +195,19 @@ struct coroutine_handle<noop_coroutine_promise> : coroutine_handle<> {
159195
constexpr void resume() const noexcept {}
160196
constexpr void destroy() const noexcept {}
161197

162-
using _Promise = noop_coroutine_promise;
163-
164-
_NODISCARD _Promise& promise() const noexcept {
198+
_NODISCARD noop_coroutine_promise& promise() const noexcept {
165199
// Returns a reference to the associated promise
166-
return *reinterpret_cast<_Promise*>(__builtin_coro_promise(_Ptr, 0, false));
200+
return *reinterpret_cast<noop_coroutine_promise*>(__builtin_coro_promise(_Ptr, 0, false));
167201
}
168202

169-
private:
170-
coroutine_handle() noexcept {
171-
_Ptr = __builtin_coro_noop();
203+
_NODISCARD constexpr void* address() const noexcept {
204+
return _Ptr;
172205
}
206+
207+
private:
208+
coroutine_handle() noexcept = default;
209+
210+
void* _Ptr = __builtin_coro_noop();
173211
};
174212

175213
// ALIAS noop_coroutine_handle

0 commit comments

Comments
 (0)