-
Notifications
You must be signed in to change notification settings - Fork 1.6k
stacktrace #2502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
stacktrace #2502
Changes from 38 commits
Commits
Show all changes
138 commits
Select commit
Hold shift + click to select a range
3891724
stacktrace initial implementation
AlexGuteniev 9943152
fix line
AlexGuteniev 1e0b47c
feature, missing (c), pmr
AlexGuteniev 96ade42
x86 build
AlexGuteniev c480c55
header!
AlexGuteniev b080877
-copypasta comments
AlexGuteniev ec9e855
Ugly Al
AlexGuteniev 5575f9b
_STD move
AlexGuteniev ec470a5
right size
AlexGuteniev 1cb8b79
test pass
AlexGuteniev df9b1ba
-lines
AlexGuteniev 603e8d7
too few [[nodiscard]]
AlexGuteniev 115229f
hash hash
AlexGuteniev ab3d65b
no, removed
AlexGuteniev a475f02
it is overspecified to me!
AlexGuteniev a7e2edd
size
AlexGuteniev f58f476
conventions
AlexGuteniev 20364f6
Don't pass nullptr to string ctor
AlexGuteniev a561b53
strengthen
AlexGuteniev 9ddfb94
typo
AlexGuteniev 59ee7fa
save displacement
AlexGuteniev 8090d3d
cache only the last address and no more
AlexGuteniev 7fb6f85
not using format yet
AlexGuteniev 98a0793
move string conversion to .cpp
AlexGuteniev bca36f3
file
AlexGuteniev 7562e13
Add module/offset
AlexGuteniev 1de504d
Update stl/src/stacktrace.cpp
AlexGuteniev dfbf80a
save on locks
AlexGuteniev 0024cbe
MAX_SYM_NAME
AlexGuteniev b18cb81
Phoenix
AlexGuteniev 8326f74
switch to <DbgEng.h>
AlexGuteniev 1e96c7a
clang format
AlexGuteniev 2256088
fix link
AlexGuteniev 67f96d5
Functional nightmare
AlexGuteniev 7cc3d11
clang format
AlexGuteniev f098d7f
desatellite
AlexGuteniev dfb0700
extern C
AlexGuteniev 03c4751
desatellite++
AlexGuteniev b71b67e
unused
AlexGuteniev ce6d007
atexit sync
AlexGuteniev 82a6c7c
top level `const`
AlexGuteniev 7aee461
#exclude
AlexGuteniev 8dc8468
unextern C for exception safety
AlexGuteniev 1cfb5c7
still extern "C"
AlexGuteniev 5cdb7bd
build
AlexGuteniev d760966
Compensate '\0'
AlexGuteniev a9d72ec
reuse capacity
AlexGuteniev 2186b32
noexcept
AlexGuteniev b1f637c
consistently exclude the current
AlexGuteniev 49be56a
BE workaround
AlexGuteniev ab89b14
test
AlexGuteniev ab5f1e9
we are the std
AlexGuteniev 631f375
-newline
AlexGuteniev 284f96b
_STACKSTRACE_
AlexGuteniev 762f72d
unnecessary void return
AlexGuteniev b5c7624
error safety on initialization
AlexGuteniev 991fb2a
Load modules from the binaries dir.
AlexGuteniev fa99f51
clang format
AlexGuteniev 9675d08
add escape hatch to alter interface properties
AlexGuteniev 671993b
move initialization to avoid unnecessary attempts
AlexGuteniev 94c6d1d
move ensure_module_symbols_loaded_from_current_dir to avoid unnecess…
AlexGuteniev fde7ac3
clang format
AlexGuteniev 93d4f1c
0
AlexGuteniev 0cf831d
fallback testing as suggested by @ben-craig
AlexGuteniev d97d6dc
clang format
AlexGuteniev caebf99
nothrowing string alloc; symbol options
AlexGuteniev cd85152
-white
AlexGuteniev 1493f97
entry number:
AlexGuteniev 9bbe0a9
zer0-based
AlexGuteniev 91a78f0
Merge remote-tracking branch 'upstream/main' into stacktrace
AlexGuteniev 71c68d8
add stacktrace to the new header
AlexGuteniev 8011c27
Merge remote-tracking branch 'upstream/main' into stacktrace
AlexGuteniev 7d5e487
thread coverage
AlexGuteniev f5392fd
Update tests/std/tests/P0881R7_stacktrace/test.cpp
AlexGuteniev 5a2e9c5
Merge remote-tracking branch 'upstream/main' into stacktrace
AlexGuteniev a275e2e
Merge branch 'stacktrace' of https://github.com/AlexGuteniev/STL into…
AlexGuteniev ae83a4e
fix header units test
AlexGuteniev baff31a
[[maybe_useless]]
AlexGuteniev f82720e
Update stl/inc/stacktrace
AlexGuteniev 8bb418a
Update stacktrace
AlexGuteniev d6f43d6
some review comments
AlexGuteniev 3ac35ed
some review comments - missed parts
AlexGuteniev 730fa69
clang format
AlexGuteniev c151a23
clang format
AlexGuteniev 42d88b6
sort
AlexGuteniev 85c76a1
remove directory populating
AlexGuteniev f8e0a30
header unit test
AlexGuteniev be59a61
more const
AlexGuteniev e5a31b9
_NODISCARD
AlexGuteniev f0e447c
Some review comments
AlexGuteniev c64b9b2
_NODISCARD_FRIEND
AlexGuteniev 3a75e2d
Update tests/std/tests/P0881R7_stacktrace/test.cpp
AlexGuteniev f6c962b
<cstddef>
AlexGuteniev 84ff6cb
allocator template parameter
AlexGuteniev cad7208
latest
AlexGuteniev f4534c6
comditional stacktrace
AlexGuteniev 5190527
snprintf
AlexGuteniev 11f38e1
|
AlexGuteniev 5d03019
Merge branch 'main' into stacktrace
StephanTLavavej f793734
Code review feedback.
StephanTLavavej a52a4fb
Oops, remove argument_type and result_type.
StephanTLavavej 6e9ad95
catch 'em all
AlexGuteniev ef4dbdc
Merge remote-tracking branch 'upstream/main' into stacktrace
AlexGuteniev 194ff85
dynamic import
AlexGuteniev 4859f12
format
AlexGuteniev c2d9ff6
Code review feedback.
StephanTLavavej 2a5fbdf
explain functional nightmare
AlexGuteniev 414c942
format
AlexGuteniev bf0c312
skip that actually
AlexGuteniev 6f939fd
_nolock
AlexGuteniev 9881073
struct
AlexGuteniev b855123
some review comments
AlexGuteniev 7c1d920
-__std_stacktrace_get_debug_interface
AlexGuteniev 6242345
fix build
AlexGuteniev 933be57
_STL_INTERNAL_STATIC_ASSERT
AlexGuteniev 5d813d6
more noexcept
AlexGuteniev 0aadf48
Adjust integers
AlexGuteniev 72d9839
fix build, exception safety
AlexGuteniev 4e95ce4
Merge branch 'main' into stacktrace
StephanTLavavej 7e543c3
Drop `#pragma comment`s for DbgEng.lib and Shlwapi.lib.
StephanTLavavej 9c5af00
Mark _To_voidptr_array/_Adjust_skip as _NODISCARD/noexcept.
StephanTLavavej 70122e6
Use SRWLOCK_INIT.
StephanTLavavej d0ca01a
Drop debug_symbols3.
StephanTLavavej eb9f444
Allow clang-format to fix indentation.
StephanTLavavej 9ac0b65
Fix comment: _Callback is what's tested for null.
StephanTLavavej 581cfe3
Improve comment grammar.
StephanTLavavej 524bb81
Fuse srw_lock_guard into dbg_eng_data and use non-static member funct…
StephanTLavavej 5071c5e
more `noexcept`
AlexGuteniev b6c7c6e
Call atexit() within `if (!initialize_attempted)`.
StephanTLavavej 9354074
Mark try_initialize() as [[nodiscard]]; its return value is important.
StephanTLavavej afd9eeb
Update stacktrace.cpp
AlexGuteniev 8399e65
Safer overflow handling for 32-bit platform
AlexGuteniev 42cf248
avoid exra ctor
AlexGuteniev 8235667
Update stl/inc/stacktrace
AlexGuteniev f63eb4d
Update stl/src/stacktrace.cpp
AlexGuteniev 3547133
TCOnsistent
AlexGuteniev 5f280d6
uniform _To_voidptr_array
AlexGuteniev 6b6a43a
Fix internal test harness.
StephanTLavavej File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,6 +95,7 @@ | |
"spanstream", | ||
"sstream", | ||
"stack", | ||
"stacktrace", | ||
"stdatomic.h", | ||
"stdexcept", | ||
"stop_token", | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,316 @@ | ||
// stacktrace standard header | ||
|
||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#pragma once | ||
#ifndef _STACKSTRACE_ | ||
#define _STACKSTRACE_ | ||
#include <yvals_core.h> | ||
#if _STL_COMPILER_PREPROCESSOR | ||
|
||
#if !_HAS_CXX23 | ||
#pragma message("The contents of <stacktrace> are available only with C++23 or later.") | ||
#else // ^^^ !_HAS_CXX23 / _HAS_CXX23 vvv | ||
|
||
#include <cstdint> | ||
#include <string> | ||
#include <type_traits> | ||
#include <vector> | ||
|
||
#pragma pack(push, _CRT_PACKING) | ||
#pragma warning(push, _STL_WARNING_LEVEL) | ||
#pragma warning(disable : _STL_DISABLED_WARNINGS) | ||
_STL_DISABLE_CLANG_WARNINGS | ||
#pragma push_macro("new") | ||
#undef new | ||
|
||
using _Stacktrace_string_fill_callback = size_t (*)(char*, size_t, void* _Context); | ||
|
||
using _Stacktrace_string_fill = size_t (*)(size_t, void* _String, void* _Context, _Stacktrace_string_fill_callback); | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
struct _Stacktrace_string_fill_op { | ||
size_t operator()(char* _Data, size_t _Size) { | ||
return _Callback(_Data, _Size, _Context); | ||
} | ||
|
||
_Stacktrace_string_fill_callback _Callback; | ||
void* _Context; | ||
}; | ||
|
||
inline size_t _Stacktrace_string_fill_impl( | ||
size_t _Size, void* _String, void* _Context, _Stacktrace_string_fill_callback _Callback) { | ||
static_cast<_STD string*>(_String)->resize_and_overwrite(_Size, _Stacktrace_string_fill_op{_Callback, _Context}); | ||
return static_cast<_STD string*>(_String)->size(); | ||
} | ||
|
||
_EXTERN_C | ||
unsigned short __stdcall __std_stacktrace_capture( | ||
unsigned long _FramesToSkip, unsigned long _FramesToCapture, void** _BackTrace, unsigned long* _BackTraceHash); | ||
|
||
void __stdcall __std_stacktrace_address_to_string(const void* _Address, void* _Str, _Stacktrace_string_fill _Fill); | ||
void __stdcall __std_stacktrace_description(const void* _Address, void* _Str, _Stacktrace_string_fill _Fill); | ||
void __stdcall __std_stacktrace_source_file(const void* _Address, void* _Str, _Stacktrace_string_fill _Fill); | ||
[[nodiscard]] unsigned __stdcall __std_stacktrace_source_line(const void* _Address); | ||
void __stdcall __std_stacktrace_to_string( | ||
const void* _Addresses, size_t _Size, void* _Str, _Stacktrace_string_fill _Fill); | ||
_END_EXTERN_C | ||
|
||
_STD_BEGIN | ||
class stacktrace_entry { | ||
public: | ||
using native_handle_type = void*; | ||
|
||
constexpr stacktrace_entry() noexcept = default; | ||
constexpr stacktrace_entry(const stacktrace_entry&) noexcept = default; | ||
constexpr stacktrace_entry& operator=(const stacktrace_entry&) noexcept = default; | ||
|
||
~stacktrace_entry() = default; | ||
|
||
[[nodiscard]] constexpr native_handle_type native_handle() const noexcept { | ||
return _Address; | ||
} | ||
|
||
[[nodiscard]] constexpr explicit operator bool() const noexcept { | ||
return _Address != nullptr; | ||
} | ||
|
||
[[nodiscard]] string description() const { | ||
string _Result; | ||
__std_stacktrace_description(_Address, &_Result, _Stacktrace_string_fill_impl); | ||
return _Result; | ||
} | ||
|
||
[[nodiscard]] string source_file() const { | ||
string _Result; | ||
__std_stacktrace_source_file(_Address, &_Result, _Stacktrace_string_fill_impl); | ||
return _Result; | ||
} | ||
|
||
[[nodiscard]] uint_least32_t source_line() const { | ||
return __std_stacktrace_source_line(_Address); | ||
} | ||
|
||
[[nodiscard]] friend constexpr bool operator==(const stacktrace_entry&, const stacktrace_entry&) noexcept = default; | ||
|
||
[[nodiscard]] friend constexpr strong_ordering operator<=>( | ||
const stacktrace_entry&, const stacktrace_entry&) noexcept = default; | ||
|
||
private: | ||
void* _Address = nullptr; | ||
}; | ||
|
||
template <class _Al> | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
class basic_stacktrace { | ||
AlexGuteniev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private: | ||
using _Frames_t = vector<stacktrace_entry, _Al>; | ||
|
||
public: | ||
using value_type = stacktrace_entry; | ||
using const_reference = const value_type&; | ||
using reference = value_type&; | ||
using const_iterator = typename _Frames_t::const_iterator; | ||
using iterator = const_iterator; | ||
using reverse_iterator = _STD reverse_iterator<iterator>; | ||
using const_reverse_iterator = _STD reverse_iterator<const_iterator>; | ||
using difference_type = ptrdiff_t; | ||
using size_type = size_t; | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
using allocator_type = _Al; | ||
|
||
[[nodiscard]] static basic_stacktrace current(const allocator_type& _Alloc = allocator_type()) noexcept { | ||
basic_stacktrace _Result(_Internal_t{}, _Max_frames, _Alloc); | ||
_Result._Frames.resize(__std_stacktrace_capture(0, static_cast<unsigned long>(_Max_frames), | ||
reinterpret_cast<void**>(_Result._Frames.data()), &_Result._Hash)); | ||
return _Result; | ||
} | ||
|
||
[[nodiscard]] static basic_stacktrace current( | ||
size_type _Skip, const allocator_type& _Alloc = allocator_type()) noexcept { | ||
basic_stacktrace _Result(_Internal_t{}, _Max_frames, _Alloc); | ||
_Result._Frames.resize(__std_stacktrace_capture(static_cast<unsigned long>(_Skip), | ||
static_cast<unsigned long>(_Max_frames), reinterpret_cast<void**>(_Result._Frames.data()), &_Result._Hash)); | ||
return _Result; | ||
} | ||
|
||
[[nodiscard]] static basic_stacktrace current( | ||
size_type _Skip, size_type _Max_depth, const allocator_type& _Alloc = allocator_type()) noexcept { | ||
basic_stacktrace _Result(_Internal_t{}, _Max_depth, _Alloc); | ||
_Result._Frames.resize(__std_stacktrace_capture(static_cast<unsigned long>(_Skip), | ||
static_cast<unsigned long>(_Max_depth), reinterpret_cast<void**>(_Result._Frames.data()), &_Result._Hash)); | ||
return _Result; | ||
} | ||
|
||
basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>) = default; | ||
explicit basic_stacktrace(const allocator_type& _Alloc) noexcept : _Frames(_Alloc) {} | ||
|
||
basic_stacktrace(const basic_stacktrace&) = default; | ||
basic_stacktrace(basic_stacktrace&&) noexcept = default; | ||
basic_stacktrace(const basic_stacktrace& _Other, const allocator_type& _Alloc) | ||
: _Frames(_Other._Frames, _Alloc), _Hash(_Other._Hash) {} | ||
|
||
basic_stacktrace(basic_stacktrace&& _Other, const allocator_type& _Alloc) | ||
: _Frames(_STD move(_Other._Frames), _Alloc), _Hash(_Other._Hash) {} | ||
|
||
basic_stacktrace& operator=(const basic_stacktrace&) = default; | ||
basic_stacktrace& operator=(basic_stacktrace&&) noexcept(_Noex_move) = default; | ||
|
||
~basic_stacktrace() = default; | ||
|
||
[[nodiscard]] allocator_type get_allocator() const noexcept { | ||
return _Frames.get_allocator(); | ||
} | ||
|
||
[[nodiscard]] const_iterator begin() const noexcept { | ||
return _Frames.cbegin(); | ||
} | ||
|
||
[[nodiscard]] const_iterator end() const noexcept { | ||
return _Frames.cend(); | ||
} | ||
|
||
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { | ||
return _Frames.crbegin(); | ||
} | ||
|
||
[[nodiscard]] const_reverse_iterator rend() const noexcept { | ||
return _Frames.crend(); | ||
} | ||
|
||
[[nodiscard]] const_iterator cbegin() const noexcept { | ||
return _Frames.cbegin(); | ||
} | ||
|
||
[[nodiscard]] const_iterator cend() const noexcept { | ||
return _Frames.cend(); | ||
} | ||
|
||
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { | ||
return _Frames.crbegin(); | ||
} | ||
|
||
[[nodiscard]] const_reverse_iterator crend() const noexcept { | ||
return _Frames.crend(); | ||
} | ||
|
||
[[nodiscard]] bool empty() const noexcept { | ||
return _Frames.empty(); | ||
} | ||
|
||
[[nodiscard]] size_type size() const noexcept { | ||
return _Frames.size(); | ||
} | ||
|
||
[[nodiscard]] size_type max_size() const noexcept { | ||
return _Frames.max_size(); | ||
} | ||
|
||
[[nodiscard]] const_reference operator[](size_type _Sx) const noexcept /* strengthened */ { | ||
return _Frames[_Sx]; | ||
} | ||
|
||
[[nodiscard]] const_reference at(size_type _Sx) const { | ||
return _Frames.at(_Sx); | ||
} | ||
|
||
template <class _Al2> | ||
[[nodiscard]] friend bool operator==(const basic_stacktrace& _Lhs, const basic_stacktrace<_Al2>& _Rhs) noexcept { | ||
return _Lhs._Hash == _Rhs._Hash && _Lhs._Frames == _Rhs._Frames; | ||
} | ||
|
||
template <class _Al2> | ||
[[nodiscard]] friend strong_ordering operator<=>( | ||
const basic_stacktrace& _Lhs, const basic_stacktrace<_Al2>& _Rhs) noexcept { | ||
const auto _Result = _Lhs._Frames.size() <=> _Rhs._Frames.size(); | ||
if (_Result != strong_ordering::equal) { | ||
return _Result; | ||
} | ||
|
||
return _Lhs._Frames <=> _Rhs._Frames; | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
|
||
void swap(basic_stacktrace& _Other) noexcept( | ||
allocator_traits<_Al>::propagate_on_container_swap::value || allocator_traits<_Al>::is_always_equal::value) { | ||
_STD swap(_Frames, _Other._Frames); | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
_STD swap(_Hash, _Other._Hash); | ||
} | ||
|
||
[[nodiscard]] unsigned long _Get_hash() const noexcept { | ||
return _Hash; | ||
} | ||
|
||
[[nodiscard]] const void* _Data() const noexcept { | ||
return _Frames.data(); | ||
} | ||
|
||
|
||
private: | ||
static constexpr size_t _Max_frames = 0xFFFF; | ||
|
||
static constexpr bool _Noex_move = allocator_traits<_Al>::propagate_on_container_move_assignment::value | ||
|| allocator_traits<_Al>::is_always_equal::value; | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
struct _Internal_t {}; | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
basic_stacktrace(_Internal_t, size_type _Max_depth, const allocator_type& _Alloc) : _Frames(_Max_depth, _Alloc) {} | ||
|
||
_Frames_t _Frames; | ||
unsigned long _Hash = 0; | ||
}; | ||
|
||
using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>; | ||
|
||
template <class _Al> | ||
StephanTLavavej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
void swap(basic_stacktrace<_Al>& _Ax, basic_stacktrace<_Al>& _Bx) noexcept(noexcept(_Ax.swap(_Bx))) { | ||
return _Ax.swap(_Bx); | ||
} | ||
|
||
[[nodiscard]] inline string to_string(const stacktrace_entry& _Fx) { | ||
string _Result; | ||
__std_stacktrace_address_to_string(_Fx.native_handle(), &_Result, _Stacktrace_string_fill_impl); | ||
return _Result; | ||
} | ||
|
||
template <class _Al> | ||
[[nodiscard]] string to_string(const basic_stacktrace<_Al>& _St) { | ||
string _Result; | ||
__std_stacktrace_to_string(_St._Data(), _St.size(), &_Result, _Stacktrace_string_fill_impl); | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
return _Result; | ||
} | ||
|
||
template <class charT, class traits> | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& _Os, const stacktrace_entry& _Fx) { | ||
return _Os << to_string(_Fx); | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
|
||
template <class charT, class traits, class _Al> | ||
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& _Os, const basic_stacktrace<_Al>& _Fx) { | ||
return _Os << to_string(_Fx); | ||
AlexGuteniev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
|
||
namespace pmr { | ||
using stacktrace = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>; | ||
} | ||
|
||
template <> | ||
struct hash<stacktrace_entry> { | ||
[[nodiscard]] size_t operator()(const stacktrace_entry& _Val) const noexcept { | ||
return _Hash_representation(_Val.native_handle()); | ||
} | ||
}; | ||
|
||
template <class _Al> | ||
struct hash<basic_stacktrace<_Al>> { | ||
[[nodiscard]] size_t operator()(const basic_stacktrace<_Al>& _Val) const noexcept { | ||
return _Val._Get_hash(); | ||
} | ||
}; | ||
_STD_END | ||
|
||
#pragma pop_macro("new") | ||
_STL_RESTORE_CLANG_WARNINGS | ||
#pragma warning(pop) | ||
#pragma pack(pop) | ||
#endif // ^^^ _HAS_CXX23 ^^^ | ||
|
||
#endif // _STL_COMPILER_PREPROCESSOR | ||
#endif // _STACK_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.