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