Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active June 16, 2018 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paniq/108057b7eea249e997661975e2ee25cd to your computer and use it in GitHub Desktop.
Save paniq/108057b7eea249e997661975e2ee25cd to your computer and use it in GitHub Desktop.
/*
The Scopes Compiler Infrastructure
This file is distributed under the MIT License.
See LICENSE.md for details.
*/
#ifndef SCOPES_RESULT_HPP
#define SCOPES_RESULT_HPP
#include <assert.h>
#pragma GCC diagnostic error "-Wunused-result"
#pragma GCC diagnostic ignored "-Wgnu-statement-expression"
namespace scopes {
// use this as return type; together with the attribute and the warning-as-error
// setting above, we get a good trap for any ignores of result values
#define SCOPES_RESULT(T) Result<T> __attribute__ ((warn_unused_result))
// declared at top of function so the subsequent macros all work
#define SCOPES_RESULT_TYPE(T) \
(void)0; /* ensure macro can only be used in function bodies */ \
typedef T _result_type;
#define SCOPES_RETURN_ERROR() return Result<_result_type>();
// if ok fails, return
#define SCOPES_CHECK_OK(OK) if (!OK) { SCOPES_RETURN_ERROR(); }
// if an expression returning a result fails, return
#define SCOPES_CHECK_RESULT(EXPR) SCOPES_CHECK_OK((EXPR).ok())
// try to extract a value from a result or return
#define SCOPES_GET_RESULT(EXPR) ({ \
auto _result = (EXPR); \
SCOPES_CHECK_RESULT(_result); \
_result.assert_ok(); \
})
#define SCOPES_ASSERT_CAST(T, EXPR) ({ \
Result<T> _result = (EXPR); \
_result.assert_ok(); \
})
#define SCOPES_CHECK_CAST(T, EXPR) ({ \
Result<T> _result = (EXPR); \
SCOPES_CHECK_RESULT(_result); \
_result.assert_ok(); \
})
template<typename T>
struct Result {
Result(const T &value) : _value(value), _ok(true) {}
Result() : _ok(false) {}
inline bool ok() const { return _ok; }
inline const T &assert_ok() const { assert(_ok); return _value; }
inline const T &unsafe_extract() const { return _value; }
protected:
T _value;
bool _ok;
};
template<>
struct Result<void> {
Result(bool ok) : _ok(ok) {}
Result() : _ok(false) {}
inline bool ok() const { return _ok; }
inline void assert_ok() const { assert(_ok); }
protected:
bool _ok;
};
// from error.hpp:
#define SCOPES_LOCATION_ERROR(MSG) \
set_last_location_error((MSG)); \
return Result<_result_type>();
} // namespace scopes
#endif // SCOPES_RESULT_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment