[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.1 General [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.1 Sequential 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.1 General [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.1 General [stacktrace.general]") represents an evaluation in a stacktrace[.](#general-3.sentence-2) ### [19.6.2](#syn) Header synopsis [[stacktrace.syn]](stacktrace.syn) [🔗](#header:%3cstacktrace%3e) #include // see [[compare.syn]](compare.syn "17.12.1 Header synopsis")namespace std {// [[stacktrace.entry]](#entry "19.6.3 Class stacktrace_­entry"), class stacktrace_entryclass stacktrace_entry; // [[stacktrace.basic]](#basic "19.6.4 Class template basic_­stacktrace"), class template basic_stacktracetemplateclass basic_stacktrace; // basic_stacktrace [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s*using stacktrace = basic_stacktrace>; // [[stacktrace.basic.nonmem]](#basic.nonmem "19.6.4.6 Non-member functions"), non-member functionstemplatevoid swap(basic_stacktrace& a, basic_stacktrace& b)noexcept(noexcept(a.swap(b))); string to_string(const stacktrace_entry& f); template string to_string(const basic_stacktrace& st); ostream& operator<<(ostream& os, const stacktrace_entry& f); template ostream& operator<<(ostream& os, const basic_stacktrace& st); // [[stacktrace.format]](#format "19.6.5 Formatting support"), formatting supporttemplate<> struct formatter; template struct formatter>; namespace pmr {using stacktrace = basic_stacktrace>; }// [[stacktrace.basic.hash]](#basic.hash "19.6.6 Hash support"), hash supporttemplate struct hash; template<> struct hash; template struct hash>;} ### [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.1 Overview [stacktrace.entry.overview]") {public:using native_handle_type = *implementation-defined*; // [[stacktrace.entry.cons]](#entry.cons "19.6.3.2 Constructors"), 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.3 Observers"), observersconstexpr native_handle_type native_handle() const noexcept; constexpr explicit operator bool() const noexcept; // [[stacktrace.entry.query]](#entry.query "19.6.3.4 Query"), query string description() const; string source_file() const; uint_least32_t source_line() const; // [[stacktrace.entry.cmp]](#entry.cmp "19.6.3.5 Comparison"), 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.6 Object concepts [concepts.object]") ([[concepts.object]](concepts.object "18.6 Object concepts")) and[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]") ([[cmp.concept]](cmp.concept "17.12.4 Concept 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.12 Predefined 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 {templateclass [basic_stacktrace](#lib:basic_stacktrace "19.6.4.1 Overview [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.3 Observers")using iterator = const_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using difference_type = *implementation-defined*; using size_type = *implementation-defined*; using allocator_type = Allocator; // [[stacktrace.basic.cons]](#basic.cons "19.6.4.2 Creation 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); 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::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); ~basic_stacktrace(); // [[stacktrace.basic.obs]](#basic.obs "19.6.4.3 Observers"), 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.4 Comparisons"), comparisonstemplatefriend bool operator==(const basic_stacktrace& x, const basic_stacktrace& y) noexcept; templatefriend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace& y) noexcept; // [[stacktrace.basic.mod]](#basic.mod "19.6.4.5 Modifiers"), modifiersvoid swap(basic_stacktrace& other)noexcept(allocator_traits::propagate_on_container_swap::value || allocator_traits::is_always_equal::value); private: vector *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.3 Reversible container requirements")), of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and of a sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence 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); ` [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::propagate_on_container_move_assignment::value || allocator_traits::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.14 Restrictions 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.13 Concept random_­access_­iterator [iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept random_­access_­iterator")) and meets the*Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random 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 friend bool operator==(const basic_stacktrace& x, const basic_stacktrace& 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 friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace& 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::propagate_on_container_swap::value || allocator_traits::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 void swap(basic_stacktrace& a, basic_stacktrace& 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 string to_string(const basic_stacktrace& 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 ostream& operator<<(ostream& os, const basic_stacktrace& 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; ` [1](#format-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2362) formatter 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.2 Standard 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 struct formatter>; ` [3](#format-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/diagnostics.tex#L2388) For formatter>,*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 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; template struct hash>; ` [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.19 Class template hash"))[.](#basic.hash-1.sentence-1)