// Standard exception classes  -*- C++ -*-

// Copyright (C) 2001-2023 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 include/stdexcept
 *  This is a Standard C++ Library header.
 */

//
// ISO C++ 19.1  Exception classes
//
#pragma once
#ifdef ARDUINO_ARCH_AVR
#pragma GCC system_header

#include "bits/c++config.h"
#include "string"

namespace std _GLIBCXX_VISIBILITY(default)
{
	_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if _GLIBCXX_USE_DUAL_ABI
#if _GLIBCXX_USE_CXX11_ABI
	// 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
	};

	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:
		/** 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;

#ifdef _GLIBCXX_TM_TS_INTERNAL
		friend void * ::_txnal_logic_error_get_msg(void *e);
#endif
	};
	// 181
	/** 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:
		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;
	};

	/** 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:
		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;
	};
	// 213
	/// @} group exceptions

	_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#else
#include_next <stdexcept>
#endif