// <stacktrace> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef _GLIBCXX_STACKTRACE
#define _GLIBCXX_STACKTRACE 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/requires_hosted.h> // std::string bound

#include <bits/c++config.h>

#define __glibcxx_want_stacktrace
#define __glibcxx_want_formatters
#include <bits/version.h>

#ifdef __cpp_lib_stacktrace // C++ >= 23 && hosted && HAVE_STACKTRACE
#include <compare>
#include <format>
#include <new>
#include <string>
#include <sstream>
#include <bits/memory_resource.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#include <bits/stl_iterator.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_tempbuf.h> // __get_temporary_buffer
#include <ext/numeric_traits.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // [stacktrace.entry], class stacktrace_entry
  class stacktrace_entry
  {
    using uint_least32_t = __UINT_LEAST32_TYPE__;
    using uintptr_t = __UINTPTR_TYPE__;

  public:
    using native_handle_type = uintptr_t;

    // [stacktrace.entry.ctor], constructors

    constexpr
    stacktrace_entry() noexcept = default;

    constexpr
    stacktrace_entry(const stacktrace_entry& __other) noexcept = default;

    constexpr stacktrace_entry&
    operator=(const stacktrace_entry& __other) noexcept = default;

    ~stacktrace_entry() = default;

    // [stacktrace.entry.obs], observers

    [[nodiscard]]
    constexpr native_handle_type
    native_handle() const noexcept { return _M_pc; }

    constexpr explicit operator bool() const noexcept
    { return _M_pc != (native_handle_type)-1; }

    // [stacktrace.entry.query], query
    [[nodiscard]]
    string
    description() const
    {
      string __s;
      _M_get_info(&__s, nullptr, nullptr);
      return __s;
    }

    [[nodiscard]]
    string
    source_file() const
    {
      string __s;
      _M_get_info(nullptr, &__s, nullptr);
      return __s;
    }

    [[nodiscard]]
    uint_least32_t
    source_line() const
    {
      int __line = 0;
      _M_get_info(nullptr, nullptr, &__line);
      return __line;
    }

    // [stacktrace.entry.cmp], comparison
    [[nodiscard]]
    friend constexpr bool
    operator==(const stacktrace_entry& __x,
	       const stacktrace_entry& __y) noexcept
    { return __x._M_pc == __y._M_pc; }

    [[nodiscard]]
    friend constexpr strong_ordering
    operator<=>(const stacktrace_entry& __x,
		const stacktrace_entry& __y) noexcept
    { return __x._M_pc <=> __y._M_pc; }

  private:
    native_handle_type _M_pc = -1;

    template<typename _Allocator> friend class basic_stacktrace;

    friend ostream&
    operator<<(ostream&, const stacktrace_entry&);

    // Type-erased wrapper for the fields of a stacktrace entry.
    // This type is independent of which std::string ABI is in use.
    struct _Info
    {
      void* _M_desc;
      void* _M_file;
      int* _M_line;
      void (*_M_set)(void*, const char*);

      _GLIBCXX_DEFAULT_ABI_TAG
      static void
      _S_set(void* __dest, const char* __str)
      { static_cast<string*>(__dest)->assign(__str); }

      _Info(string* __desc, string* __file, int* __line)
      : _M_desc(__desc), _M_file(__file), _M_line(__line), _M_set(_S_set)
      { }

      bool
      _M_populate(native_handle_type);

      void _M_set_file(const char*);
      void _M_set_desc(const char*);
    };

    bool
    _M_get_info(string* __desc, string* __file, int* __line) const
    {
      if (!*this)
	return false;
      return _Info(__desc, __file, __line)._M_populate(_M_pc);
    }
  };

  class __stacktrace_impl
  {
  protected:
    static int _S_current(int (*) (void*, __UINTPTR_TYPE__), void*, int = 0);
  };

  // [stacktrace.basic], class template basic_stacktrace
  template<typename _Allocator>
    class basic_stacktrace
    : private __stacktrace_impl
    {
      using _AllocTraits = allocator_traits<_Allocator>;
      using uintptr_t = __UINTPTR_TYPE__;
      struct _Impl;

    public:
      using value_type = stacktrace_entry;
      using const_reference = const value_type&;
      using reference = value_type&;
      using const_iterator
	= __gnu_cxx::__normal_iterator<typename _AllocTraits::const_pointer,
				       _Impl>;
      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 = unsigned short;
      using allocator_type = _Allocator;

      // [stacktrace.basic.ctor], creation and assignment

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(const allocator_type& __alloc = allocator_type()) noexcept
      {
	basic_stacktrace __ret(__alloc);
	if (auto __cb = __ret._M_prepare()) [[likely]]
	  {
	    if (_S_current(__cb, std::__addressof(__ret)))
	      __ret._M_clear();
	    else
	      __ret._M_trim();
	  }
	return __ret;
      }

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(size_type __skip,
	      const allocator_type& __alloc = allocator_type()) noexcept
      {
	basic_stacktrace __ret(__alloc);
	if (__skip >= __INT_MAX__) [[unlikely]]
	  return __ret;
	if (auto __cb = __ret._M_prepare()) [[likely]]
	  {
	    if (_S_current(__cb, std::__addressof(__ret), __skip))
	      __ret._M_clear();
	    else
	      __ret._M_trim();
	  }

	return __ret;
      }

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(size_type __skip, size_type __max_depth,
	      const allocator_type& __alloc = allocator_type()) noexcept
      {
	__glibcxx_assert(__skip <= (size_type(-1) - __max_depth));

	basic_stacktrace __ret(__alloc);
	if (__max_depth == 0) [[unlikely]]
	  return __ret;
	if (__skip >= __INT_MAX__) [[unlikely]]
	  return __ret;
	if (auto __cb = __ret._M_prepare(__max_depth)) [[likely]]
	  {
	    if (_S_current(__cb, std::__addressof(__ret), __skip) < 0)
	      __ret._M_clear();
	    else if (__ret.size() > __max_depth)
	      {
		__ret._M_impl._M_resize(__max_depth, __ret._M_alloc);

		if (__ret._M_impl._M_capacity / 2 >= __max_depth)
		  {
		    // shrink to fit
		    _Impl __tmp = __ret._M_impl._M_clone(__ret._M_alloc);
		    if (__tmp._M_capacity)
		      {
			__ret._M_clear();
			__ret._M_impl = __tmp;
		      }
		  }
	      }
	    else
	      __ret._M_trim();
	  }
	return __ret;
      }

      basic_stacktrace()
      noexcept(is_nothrow_default_constructible_v<allocator_type>)
      { }

      explicit
      basic_stacktrace(const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      { }

      basic_stacktrace(const basic_stacktrace& __other) noexcept
      : basic_stacktrace(__other,
	  _AllocTraits::select_on_container_copy_construction(__other._M_alloc))
      { }

      basic_stacktrace(basic_stacktrace&& __other) noexcept
      : _M_alloc(std::move(__other._M_alloc)),
	_M_impl(std::__exchange(__other._M_impl, {}))
      { }

      basic_stacktrace(const basic_stacktrace& __other,
		       const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      {
	if (const auto __s = __other._M_impl._M_size)
	  _M_impl = __other._M_impl._M_clone(_M_alloc);
      }

      basic_stacktrace(basic_stacktrace&& __other,
		       const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      {
	if constexpr (_AllocTraits::is_always_equal::value)
	  _M_impl = std::__exchange(__other._M_impl, {});
	else if (_M_alloc == __other._M_alloc)
	  _M_impl = std::__exchange(__other._M_impl, {});
	else if (const auto __s = __other._M_impl._M_size)
	  _M_impl = __other._M_impl._M_clone(_M_alloc);
      }

      basic_stacktrace&
      operator=(const basic_stacktrace& __other) noexcept
      {
	if (std::__addressof(__other) == this)
	  return *this;

	constexpr bool __pocca
	  = _AllocTraits::propagate_on_container_copy_assignment::value;
	constexpr bool __always_eq = _AllocTraits::is_always_equal::value;

	const auto __s = __other.size();

	if constexpr (!__always_eq && __pocca)
	  {
	    if (_M_alloc != __other._M_alloc)
	      {
		// Cannot keep the same storage, so deallocate it now.
		_M_clear();
	      }
	  }

	if (_M_impl._M_capacity < __s)
	  {
	    // Need to allocate new storage.
	    _M_clear();

	    if constexpr (__pocca)
	      _M_alloc = __other._M_alloc;

	    _M_impl = __other._M_impl._M_clone(_M_alloc);
	  }
	else
	  {
	    // Current storage is large enough.
	    _M_impl._M_resize(0, _M_alloc);
	    _M_impl._M_assign(__other._M_impl, _M_alloc);

	    if constexpr (__pocca)
	      _M_alloc = __other._M_alloc;
	  }

	return *this;
      }

      basic_stacktrace&
      operator=(basic_stacktrace&& __other) noexcept
      {
	if (std::__addressof(__other) == this)
	  return *this;

	constexpr bool __pocma
	  = _AllocTraits::propagate_on_container_move_assignment::value;

	if constexpr (_AllocTraits::is_always_equal::value)
	  std::swap(_M_impl, __other._M_impl);
	else if (_M_alloc == __other._M_alloc)
	  std::swap(_M_impl, __other._M_impl);
	else if constexpr (__pocma)
	  {
	    // Free current storage and take ownership of __other's storage.
	    _M_clear();
	    _M_impl = std::__exchange(__other._M_impl, {});
	  }
	else // Allocators are unequal and don't propagate.
	  {
	    const size_type __s = __other.size();

	    if (_M_impl._M_capacity < __s)
	      {
		// Need to allocate new storage.
		_M_clear();
		_M_impl = __other._M_impl._M_clone(_M_alloc);
	      }
	    else
	      {
		// Current storage is large enough.
		_M_impl._M_resize(0, _M_alloc);
		_M_impl._M_assign(__other._M_impl, _M_alloc);
	      }
	  }

	if constexpr (__pocma)
	  _M_alloc = std::move(__other._M_alloc);

	return *this;
      }

      constexpr ~basic_stacktrace()
      {
	_M_clear();
      }

      // [stacktrace.basic.obs], observers
      [[nodiscard]]
      allocator_type get_allocator() const noexcept { return _M_alloc; }

      [[nodiscard]]
      const_iterator
      begin() const noexcept
      { return const_iterator{_M_impl._M_frames}; }

      [[nodiscard]]
      const_iterator
      end() const noexcept
      { return begin() + size(); }

      [[nodiscard]]
      const_reverse_iterator
      rbegin() const noexcept
      { return std::make_reverse_iterator(end()); }

      [[nodiscard]]
      const_reverse_iterator
      rend() const noexcept
      { return std::make_reverse_iterator(begin()); }

      [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
      [[nodiscard]] const_iterator cend() const noexcept { return end(); }

      [[nodiscard]]
      const_reverse_iterator
      crbegin() const noexcept { return rbegin(); };

      [[nodiscard]]
      const_reverse_iterator
      crend() const noexcept { return rend(); };

      [[nodiscard]] bool empty() const noexcept { return size() == 0; }
      [[nodiscard]] size_type size() const noexcept { return _M_impl._M_size; }

      [[nodiscard]]
      size_type
      max_size() const noexcept
      { return _Impl::_S_max_size(_M_alloc); }

      [[nodiscard]]
      const_reference
      operator[](size_type __n) const noexcept
      {
	__glibcxx_assert(__n < size());
	return begin()[__n];
      }

      [[nodiscard]]
      const_reference
      at(size_type __n) const
      {
	if (__n >= size())
	  __throw_out_of_range("basic_stacktrace::at: bad frame number");
	return begin()[__n];
      }

      // [stacktrace.basic.cmp], comparisons
      template<typename _Allocator2>
	[[nodiscard]]
	friend bool
	operator==(const basic_stacktrace& __x,
		   const basic_stacktrace<_Allocator2>& __y) noexcept
	{ return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end()); }

      template<typename _Allocator2>
	[[nodiscard]]
	friend strong_ordering
	operator<=>(const basic_stacktrace& __x,
		    const basic_stacktrace<_Allocator2>& __y) noexcept
	{
	  if (auto __s = __x.size() <=> __y.size(); __s != 0)
	    return __s;
	  return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
							__y.begin(), __y.end());
	}

      // [stacktrace.basic.mod], modifiers
      void
      swap(basic_stacktrace& __other) noexcept
      {
	std::swap(_M_impl, __other._M_impl);
	if constexpr (_AllocTraits::propagate_on_container_swap::value)
	  std::swap(_M_alloc, __other._M_alloc);
	else if constexpr (!_AllocTraits::is_always_equal::value)
	  {
	    __glibcxx_assert(_M_alloc == __other._M_alloc);
	  }
      }

    private:
      bool
      _M_push_back(const value_type& __x) noexcept
      {
	return _M_impl._M_push_back(_M_alloc, __x);
      }

      void
      _M_clear() noexcept
      {
	_M_impl._M_resize(0, _M_alloc);
	_M_impl._M_deallocate(_M_alloc);
      }

      // Precondition: __max_depth != 0
      auto
      _M_prepare(size_type __max_depth = -1) noexcept
      -> int (*) (void*, uintptr_t)
      {
	auto __cb = +[](void* __data, uintptr_t __pc) {
	  auto& __s = *static_cast<basic_stacktrace*>(__data);
	  stacktrace_entry __f;
	  __f._M_pc = __pc;
	  if (__s._M_push_back(__f)) [[likely]]
	    return 0; // continue tracing
	  return -1; // stop tracing due to error
	};

	if (__max_depth > 128)
	  __max_depth = 64; // soft limit, _M_push_back will reallocate
	else
	  __cb = [](void* __data, uintptr_t __pc) {
	    auto& __s = *static_cast<basic_stacktrace*>(__data);
	    stacktrace_entry __f;
	    __f._M_pc = __pc;
	    if (__s.size() == __s._M_impl._M_capacity) [[unlikely]]
	      return 1; // stop tracing due to reaching max depth
	    if (__s._M_push_back(__f)) [[likely]]
	      return 0; // continue tracing
	    return -1; // stop tracing due to error
	  };

	if (_M_impl._M_allocate(_M_alloc, __max_depth)) [[likely]]
	  return __cb;
	return nullptr;
      }

      struct _Impl
      {
	using pointer = typename _AllocTraits::pointer;

	pointer	  _M_frames   = nullptr;
	size_type _M_size     = 0;
	size_type _M_capacity = 0;

	static size_type
	_S_max_size(const allocator_type& __alloc) noexcept
	{
	  const size_t __size_max = __gnu_cxx::__int_traits<size_type>::__max;
	  const size_t __alloc_max = _AllocTraits::max_size(__alloc);
	  return std::min(__size_max, __alloc_max);
	}

	// Precondition: _M_frames == nullptr && __n != 0
	pointer
	_M_allocate(allocator_type& __alloc, size_type __n) noexcept
	{
	  if (__n <= _S_max_size(__alloc)) [[likely]]
	    {
	      if constexpr (is_same_v<allocator_type, allocator<value_type>>)
		{
		  // Use non-throwing __get_temporary_buffer, so that we
		  // don't need to handle exceptions from __alloc.allocate(n).
		  auto __p = __detail::__get_temporary_buffer<value_type>(__n);
		  if (__p == nullptr) [[unlikely]]
		    return nullptr;
		  _M_frames = __p;
		}
	      else
		{
		  __try
		    {
		      _M_frames = __alloc.allocate(__n);
		    }
		  __catch (...)
		    {
		      return nullptr;
		    }
		}
	      _M_capacity = __n;
	      return _M_frames;
	    }
	  return nullptr;
	}

	void
	_M_deallocate(allocator_type& __alloc) noexcept
	{
	  if (_M_capacity)
	    {
	      if constexpr (is_same_v<allocator_type, allocator<value_type>>)
		__detail::__return_temporary_buffer(_M_frames, _M_capacity);
	      else
		__alloc.deallocate(_M_frames, _M_capacity);
	      _M_frames = nullptr;
	      _M_capacity = 0;
	    }
	}

	// Precondition: __n <= _M_size
	void
	_M_resize(size_type __n, allocator_type& __alloc) noexcept
	{
	  std::_Destroy(_M_frames + __n, _M_frames + _M_size, __alloc);
	  _M_size = __n;
	}

	bool
	_M_push_back(allocator_type& __alloc,
		     const stacktrace_entry& __f) noexcept
	{
	  if (_M_size == _M_capacity) [[unlikely]]
	    {
	      _Impl __tmp = _M_xclone(_M_capacity ? _M_capacity : 8, __alloc);
	      if (!__tmp._M_capacity) [[unlikely]]
		return false;
	      _M_resize(0, __alloc);
	      _M_deallocate(__alloc);
	      *this = __tmp;
	    }
	  stacktrace_entry* __addr = std::to_address(_M_frames + _M_size++);
	  _AllocTraits::construct(__alloc, __addr, __f);
	  return true;
	}

	// Precondition: _M_size != 0
	_Impl
	_M_clone(allocator_type& __alloc) const noexcept
	{
	  return _M_xclone(_M_size, __alloc);
	}

	// Precondition: _M_size != 0 || __extra != 0
	_Impl
	_M_xclone(size_type __extra, allocator_type& __alloc) const noexcept
	{
	  _Impl __i;
	  if (__i._M_allocate(__alloc, _M_size + __extra)) [[likely]]
	    __i._M_assign(*this, __alloc);
	  return __i;
	}

	// Precondition: _M_capacity >= __other._M_size
	void
	_M_assign(const _Impl& __other, allocator_type& __alloc) noexcept
	{
	  std::__uninitialized_copy_a(__other._M_frames,
				      __other._M_frames + __other._M_size,
				      _M_frames, __alloc);
	  _M_size = __other._M_size;
	}
      };

      void
      _M_trim() noexcept
      {
	// libbacktrace adds an invalid -1UL entry at the end, remove it.
	if (!empty() && !end()[-1])
	  _M_impl._M_resize(size() - 1, _M_alloc);
      }

      [[no_unique_address]] allocator_type  _M_alloc{};

      _Impl _M_impl{};
    };

  // basic_stacktrace typedef names
  using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>;

  // [stacktrace.basic.nonmem], non-member functions
  template<typename _Allocator>
    inline void
    swap(basic_stacktrace<_Allocator>& __a, basic_stacktrace<_Allocator>& __b)
    noexcept(noexcept(__a.swap(__b)))
    { __a.swap(__b); }

  inline ostream&
  operator<<(ostream& __os, const stacktrace_entry& __f)
  {
    if (!__f) [[unlikely]]
      return __os << "<unknown>";

    string __desc, __file;
    int __line;
    if (__f._M_get_info(&__desc, &__file, &__line)) [[likely]]
      {
	__os << ' ';
	if (__desc.empty()) [[unlikely]]
	  __os << "<unknown>";
	else
	  __os << __desc;
	if (!__file.empty()) [[likely]]
	  __os << " at " << __file << ':' << __line;
      }

    struct _Flag_guard // Set and restore hex format
    {
      _Flag_guard(ios& __s) : _M_ios(__s) { }
      ~_Flag_guard() { _M_ios.setf(_M_f); }

      ios& _M_ios;
      ios::fmtflags _M_f = _M_ios.setf(ios::hex, ios::basefield);
    };
    _Flag_guard __g(__os);
    __os << " [0x" << __f.native_handle() << ']';
    return __os;
  }

  template<typename _Allocator>
    inline ostream&
    operator<<(ostream& __os, const basic_stacktrace<_Allocator>& __st)
    {
      using size_type = typename basic_stacktrace<_Allocator>::size_type;
      for (size_type __i = 0, __size = __st.size(); __i < __size; ++__i)
	{
	  __os.width(4);
	  __os << __i << "# " << __st[__i] << '\n';
	}
      return __os;
    }

  [[nodiscard]]
  inline string
  to_string(const stacktrace_entry& __f)
  {
    std::ostringstream __os;
    __os << __f;
    return std::move(__os).str();
  }

  template<typename _Allocator>
    [[nodiscard]]
    string
    to_string(const basic_stacktrace<_Allocator>& __st)
    {
      std::ostringstream __os;
      __os << __st;
      return std::move(__os).str();
    }

  template<>
    class formatter<stacktrace_entry>
    {
    public:
      constexpr typename basic_format_parse_context<char>::iterator
      parse(basic_format_parse_context<char>& __pc)
      {
	__format::_Spec<char> __spec{};
	const auto __last = __pc.end();
	auto __first = __pc.begin();

	auto __finalize = [this, &__spec] {
	  _M_spec = __spec;
	};

	auto __finished = [&] {
	  if (__first == __last || *__first == '}')
	    {
	      __finalize();
	      return true;
	    }
	  return false;
	};

	if (__finished())
	  return __first;

	__first = __spec._M_parse_fill_and_align(__first, __last);
	if (__finished())
	  return __first;

	__first = __spec._M_parse_width(__first, __last, __pc);
	if (__finished())
	  return __first;

	__throw_format_error("format error: invalid format-spec for "
			     "std::stacktrace_entry");
      }

      template<typename _Out>
	typename basic_format_context<_Out, char>::iterator
	format(const stacktrace_entry& __x,
	       basic_format_context<_Out, char>& __fc) const
	{
	  std::ostringstream __os;
	  __os << __x;
	  auto __str = __os.view();
	  return __format::__write_padded_as_spec(__str, __str.size(),
						  __fc, _M_spec);
	}

    private:
      __format::_Spec<char> _M_spec;
    };

#if __glibcxx_print >= 202406L
  template<>
    inline constexpr bool
    enable_nonlocking_formatter_optimization<stacktrace_entry> = true;
#endif

  template<typename _Allocator>
    class formatter<basic_stacktrace<_Allocator>>
    {
    public:
      constexpr typename basic_format_parse_context<char>::iterator
      parse(basic_format_parse_context<char>& __pc)
      {
	const auto __first = __pc.begin();
	if (__first == __pc.end() || *__first == '}')
	  return __first;
	__throw_format_error("format error: invalid format-spec for "
			     "std::basic_stacktrace");
      }

      template<typename _Out>
	typename basic_format_context<_Out, char>::iterator
	format(const basic_stacktrace<_Allocator>& __x,
	       basic_format_context<_Out, char>& __fc) const
	{
	  std::ostringstream __os;
	  __os << __x;
	  return __format::__write(__fc.out(), __os.view());
	}
    };

#if __glibcxx_print >= 202406L
  template<typename _Allocator>
    constexpr bool
    enable_nonlocking_formatter_optimization<basic_stacktrace<_Allocator>> = true;
#endif

  namespace pmr
  {
    using stacktrace
      = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>;
  }

  // [stacktrace.basic.hash], hash support

  template<>
    struct hash<stacktrace_entry>
    {
      [[nodiscard]]
      size_t
      operator()(const stacktrace_entry& __f) const noexcept
      {
	using __h = hash<stacktrace_entry::native_handle_type>;
	return __h()(__f.native_handle());
      }
    };

  template<typename _Allocator>
    struct hash<basic_stacktrace<_Allocator>>
    {
      [[nodiscard]]
      size_t
      operator()(const basic_stacktrace<_Allocator>& __st) const noexcept
      {
	hash<stacktrace_entry> __h;
	size_t __val = _Hash_impl::hash(__st.size());
	for (const auto& __f : __st)
	  __val = _Hash_impl::__hash_combine(__h(__f), __val);
	return __val;
      }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_stacktrace
#endif /* _GLIBCXX_STACKTRACE */
