Files
gcc-reflection/libstdc++-v3/include/bits/stdexcept_except.h
Jakub Jelinek 62c126db6b libstdc++: Implement C++26 P3378R2 - constexpr exception types
The following patch attempts to implement the C++26 P3378R2 - constexpr
exception types paper.

This is quite complicated, because most of these classes which should
be constexpr-ized use solely or mostly out of line definitions in
libstdc++, both for historical, code size and dual ABI reasons, so that
one can throw these as exceptions between TUs with old vs. new (or vice
versa) ABIs.
For this reason, logic_error/runtime_error and classes derived from it
have the old ABI std::string object inside of them and the exported
APIs from libstdc++.so.6 ensure the right thing.

Now, because new invoked during constant evaluation needs to be deleted
during the same constant evaluation and can't leak into the constant
expressions, I think we don't have to use COW strings under the hood
(which aren't constexpr I guess because of reference counting/COW) and
we can use something else, the patch uses heap allocated std::string
object (where __cow_constexpr_string class has just a pointer to that).
As I think we still want to hide the ugly details if !consteval in the
library, the patch exports 8 __cow_string class symbols (6 existing which
were previously just not exported and 2 new ones) and if !consteval
calls those through extern "C" _Zmangled_name symbols.  The functions
are always_inline.

And then logic_error etc. have for C++26 (precisely for
__cpp_lib_constexpr_exceptions >= 202502L) constexpr definitions of
cdtors/methods.  This results in slightly larger code (a few insns at most)
at runtime for C++26, e.g. instead of calling say some logic error
cdtor/method with 2 arguments it calls some __cow_string one with 2
arguments but + 8 bytes pointer additions on both.

The patch also removes the __throw_format_error forward declaration
which apparently wasn't needed for anything as all __throw_format_error
users were either in <format> or included <format> before the uses,
reverts the
https://gcc.gnu.org/pipermail/libstdc++/2025-July/062598.html
patch and makes sure __throw_* functions (only those for exception types
which the P3378R2 or P3068R5 papers made constexpr usable and there are
actually constexpr/consteval uses of those) are constexpr for C++26
constexpr exceptions.

The patch does that by splitting the bits/functexcept.h header:
1) bits/functexcept.h stays for the __throw_* functions which are (at
least for now) never constexpr (the <ios>, <system_error>, <future>
and <functional> std::exception derived classes) or are never used
or never used in constexpr/consteval contexts (<exception>, <typeinfo>
std::exception derived classes and std::range_error).
2) bits/new_{throw,except}.h for __throw_bad_alloc/__throw_bad_array_new_length
and std::bad_alloc/std::bad_array_new_length (where <new> includes
<bits/new_except.h> and <bits/new_throw.h> as well for the C++26 constexpr
exceptions case)
3) for the most complicated <stdexcept> stuff, one header
addition to bits/stdexcept.h one header for the __throw_logic_error etc.
forward declarations, one header for the __throw_logic_error etc.
definitions and one header without header guards which will
depending on __glibcxx_exc_in_string include one or the other because
<string> vs. <string_view> vs. <stdexcept> have heavy interdependencies

2025-12-11  Jakub Jelinek  <jakub@redhat.com>

	PR libstdc++/121114
libstdc++-v3/
	* include/bits/version.def: Implement C++26 P3378R2 - constexpr
	exception types.
	(constexpr_exceptions): Change value from 1 to 202502, remove
	no_stdname and TODO comments.
	* include/bits/version.h: Regenerate.
	* src/c++11/cow-stdexcept.cc (__cow_string(const char*)): New
	ctor.
	(__cow_string::c_str()): New method.
	* config/abi/pre/gnu.ver (GLIBCXX_3.4.35): Export 8 __cow_string
	symbols.
	* include/bits/new_except.h: New file.
	* include/bits/new_throw.h: New file.
	* include/bits/stdexcept_throw.h: New file.
	* include/bits/stdexcept_throwdef.h: New file.
	* include/bits/stdexcept_throwfwd.h: New file.
	* include/std/stdexcept: Include bits/stdexcept_except.h and move
	everything after <string> include except for std::range_error into
	include/bits/stdexcept_except.h.
	(std::range_error): If __cpp_lib_constexpr_exceptions >= 202502L
	make all cdtors and methods constexpr.
	* include/bits/stdexcept_except.h: New file.
	* include/std/optional (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(bad_optional_access::what): Make constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L.
	(__throw_bad_optional_access): Likewise.
	* include/std/expected (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(bad_expected_access): Make cdtors and all methods constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L.
	* include/std/format (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(_GLIBCXX_CONSTEXPR_FORMAT_ERROR): Define and undef later.
	(format_error): Use _GLIBCXX_CONSTEXPR_FORMAT_ERROR on ctors.
	* include/std/variant (__glibcxx_want_constexpr_exceptions): Define
	before including bits/version.h.
	(_GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS): Define and undef later.
	(bad_variant_access): Use it on ctors and what() method.
	(__throw_bad_variant_access): Use it here too.
	* testsuite/18_support/exception/version.cc: Adjust expected
	__cpp_lib_constexpr_exceptions value.
	* testsuite/19_diagnostics/runtime_error/constexpr.cc: New test.
	* testsuite/19_diagnostics/headers/stdexcept/version.cc: New test.
	* testsuite/19_diagnostics/logic_error/constexpr.cc: New test.
	* testsuite/20_util/expected/observers.cc (test_value_throw): Change
	return type to bool from void, return true at the end, add test
	to dereference what() first character.  Make it constexpr for
	__cpp_lib_constexpr_exceptions >= 202502L and add static_assert.
	* testsuite/20_util/expected/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* testsuite/20_util/variant/constexpr.cc: For
	__cpp_lib_constexpr_exceptions >= 202502L include <string>.
	(test_get): New function if __cpp_lib_constexpr_exceptions >= 202502L,
	assert calling it is true.
	* testsuite/20_util/variant/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* testsuite/20_util/optional/constexpr/observers/3.cc: Include
	testsuite_hooks.h.
	(eat, test01): New functions.  Assert test01() is true.
	* testsuite/20_util/optional/version.cc: Add tests for
	__cpp_lib_constexpr_exceptions value.
	* include/std/future: Add #include <bits/functexcept.h>.
	* include/std/shared_mutex: Include <bits/new_throw.h>.
	* include/std/flat_map: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/syncstream: Remove <bits/functexcept.h> include.
	* include/std/flat_set: Likewise.
	* include/std/bitset: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/string_view: Don't include <bits/functexcept.h>, include
	<bits/stdexcept_throw.h> early if __glibcxx_exc_in_string is not
	defined and include <bits/stdexcept_throw.h> at the end of
	the header again if __glibcxx_exc_in_string is 2 and C++26 constexpr
	exceptions are enabled.
	(__glibcxx_exc_in_string): Define if __glibcxx_exc_in_string wasn't
	defined before including <bits/stdexcept_throw.h>.
	* include/std/array: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/std/inplace_vector: Likewise.
	* include/std/string: Include <bits/stdexcept_except.h> and
	<bits/stdexcept_throw.h> after bits/basic_string.tcc include if
	C++26 constexpr exceptions are enabled and include
	<bits/stdexcept_throw.h> instead of <bits/functexcept.h> early.
	(__glibcxx_exc_in_string): Define early to 1, undefine at the end.
	* include/std/deque: Include <bits/stdexcept_throw.h>.
	* include/bits/new_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/stl_algobase.h: Remove <bits/functexcept.h> include.
	* include/bits/stl_vector.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/memory_resource.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/functexcept.h: Guard everything after includes with
	#if _GLIBCXX_HOSTED.
	(__throw_bad_alloc, __throw_bad_array_new_length,  __throw_logic_error,
	__throw_domain_error, __throw_invalid_argument, __throw_length_error,
	__throw_out_of_range, __throw_out_of_range_fmt, __throw_runtime_error,
	__throw_overflow_error, __throw_underflow_error): Move declarations to
	other headers - <bits/new_throw.h> and <bits/stdexcept_throwfwd.h>.
	* include/bits/stl_map.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/bits/hashtable_policy.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/bits/formatfwd.h (std::__throw_format_error): Remove
	declaration.
	* include/bits/specfun.h: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/bits/basic_ios.h: Include <bits/functexcept.h>.
	* include/bits/locale_classes.h: Likewise.
	* include/tr1/cmath: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/tr1/memory: Remove <bits/functexcept.h> include.
	* include/tr1/array: Include <bits/stdexcept_throw.h>.
	* include/ext/vstring_util.h: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/bitmap_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/mt_allocator.h: Likewise.
	* include/ext/malloc_allocator.h: Likewise.
	* include/ext/debug_allocator.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/ext/concurrence.h: Include <bits/exception_defines.h>
	instead of <bits/functexcept.h>.
	* include/ext/throw_allocator.h: Include <bits/new_throw.h> and
	<bits/stdexcept_throw.h> instead of <bits/functexcept.h>.
	* include/ext/string_conversions.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* include/ext/pool_allocator.h: Include <bits/new_throw.h> instead
	of <bits/functexcept.h>.
	* include/ext/ropeimpl.h: Include <bits/stdexcept_throw.h> instead of
	<bits/functexcept.h>.
	* include/tr2/dynamic_bitset: Likewise.
	* include/experimental/optional: Include <bits/exception_defines.h>
	instead of <bits/functexcept.h>.
	* include/Makefile.am (bits_freestanding): Add
	${bits_srcdir}/{new,stdexcept}_{except,throw}.h
	and ${bits_srcdir}/stdexcept_throw{fwd,def}.h.
	* include/Makefile.in: Regenerate.
	* src/c++17/floating_from_chars.cc: Remove <bits/functexcept.h>
	include.
	* src/c++11/regex.cc: Likewise.
	* src/c++11/functexcept.cc: Likewise.
	* src/c++11/snprintf_lite.cc: Include <bits/stdexcept_throw.h> instead
	of <bits/functexcept.h>.
	* src/c++11/thread.cc: Include <bits/functexcept.h>.
	* testsuite/util/testsuite_hooks.h: Include <bits/stdexcept_throw.h>
	instead of <bits/functexcept.h>.
	* testsuite/util/io/verified_cmd_line_input.cc: Include
	<bits/exception_defines.h> instead of <bits/functexcept.h>.
	* testsuite/20_util/allocator/105975.cc: Expect different diagnostics
	for C++26.
	* testsuite/23_containers/inplace_vector/access/capacity.cc: Remove
	#error, guard if consteval { return; } with
	#ifndef __cpp_lib_constexpr_exceptions.
	* testsuite/23_containers/inplace_vector/access/elem.cc: Likewise.
	* testsuite/23_containers/inplace_vector/cons/1.cc: Likewise.
	* testsuite/23_containers/inplace_vector/cons/from_range.cc: Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/single_insert.cc:
	Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/assign.cc:
	Likewise.
	* testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
	Likewise.
	* libsupc++/new: Include <bits/new_except.h>.
	(std::bad_alloc, std::bad_array_new_length): Move defintion to
	<bits/new_except.h>.
libgomp/
	* omp.h.in: Include <bits/new_throw.h> instead of
	<bits/functexcept.h>.
gcc/testsuite/
	* g++.dg/tree-ssa/pr110819.C: Guard scan-tree-dump-not delete on
	c++23_down and add comment explaining why C++26 fails that.
	* g++.dg/tree-ssa/pr96945.C: Likewise.
	* g++.dg/tree-ssa/pr109442.C: Likewise.
	* g++.dg/tree-ssa/pr116868.C: Likewise.
	* g++.dg/tree-ssa/pr58483.C: Likewise.
2025-12-11 19:54:44 +01:00

553 lines
18 KiB
C++

// Exception classes for <stdexcept> -*- C++ -*-
// Copyright (C) 2001-2025 Free Software Foundation, Inc.
//
// 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, or (at your option)
// any later version.
// 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/>.
/** @file bits/stdexcept_except.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{stdexcept} */
#ifndef _STDEXCEPT_EXCEPT_H
#define _STDEXCEPT_EXCEPT_H 1
#include <exception>
#include <string>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if _GLIBCXX_USE_DUAL_ABI
#if _GLIBCXX_USE_CXX11_ABI
#if __cpp_lib_constexpr_exceptions >= 202502L
struct __cow_constexpr_string;
namespace __detail
{
extern "C"
{
void _ZNSt12__cow_stringC2EPKcm(__cow_constexpr_string*, const char*,
unsigned long);
void _ZNSt12__cow_stringC2EPKcj(__cow_constexpr_string*, const char*,
unsigned int);
void _ZNSt12__cow_stringC2EPKcy(__cow_constexpr_string*, const char*,
unsigned long long);
void _ZNSt12__cow_stringC2EPKc(__cow_constexpr_string*, const char*);
void _ZNSt12__cow_stringC2ERKS_(__cow_constexpr_string*,
const __cow_constexpr_string&) noexcept;
void _ZNSt12__cow_stringC2EOS_(__cow_constexpr_string*,
__cow_constexpr_string&&) noexcept;
void _ZNSt12__cow_stringD2Ev(__cow_constexpr_string*);
__cow_constexpr_string&
_ZNSt12__cow_stringaSERKS_(__cow_constexpr_string*,
const __cow_constexpr_string&) noexcept;
__cow_constexpr_string&
_ZNSt12__cow_stringaSEOS_(__cow_constexpr_string*,
__cow_constexpr_string&&) noexcept;
const char*
_ZNKSt12__cow_string5c_strEv(const __cow_constexpr_string*) noexcept;
}
} // namespace __detail
// Emulates an old COW string when the new std::string is in use,
// but in addition is constexpr and uses the __cow_string out of
// line cdtors/methods unless manifestly constant evaluated.
struct __cow_constexpr_string
{
union {
const char* _M_p;
char _M_bytes[sizeof(const char*)];
string* _M_str;
};
[[__gnu__::__always_inline__]] constexpr
__cow_constexpr_string(const string& __o)
{
if consteval {
_M_str = new string(__o);
} else {
__cow_constexpr_string_ctor(__o.c_str(), __o.length());
}
}
[[__gnu__::__always_inline__]] inline void
__cow_constexpr_string_ctor(const char *__s, unsigned long __l)
{
__detail::_ZNSt12__cow_stringC2EPKcm(this, __s, __l);
}
[[__gnu__::__always_inline__]] inline void
__cow_constexpr_string_ctor(const char *__s, unsigned int __l)
{
__detail::_ZNSt12__cow_stringC2EPKcj(this, __s, __l);
}
[[__gnu__::__always_inline__]] inline void
__cow_constexpr_string_ctor(const char *__s, unsigned long long __l)
{
__detail::_ZNSt12__cow_stringC2EPKcy(this, __s, __l);
}
[[__gnu__::__always_inline__]] constexpr
__cow_constexpr_string(const char* __o)
{
if consteval {
_M_str = new string(__o);
} else {
__detail::_ZNSt12__cow_stringC2EPKc(this, __o);
}
}
[[__gnu__::__always_inline__]] constexpr
__cow_constexpr_string(const __cow_constexpr_string& __o) noexcept
{
if consteval {
_M_str = new string(*__o._M_str);
} else {
__detail::_ZNSt12__cow_stringC2ERKS_(this, __o);
}
}
[[__gnu__::__always_inline__]] constexpr __cow_constexpr_string&
operator=(const __cow_constexpr_string& __o) noexcept
{
if consteval {
string* __p = _M_str;
_M_str = new string(*__o._M_str);
delete __p;
return *this;
} else {
return __detail::_ZNSt12__cow_stringaSERKS_(this, __o);
}
}
[[__gnu__::__always_inline__]] constexpr
~__cow_constexpr_string()
{
if consteval {
delete _M_str;
} else {
__detail::_ZNSt12__cow_stringD2Ev(this);
}
}
[[__gnu__::__always_inline__]] constexpr
__cow_constexpr_string(__cow_constexpr_string&& __o) noexcept
{
if consteval {
_M_str = new string(std::move(*__o._M_str));
} else {
__detail::_ZNSt12__cow_stringC2EOS_(this, std::move(__o));
}
}
[[__gnu__::__always_inline__]] constexpr __cow_constexpr_string&
operator=(__cow_constexpr_string&& __o) noexcept
{
if consteval {
string* __p = _M_str;
_M_str = new string(std::move(*__o._M_str));
delete __p;
return *this;
} else {
return __detail::_ZNSt12__cow_stringaSEOS_(this, std::move(__o));
}
}
[[__gnu__::__always_inline__]] constexpr const char*
c_str() const noexcept
{
if consteval {
return _M_str->c_str();
} else {
return __detail::_ZNKSt12__cow_string5c_strEv(this);
}
}
};
typedef __cow_constexpr_string __cow_string;
#else
// Emulates an old COW string when the new std::string is in use.
struct __cow_string
{
union {
const char* _M_p;
char _M_bytes[sizeof(const char*)];
};
__cow_string();
__cow_string(const std::string&);
__cow_string(const char*, size_t);
__cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
__cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
~__cow_string();
#if __cplusplus >= 201103L
__cow_string(__cow_string&&) noexcept;
__cow_string& operator=(__cow_string&&) noexcept;
#endif
};
#endif
typedef basic_string<char> __sso_string;
#else // _GLIBCXX_USE_CXX11_ABI
typedef basic_string<char> __cow_string;
// Emulates a new SSO string when the old std::string is in use.
struct __sso_string
{
struct __str
{
const char* _M_p;
size_t _M_string_length;
char _M_local_buf[16];
};
union {
__str _M_s;
char _M_bytes[sizeof(__str)];
};
__sso_string() _GLIBCXX_NOTHROW;
__sso_string(const std::string&);
__sso_string(const char*, size_t);
__sso_string(const __sso_string&);
__sso_string& operator=(const __sso_string&);
~__sso_string();
#if __cplusplus >= 201103L
__sso_string(__sso_string&&) noexcept;
__sso_string& operator=(__sso_string&&) noexcept;
#endif
};
#endif // _GLIBCXX_USE_CXX11_ABI
#else // _GLIBCXX_USE_DUAL_ABI
typedef basic_string<char> __sso_string;
typedef basic_string<char> __cow_string;
#endif
/**
* @addtogroup exceptions
* @{
*/
/** Logic errors represent problems in the internal logic of a program;
* in theory, these are preventable, and even detectable before the
* program runs (e.g., violations of class invariants).
* @brief One of two subclasses of exception.
*/
class logic_error : public exception
{
__cow_string _M_msg;
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit
logic_error(const string& __arg) _GLIBCXX_TXN_SAFE
: _M_msg(__arg) {}
constexpr explicit
logic_error(const char* __arg) _GLIBCXX_TXN_SAFE
: _M_msg(__arg) {}
constexpr logic_error(logic_error&& __arg) noexcept = default;
constexpr logic_error& operator=(logic_error&& __arg) noexcept = default;
constexpr logic_error(const logic_error&) noexcept = default;
constexpr logic_error& operator=(const logic_error&) noexcept = default;
constexpr virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
constexpr virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN noexcept
{
return _M_msg.c_str();
}
#else
/** Takes a character string describing the error. */
explicit
logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit
logic_error(const char*) _GLIBCXX_TXN_SAFE;
logic_error(logic_error&&) noexcept;
logic_error& operator=(logic_error&&) noexcept;
#endif
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
logic_error(const logic_error&) _GLIBCXX_NOTHROW;
logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
#elif __cplusplus >= 201103L
logic_error(const logic_error&) = default;
logic_error& operator=(const logic_error&) = default;
#endif
virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
#endif
# ifdef _GLIBCXX_TM_TS_INTERNAL
friend void*
::_txnal_logic_error_get_msg(void* e);
# endif
};
/** Thrown by the library, or by you, to report domain errors (domain in
* the mathematical sense). */
class domain_error : public logic_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr explicit domain_error(const char* __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr domain_error(const domain_error&) = default;
constexpr domain_error& operator=(const domain_error&) = default;
constexpr domain_error(domain_error&&) = default;
constexpr domain_error& operator=(domain_error&&) = default;
constexpr virtual ~domain_error() _GLIBCXX_NOTHROW { }
#else
explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
domain_error(const domain_error&) = default;
domain_error& operator=(const domain_error&) = default;
domain_error(domain_error&&) = default;
domain_error& operator=(domain_error&&) = default;
#endif
virtual ~domain_error() _GLIBCXX_NOTHROW;
#endif
};
/** Thrown to report invalid arguments to functions. */
class invalid_argument : public logic_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr explicit invalid_argument(const char* __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr invalid_argument(const invalid_argument&) = default;
constexpr invalid_argument& operator=(const invalid_argument&) = default;
constexpr invalid_argument(invalid_argument&&) = default;
constexpr invalid_argument& operator=(invalid_argument&&) = default;
constexpr virtual ~invalid_argument() _GLIBCXX_NOTHROW { }
#else
explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
invalid_argument(const invalid_argument&) = default;
invalid_argument& operator=(const invalid_argument&) = default;
invalid_argument(invalid_argument&&) = default;
invalid_argument& operator=(invalid_argument&&) = default;
#endif
virtual ~invalid_argument() _GLIBCXX_NOTHROW;
#endif
};
/** Thrown when an object is constructed that would exceed its maximum
* permitted size (e.g., a basic_string instance). */
class length_error : public logic_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr explicit length_error(const char* __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr length_error(const length_error&) = default;
constexpr length_error& operator=(const length_error&) = default;
constexpr length_error(length_error&&) = default;
constexpr length_error& operator=(length_error&&) = default;
constexpr virtual ~length_error() _GLIBCXX_NOTHROW { }
#else
explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
length_error(const length_error&) = default;
length_error& operator=(const length_error&) = default;
length_error(length_error&&) = default;
length_error& operator=(length_error&&) = default;
#endif
virtual ~length_error() _GLIBCXX_NOTHROW;
#endif
};
/** This represents an argument whose value is not within the expected
* range (e.g., boundary checks in basic_string). */
class out_of_range : public logic_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr explicit out_of_range(const char* __arg) _GLIBCXX_TXN_SAFE
: logic_error(__arg) { }
constexpr out_of_range(const out_of_range&) = default;
constexpr out_of_range& operator=(const out_of_range&) = default;
constexpr out_of_range(out_of_range&&) = default;
constexpr out_of_range& operator=(out_of_range&&) = default;
constexpr virtual ~out_of_range() _GLIBCXX_NOTHROW { }
#else
explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
out_of_range(const out_of_range&) = default;
out_of_range& operator=(const out_of_range&) = default;
out_of_range(out_of_range&&) = default;
out_of_range& operator=(out_of_range&&) = default;
#endif
virtual ~out_of_range() _GLIBCXX_NOTHROW;
#endif
};
/** Runtime errors represent problems outside the scope of a program;
* they cannot be easily predicted and can generally only be caught as
* the program executes.
* @brief One of two subclasses of exception.
*/
class runtime_error : public exception
{
__cow_string _M_msg;
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit
runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE
: _M_msg(__arg) {}
constexpr explicit
runtime_error(const char* __arg) _GLIBCXX_TXN_SAFE
: _M_msg(__arg) {}
constexpr runtime_error(runtime_error&&) noexcept = default;
constexpr runtime_error& operator=(runtime_error&&) noexcept = default;
constexpr runtime_error(const runtime_error&) noexcept = default;
runtime_error& operator=(const runtime_error&) noexcept = default;
constexpr virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
constexpr virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN noexcept
{
return _M_msg.c_str();
}
#else
/** Takes a character string describing the error. */
explicit
runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit
runtime_error(const char*) _GLIBCXX_TXN_SAFE;
runtime_error(runtime_error&&) noexcept;
runtime_error& operator=(runtime_error&&) noexcept;
#endif
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
#elif __cplusplus >= 201103L
runtime_error(const runtime_error&) = default;
runtime_error& operator=(const runtime_error&) = default;
#endif
virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
#endif
# ifdef _GLIBCXX_TM_TS_INTERNAL
friend void*
::_txnal_runtime_error_get_msg(void* e);
# endif
};
/** Thrown to indicate arithmetic overflow. */
class overflow_error : public runtime_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
: runtime_error(__arg) { }
constexpr explicit overflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
: runtime_error(__arg) { }
constexpr overflow_error(const overflow_error&) = default;
constexpr overflow_error& operator=(const overflow_error&) = default;
constexpr overflow_error(overflow_error&&) = default;
constexpr overflow_error& operator=(overflow_error&&) = default;
constexpr virtual ~overflow_error() noexcept { }
#else
explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
overflow_error(const overflow_error&) = default;
overflow_error& operator=(const overflow_error&) = default;
overflow_error(overflow_error&&) = default;
overflow_error& operator=(overflow_error&&) = default;
#endif
virtual ~overflow_error() _GLIBCXX_NOTHROW;
#endif
};
/** Thrown to indicate arithmetic underflow. */
class underflow_error : public runtime_error
{
public:
#if __cpp_lib_constexpr_exceptions >= 202502L
constexpr explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
: runtime_error(__arg) { }
constexpr explicit underflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
: runtime_error(__arg) { }
constexpr underflow_error(const underflow_error&) = default;
constexpr underflow_error& operator=(const underflow_error&) = default;
constexpr underflow_error(underflow_error&&) = default;
constexpr underflow_error& operator=(underflow_error&&) = default;
constexpr virtual ~underflow_error() noexcept { }
#else
explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
#if __cplusplus >= 201103L
explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
underflow_error(const underflow_error&) = default;
underflow_error& operator=(const underflow_error&) = default;
underflow_error(underflow_error&&) = default;
underflow_error& operator=(underflow_error&&) = default;
#endif
virtual ~underflow_error() _GLIBCXX_NOTHROW;
#endif
};
/// @} group exceptions
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STDEXCEPT_EXCEPT_H */