Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Throw.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <typeinfo> // needed for use of typeid()
5
7
8 namespace Private_ {
9// avoid header dependencies on Debug/BackTrace and no Characters/String
10#if qStroika_Foundation_Execution_Throw_TraceThrowpointBacktrace
11 string GetBT_s ();
12 wstring GetBT_ws ();
13#endif
14 string ToString_ (const type_info&);
15 template <typename T>
16 inline string ToString_ (const T& t)
17 {
18 if constexpr (is_convertible_v<T, const exception&>) {
19 return t.what ();
20 }
21 else {
22 return ToString_ (typeid (T)); // exact match preferred over template
23 }
24 }
25
26#if qStroika_Foundation_Debug_DefaultTracingOn
27 void JustDbgTrace_ (const string& msg);
28 void JustDbgTrace_ (const wstring& msg);
29 void ThrowingExceptionDbgTrace_ (const string& msg);
30 void ThrowingExceptionDbgTrace_ (const wstring& msg);
31 void ReThrowingExceptionDbgTrace_ (const string& msg);
32 void ReThrowingExceptionDbgTrace_ (const wstring& msg = {});
33#endif
34
35 }
36
37 /*
38 ********************************************************************************
39 ***************************** Execution::Throw *********************************
40 ********************************************************************************
41 */
42 template <typename T>
43 [[noreturn]] inline void Throw (T&& e2Throw)
44 {
45 static_assert (is_convertible_v<remove_cvref_t<T>*, exception*>);
46#if qStroika_Foundation_Debug_DefaultTracingOn
47 Private_::ThrowingExceptionDbgTrace_ (Private_::ToString_ (forward<T> (e2Throw)));
48#endif
49 throw e2Throw;
50 }
51 template <typename T>
52 [[noreturn]] inline void Throw (T&& e2Throw, [[maybe_unused]] const char* traceMsg)
53 {
54 static_assert (is_convertible_v<remove_cvref_t<T>*, exception*>);
55#if qStroika_Foundation_Debug_DefaultTracingOn
56 Private_::JustDbgTrace_ (traceMsg);
57#endif
58 Throw (forward<T> (e2Throw)); // important todo this way to get its template specialization (even though the cost is an extra trace message)
59 }
60 template <typename T>
61 [[noreturn]] inline void Throw (T&& e2Throw, [[maybe_unused]] const wchar_t* traceMsg)
62 {
63 static_assert (is_convertible_v<remove_cvref_t<T>*, exception*>);
64#if qStroika_Foundation_Debug_DefaultTracingOn
65 Private_::JustDbgTrace_ (traceMsg);
66#endif
67 Throw (forward<T> (e2Throw)); // important todo this way to get its template specialization (even though the cost is an extra trace message)
68 }
69
70 /*
71 ********************************************************************************
72 ***************************** Execution::ReThrow *******************************
73 ********************************************************************************
74 */
75 [[noreturn]] inline void ReThrow ()
76 {
77#if qStroika_Foundation_Debug_DefaultTracingOn
78 Private_::ReThrowingExceptionDbgTrace_ ();
79#endif
80 throw;
81 }
82 [[noreturn]] inline void ReThrow (const exception_ptr& e)
83 {
84#if qStroika_Foundation_Debug_DefaultTracingOn
85 Private_::ReThrowingExceptionDbgTrace_ ();
86#endif
87 rethrow_exception (e);
88 }
89 [[noreturn]] inline void ReThrow ([[maybe_unused]] const char* traceMsg)
90 {
91#if qStroika_Foundation_Debug_DefaultTracingOn
92 Private_::ReThrowingExceptionDbgTrace_ (traceMsg);
93#endif
94 throw;
95 }
96 [[noreturn]] inline void ReThrow (const exception_ptr& e, [[maybe_unused]] const char* traceMsg)
97 {
98#if qStroika_Foundation_Debug_DefaultTracingOn
99 Private_::ReThrowingExceptionDbgTrace_ (traceMsg);
100#endif
101 rethrow_exception (e);
102 }
103 [[noreturn]] inline void ReThrow ([[maybe_unused]] const wchar_t* traceMsg)
104 {
105#if qStroika_Foundation_Debug_DefaultTracingOn
106 Private_::ReThrowingExceptionDbgTrace_ (traceMsg);
107#endif
108 throw;
109 }
110 [[noreturn]] inline void ReThrow (const exception_ptr& e, [[maybe_unused]] const wchar_t* traceMsg)
111 {
112#if qStroika_Foundation_Debug_DefaultTracingOn
113 Private_::ReThrowingExceptionDbgTrace_ (traceMsg);
114#endif
115 rethrow_exception (e);
116 }
117
118 /*
119 ********************************************************************************
120 *************************** Execution::ThrowIfNull *****************************
121 ********************************************************************************
122 */
123 template <equality_comparable_with<nullptr_t> T, typename E>
124 inline void ThrowIfNull (const T& p, const E& e)
125 {
126 if (p == nullptr) [[unlikely]] {
127 Throw (e, "ThrowIfNull (nullptr) - throwing bad_alloc"); // todo fix trace message to depend on 'E'
128 }
129 }
130 template <equality_comparable_with<nullptr_t> T>
131 inline void ThrowIfNull (const T& p)
132 {
133 static const bad_alloc kException_;
134 ThrowIfNull (p, kException_);
135 }
136 template <Common::Weak_Equality_Comparable_With<nullopt_t> T, typename E>
137 inline void ThrowIfNull (const T& p, const E& e)
138 requires (not equality_comparable_with<nullptr_t, T>)
139 {
140 if (p == nullopt) [[unlikely]] {
141 Throw (e, "ThrowIfNull (nullopt) - throwing bad_optional_access"); // todo fix trace message to depend on 'E'
142 }
143 }
144 template <Common::Weak_Equality_Comparable_With<nullopt_t> T>
145 inline void ThrowIfNull (const T& p)
146 requires (not equality_comparable_with<nullptr_t, T>)
147 {
148 static const bad_optional_access kException_;
149 ThrowIfNull (p, kException_);
150 }
151
152}
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43
void ThrowIfNull(const Private_::ConstVoidStar &p, const HRESULT &hr)
Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErro...