schema_editor/comdel/parser/presult.h

64 lines
1.9 KiB
C++

#ifndef PRESULT_H
#define PRESULT_H
#include "expected.h"
#include "source_error.h"
#include <optional>
/// Returns from the CURRENT function, the one this macro is used in,
/// if PResult contains an error
#define RETURN_IF_ERR(presult) \
do { \
auto&& return_if_err_temp_ = (presult); \
if (!return_if_err_temp_) { \
return PError(return_if_err_temp_.error()); \
} \
} while (0)
/// Works the same as RETURN_IF_ERR but can also assign the unwrapped result
/// to a variable if successful
#define ASSIGN_OR_RETURN_IF_ERR(var, presult) \
do { \
auto&& assign_or_return_if_err_temp_ = (presult); \
if (!assign_or_return_if_err_temp_) { \
return PError(assign_or_return_if_err_temp_.error()); \
} else { \
var = *assign_or_return_if_err_temp_; \
} \
} while (0)
using PError = tl::unexpected<SourceError>;
/// Holds either an AST node or an error
/// The value MUST be checked before usage, e.g. using RETURN_IF_ERR
template<typename T>
struct PResult : tl::expected<T, SourceError> {
using tl::expected<T, SourceError>::expected;
/// Implicit conversion from PResult<U> to PResult<T>
/// if U is convertible to T
template<typename U, class V = std::enable_if_t<std::is_convertible<std::decay_t<U>, T>::value>>
PResult(PResult<U> presult) :
tl::expected<T, SourceError>(presult ? PResult<T>(*presult) : PError(presult.error())) {}
};
/// Alternative to PResult that is returned from parseLibrary* functions
/// that only consume one token so they can fail without affecting
/// the parser state
template<typename T>
struct POptResult : public PResult<T> {
using PResult<T>::PResult;
std::optional<T> optional() {
if (*this) {
return **this;
} else {
return std::nullopt;
}
}
};
#endif // PRESULT_H