Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions stl/inc/functional
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <xmemory>
#include <xstddef>
#if _HAS_CXX17
#include <memory>
#include <unordered_map>
#endif // _HAS_CXX17
#ifdef __cpp_lib_concepts
Expand Down Expand Up @@ -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 <class _FwdItHaystack, class _FwdItPat, class _Pred_eq>
_CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked(
_FwdItHaystack _First1, _FwdItHaystack _Last1, _FwdItPat _First2, _FwdItPat _Last2, _Pred_eq& _Eq) {
Expand Down Expand Up @@ -2325,6 +2318,41 @@ private:
_Diff _Table[_Limit];
};

// _Mini_ptr avoids needing to include <memory> which includes <atomic>.
// 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 _Ty, _Deletion_kind _Del>
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 <class _RanItPat, class _Pred_eq>
void _Build_boyer_moore_delta_2_table(_Iter_diff_t<_RanItPat>* const _Shifts, const _RanItPat _Pat_first,
Expand All @@ -2345,7 +2373,8 @@ void _Build_boyer_moore_delta_2_table(_Iter_diff_t<_RanItPat>* const _Shifts, co

const auto _Mx = static_cast<size_t>(_Pat_size);

const unique_ptr<size_t[]> _Fx{new size_t[_Mx]};
const _Mini_ptr<size_t, _Deletion_kind::_Normal_array> _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);
Expand Down Expand Up @@ -2496,8 +2525,8 @@ struct _Single_delta1_type_boyer_moore_traits {
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
}

unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
void* _Buf = _Buf_bytes.get();
_Mini_ptr<void, _Deletion_kind::_Global_scalar> _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) {
Expand All @@ -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 <class _RanItHaystack>
Expand Down Expand Up @@ -2590,8 +2619,8 @@ struct _Boyer_moore_traits_wchar_t_mode {
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
}

unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
void* _Buf = _Buf_bytes.get();
_Mini_ptr<void, _Deletion_kind::_Global_scalar> _Buf_bytes(::operator new(_Buf_size));
void* _Buf = _Buf_bytes._Get();
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
*_Decode_aligned_block<bool>(_Buf) = _Use_large_table;
if (_Use_large_table) {
Expand All @@ -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 <class _RanItHaystack>
Expand Down
56 changes: 0 additions & 56 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -2396,45 +2396,6 @@ private:
};
#endif // _HAS_CXX20

template <class _Ty,
bool = is_empty_v<_Ty> && !is_final_v<_Ty>>
class _Ebco_base : private _Ty { // Empty Base Class Optimization, active
private:
using _Mybase = _Ty; // for visualization

protected:
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _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 _Ty>
class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive
private:
_Ty _Myval;

protected:
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _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 _Ty, class _Alloc>
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
Expand Down Expand Up @@ -3710,23 +3671,6 @@ struct hash<shared_ptr<_Ty>> {
}
};

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<size_t>(reinterpret_cast<uintptr_t>(_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<char*>(_Ptr) + _Off;
_Space -= _Off;
return _Ptr;
}

#if _HAS_CXX20
template <size_t _Nx, class _Ty>
_NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ {
Expand Down
56 changes: 56 additions & 0 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2337,6 +2337,62 @@ template <_RANGES input_range _Rng>
using _Range_to_alloc_type =
pair<const typename _RANGES range_value_t<_Rng>::first_type, typename _RANGES range_value_t<_Rng>::second_type>;
#endif // __cpp_lib_containers_ranges

template <class _Ty,
bool = is_empty_v<_Ty> && !is_final_v<_Ty>>
class _Ebco_base : private _Ty { // Empty Base Class Optimization, active
private:
using _Mybase = _Ty; // for visualization

protected:
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _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 _Ty>
class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive
private:
_Ty _Myval;

protected:
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _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<size_t>(reinterpret_cast<uintptr_t>(_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<char*>(_Ptr) + _Off;
_Space -= _Off;
return _Ptr;
}
_STD_END

#pragma pop_macro("new")
Expand Down