Files
cppdraft_translate/cppdraft/stacktrace.md
2025-10-25 03:02:53 +03:00

705 lines
28 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[stacktrace]
# 19 Diagnostics library [[diagnostics]](./#diagnostics)
## 19.6 Stacktrace [stacktrace]
### [19.6.1](#general) General [[stacktrace.general]](stacktrace.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1651)
Subclause [stacktrace] describes components
that C++ programs may use to store
the stacktrace of the current thread of execution and
query information about the stored stacktrace at runtime[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1657)
The [*invocation sequence*](#def:invocation_sequence "19.6.1General[stacktrace.general]") of the current evaluation x0 in the current thread of execution
is a sequence (x0,…,xn) of evaluations such that, for i ≥ 0,xi is within the function invocation xi+1 ([[intro.execution]](intro.execution "6.10.1Sequential execution"))[.](#general-2.sentence-1)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1663)
A [*stacktrace*](#def:stacktrace "19.6.1General[stacktrace.general]") is an approximate representation of
an invocation sequence and consists of stacktrace entries[.](#general-3.sentence-1)
A [*stacktrace entry*](#def:stacktrace_entry "19.6.1General[stacktrace.general]") represents an evaluation in a stacktrace[.](#general-3.sentence-2)
### [19.6.2](#syn) Header <stacktrace> synopsis [[stacktrace.syn]](stacktrace.syn)
[🔗](#header:%3cstacktrace%3e)
#include <compare> // see [[compare.syn]](compare.syn "17.12.1Header <compare> synopsis")namespace std {// [[stacktrace.entry]](#entry "19.6.3Class stacktrace_­entry"), class stacktrace_entryclass stacktrace_entry; // [[stacktrace.basic]](#basic "19.6.4Class template basic_­stacktrace"), class template basic_stacktracetemplate<class Allocator>class basic_stacktrace; // basic_stacktrace [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s*using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>; // [[stacktrace.basic.nonmem]](#basic.nonmem "19.6.4.6Non-member functions"), non-member functionstemplate<class Allocator>void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b)noexcept(noexcept(a.swap(b)));
string to_string(const stacktrace_entry& f); template<class Allocator> string to_string(const basic_stacktrace<Allocator>& st);
ostream& operator<<(ostream& os, const stacktrace_entry& f); template<class Allocator> ostream& operator<<(ostream& os, const basic_stacktrace<Allocator>& st); // [[stacktrace.format]](#format "19.6.5Formatting support"), formatting supporttemplate<> struct formatter<stacktrace_entry>; template<class Allocator> struct formatter<basic_stacktrace<Allocator>>; namespace pmr {using stacktrace = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>; }// [[stacktrace.basic.hash]](#basic.hash "19.6.6Hash support"), hash supporttemplate<class T> struct hash; template<> struct hash<stacktrace_entry>; template<class Allocator> struct hash<basic_stacktrace<Allocator>>;}
### [19.6.3](#entry) Class stacktrace_entry [[stacktrace.entry]](stacktrace.entry)
#### [19.6.3.1](#entry.overview) Overview [[stacktrace.entry.overview]](stacktrace.entry.overview)
namespace std {class [stacktrace_entry](#lib:stacktrace_entry "19.6.3.1Overview[stacktrace.entry.overview]") {public:using native_handle_type = *implementation-defined*; // [[stacktrace.entry.cons]](#entry.cons "19.6.3.2Constructors"), constructorsconstexpr stacktrace_entry() noexcept; constexpr stacktrace_entry(const stacktrace_entry& other) noexcept; constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept; ~stacktrace_entry(); // [[stacktrace.entry.obs]](#entry.obs "19.6.3.3Observers"), observersconstexpr native_handle_type native_handle() const noexcept; constexpr explicit operator bool() const noexcept; // [[stacktrace.entry.query]](#entry.query "19.6.3.4Query"), query string description() const;
string source_file() const;
uint_least32_t source_line() const; // [[stacktrace.entry.cmp]](#entry.cmp "19.6.3.5Comparison"), comparisonfriend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; friend constexpr strong_ordering operator<=>(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; };}
[1](#entry.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1749)
An object of type stacktrace_entry is either empty,
or represents a stacktrace entry and
provides operations for querying information about it[.](#entry.overview-1.sentence-1)
The class stacktrace_entry models[regular](concepts.object#concept:regular "18.6Object concepts[concepts.object]") ([[concepts.object]](concepts.object "18.6Object concepts")) and[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<strong_ordering> ([[cmp.concept]](cmp.concept "17.12.4Concept three_­way_­comparable"))[.](#entry.overview-1.sentence-2)
#### [19.6.3.2](#entry.cons) Constructors [[stacktrace.entry.cons]](stacktrace.entry.cons)
[🔗](#lib:stacktrace_entry,constructor)
`constexpr stacktrace_entry() noexcept;
`
[1](#entry.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1765)
*Postconditions*: *this is empty[.](#entry.cons-1.sentence-1)
#### [19.6.3.3](#entry.obs) Observers [[stacktrace.entry.obs]](stacktrace.entry.obs)
[🔗](#lib:native_handle,stacktrace_entry)
`constexpr native_handle_type native_handle() const noexcept;
`
[1](#entry.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1778)
The semantics of this function areimplementation-defined[.](#entry.obs-1.sentence-1)
[2](#entry.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1782)
*Remarks*: Successive invocations of the native_handle function
for an unchanged stacktrace_entry object return identical values[.](#entry.obs-2.sentence-1)
[🔗](#lib:operator_bool,stacktrace_entry)
`constexpr explicit operator bool() const noexcept;
`
[3](#entry.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1794)
*Returns*: false if and only if *this is empty[.](#entry.obs-3.sentence-1)
#### [19.6.3.4](#entry.query) Query [[stacktrace.entry.query]](stacktrace.entry.query)
[1](#entry.query-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1801)
[*Note [1](#entry.query-note-1)*:
All the stacktrace_entry query functions treat
errors other than memory allocation errors
as “no information available” and do not throw in that case[.](#entry.query-1.sentence-1)
— *end note*]
[🔗](#lib:description,stacktrace_entry)
`string description() const;
`
[2](#entry.query-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1814)
*Returns*: A description of the evaluation represented by *this,
or an empty string[.](#entry.query-2.sentence-1)
[3](#entry.query-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1819)
*Throws*: bad_alloc if memory for
the internal data structures or the resulting string cannot be allocated[.](#entry.query-3.sentence-1)
[🔗](#lib:source_file,stacktrace_entry)
`string source_file() const;
`
[4](#entry.query-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1831)
*Returns*: The presumed or actual name of the source file ([[cpp.predefined]](cpp.predefined "15.12Predefined macro names"))
that lexically contains the expression or statement
whose evaluation is represented by *this, or an empty string[.](#entry.query-4.sentence-1)
[5](#entry.query-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1837)
*Throws*: bad_alloc if memory for
the internal data structures or the resulting string cannot be allocated[.](#entry.query-5.sentence-1)
[🔗](#lib:source_line,stacktrace_entry)
`uint_least32_t source_line() const;
`
[6](#entry.query-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1849)
*Returns*: 0, or a 1-based line number that lexically relates to the evaluation
represented by *this[.](#entry.query-6.sentence-1)
If source_file returns the presumed name of the source file,
returns the presumed line number;
if source_file returns the actual name of the source file,
returns the actual line number[.](#entry.query-6.sentence-2)
[7](#entry.query-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1858)
*Throws*: bad_alloc if memory for
the internal data structures cannot be allocated[.](#entry.query-7.sentence-1)
#### [19.6.3.5](#entry.cmp) Comparison [[stacktrace.entry.cmp]](stacktrace.entry.cmp)
[🔗](#lib:operator==,stacktrace_entry)
`friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
`
[1](#entry.cmp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1872)
*Returns*: true if and only if x and y represent
the same stacktrace entry or both x and y are empty[.](#entry.cmp-1.sentence-1)
### [19.6.4](#basic) Class template basic_stacktrace [[stacktrace.basic]](stacktrace.basic)
#### [19.6.4.1](#basic.overview) Overview [[stacktrace.basic.overview]](stacktrace.basic.overview)
namespace std {template<class Allocator>class [basic_stacktrace](#lib:basic_stacktrace "19.6.4.1Overview[stacktrace.basic.overview]") {public:using value_type = stacktrace_entry; using const_reference = const value_type&; using reference = value_type&; using const_iterator = *implementation-defined*; // see [[stacktrace.basic.obs]](#basic.obs "19.6.4.3Observers")using iterator = const_iterator; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using difference_type = *implementation-defined*; using size_type = *implementation-defined*; using allocator_type = Allocator; // [[stacktrace.basic.cons]](#basic.cons "19.6.4.2Creation and assignment"), creation and assignmentstatic basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, size_type max_depth, const allocator_type& alloc = allocator_type()) noexcept;
basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>); explicit basic_stacktrace(const allocator_type& alloc) noexcept;
basic_stacktrace(const basic_stacktrace& other);
basic_stacktrace(basic_stacktrace&& other) noexcept;
basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc);
basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc);
basic_stacktrace& operator=(const basic_stacktrace& other);
basic_stacktrace& operator=(basic_stacktrace&& other)noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); ~basic_stacktrace(); // [[stacktrace.basic.obs]](#basic.obs "19.6.4.3Observers"), observers allocator_type get_allocator() const noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept; bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
const_reference operator[](size_type) const;
const_reference at(size_type) const; // [[stacktrace.basic.cmp]](#basic.cmp "19.6.4.4Comparisons"), comparisonstemplate<class Allocator2>friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; template<class Allocator2>friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; // [[stacktrace.basic.mod]](#basic.mod "19.6.4.5Modifiers"), modifiersvoid swap(basic_stacktrace& other)noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); private: vector<value_type, allocator_type> *frames_*; // *exposition only*};}
[1](#basic.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1958)
The class template basic_stacktrace satisfies
the requirements
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers")), and
of a sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers")),
except that
- [(1.1)](#basic.overview-1.1)
only move, assignment, swap, and
operations defined for const-qualified sequence containers are supported and,
- [(1.2)](#basic.overview-1.2)
the semantics of comparison functions
are different from those required for a container[.](#basic.overview-1.sentence-1)
#### [19.6.4.2](#basic.cons) Creation and assignment [[stacktrace.basic.cons]](stacktrace.basic.cons)
[🔗](#lib:current,basic_stacktrace)
`static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept;
`
[1](#basic.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L1982)
*Returns*: A basic_stacktrace object
with *frames_* storing
the stacktrace of the current evaluation in the current thread of execution, or
an empty basic_stacktrace object
if the initialization of *frames_* failed[.](#basic.cons-1.sentence-1)
alloc is passed to the constructor of the *frames_* object[.](#basic.cons-1.sentence-2)
[*Note [1](#basic.cons-note-1)*:
If the stacktrace was successfully obtained,
then *frames_*.front() is the stacktrace_entry representing approximately the current evaluation, and*frames_*.back() is the stacktrace_entry representing approximately the initial function of
the current thread of execution[.](#basic.cons-1.sentence-3)
— *end note*]
[🔗](#lib:current,basic_stacktrace_)
`static basic_stacktrace current(size_type skip,
const allocator_type& alloc = allocator_type()) noexcept;
`
[2](#basic.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2008)
Let t be a stacktrace
as-if obtained via basic_stacktrace::current(alloc)[.](#basic.cons-2.sentence-1)
Let n be t.size()[.](#basic.cons-2.sentence-2)
[3](#basic.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2013)
*Returns*: A basic_stacktrace object
where *frames_* is direct-non-list-initialized from argumentst.begin() + min(n, skip), t.end(), and alloc,
or an empty basic_stacktrace object
if the initialization of *frames_* failed[.](#basic.cons-3.sentence-1)
[🔗](#lib:current,basic_stacktrace__)
`static basic_stacktrace current(size_type skip, size_type max_depth,
const allocator_type& alloc = allocator_type()) noexcept;
`
[4](#basic.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2029)
Let t be a stacktrace
as-if obtained via basic_stacktrace::current(alloc)[.](#basic.cons-4.sentence-1)
Let n be t.size()[.](#basic.cons-4.sentence-2)
[5](#basic.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2034)
*Hardened preconditions*: skip <= skip + max_depth is true[.](#basic.cons-5.sentence-1)
[6](#basic.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2038)
*Returns*: A basic_stacktrace object
where *frames_* is direct-non-list-initialized from argumentst.begin() + min(n, skip), t.begin() + min(n, skip + max_depth),
and alloc,
or an empty basic_stacktrace object
if the initialization of *frames_* failed[.](#basic.cons-6.sentence-1)
[🔗](#lib:basic_stacktrace,constructor)
`basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>);
`
[7](#basic.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2054)
*Postconditions*: empty() is true[.](#basic.cons-7.sentence-1)
[🔗](#lib:basic_stacktrace,constructor_)
`explicit basic_stacktrace(const allocator_type& alloc) noexcept;
`
[8](#basic.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2065)
*Effects*: alloc is passed to the *frames_* constructor[.](#basic.cons-8.sentence-1)
[9](#basic.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2069)
*Postconditions*: empty() is true[.](#basic.cons-9.sentence-1)
[🔗](#lib:basic_stacktrace,constructor__)
`basic_stacktrace(const basic_stacktrace& other);
basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc);
basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc);
basic_stacktrace& operator=(const basic_stacktrace& other);
basic_stacktrace& operator=(basic_stacktrace&& other)
noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
allocator_traits<Allocator>::is_always_equal::value);
`
[10](#basic.cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2087)
*Remarks*: Implementations may strengthen the exception specification
for these functions ([[res.on.exception.handling]](res.on.exception.handling "16.4.6.14Restrictions on exception handling"))
by ensuring that empty() is true on failed allocation[.](#basic.cons-10.sentence-1)
#### [19.6.4.3](#basic.obs) Observers [[stacktrace.basic.obs]](stacktrace.basic.obs)
[🔗](#lib:const_iterator,basic_stacktrace)
`using const_iterator = implementation-defined;
`
[1](#basic.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2102)
The type models[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator")) and
meets the*Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators"))[.](#basic.obs-1.sentence-1)
[🔗](#lib:get_allocator,basic_stacktrace)
`allocator_type get_allocator() const noexcept;
`
[2](#basic.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2115)
*Returns*: *frames_*.get_allocator()[.](#basic.obs-2.sentence-1)
[🔗](#lib:begin,basic_stacktrace)
`const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
`
[3](#basic.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2128)
*Returns*: An iterator referring to the first element in *frames_*[.](#basic.obs-3.sentence-1)
If empty() is true,
then it returns the same value as end()[.](#basic.obs-3.sentence-2)
[🔗](#lib:end,basic_stacktrace)
`const_iterator end() const noexcept;
const_iterator cend() const noexcept;
`
[4](#basic.obs-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2143)
*Returns*: The end iterator[.](#basic.obs-4.sentence-1)
[🔗](#lib:rbegin,basic_stacktrace)
`const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
`
[5](#basic.obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2156)
*Returns*: reverse_iterator(cend())[.](#basic.obs-5.sentence-1)
[🔗](#lib:rend,basic_stacktrace)
`const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
`
[6](#basic.obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2169)
*Returns*: reverse_iterator(cbegin())[.](#basic.obs-6.sentence-1)
[🔗](#lib:empty,basic_stacktrace)
`bool empty() const noexcept;
`
[7](#basic.obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2180)
*Returns*: *frames_*.empty()[.](#basic.obs-7.sentence-1)
[🔗](#lib:size,basic_stacktrace)
`size_type size() const noexcept;
`
[8](#basic.obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2191)
*Returns*: *frames_*.size()[.](#basic.obs-8.sentence-1)
[🔗](#lib:max_size,basic_stacktrace)
`size_type max_size() const noexcept;
`
[9](#basic.obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2202)
*Returns*: *frames_*.max_size()[.](#basic.obs-9.sentence-1)
[🔗](#lib:operator%5b%5d,basic_stacktrace)
`const_reference operator[](size_type frame_no) const;
`
[10](#basic.obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2213)
*Hardened preconditions*: frame_no < size() is true[.](#basic.obs-10.sentence-1)
[11](#basic.obs-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2217)
*Returns*: *frames_*[frame_no][.](#basic.obs-11.sentence-1)
[12](#basic.obs-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2221)
*Throws*: Nothing[.](#basic.obs-12.sentence-1)
[🔗](#lib:at,basic_stacktrace)
`const_reference at(size_type frame_no) const;
`
[13](#basic.obs-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2232)
*Returns*: *frames_*[frame_no][.](#basic.obs-13.sentence-1)
[14](#basic.obs-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2236)
*Throws*: out_of_range if frame_no >= size()[.](#basic.obs-14.sentence-1)
#### [19.6.4.4](#basic.cmp) Comparisons [[stacktrace.basic.cmp]](stacktrace.basic.cmp)
[🔗](#lib:operator==,basic_stacktrace)
`template<class Allocator2>
friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
`
[1](#basic.cmp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2250)
*Returns*: equal(x.begin(), x.end(), y.begin(), y.end())[.](#basic.cmp-1.sentence-1)
[🔗](#lib:operator%3c=%3e,basic_stacktrace)
`template<class Allocator2>
friend strong_ordering
operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
`
[2](#basic.cmp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2263)
*Returns*: x.size() <=> y.size() if x.size() != y.size();lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end()) otherwise[.](#basic.cmp-2.sentence-1)
#### [19.6.4.5](#basic.mod) Modifiers [[stacktrace.basic.mod]](stacktrace.basic.mod)
[🔗](#lib:swap,basic_stacktrace)
`void swap(basic_stacktrace& other)
noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
allocator_traits<Allocator>::is_always_equal::value);
`
[1](#basic.mod-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2280)
*Effects*: Exchanges the contents of *this and other[.](#basic.mod-1.sentence-1)
#### [19.6.4.6](#basic.nonmem) Non-member functions [[stacktrace.basic.nonmem]](stacktrace.basic.nonmem)
[🔗](#lib:swap,basic_stacktrace_)
`template<class Allocator>
void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b)
noexcept(noexcept(a.swap(b)));
`
[1](#basic.nonmem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2295)
*Effects*: Equivalent to a.swap(b)[.](#basic.nonmem-1.sentence-1)
[🔗](#lib:to_string,basic_stacktrace)
`string to_string(const stacktrace_entry& f);
`
[2](#basic.nonmem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2306)
*Returns*: A string with a description of f[.](#basic.nonmem-2.sentence-1)
[3](#basic.nonmem-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2310)
*Recommended practice*: The description should provide information about the contained evaluation,
including information fromf.source_file() and f.source_line()[.](#basic.nonmem-3.sentence-1)
[🔗](#lib:to_string,basic_stacktrace_)
`template<class Allocator>
string to_string(const basic_stacktrace<Allocator>& st);
`
[4](#basic.nonmem-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2324)
*Returns*: A string with a description of st[.](#basic.nonmem-4.sentence-1)
[*Note [1](#basic.nonmem-note-1)*:
The number of lines is not guaranteed to be equal to st.size()[.](#basic.nonmem-4.sentence-2)
— *end note*]
[🔗](#lib:operator%3c%3c,stacktrace_entry)
`ostream& operator<<(ostream& os, const stacktrace_entry& f);
`
[5](#basic.nonmem-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2338)
*Effects*: Equivalent to: return os << to_string(f);
[🔗](#lib:operator%3c%3c,basic_stacktrace)
`template<class Allocator>
ostream& operator<<(ostream& os, const basic_stacktrace<Allocator>& st);
`
[6](#basic.nonmem-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2350)
*Effects*: Equivalent to: return os << to_string(st);
### [19.6.5](#format) Formatting support [[stacktrace.format]](stacktrace.format)
[🔗](#format-itemdecl:1)
`template<> struct formatter<stacktrace_entry>;
`
[1](#format-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2362)
formatter<stacktrace_entry> interprets *format-spec* as a *stacktrace-entry-format-spec*[.](#format-1.sentence-1)
The syntax of format specifications is as follows:
stacktrace-entry-format-spec :
fill-and-alignopt widthopt
[*Note [1](#format-note-1)*:
The productions *fill-and-align* and *width* are described in [[format.string.std]](format.string.std "28.5.2.2Standard format specifiers")[.](#format-1.sentence-3)
— *end note*]
[2](#format-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2377)
A stacktrace_entry object se is formatted as if by
copying to_string(se) through the output iterator of the context
with additional padding and adjustments as specified by the format specifiers[.](#format-2.sentence-1)
[🔗](#format-itemdecl:2)
`template<class Allocator> struct formatter<basic_stacktrace<Allocator>>;
`
[3](#format-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2388)
For formatter<basic_stacktrace<Allocator>>,*format-spec* is empty[.](#format-3.sentence-1)
[4](#format-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2392)
A basic_stacktrace<Allocator> object s is formatted as if by
copying to_string(s) through the output iterator of the context[.](#format-4.sentence-1)
### [19.6.6](#basic.hash) Hash support [[stacktrace.basic.hash]](stacktrace.basic.hash)
[🔗](#basic.hash-itemdecl:1)
`template<> struct hash<stacktrace_entry>;
template<class Allocator> struct hash<basic_stacktrace<Allocator>>;
`
[1](#basic.hash-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2405)
The specializations are enabled ([[unord.hash]](unord.hash "22.10.19Class template hash"))[.](#basic.hash-1.sentence-1)