elna/include/elna/source/result.hpp

87 lines
1.8 KiB
C++

#pragma once
#include <cstddef>
#include <variant>
#include <forward_list>
namespace elna::source
{
/**
* Position in the source text.
*/
struct position
{
/// Line.
std::size_t line = 1;
/// Column.
std::size_t column = 1;
};
/**
* A compilation error consists of an error message and position.
*/
struct error
{
private:
char const *message;
source::position position;
public:
/**
* \param message Error text.
* \param position Error position in the source text.
*/
error(char const *message, const source::position position) noexcept;
/// Error text.
const char *what() const noexcept;
/// Error line in the source text.
std::size_t line() const noexcept;
/// Error column in the source text.
std::size_t column() const noexcept;
};
template<typename T>
struct result
{
using E = std::forward_list<source::error>;
template<typename... Args>
explicit result(Args&&... arguments)
: payload(std::forward<Args>(arguments)...)
{
}
explicit result(const char *message, const source::position position)
: payload(E{ source::error(message, position) })
{
}
bool has_errors() const noexcept
{
return std::holds_alternative<E>(payload);
}
bool is_success() const noexcept
{
return std::holds_alternative<T>(payload);
}
T& success()
{
return std::get<T>(payload);
}
E& errors()
{
return std::get<E>(payload);
}
private:
std::variant<T, E> payload;
};
}