-
Notifications
You must be signed in to change notification settings - Fork 6
/
throw_this_exception.hpp
130 lines (101 loc) · 3.07 KB
/
throw_this_exception.hpp
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
/**
* @file throw_this_exception.hpp
* @brief
* @date 2019-7-29
* @author Peter
* @copyright
* Peter of [ThinkSpirit Laboratory](http://thinkspirit.org/)
* of [Nanjing University of Information Science & Technology](http://www.nuist.edu.cn/)
* all rights reserved
*/
#ifndef KERBAL_UTILITY_THROW_THIS_EXCEPTION_HPP
#define KERBAL_UTILITY_THROW_THIS_EXCEPTION_HPP
#include <kerbal/compatibility/noexcept.hpp>
#include <kerbal/config/exceptions.hpp>
#if __cplusplus < 201103L
# include <kerbal/macro/macro_concat.hpp>
# include <kerbal/macro/ppexpand.hpp>
#endif
#if __cplusplus >= 201103L
# include <kerbal/utility/forward.hpp>
#endif
#if !KERBAL_HAS_EXCEPTIONS_SUPPORT
# include <cstdlib> // std::abort
#endif
namespace kerbal
{
namespace utility
{
template <typename Exception>
class throw_this_exception_helper
{
public:
# if KERBAL_HAS_EXCEPTIONS_SUPPORT
# if __cplusplus >= 201103L
template <typename ... Args>
[[noreturn]]
static
void throw_this_exception(Args && ... args)
{
throw Exception(kerbal::utility::forward<Args>(args)...);
}
# else
# define EMPTY
# define REMAINF(exp) exp
# define THEAD_NOT_EMPTY(exp) template <exp>
# define TARGS_DECL(i) typename KERBAL_MACRO_CONCAT(Arg, i)
# define ARGS_DECL(i) const KERBAL_MACRO_CONCAT(Arg, i) & KERBAL_MACRO_CONCAT(arg, i)
# define ARGS_USE(i) KERBAL_MACRO_CONCAT(arg, i)
# define FBODY(i) \
KERBAL_OPT_PPEXPAND_WITH_COMMA_N(THEAD_NOT_EMPTY, EMPTY, TARGS_DECL, i) \
static \
void throw_this_exception(KERBAL_OPT_PPEXPAND_WITH_COMMA_N(REMAINF, EMPTY, ARGS_DECL, i)) \
{ \
throw Exception(KERBAL_OPT_PPEXPAND_WITH_COMMA_N(REMAINF, EMPTY, ARGS_USE, i)); \
} \
KERBAL_PPEXPAND_N(FBODY, KERBAL_PPEXPAND_EMPTY_SEPARATOR, 0)
KERBAL_PPEXPAND_N(FBODY, KERBAL_PPEXPAND_EMPTY_SEPARATOR, 20)
# undef EMPTY
# undef REMAINF
# undef THEAD_NOT_EMPTY
# undef TARGS_DECL
# undef ARGS_DECL
# undef ARGS_USE
# undef FBODY
# endif
# else // no exception
# if __cplusplus >= 201103L
template <typename ... Args>
[[noreturn]]
static
void throw_this_exception(Args && ...) noexcept
{
std::abort();
}
# else
# define EMPTY
# define REMAINF(exp) exp
# define THEAD_NOT_EMPTY(exp) template <exp>
# define TARGS_DECL(i) typename KERBAL_MACRO_CONCAT(Arg, i)
# define ARGS_DECL(i) const KERBAL_MACRO_CONCAT(Arg, i) &
# define FBODY(i) \
KERBAL_OPT_PPEXPAND_WITH_COMMA_N(THEAD_NOT_EMPTY, EMPTY, TARGS_DECL, i) \
static \
void throw_this_exception(KERBAL_OPT_PPEXPAND_WITH_COMMA_N(REMAINF, EMPTY, ARGS_DECL, i)) KERBAL_NOEXCEPT \
{ \
std::abort(); \
} \
KERBAL_PPEXPAND_N(FBODY, KERBAL_PPEXPAND_EMPTY_SEPARATOR, 0)
KERBAL_PPEXPAND_N(FBODY, KERBAL_PPEXPAND_EMPTY_SEPARATOR, 20)
# undef EMPTY
# undef REMAINF
# undef THEAD_NOT_EMPTY
# undef TARGS_DECL
# undef ARGS_DECL
# undef FBODY
# endif
# endif
};
} // namespace utility
} // namespace kerbal
#endif // KERBAL_UTILITY_THROW_THIS_EXCEPTION_HPP