32 #include <system_error>
33 #include <type_traits>
39 #define ELECTRONEUM_PRECOND(...) \
42 if (!( __VA_ARGS__ )) \
43 return {::common_error::kInvalidArgument}; \
47 #define ELECTRONEUM_CHECK(...) \
50 const ::expect<void> result = __VA_ARGS__ ; \
52 return result.error(); \
60 #define ELECTRONEUM_UNWRAP(...) \
61 ::detail::expect::unwrap( __VA_ARGS__ , nullptr, __FILE__ , __LINE__ )
66 #define ELECTRONEUM_THROW(code, msg) \
67 ::detail::expect::throw_( code , msg , __FILE__ , __LINE__ )
70 template<
typename>
class expect;
81 static void throw_(std::error_code ec,
const char* msg,
const char* file,
unsigned line);
85 static T unwrap(::
expect<T>&& result,
const char* error_msg,
const char* file,
unsigned line)
88 throw_(result.error(), error_msg, file, line);
89 return std::move(*result);
93 static void unwrap(::
expect<void>&& result,
const char* error_msg,
const char* file,
unsigned line);
134 static_assert(std::is_nothrow_destructible<T>(),
"T must have a nothrow destructor");
139 return std::is_constructible<T, U>() &&
140 std::is_convertible<U, T>();
145 typename std::aligned_storage<
sizeof(
T),
alignof(
T)>::type
storage_;
151 return *
reinterpret_cast<T*
>(std::addressof(
storage_));
161 void store(U&&
value) noexcept(std::is_nothrow_constructible<T, U>())
164 code_ = std::error_code{};
182 expect(std::error_code
const& code) noexcept
186 code_ = ::common_error::kInvalidErrorCode;
190 expect(
T val) noexcept(std::is_nothrow_move_constructible<T>())
193 store(std::move(val));
196 expect(
expect const& src) noexcept(std::is_nothrow_copy_constructible<T>())
204 template<typename U, typename = detail::enable_if<is_convertible<U const&>()>>
216 store(std::move(src.get()));
220 template<typename U, typename = detail::enable_if<is_convertible<U>()>>
225 store(std::move(*src));
234 expect&
operator=(
expect const& src) noexcept(std::is_nothrow_copy_constructible<T>() && std::is_nothrow_copy_assignable<T>())
236 if (
this != std::addressof(src))
242 else if (src.has_value())
251 expect&
operator=(
expect&& src) noexcept(std::is_nothrow_move_constructible<T>() && std::is_nothrow_move_assignable<T>())
253 if (
this != std::addressof(src))
256 get() = std::move(src.get());
259 else if (src.has_value())
260 store(std::move(src.get()));
297 return std::move(
get());
317 get() == *rhs :
error() == rhs.error();
321 bool equal(std::error_code
const& rhs)
const noexcept
330 template<typename U, typename = detail::enable_if<!std::is_constructible<std::error_code, U>::value>>
331 bool equal(U
const& rhs)
const noexcept(noexcept(*std::declval<
expect<T>>() == rhs))
337 bool matches(std::error_condition
const& rhs)
const noexcept
357 expect(std::error_code
const& code) noexcept
361 code_ = ::common_error::kInvalidErrorCode;
380 return error() == rhs.error();
384 bool equal(std::error_code
const& rhs)
const noexcept
390 bool matches(std::error_condition
const& rhs)
const noexcept
399 template<
typename T,
typename U>
403 return lhs.equal(rhs);
406 template<
typename T,
typename U>
410 return lhs.equal(rhs);
413 template<
typename T,
typename U>
417 return rhs.equal(lhs);
420 template<
typename T,
typename U>
424 return !lhs.equal(rhs);
427 template<
typename T,
typename U>
431 return !lhs.equal(rhs);
434 template<
typename T,
typename U>
438 return !rhs.equal(lhs);
446 throw_(result.error(), error_msg, file, line);
expect & operator=(expect const &)=default
std::error_code error_type
Definition: expect.h:350
bool matches(std::error_condition const &rhs) const noexcept
Definition: expect.h:390
std::error_code code_
Definition: expect.h:346
std::error_code error() const noexcept
Definition: expect.h:375
expect(std::error_code const &code) noexcept
Definition: expect.h:357
expect(expect const &)=default
bool equal(expect const &rhs) const noexcept
Definition: expect.h:378
expect() noexcept
Create a successful object.
Definition: expect.h:353
bool has_error() const noexcept
Definition: expect.h:372
void value_type
Definition: expect.h:349
bool equal(std::error_code const &rhs) const noexcept
Definition: expect.h:384
T * operator->() noexcept
Definition: expect.h:301
bool equal(std::error_code const &rhs) const noexcept
Definition: expect.h:321
T & operator*() noexcept
Definition: expect.h:305
void maybe_throw() const
Definition: expect.h:167
expect(expect< U > &&src) noexcept(std::is_nothrow_constructible< T, U >())
Move conversion from U to T.
Definition: expect.h:221
T const & value() const &
Definition: expect.h:286
~expect() noexcept
Definition: expect.h:228
bool has_value() const noexcept
Definition: expect.h:273
T value_type
Definition: expect.h:174
std::aligned_storage< sizeof(T), alignof(T)>::type storage_
Definition: expect.h:145
T const & operator*() const noexcept
Definition: expect.h:307
bool has_error() const noexcept
Definition: expect.h:270
static constexpr bool is_convertible() noexcept
Definition: expect.h:137
T & value() &
Definition: expect.h:279
std::error_code error() const noexcept
Definition: expect.h:276
T & get() noexcept
Definition: expect.h:148
bool matches(std::error_condition const &rhs) const noexcept
Definition: expect.h:337
bool equal(expect< U > const &rhs) const noexcept(noexcept(*std::declval< expect< T >>()== *rhs))
Definition: expect.h:314
std::error_code code_
Definition: expect.h:144
expect(expect< U > const &src) noexcept(std::is_nothrow_constructible< T, U const & >())
Copy conversion from U to T.
Definition: expect.h:205
T && value() &&
Definition: expect.h:294
expect & operator=(expect const &src) noexcept(std::is_nothrow_copy_constructible< T >() &&std::is_nothrow_copy_assignable< T >())
Definition: expect.h:234
expect(expect const &src) noexcept(std::is_nothrow_copy_constructible< T >())
Definition: expect.h:196
expect(T val) noexcept(std::is_nothrow_move_constructible< T >())
Store a value, val, in the expect object.
Definition: expect.h:190
void store(U &&value) noexcept(std::is_nothrow_constructible< T, U >())
Definition: expect.h:161
T const * operator->() const noexcept
Definition: expect.h:303
bool equal(U const &rhs) const noexcept(noexcept(*std::declval< expect< T >>()==rhs))
Definition: expect.h:331
expect(expect &&src) noexcept(std::is_nothrow_move_constructible< T >())
Definition: expect.h:212
expect & operator=(expect &&src) noexcept(std::is_nothrow_move_constructible< T >() &&std::is_nothrow_move_assignable< T >())
Definition: expect.h:251
T const & get() const noexcept
Definition: expect.h:154
std::error_code error_type
Definition: expect.h:175
expect(std::error_code const &code) noexcept
Definition: expect.h:182
bool operator!=(expect< T > const &lhs, expect< U > const &rhs) noexcept(noexcept(lhs.equal(rhs)))
Definition: expect.h:422
expect< void > success() noexcept
Definition: expect.h:397
bool operator==(expect< T > const &lhs, expect< U > const &rhs) noexcept(noexcept(lhs.equal(rhs)))
Definition: expect.h:401
const uint32_t T[512]
Definition: groestl_tables.h:37
const
Definition: build_protob.py:9
declaration and default definition for the functions used the API
Definition: expect.cpp:34
typename std::enable_if< C >::type enable_if
Definition: expect.h:76
int bool
Definition: stdbool.h:36
static T unwrap(::expect< T > &&result, const char *error_msg, const char *file, unsigned line)
If result.has_error() call throw_. Otherwise,.
Definition: expect.h:85
static void throw_(std::error_code ec, const char *msg, const char *file, unsigned line)
Definition: expect.cpp:64