ROSE 2.1.0
Loading...
Searching...
No Matches
Affirm.h
1#ifndef ROSE_Affirm_H
2#define ROSE_Affirm_H
3
4#include <Rose/Exception.h>
5#include <string>
6
7namespace Rose {
8
11public:
13 explicit AffirmationError(const std::string &mesg)
14 : Exception(mesg) {}
15
16 ~AffirmationError() throw() {}
17};
18
19// std::is_invocable backported for C++14
20template<class F, class... Args>
22 template<class U>
23 static auto test(U *p) -> decltype((*p)(std::declval<Args>()...), void(), std::true_type());
24
25 template<class U>
26 static auto test(...) -> decltype(std::false_type());
27
28 static constexpr bool value = decltype(test<F>(0))::value;
29};
30
79template<class Value, class Predicate>
80typename std::enable_if<is_invocable<Predicate, Value>::value, Value&>::type
81affirm(Value&& value, Predicate predicate) {
82 if (predicate(value))
83 return value;
84 throw AffirmationError("predicate failed for value");
85}
86
87template<class Value, class Predicate>
88typename std::enable_if<is_invocable<Predicate, Value>::value, Value&>::type
89affirm(Value& value, Predicate predicate) {
90 if (predicate(value))
91 return value;
92 throw AffirmationError("predicate failed for value");
93}
94
95template<class Value, class Predicate>
96typename std::enable_if<is_invocable<Predicate, Value>::value, Value&>::type
97affirm(Value&& value, Predicate predicate, std::string const& message) {
98 if (predicate(value))
99 return value;
100 throw AffirmationError(message);
101}
102
103template<class Value, class Predicate>
104typename std::enable_if<is_invocable<Predicate, Value>::value, Value&>::type
105affirm(Value& value, Predicate predicate, std::string const& message) {
106 if (predicate(value))
107 return value;
108 throw AffirmationError(message);
109}
138template<class Value>
139Value&
140affirm(Value&& value) {
141 if (value)
142 return value;
143 throw AffirmationError("value does not evaluate to true in Boolean context");
144}
145
146template<class Value>
147Value&
148affirm(Value& value) {
149 if (value)
150 return value;
151 throw AffirmationError("value does not evaluate to true in Boolean context");
152}
153
154template<class Value>
155Value&
156affirm(Value&& value, std::string const& message) {
157 if (value)
158 return value;
159 throw AffirmationError(message);
160}
161
162template<class Value>
163Value&
164affirm(Value& value, std::string const& message) {
165 if (value)
166 return value;
167 throw AffirmationError(message);
168}
194template<class Pointer>
195Pointer&
196notnull(Pointer&& pointer) {
197 if (pointer)
198 return pointer;
199 throw AffirmationError("null pointer");
200}
201
202template<class Pointer>
203Pointer&
204notnull(Pointer& pointer) {
205 if (pointer)
206 return pointer;
207 throw AffirmationError("null pointer");
208}
211} // namespace
212
213// Convenience macro. The predicate should be a C++ Boolean expression in terms of a variable `x`. For example:
214//
215// const int n = ROSE_AFFIRM(foo(a, b), x < 100); // will throw if foo(a,b) returns a value >= 100
216//
217#define ROSE_AFFIRM(VALUE, PREDICATE) ::Rose::affirm((VALUE), [](auto x) -> bool { return PREDICATE; })
218
219#endif
Exceptions for value assertions.
Definition Affirm.h:10
AffirmationError(const std::string &mesg)
Construct error with message.
Definition Affirm.h:13
Base class for all ROSE exceptions.
The ROSE library.
std::enable_if< is_invocable< Predicate, Value >::value, Value & >::type affirm(Value &&value, Predicate predicate)
Test something about a value and then return it.
Definition Affirm.h:81
Pointer & notnull(Pointer &&pointer)
Check for non-null pointer.
Definition Affirm.h:196