87 lines
1.8 KiB
C++
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;
|
|
};
|
|
}
|