From bc00676fea5bafc74ed1991cac829c5067c3ff44 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 5 Aug 2022 14:56:59 -0700 Subject: [PATCH 1/2] Replace 's usage of unique_ptr. --- stl/inc/functional | 57 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 01fe1fb5bbd..2fe8045c3d2 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -14,7 +14,6 @@ #include #include #if _HAS_CXX17 -#include #include #endif // _HAS_CXX17 #ifdef __cpp_lib_concepts @@ -2176,12 +2175,6 @@ _Ty* _Decode_aligned_block(void*& _Base, const size_t _Count) { return static_cast<_Ty*>(_Decode_aligned_block(_Base, sizeof(_Ty) * _Count, alignof(_Ty))); } -struct _Global_delete { - void operator()(void* const _Ptr) const { - ::operator delete(_Ptr); - } -}; - template _CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked( _FwdItHaystack _First1, _FwdItHaystack _Last1, _FwdItPat _First2, _FwdItPat _Last2, _Pred_eq& _Eq) { @@ -2325,6 +2318,41 @@ private: _Diff _Table[_Limit]; }; +// _Mini_ptr avoids needing to include which includes . +// It doesn't attempt to provide all of unique_ptr's safety features; use carefully. +enum class _Deletion_kind { _Global_scalar, _Normal_array }; + +template +class _Mini_ptr { +public: + explicit _Mini_ptr(_Ty* const _Ptr_) noexcept : _Ptr(_Ptr_) {} + + ~_Mini_ptr() noexcept { + if (_Ptr) { + if constexpr (_Del == _Deletion_kind::_Global_scalar) { + ::operator delete(_Ptr); + } else if constexpr (_Del == _Deletion_kind::_Normal_array) { + delete[] _Ptr; + } else { + static_assert(_Always_false<_Ty>, "Unknown _Deletion_kind."); + } + } + } + + _NODISCARD _Ty* _Get() const noexcept { + return _Ptr; + } + + _NODISCARD _Ty* _Release() noexcept { + return _STD exchange(_Ptr, nullptr); + } + + _Mini_ptr(const _Mini_ptr&) = delete; + _Mini_ptr& operator=(const _Mini_ptr&) = delete; + +private: + _Ty* _Ptr; +}; template void _Build_boyer_moore_delta_2_table(_Iter_diff_t<_RanItPat>* const _Shifts, const _RanItPat _Pat_first, @@ -2345,7 +2373,8 @@ void _Build_boyer_moore_delta_2_table(_Iter_diff_t<_RanItPat>* const _Shifts, co const auto _Mx = static_cast(_Pat_size); - const unique_ptr _Fx{new size_t[_Mx]}; + const _Mini_ptr _Fx_ptr{new size_t[_Mx]}; + size_t* const _Fx = _Fx_ptr._Get(); for (size_t _Kx = 1; _Kx <= _Mx; ++_Kx) { _Shifts[_Kx - 1] = static_cast<_Diff>(2 * _Mx - _Kx); @@ -2496,8 +2525,8 @@ struct _Single_delta1_type_boyer_moore_traits { _Add_alloc_size<_Diff>(_Buf_size, _Pat_size); } - unique_ptr _Buf_bytes(::operator new(_Buf_size)); - void* _Buf = _Buf_bytes.get(); + _Mini_ptr _Buf_bytes(::operator new(_Buf_size)); + void* _Buf = _Buf_bytes._Get(); *_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1; void* const _Delta1 = _Decode_aligned_block<_Delta1_t>(_Buf); if (_Build_delta2) { @@ -2506,7 +2535,7 @@ struct _Single_delta1_type_boyer_moore_traits { } ::new (_Delta1) _Delta1_t(_First, _UFirst, _Pat_size_raw, _STD move(_Hash_fn), _STD move(_Eq)); - return _Buf_bytes.release(); + return _Buf_bytes._Release(); } template @@ -2590,8 +2619,8 @@ struct _Boyer_moore_traits_wchar_t_mode { _Add_alloc_size<_Diff>(_Buf_size, _Pat_size); } - unique_ptr _Buf_bytes(::operator new(_Buf_size)); - void* _Buf = _Buf_bytes.get(); + _Mini_ptr _Buf_bytes(::operator new(_Buf_size)); + void* _Buf = _Buf_bytes._Get(); *_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1; *_Decode_aligned_block(_Buf) = _Use_large_table; if (_Use_large_table) { @@ -2610,7 +2639,7 @@ struct _Boyer_moore_traits_wchar_t_mode { _Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq); } - return _Buf_bytes.release(); + return _Buf_bytes._Release(); } template From eb7a86df545d5ca214d762bd89918b9516214870 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 5 Aug 2022 15:08:54 -0700 Subject: [PATCH 2/2] Move _Ebco_base and align() from up to . --- stl/inc/memory | 56 ------------------------------------------------- stl/inc/xmemory | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 02c7320f88b..293f518e825 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -2396,45 +2396,6 @@ private: }; #endif // _HAS_CXX20 -template && !is_final_v<_Ty>> -class _Ebco_base : private _Ty { // Empty Base Class Optimization, active -private: - using _Mybase = _Ty; // for visualization - -protected: - template , _Ebco_base>, int> = 0> - constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>) - : _Ty(_STD forward<_Other>(_Val)) {} - - constexpr _Ty& _Get_val() noexcept { - return *this; - } - - constexpr const _Ty& _Get_val() const noexcept { - return *this; - } -}; - -template -class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive -private: - _Ty _Myval; - -protected: - template , _Ebco_base>, int> = 0> - constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>) - : _Myval(_STD forward<_Other>(_Val)) {} - - constexpr _Ty& _Get_val() noexcept { - return _Myval; - } - - constexpr const _Ty& _Get_val() const noexcept { - return _Myval; - } -}; - template class _Ref_count_obj_alloc3 : public _Ebco_base<_Rebind_alloc_t<_Alloc, _Ty>>, public _Ref_count_base { // handle reference counting for object in control block, allocator @@ -3710,23 +3671,6 @@ struct hash> { } }; -inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noexcept /* strengthened */ { - // try to carve out _Size bytes on boundary _Bound - size_t _Off = static_cast(reinterpret_cast(_Ptr) & (_Bound - 1)); - if (_Off != 0) { - _Off = _Bound - _Off; // number of bytes to skip - } - - if (_Space < _Off || _Space - _Off < _Size) { - return nullptr; - } - - // enough room, update - _Ptr = static_cast(_Ptr) + _Off; - _Space -= _Off; - return _Ptr; -} - #if _HAS_CXX20 template _NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ { diff --git a/stl/inc/xmemory b/stl/inc/xmemory index aca8c5dd783..36e8204dd5f 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2276,6 +2276,62 @@ constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc& _STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); } #endif // _HAS_CXX20 + +template && !is_final_v<_Ty>> +class _Ebco_base : private _Ty { // Empty Base Class Optimization, active +private: + using _Mybase = _Ty; // for visualization + +protected: + template , _Ebco_base>, int> = 0> + constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>) + : _Ty(_STD forward<_Other>(_Val)) {} + + constexpr _Ty& _Get_val() noexcept { + return *this; + } + + constexpr const _Ty& _Get_val() const noexcept { + return *this; + } +}; + +template +class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive +private: + _Ty _Myval; + +protected: + template , _Ebco_base>, int> = 0> + constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>) + : _Myval(_STD forward<_Other>(_Val)) {} + + constexpr _Ty& _Get_val() noexcept { + return _Myval; + } + + constexpr const _Ty& _Get_val() const noexcept { + return _Myval; + } +}; + +inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noexcept /* strengthened */ { + // try to carve out _Size bytes on boundary _Bound + size_t _Off = static_cast(reinterpret_cast(_Ptr) & (_Bound - 1)); + if (_Off != 0) { + _Off = _Bound - _Off; // number of bytes to skip + } + + if (_Space < _Off || _Space - _Off < _Size) { + return nullptr; + } + + // enough room, update + _Ptr = static_cast(_Ptr) + _Off; + _Space -= _Off; + return _Ptr; +} _STD_END #pragma pop_macro("new")