Skip to content

Commit 5142acf

Browse files
StephanTLavavejfsb4000
authored andcommitted
<functional> should avoid including <memory> (microsoft#2998)
1 parent 72b066d commit 5142acf

File tree

3 files changed

+99
-70
lines changed

3 files changed

+99
-70
lines changed

stl/inc/functional

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <xmemory>
1515
#include <xstddef>
1616
#if _HAS_CXX17
17-
#include <memory>
1817
#include <unordered_map>
1918
#endif // _HAS_CXX17
2019
#ifdef __cpp_lib_concepts
@@ -2176,12 +2175,6 @@ _Ty* _Decode_aligned_block(void*& _Base, const size_t _Count) {
21762175
return static_cast<_Ty*>(_Decode_aligned_block(_Base, sizeof(_Ty) * _Count, alignof(_Ty)));
21772176
}
21782177

2179-
struct _Global_delete {
2180-
void operator()(void* const _Ptr) const {
2181-
::operator delete(_Ptr);
2182-
}
2183-
};
2184-
21852178
template <class _FwdItHaystack, class _FwdItPat, class _Pred_eq>
21862179
_CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked(
21872180
_FwdItHaystack _First1, _FwdItHaystack _Last1, _FwdItPat _First2, _FwdItPat _Last2, _Pred_eq& _Eq) {
@@ -2325,6 +2318,41 @@ private:
23252318
_Diff _Table[_Limit];
23262319
};
23272320

2321+
// _Mini_ptr avoids needing to include <memory> which includes <atomic>.
2322+
// It doesn't attempt to provide all of unique_ptr's safety features; use carefully.
2323+
enum class _Deletion_kind { _Global_scalar, _Normal_array };
2324+
2325+
template <class _Ty, _Deletion_kind _Del>
2326+
class _Mini_ptr {
2327+
public:
2328+
explicit _Mini_ptr(_Ty* const _Ptr_) noexcept : _Ptr(_Ptr_) {}
2329+
2330+
~_Mini_ptr() noexcept {
2331+
if (_Ptr) {
2332+
if constexpr (_Del == _Deletion_kind::_Global_scalar) {
2333+
::operator delete(_Ptr);
2334+
} else if constexpr (_Del == _Deletion_kind::_Normal_array) {
2335+
delete[] _Ptr;
2336+
} else {
2337+
static_assert(_Always_false<_Ty>, "Unknown _Deletion_kind.");
2338+
}
2339+
}
2340+
}
2341+
2342+
_NODISCARD _Ty* _Get() const noexcept {
2343+
return _Ptr;
2344+
}
2345+
2346+
_NODISCARD _Ty* _Release() noexcept {
2347+
return _STD exchange(_Ptr, nullptr);
2348+
}
2349+
2350+
_Mini_ptr(const _Mini_ptr&) = delete;
2351+
_Mini_ptr& operator=(const _Mini_ptr&) = delete;
2352+
2353+
private:
2354+
_Ty* _Ptr;
2355+
};
23282356

23292357
template <class _RanItPat, class _Pred_eq>
23302358
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
23452373

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

2348-
const unique_ptr<size_t[]> _Fx{new size_t[_Mx]};
2376+
const _Mini_ptr<size_t, _Deletion_kind::_Normal_array> _Fx_ptr{new size_t[_Mx]};
2377+
size_t* const _Fx = _Fx_ptr._Get();
23492378

23502379
for (size_t _Kx = 1; _Kx <= _Mx; ++_Kx) {
23512380
_Shifts[_Kx - 1] = static_cast<_Diff>(2 * _Mx - _Kx);
@@ -2496,8 +2525,8 @@ struct _Single_delta1_type_boyer_moore_traits {
24962525
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
24972526
}
24982527

2499-
unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
2500-
void* _Buf = _Buf_bytes.get();
2528+
_Mini_ptr<void, _Deletion_kind::_Global_scalar> _Buf_bytes(::operator new(_Buf_size));
2529+
void* _Buf = _Buf_bytes._Get();
25012530
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
25022531
void* const _Delta1 = _Decode_aligned_block<_Delta1_t>(_Buf);
25032532
if (_Build_delta2) {
@@ -2506,7 +2535,7 @@ struct _Single_delta1_type_boyer_moore_traits {
25062535
}
25072536

25082537
::new (_Delta1) _Delta1_t(_First, _UFirst, _Pat_size_raw, _STD move(_Hash_fn), _STD move(_Eq));
2509-
return _Buf_bytes.release();
2538+
return _Buf_bytes._Release();
25102539
}
25112540

25122541
template <class _RanItHaystack>
@@ -2590,8 +2619,8 @@ struct _Boyer_moore_traits_wchar_t_mode {
25902619
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
25912620
}
25922621

2593-
unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
2594-
void* _Buf = _Buf_bytes.get();
2622+
_Mini_ptr<void, _Deletion_kind::_Global_scalar> _Buf_bytes(::operator new(_Buf_size));
2623+
void* _Buf = _Buf_bytes._Get();
25952624
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
25962625
*_Decode_aligned_block<bool>(_Buf) = _Use_large_table;
25972626
if (_Use_large_table) {
@@ -2610,7 +2639,7 @@ struct _Boyer_moore_traits_wchar_t_mode {
26102639
_Decode_aligned_block<_Diff>(_Buf, _Pat_size), _UFirst, _Pat_size_raw, _Eq);
26112640
}
26122641

2613-
return _Buf_bytes.release();
2642+
return _Buf_bytes._Release();
26142643
}
26152644

26162645
template <class _RanItHaystack>

stl/inc/memory

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,45 +2396,6 @@ private:
23962396
};
23972397
#endif // _HAS_CXX20
23982398

2399-
template <class _Ty,
2400-
bool = is_empty_v<_Ty> && !is_final_v<_Ty>>
2401-
class _Ebco_base : private _Ty { // Empty Base Class Optimization, active
2402-
private:
2403-
using _Mybase = _Ty; // for visualization
2404-
2405-
protected:
2406-
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _Ebco_base>, int> = 0>
2407-
constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>)
2408-
: _Ty(_STD forward<_Other>(_Val)) {}
2409-
2410-
constexpr _Ty& _Get_val() noexcept {
2411-
return *this;
2412-
}
2413-
2414-
constexpr const _Ty& _Get_val() const noexcept {
2415-
return *this;
2416-
}
2417-
};
2418-
2419-
template <class _Ty>
2420-
class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive
2421-
private:
2422-
_Ty _Myval;
2423-
2424-
protected:
2425-
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _Ebco_base>, int> = 0>
2426-
constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>)
2427-
: _Myval(_STD forward<_Other>(_Val)) {}
2428-
2429-
constexpr _Ty& _Get_val() noexcept {
2430-
return _Myval;
2431-
}
2432-
2433-
constexpr const _Ty& _Get_val() const noexcept {
2434-
return _Myval;
2435-
}
2436-
};
2437-
24382399
template <class _Ty, class _Alloc>
24392400
class _Ref_count_obj_alloc3 : public _Ebco_base<_Rebind_alloc_t<_Alloc, _Ty>>, public _Ref_count_base {
24402401
// handle reference counting for object in control block, allocator
@@ -3710,23 +3671,6 @@ struct hash<shared_ptr<_Ty>> {
37103671
}
37113672
};
37123673

3713-
inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noexcept /* strengthened */ {
3714-
// try to carve out _Size bytes on boundary _Bound
3715-
size_t _Off = static_cast<size_t>(reinterpret_cast<uintptr_t>(_Ptr) & (_Bound - 1));
3716-
if (_Off != 0) {
3717-
_Off = _Bound - _Off; // number of bytes to skip
3718-
}
3719-
3720-
if (_Space < _Off || _Space - _Off < _Size) {
3721-
return nullptr;
3722-
}
3723-
3724-
// enough room, update
3725-
_Ptr = static_cast<char*>(_Ptr) + _Off;
3726-
_Space -= _Off;
3727-
return _Ptr;
3728-
}
3729-
37303674
#if _HAS_CXX20
37313675
template <size_t _Nx, class _Ty>
37323676
_NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ {

stl/inc/xmemory

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,62 @@ template <_RANGES input_range _Rng>
23372337
using _Range_to_alloc_type =
23382338
pair<const typename _RANGES range_value_t<_Rng>::first_type, typename _RANGES range_value_t<_Rng>::second_type>;
23392339
#endif // __cpp_lib_containers_ranges
2340+
2341+
template <class _Ty,
2342+
bool = is_empty_v<_Ty> && !is_final_v<_Ty>>
2343+
class _Ebco_base : private _Ty { // Empty Base Class Optimization, active
2344+
private:
2345+
using _Mybase = _Ty; // for visualization
2346+
2347+
protected:
2348+
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _Ebco_base>, int> = 0>
2349+
constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>)
2350+
: _Ty(_STD forward<_Other>(_Val)) {}
2351+
2352+
constexpr _Ty& _Get_val() noexcept {
2353+
return *this;
2354+
}
2355+
2356+
constexpr const _Ty& _Get_val() const noexcept {
2357+
return *this;
2358+
}
2359+
};
2360+
2361+
template <class _Ty>
2362+
class _Ebco_base<_Ty, false> { // Empty Base Class Optimization, inactive
2363+
private:
2364+
_Ty _Myval;
2365+
2366+
protected:
2367+
template <class _Other, enable_if_t<!is_same_v<_Remove_cvref_t<_Other>, _Ebco_base>, int> = 0>
2368+
constexpr explicit _Ebco_base(_Other&& _Val) noexcept(is_nothrow_constructible_v<_Ty, _Other>)
2369+
: _Myval(_STD forward<_Other>(_Val)) {}
2370+
2371+
constexpr _Ty& _Get_val() noexcept {
2372+
return _Myval;
2373+
}
2374+
2375+
constexpr const _Ty& _Get_val() const noexcept {
2376+
return _Myval;
2377+
}
2378+
};
2379+
2380+
inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noexcept /* strengthened */ {
2381+
// try to carve out _Size bytes on boundary _Bound
2382+
size_t _Off = static_cast<size_t>(reinterpret_cast<uintptr_t>(_Ptr) & (_Bound - 1));
2383+
if (_Off != 0) {
2384+
_Off = _Bound - _Off; // number of bytes to skip
2385+
}
2386+
2387+
if (_Space < _Off || _Space - _Off < _Size) {
2388+
return nullptr;
2389+
}
2390+
2391+
// enough room, update
2392+
_Ptr = static_cast<char*>(_Ptr) + _Off;
2393+
_Space -= _Off;
2394+
return _Ptr;
2395+
}
23402396
_STD_END
23412397

23422398
#pragma pop_macro("new")

0 commit comments

Comments
 (0)