@@ -1485,10 +1485,6 @@ _NODISCARD constexpr _Ty* _Get_unwrapped_n(_Ty* const _Src, _Diff) {
14851485}
14861486#endif // _HAS_IF_CONSTEXPR
14871487
1488- template <class _Iter>
1489- using _Unwrapped_n_t =
1490- _Remove_cvref_t<decltype(_Get_unwrapped_n(_STD declval<_Iter>(), _Iter_diff_t<_Remove_cvref_t<_Iter>>{}))>;
1491-
14921488// FUNCTION TEMPLATE _Seek_wrapped
14931489template <class _Iter, class _UIter, class = void>
14941490_INLINE_VAR constexpr bool _Wrapped_seekable_v = false;
@@ -4813,12 +4809,33 @@ _INLINE_VAR constexpr bool _Fill_memset_is_safe = conjunction_v<is_scalar<_Ty>,
48134809template <class _FwdIt, class _Ty>
48144810_INLINE_VAR constexpr bool _Fill_memset_is_safe<_FwdIt, _Ty, false> = false;
48154811
4812+ template <class _FwdIt, class _Ty, bool = is_pointer_v<_FwdIt>>
4813+ _INLINE_VAR constexpr bool _Fill_zero_memset_is_safe =
4814+ conjunction_v<is_scalar<_Ty>, is_scalar<_Iter_value_t<_FwdIt>>, negation<is_member_pointer<_Iter_value_t<_FwdIt>>>,
4815+ negation<is_volatile<remove_reference_t<_Iter_ref_t<_FwdIt>>>>, is_assignable<_Iter_ref_t<_FwdIt>, const _Ty&>>;
4816+
4817+ template <class _FwdIt, class _Ty>
4818+ _INLINE_VAR constexpr bool _Fill_zero_memset_is_safe<_FwdIt, _Ty, false> = false;
4819+
48164820template <class _DestTy, class _Ty>
48174821void _Fill_memset(_DestTy* const _Dest, const _Ty _Val, const size_t _Count) {
48184822 _DestTy _Dest_val = _Val; // implicitly convert (a cast would suppress warnings); also handles _DestTy being bool
48194823 _CSTD memset(_Dest, static_cast<unsigned char>(_Dest_val), _Count);
48204824}
48214825
4826+ template <class _DestTy>
4827+ void _Fill_zero_memset(_DestTy* const _Dest, const size_t _Count) {
4828+ _CSTD memset(_Dest, 0, _Count * sizeof(_DestTy));
4829+ }
4830+
4831+ template <class _Ty>
4832+ _NODISCARD bool _Is_all_bits_zero(const _Ty& _Val) {
4833+ // checks if scalar type has all bits set to zero
4834+ _STL_INTERNAL_STATIC_ASSERT(is_scalar_v<_Ty> && !is_member_pointer_v<_Ty>);
4835+ constexpr _Ty _Zero{};
4836+ return _CSTD memcmp(&_Val, &_Zero, sizeof(_Ty)) == 0;
4837+ }
4838+
48224839#if _HAS_IF_CONSTEXPR
48234840template <class _FwdIt, class _Ty>
48244841_CONSTEXPR20 void fill(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
@@ -4829,13 +4846,18 @@ _CONSTEXPR20 void fill(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val)
48294846 } else {
48304847 auto _UFirst = _Get_unwrapped(_First);
48314848 const auto _ULast = _Get_unwrapped(_Last);
4832- if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
48334849#ifdef __cpp_lib_is_constant_evaluated
4834- if (!_STD is_constant_evaluated())
4850+ if (!_STD is_constant_evaluated())
48354851#endif // __cpp_lib_is_constant_evaluated
4836- {
4852+ {
4853+ if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
48374854 _Fill_memset(_UFirst, _Val, static_cast<size_t>(_ULast - _UFirst));
48384855 return;
4856+ } else if constexpr (_Fill_zero_memset_is_safe<decltype(_UFirst), _Ty>) {
4857+ if (_Is_all_bits_zero(_Val)) {
4858+ _Fill_zero_memset(_UFirst, static_cast<size_t>(_ULast - _UFirst));
4859+ return;
4860+ }
48394861 }
48404862 }
48414863
@@ -4890,15 +4912,20 @@ _CONSTEXPR20 _OutIt fill_n(_OutIt _Dest, const _Diff _Count_raw, const _Ty& _Val
48904912 return _Last;
48914913 } else {
48924914 auto _UDest = _Get_unwrapped_n(_Dest, _Count);
4893- if constexpr (_Fill_memset_is_safe<decltype(_UDest), _Ty>) {
48944915#ifdef __cpp_lib_is_constant_evaluated
4895- if (!_STD is_constant_evaluated())
4916+ if (!_STD is_constant_evaluated())
48964917#endif // __cpp_lib_is_constant_evaluated
4897- {
4918+ {
4919+ if constexpr (_Fill_memset_is_safe<decltype(_UDest), _Ty>) {
48984920 _Fill_memset(_UDest, _Val, static_cast<size_t>(_Count));
4899- _UDest += _Count;
4900- _Seek_wrapped(_Dest, _UDest);
4921+ _Seek_wrapped(_Dest, _UDest + _Count);
49014922 return _Dest;
4923+ } else if constexpr (_Fill_zero_memset_is_safe<decltype(_UDest), _Ty>) {
4924+ if (_Is_all_bits_zero(_Val)) {
4925+ _Fill_zero_memset(_UDest, static_cast<size_t>(_Count));
4926+ _Seek_wrapped(_Dest, _UDest + _Count);
4927+ return _Dest;
4928+ }
49024929 }
49034930 }
49044931
0 commit comments