summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pexception.h
blob: 7317a320e285b05db58af719be30156d3886356b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// license:GPL-2.0+
// copyright-holders:Couriersud

#ifndef PEXCEPTION_H_
#define PEXCEPTION_H_

///
/// \file: pexception.h
///

#include "pstring.h"
#include "ptypes.h"

#include <exception>

namespace plib {

	/// \brief Terminate the program.
	///
	/// \note could be enhanced by setting a termination handler
	///
	[[noreturn]] void terminate(const pstring &msg) noexcept;

	/// \brief throw an exception.
	///
	/// throws an exception E. The purpose is to clearly identify exception
	/// throwing in the code
	///
	/// \tparam E Type of exception to be thrown
	///
	template<typename E, typename... Args>
	[[noreturn]] static inline void pthrow(Args&&... args) noexcept(false)
	{
		throw E(std::forward<Args>(args)...);
	}

	//============================================================
	//  exception base
	//============================================================

	class pexception : public std::exception
	{
	public:
		explicit pexception(const pstring &text);

		const pstring &text() const noexcept { return m_text; }
		const char* what() const noexcept override { return m_text.c_str(); }

	private:
		pstring m_text;
	};

	class file_e : public plib::pexception
	{
	public:
		file_e(const pstring &fmt, const pstring &filename);
	};

	class file_open_e : public file_e
	{
	public:
		explicit file_open_e(const pstring &filename);
	};

	class file_read_e : public file_e
	{
	public:
		explicit file_read_e(const pstring &filename);
	};

	class file_write_e : public file_e
	{
	public:
		explicit file_write_e(const pstring &filename);
	};

	class null_argument_e : public plib::pexception
	{
	public:
		explicit null_argument_e(const pstring &argument);
	};

	class out_of_mem_e : public plib::pexception
	{
	public:
		explicit out_of_mem_e(const pstring &location);
	};

	// FIXME: currently only a stub for later use. More use could be added by
	// using “-fnon-call-exceptions" and sigaction to enable c++ exception supported.
	//

	class fpexception_e : public pexception
	{
	public:
		explicit fpexception_e(const pstring &text);
	};

	static constexpr unsigned FP_INEXACT = 0x0001;
	static constexpr unsigned FP_DIVBYZERO = 0x0002;
	static constexpr unsigned FP_UNDERFLOW = 0x0004;
	static constexpr unsigned FP_OVERFLOW = 0x0008;
	static constexpr unsigned FP_INVALID = 0x00010;
	static constexpr unsigned FP_ALL = 0x0001f;

	/// \brief Catch SIGFPE on linux for debugging purposes.
	///
	class fpsignalenabler
	{
	public:
		explicit fpsignalenabler(unsigned fpexceptions);

		COPYASSIGNMOVE(fpsignalenabler, delete)

		~fpsignalenabler();

		/// \brief is the functionality supported.
		///
		/// \return current status
		///
		static bool supported();
		/// \brief get/set global enable status
		///
		/// \param enable new status
		/// \return returns last global enable state
		///
		static bool global_enable(bool enable);

	private:
		int m_last_enabled;

		static bool m_enable;
	};


} // namespace plib

#endif // PEXCEPTION_H_