in process Camel to snake case

This commit is contained in:
Claudius Holeksa 2022-12-05 01:49:38 +01:00
parent a1a718967d
commit 947004fd65
9 changed files with 856 additions and 805 deletions

8
.clang-tidy Normal file
View File

@ -0,0 +1,8 @@
Checks: '-*,readability-identifier-naming'
CheckOptions:
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
- { key: readability-identifier-naming.ClassCase, value: lower_case }
- { key: readability-identifier-naming.StructCase, value: lower_case }
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }

View File

@ -32,16 +32,18 @@ def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, ta
def isAbsolutePath(key, dirname, env): def isAbsolutePath(key, dirname, env):
assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,) assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
## Environment variables
env_vars = Variables( env_vars = Variables(
args=ARGUMENTS args=ARGUMENTS
) )
env_vars.Add('prefix', env_vars.Add('prefix',
help='Installation target location of build results and headers', help='Installation target location of build results and headers',
default='/usr/local/', default='/usr/local/',
validator=isAbsolutePath validator=isAbsolutePath
) )
## Environment setup
env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=['#source/forstio','#source','#','#driver'], env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=['#source/forstio','#source','#','#driver'],
CXX='clang++', CXX='clang++',
CPPDEFINES=['SAW_UNIX'], CPPDEFINES=['SAW_UNIX'],
@ -73,15 +75,23 @@ env.Alias('test', env.test_program)
# Clang format part # Clang format part
env.Append(BUILDERS={'ClangFormat' : Builder(action = 'clang-format --style=file -i $SOURCE')}) env.Append(BUILDERS={'ClangFormat' : Builder(action = 'clang-format --style=file -i $SOURCE')})
env.Append(BUILDERS={'ClangTidyFix' : Builder(action = 'clang-tidy -extra-arg-before=-xc++ --fix $SOURCE -- -std=c++17 -DSAW_UNIX -Isource')})
env.format_actions = [] env.format_actions = []
def format_iter(env,files): def format_iter(env,files):
for f in files: for f in files:
env.format_actions.append(env.AlwaysBuild(env.ClangFormat(target=f+"-clang-format",source=f))) env.format_actions.append(env.AlwaysBuild(env.ClangFormat(target=f+"-clang-format",source=f)));
pass
env.tidy_actions = []
def tidy_iter(env,files):
for f in files:
env.tidy_actions.append(env.AlwaysBuild(env.ClangTidyFix(target=f+"-clang-tidy-fix",source=f)));
pass pass
format_iter(env,env.sources + env.driver_sources + env.headers + env.driver_headers) format_iter(env,env.sources + env.driver_sources + env.headers + env.driver_headers)
env.Alias('format', env.format_actions) env.Alias('format', env.format_actions);
env.Alias('tidy', env.tidy_actions);
env.Alias('cdb', env.cdb); env.Alias('cdb', env.cdb);
env.Alias('all', ['format', 'library', 'test']) env.Alias('all', ['format', 'library', 'test'])

View File

@ -1,4 +1,4 @@
#include "driver/io-unix.h" #include "io-unix.h"
#include <sstream> #include <sstream>
@ -129,7 +129,7 @@ UnixDatagram::UnixDatagram(UnixEventPort &event_port, int file_descriptor,
: IFdOwner{event_port, file_descriptor, fd_flags, EPOLLIN | EPOLLOUT} {} : IFdOwner{event_port, file_descriptor, fd_flags, EPOLLIN | EPOLLOUT} {}
namespace { namespace {
ssize_t unixReadMsg(int fd, void *buffer, size_t length) { ssize_t unix_read_msg(int fd, void *buffer, size_t length) {
struct ::sockaddr_storage their_addr; struct ::sockaddr_storage their_addr;
socklen_t addr_len = sizeof(sockaddr_storage); socklen_t addr_len = sizeof(sockaddr_storage);
return ::recvfrom(fd, buffer, length, 0, return ::recvfrom(fd, buffer, length, 0,
@ -137,15 +137,15 @@ ssize_t unixReadMsg(int fd, void *buffer, size_t length) {
&addr_len); &addr_len);
} }
ssize_t unixWriteMsg(int fd, const void *buffer, size_t length, ssize_t unix_write_msg(int fd, const void *buffer, size_t length,
::sockaddr *dest_addr, socklen_t dest_addr_len) { ::sockaddr *dest_addr, socklen_t dest_addr_len) {
return ::sendto(fd, buffer, length, 0, dest_addr, dest_addr_len); return ::sendto(fd, buffer, length, 0, dest_addr, dest_addr_len);
} }
} // namespace } // namespace
ErrorOr<size_t> UnixDatagram::read(void *buffer, size_t length) { ErrorOr<size_t> UnixDatagram::read(void *buffer, size_t length) {
ssize_t read_bytes = unixReadMsg(fd(), buffer, length); ssize_t read_bytes = unix_read_msg(fd(), buffer, length);
if (read_bytes > 0) { if (read_bytes > 0) {
return static_cast<size_t>(read_bytes); return static_cast<size_t>(read_bytes);
} }
@ -163,8 +163,8 @@ ErrorOr<size_t> UnixDatagram::write(const void *buffer, size_t length,
UnixNetworkAddress &unix_dest = static_cast<UnixNetworkAddress &>(dest); UnixNetworkAddress &unix_dest = static_cast<UnixNetworkAddress &>(dest);
SocketAddress &sock_addr = unix_dest.unixAddress(); SocketAddress &sock_addr = unix_dest.unixAddress();
socklen_t sock_addr_length = sock_addr.getRawLength(); socklen_t sock_addr_length = sock_addr.getRawLength();
ssize_t write_bytes = unixWriteMsg(fd(), buffer, length, sock_addr.getRaw(), ssize_t write_bytes = unix_write_msg(fd(), buffer, length,
sock_addr_length); sock_addr.getRaw(), sock_addr_length);
if (write_bytes > 0) { if (write_bytes > 0) {
return static_cast<size_t>(write_bytes); return static_cast<size_t>(write_bytes);
} }
@ -192,14 +192,14 @@ void UnixDatagram::notify(uint32_t mask) {
} }
namespace { namespace {
bool beginsWith(const std::string_view &viewed, bool string_view_begins_with(const std::string_view &viewed,
const std::string_view &begins) { const std::string_view &begins) {
return viewed.size() >= begins.size() && return viewed.size() >= begins.size() &&
viewed.compare(0, begins.size(), begins) == 0; viewed.compare(0, begins.size(), begins) == 0;
} }
std::variant<UnixNetworkAddress, UnixNetworkAddress *> std::variant<UnixNetworkAddress, UnixNetworkAddress *>
translateNetworkAddressToUnixNetworkAddress(NetworkAddress &addr) { translate_network_address_to_unix_network_address(NetworkAddress &addr) {
auto addr_variant = addr.representation(); auto addr_variant = addr.representation();
std::variant<UnixNetworkAddress, UnixNetworkAddress *> os_addr = std::visit( std::variant<UnixNetworkAddress, UnixNetworkAddress *> os_addr = std::visit(
[](auto &arg) [](auto &arg)
@ -220,7 +220,7 @@ translateNetworkAddressToUnixNetworkAddress(NetworkAddress &addr) {
return os_addr; return os_addr;
} }
UnixNetworkAddress &translateToUnixAddressRef( UnixNetworkAddress &translate_to_unix_address_ref(
std::variant<UnixNetworkAddress, UnixNetworkAddress *> &addr_variant) { std::variant<UnixNetworkAddress, UnixNetworkAddress *> &addr_variant) {
return std::visit( return std::visit(
[](auto &arg) -> UnixNetworkAddress & { [](auto &arg) -> UnixNetworkAddress & {
@ -240,8 +240,10 @@ UnixNetworkAddress &translateToUnixAddressRef(
} // namespace } // namespace
Own<Server> UnixNetwork::listen(NetworkAddress &addr) { Own<Server> UnixNetwork::listen(NetworkAddress &addr) {
auto unix_addr_storage = translateNetworkAddressToUnixNetworkAddress(addr); auto unix_addr_storage =
UnixNetworkAddress &address = translateToUnixAddressRef(unix_addr_storage); translate_network_address_to_unix_network_address(addr);
UnixNetworkAddress &address =
translate_to_unix_address_ref(unix_addr_storage);
assert(address.unixAddressSize() > 0); assert(address.unixAddressSize() > 0);
if (address.unixAddressSize() == 0) { if (address.unixAddressSize() == 0) {
@ -272,8 +274,10 @@ Own<Server> UnixNetwork::listen(NetworkAddress &addr) {
} }
Conveyor<Own<IoStream>> UnixNetwork::connect(NetworkAddress &addr) { Conveyor<Own<IoStream>> UnixNetwork::connect(NetworkAddress &addr) {
auto unix_addr_storage = translateNetworkAddressToUnixNetworkAddress(addr); auto unix_addr_storage =
UnixNetworkAddress &address = translateToUnixAddressRef(unix_addr_storage); translate_network_address_to_unix_network_address(addr);
UnixNetworkAddress &address =
translate_to_unix_address_ref(unix_addr_storage);
assert(address.unixAddressSize() > 0); assert(address.unixAddressSize() > 0);
if (address.unixAddressSize() == 0) { if (address.unixAddressSize() == 0) {
@ -332,8 +336,10 @@ Conveyor<Own<IoStream>> UnixNetwork::connect(NetworkAddress &addr) {
} }
Own<Datagram> UnixNetwork::datagram(NetworkAddress &addr) { Own<Datagram> UnixNetwork::datagram(NetworkAddress &addr) {
auto unix_addr_storage = translateNetworkAddressToUnixNetworkAddress(addr); auto unix_addr_storage =
UnixNetworkAddress &address = translateToUnixAddressRef(unix_addr_storage); translate_network_address_to_unix_network_address(addr);
UnixNetworkAddress &address =
translate_to_unix_address_ref(unix_addr_storage);
SAW_ASSERT(address.unixAddressSize() > 0) { return nullptr; } SAW_ASSERT(address.unixAddressSize() > 0) { return nullptr; }
@ -375,7 +381,7 @@ UnixNetwork::resolveAddress(const std::string &path, uint16_t port_hint) {
std::string_view addr_view{path}; std::string_view addr_view{path};
{ {
std::string_view begins_with = "unix:"; std::string_view begins_with = "unix:";
if (beginsWith(addr_view, begins_with)) { if (string_view_begins_with(addr_view, begins_with)) {
addr_view.remove_prefix(begins_with.size()); addr_view.remove_prefix(begins_with.size());
} }
} }

View File

@ -7,38 +7,38 @@
namespace saw { namespace saw {
namespace { namespace {
thread_local EventLoop *local_loop = nullptr; thread_local event_loop *local_loop = nullptr;
EventLoop &currentEventLoop() { event_loop &current_event_loop() {
EventLoop *loop = local_loop; event_loop *loop = local_loop;
assert(loop); assert(loop);
return *loop; return *loop;
} }
} // namespace } // namespace
ConveyorNode::ConveyorNode() {} conveyor_node::conveyor_node() {}
ConveyorNodeWithChildMixin::ConveyorNodeWithChildMixin( conveyor_node_with_child_mixin::conveyor_node_with_child_mixin(
Own<ConveyorNode> &&child_, ConveyorNode &owner) own<conveyor_node> &&child_, conveyor_node &owner)
: child{std::move(child_)} { : child{std::move(child_)} {
assert(child); assert(child);
child->notifyParentAttached(owner); child->notifyParentAttached(owner);
} }
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
ConveyorNodeWithChildMixin::swapChild(Own<ConveyorNode> &&swapee) { conveyor_node_with_child_mixin::swap_child(own<conveyor_node> &&swapee) {
SAW_ASSERT(child) { SAW_ASSERT(child) {
return criticalError("Child should exist if this function is called"); return criticalerror("Child should exist if this function is called");
} }
Own<ConveyorNode> old_child = std::move(child); own<conveyor_node> old_child = std::move(child);
/** /**
* We need the parent of the old_child's next storage * We need the parent of the old_child's next storage
*/ */
ConveyorStorage *old_storage = old_child->nextStorage(); conveyor_storage *old_storage = old_child->nextStorage();
ConveyorStorage *old_storage_parent = old_storage ? old_storage->getParent() conveyor_storage *old_storage_parent =
: nullptr; old_storage ? old_storage->getParent() : nullptr;
/** /**
* Swap in the new child * Swap in the new child
@ -51,7 +51,7 @@ ConveyorNodeWithChildMixin::swapChild(Own<ConveyorNode> &&swapee) {
* storage has a nullptr set And if the old_storage_parent is a nullptr, * storage has a nullptr set And if the old_storage_parent is a nullptr,
* then it doesn't matter. So we don't check for it * then it doesn't matter. So we don't check for it
*/ */
ConveyorStorage *swapee_storage = child->nextStorage(); conveyor_storage *swapee_storage = child->nextStorage();
if (swapee_storage) { if (swapee_storage) {
swapee_storage->setParent(old_storage_parent); swapee_storage->setParent(old_storage_parent);
} }
@ -60,13 +60,13 @@ ConveyorNodeWithChildMixin::swapChild(Own<ConveyorNode> &&swapee) {
return old_child; return old_child;
} }
ConveyorStorage::ConveyorStorage() {} conveyor_storage::conveyor_storage() {}
ConveyorStorage::~ConveyorStorage() {} conveyor_storage::~conveyor_storage() {}
ConveyorStorage *ConveyorStorage::getParent() const { return parent; } conveyor_storage *conveyor_storage::getParent() const { return parent; }
void ConveyorEventStorage::setParent(ConveyorStorage *p) { void conveyor_event_storage::setParent(conveyor_storage *p) {
/* /*
* parent check isn't needed, but is used * parent check isn't needed, but is used
* for the assert, because the storage should * for the assert, because the storage should
@ -83,24 +83,24 @@ void ConveyorEventStorage::setParent(ConveyorStorage *p) {
parent = p; parent = p;
} }
ConveyorEventStorage::ConveyorEventStorage() : ConveyorStorage{} {} conveyor_event_storage::conveyor_event_storage() : conveyor_storage{} {}
ConveyorBase::ConveyorBase(Own<ConveyorNode> &&node_p) conveyor_base::conveyor_base(own<conveyor_node> &&node_p)
: node{std::move(node_p)} {} : node{std::move(node_p)} {}
Error PropagateError::operator()(const Error &error) const { error propagate_error::operator()(const error &error) const {
return error.copyError(); return error.copyerror();
} }
Error PropagateError::operator()(Error &&error) { return std::move(error); } error propagate_error::operator()(error &&error) { return std::move(error); }
Event::Event() : Event(currentEventLoop()) {} event::event() : event(current_event_loop()) {}
Event::Event(EventLoop &loop) : loop{loop} {} event::event(event_loop &loop) : loop{loop} {}
Event::~Event() { disarm(); } event::~event() { disarm(); }
void Event::armNext() { void event::armNext() {
assert(&loop == local_loop); assert(&loop == local_loop);
if (prev == nullptr) { if (prev == nullptr) {
// Push the next_insert_point back by one // Push the next_insert_point back by one
@ -133,7 +133,7 @@ void Event::armNext() {
} }
} }
void Event::armLater() { void event::armLater() {
assert(&loop == local_loop); assert(&loop == local_loop);
if (prev == nullptr) { if (prev == nullptr) {
@ -153,7 +153,7 @@ void Event::armLater() {
} }
} }
void Event::armLast() { void event::armLast() {
assert(&loop == local_loop); assert(&loop == local_loop);
if (prev == nullptr) { if (prev == nullptr) {
@ -172,7 +172,7 @@ void Event::armLast() {
} }
} }
void Event::disarm() { void event::disarm() {
if (prev != nullptr) { if (prev != nullptr) {
if (loop.tail == &next) { if (loop.tail == &next) {
loop.tail = prev; loop.tail = prev;
@ -192,33 +192,33 @@ void Event::disarm() {
} }
} }
bool Event::isArmed() const { return prev != nullptr; } bool event::isArmed() const { return prev != nullptr; }
ConveyorSink::ConveyorSink() : node{nullptr} {} conveyorSink::conveyorSink() : node{nullptr} {}
ConveyorSink::ConveyorSink(Own<ConveyorNode> &&node_p) conveyorSink::conveyorSink(own<conveyor_node> &&node_p)
: node{std::move(node_p)} {} : node{std::move(node_p)} {}
void EventLoop::setRunnable(bool runnable) { is_runnable = runnable; } void event_loop::setRunnable(bool runnable) { is_runnable = runnable; }
EventLoop::EventLoop() {} event_loop::event_loop() {}
EventLoop::EventLoop(Own<EventPort> &&event_port) event_loop::event_loop(own<eventPort> &&event_port)
: event_port{std::move(event_port)} {} : event_port{std::move(event_port)} {}
EventLoop::~EventLoop() { assert(local_loop != this); } event_loop::~event_loop() { assert(local_loop != this); }
void EventLoop::enterScope() { void event_loop::enterScope() {
assert(!local_loop); assert(!local_loop);
local_loop = this; local_loop = this;
} }
void EventLoop::leaveScope() { void event_loop::leaveScope() {
assert(local_loop == this); assert(local_loop == this);
local_loop = nullptr; local_loop = nullptr;
} }
bool EventLoop::turnLoop() { bool event_loop::turnLoop() {
size_t turn_step = 0; size_t turn_step = 0;
while (head && turn_step < 65536) { while (head && turn_step < 65536) {
if (!turn()) { if (!turn()) {
@ -229,8 +229,8 @@ bool EventLoop::turnLoop() {
return true; return true;
} }
bool EventLoop::turn() { bool event_loop::turn() {
Event *event = head; event *event = head;
if (!event) { if (!event) {
return false; return false;
@ -259,7 +259,7 @@ bool EventLoop::turn() {
return true; return true;
} }
bool EventLoop::wait(const std::chrono::steady_clock::duration &duration) { bool event_loop::wait(const std::chrono::steady_clock::duration &duration) {
if (event_port) { if (event_port) {
event_port->wait(duration); event_port->wait(duration);
} }
@ -267,7 +267,7 @@ bool EventLoop::wait(const std::chrono::steady_clock::duration &duration) {
return turnLoop(); return turnLoop();
} }
bool EventLoop::wait(const std::chrono::steady_clock::time_point &time_point) { bool event_loop::wait(const std::chrono::steady_clock::time_point &time_point) {
if (event_port) { if (event_port) {
event_port->wait(time_point); event_port->wait(time_point);
} }
@ -275,7 +275,7 @@ bool EventLoop::wait(const std::chrono::steady_clock::time_point &time_point) {
return turnLoop(); return turnLoop();
} }
bool EventLoop::wait() { bool event_loop::wait() {
if (event_port) { if (event_port) {
event_port->wait(); event_port->wait();
} }
@ -283,7 +283,7 @@ bool EventLoop::wait() {
return turnLoop(); return turnLoop();
} }
bool EventLoop::poll() { bool event_loop::poll() {
if (event_port) { if (event_port) {
event_port->poll(); event_port->poll();
} }
@ -291,16 +291,16 @@ bool EventLoop::poll() {
return turnLoop(); return turnLoop();
} }
EventPort *EventLoop::eventPort() { return event_port.get(); } eventPort *event_loop::eventPort() { return event_port.get(); }
ConveyorSinkSet &EventLoop::daemon() { conveyor_sink_set &event_loop::daemon() {
if (!daemon_sink) { if (!daemon_sink) {
daemon_sink = heap<ConveyorSinkSet>(); daemon_sink = heap<conveyor_sink_set>();
} }
return *daemon_sink; return *daemon_sink;
} }
WaitScope::WaitScope(EventLoop &loop) : loop{loop} { loop.enterScope(); } WaitScope::WaitScope(event_loop &loop) : loop{loop} { loop.enterScope(); }
WaitScope::~WaitScope() { loop.leaveScope(); } WaitScope::~WaitScope() { loop.leaveScope(); }
@ -316,29 +316,29 @@ void WaitScope::wait(const std::chrono::steady_clock::time_point &time_point) {
void WaitScope::poll() { loop.poll(); } void WaitScope::poll() { loop.poll(); }
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
ConvertConveyorNodeBase::swapChild(Own<ConveyorNode> &&swapee) noexcept { convert_conveyor_node_base::swap_child(own<conveyor_node> &&swapee) noexcept {
return child_mixin.swapChild(std::move(swapee)); return child_mixin.swap_child(std::move(swapee));
} }
ConveyorStorage *ConvertConveyorNodeBase::nextStorage() noexcept { conveyor_storage *convert_conveyor_node_base::nextStorage() noexcept {
if (!child_mixin.child) { if (!child_mixin.child) {
return nullptr; return nullptr;
} }
return child_mixin.child->nextStorage(); return child_mixin.child->nextStorage();
} }
ImmediateConveyorNodeBase::ImmediateConveyorNodeBase() Immediateconveyor_nodeBase::Immediateconveyor_nodeBase()
: ConveyorEventStorage{} {} : conveyor_event_storage{} {}
MergeConveyorNodeBase::MergeConveyorNodeBase() : ConveyorEventStorage{} {} Mergeconveyor_nodeBase::Mergeconveyor_nodeBase() : conveyor_event_storage{} {}
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>> QueueBufferconveyor_nodeBase::swap_child(
QueueBufferConveyorNodeBase::swapChild(Own<ConveyorNode> &&swapee_) noexcept { own<conveyor_node> &&swapee_) noexcept {
return child_mixin.swapChild(std::move(swapee_)); return child_mixin.swap_child(std::move(swapee_));
} }
void ConveyorSinkSet::destroySinkConveyorNode(ConveyorNode &node) { void conveyor_sink_set::destroysink_conveyor_node(conveyor_node &node) {
if (!isArmed()) { if (!isArmed()) {
armLast(); armLast();
} }
@ -346,20 +346,21 @@ void ConveyorSinkSet::destroySinkConveyorNode(ConveyorNode &node) {
delete_nodes.push(&node); delete_nodes.push(&node);
} }
void ConveyorSinkSet::fail(Error &&error) { void conveyor_sink_set::fail(error &&error) {
/// @todo call error_handler /// @todo call error_handler
} }
ConveyorSinkSet::ConveyorSinkSet(EventLoop &event_loop) : Event{event_loop} {} conveyor_sink_set::conveyor_sink_set(event_loop &event_loop)
: event{event_loop} {}
void ConveyorSinkSet::add(Conveyor<void> &&sink) { void conveyor_sink_set::add(conveyor<void> &&sink) {
auto nas = Conveyor<void>::fromConveyor(std::move(sink)); auto nas = conveyor<void>::fromconveyor(std::move(sink));
SAW_ASSERT(nas) { return; } SAW_ASSERT(nas) { return; }
ConveyorStorage *storage = nas->nextStorage(); conveyor_storage *storage = nas->nextStorage();
Own<SinkConveyorNode> sink_node = nullptr; own<sink_conveyor_node> sink_node = nullptr;
try { try {
sink_node = heap<SinkConveyorNode>(std::move(nas), *this); sink_node = heap<sink_conveyor_node>(std::move(nas), *this);
} catch (std::bad_alloc &) { } catch (std::bad_alloc &) {
return; return;
} }
@ -370,36 +371,36 @@ void ConveyorSinkSet::add(Conveyor<void> &&sink) {
sink_nodes.emplace_back(std::move(sink_node)); sink_nodes.emplace_back(std::move(sink_node));
} }
void ConveyorSinkSet::fire() { void conveyor_sink_set::fire() {
while (!delete_nodes.empty()) { while (!delete_nodes.empty()) {
ConveyorNode *node = delete_nodes.front(); conveyor_node *node = delete_nodes.front();
/*auto erased = */ std::remove_if(sink_nodes.begin(), sink_nodes.end(), /*auto erased = */ std::remove_if(sink_nodes.begin(), sink_nodes.end(),
[node](Own<ConveyorNode> &element) { [node](own<conveyor_node> &element) {
return node == element.get(); return node == element.get();
}); });
delete_nodes.pop(); delete_nodes.pop();
} }
} }
ConvertConveyorNodeBase::ConvertConveyorNodeBase(Own<ConveyorNode> &&dep) convert_conveyor_node_base::convert_conveyor_node_base(own<conveyor_node> &&dep)
: child_mixin{std::move(dep), *this} {} : child_mixin{std::move(dep), *this} {}
void ConvertConveyorNodeBase::getResult(ErrorOrValue &err_or_val) { void convert_conveyor_node_base::getResult(error_or_value &err_or_val) {
getImpl(err_or_val); getImpl(err_or_val);
} }
void AttachConveyorNodeBase::getResult(ErrorOrValue &err_or_val) noexcept { void attach_conveyor_node_base::getResult(error_or_value &err_or_val) noexcept {
if (child_mixin.child) { if (child_mixin.child) {
child_mixin.child->getResult(err_or_val); child_mixin.child->getResult(err_or_val);
} }
} }
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
AttachConveyorNodeBase::swapChild(Own<ConveyorNode> &&swapee_) noexcept { attach_conveyor_node_base::swap_child(own<conveyor_node> &&swapee_) noexcept {
return child_mixin.swapChild(std::move(swapee_)); return child_mixin.swap_child(std::move(swapee_));
} }
ConveyorStorage *AttachConveyorNodeBase::nextStorage() noexcept { conveyor_storage *attach_conveyor_node_base::nextStorage() noexcept {
if (!child_mixin.child) { if (!child_mixin.child) {
return nullptr; return nullptr;
} }
@ -407,9 +408,9 @@ ConveyorStorage *AttachConveyorNodeBase::nextStorage() noexcept {
return child_mixin.child->nextStorage(); return child_mixin.child->nextStorage();
} }
void detachConveyor(Conveyor<void> &&conveyor) { void detach_conveyor(conveyor<void> &&conveyor) {
EventLoop &loop = currentEventLoop(); event_loop &loop = current_event_loop();
ConveyorSinkSet &sink = loop.daemon(); conveyor_sink_set &sink = loop.daemon();
sink.add(std::move(conveyor)); sink.add(std::move(conveyor));
} }
} // namespace saw } // namespace saw

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include "async.h"
#include "common.h" #include "common.h"
#include "error.h" #include "error.h"
@ -11,18 +10,18 @@
namespace saw { namespace saw {
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) { template <typename Func> conveyor_result<Func, void> exec_later(Func &&func) {
Conveyor<void> conveyor{FixVoid<void>{}}; conveyor<void> conveyor{fix_void<void>{}};
return conveyor.then(std::move(func)); return conveyor.then(std::move(func));
} }
template <typename T> template <typename T>
Conveyor<T>::Conveyor(FixVoid<T> value) : ConveyorBase(nullptr) { conveyor<T>::conveyor(fix_void<T> value) : conveyor_base(nullptr) {
// Is there any way to do this? // Is there any way to do this?
// @todo new ConveyorBase constructor for Immediate values // @todo new conveyorBase constructor for Immediate values
Own<ImmediateConveyorNode<FixVoid<T>>> immediate = own<immediate_conveyor_node<fix_void<T>>> immediate =
heap<ImmediateConveyorNode<FixVoid<T>>>(std::move(value)); heap<immediate_conveyor_node<fix_void<T>>>(std::move(value));
if (!immediate) { if (!immediate) {
return; return;
@ -32,9 +31,9 @@ Conveyor<T>::Conveyor(FixVoid<T> value) : ConveyorBase(nullptr) {
} }
template <typename T> template <typename T>
Conveyor<T>::Conveyor(Error &&error) : ConveyorBase(nullptr) { conveyor<T>::conveyor(error &&error) : conveyor_base(nullptr) {
Own<ImmediateConveyorNode<FixVoid<T>>> immediate = own<immediate_conveyor_node<fix_void<T>>> immediate =
heap<ImmediateConveyorNode<FixVoid<T>>>(std::move(error)); heap<immediate_conveyor_node<fix_void<T>>>(std::move(error));
if (!immediate) { if (!immediate) {
return; return;
@ -44,145 +43,150 @@ Conveyor<T>::Conveyor(Error &&error) : ConveyorBase(nullptr) {
} }
template <typename T> template <typename T>
Conveyor<T>::Conveyor(Own<ConveyorNode> node_p) conveyor<T>::conveyor(own<conveyor_node> node_p)
: ConveyorBase{std::move(node_p)} {} : conveyor_base{std::move(node_p)} {}
template <typename T> template <typename T>
template <typename Func, typename ErrorFunc> template <typename Func, typename ErrorFunc>
ConveyorResult<Func, T> Conveyor<T>::then(Func &&func, ErrorFunc &&error_func) { conveyor_result<Func, T> conveyor<T>::then(Func &&func,
Own<ConveyorNode> conversion_node = ErrorFunc &&error_func) {
heap<ConvertConveyorNode<FixVoid<ReturnType<Func, T>>, FixVoid<T>, Func, own<conveyor_node> conversion_node =
ErrorFunc>>(std::move(node), std::move(func), heap<convert_conveyor_node<fix_void<return_type<Func, T>>, fix_void<T>,
std::move(error_func)); Func, ErrorFunc>>(
std::move(node), std::move(func), std::move(error_func));
return Conveyor<RemoveErrorOr<ReturnType<Func, T>>>::toConveyor( return conveyor<remove_error_or<return_type<Func, T>>>::to_conveyor(
std::move(conversion_node)); std::move(conversion_node));
} }
template <typename T> Conveyor<T> Conveyor<T>::buffer(size_t size) { template <typename T> conveyor<T> conveyor<T>::buffer(size_t size) {
SAW_ASSERT(node) { return Conveyor<T>{Own<ConveyorNode>{nullptr}}; } SAW_ASSERT(node) { return conveyor<T>{own<conveyor_node>{nullptr}}; }
ConveyorStorage *storage = node->nextStorage(); conveyor_storage *storage = node->next_storage();
SAW_ASSERT(storage) { return Conveyor<T>{Own<ConveyorNode>{nullptr}}; } SAW_ASSERT(storage) { return conveyor<T>{own<conveyor_node>{nullptr}}; }
Own<QueueBufferConveyorNode<FixVoid<T>>> storage_node = own<queue_buffer_conveyor_node<fix_void<T>>> storage_node =
heap<QueueBufferConveyorNode<FixVoid<T>>>(std::move(node), size); heap<queue_buffer_conveyor_node<fix_void<T>>>(std::move(node), size);
ConveyorStorage *storage_ptr = conveyor_storage *storage_ptr =
static_cast<ConveyorStorage *>(storage_node.get()); static_cast<conveyor_storage *>(storage_node.get());
storage->setParent(storage_ptr); storage->set_parent(storage_ptr);
return Conveyor<T>{std::move(storage_node)}; return conveyor<T>{std::move(storage_node)};
} }
template <typename T> template <typename T>
template <typename... Args> template <typename... Args>
Conveyor<T> Conveyor<T>::attach(Args &&...args) { conveyor<T> conveyor<T>::attach(Args &&...args) {
Own<AttachConveyorNode<Args...>> attach_node = own<attach_conveyor_node<Args...>> attach_node =
heap<AttachConveyorNode<Args...>>(std::move(node), std::move(args...)); heap<attach_conveyor_node<Args...>>(std::move(node),
return Conveyor<T>{std::move(attach_node)}; std::move(args...));
return conveyor<T>{std::move(attach_node)};
} }
template <typename T> template <typename T>
std::pair<Conveyor<T>, MergeConveyor<T>> Conveyor<T>::merge() { std::pair<conveyor<T>, merge_conveyor<T>> conveyor<T>::merge() {
Our<MergeConveyorNodeData<T>> data = share<MergeConveyorNodeData<T>>(); our<merge_conveyor_node_data<T>> data =
share<merge_conveyor_node_data<T>>();
Own<MergeConveyorNode<T>> merge_node = heap<MergeConveyorNode<T>>(data); own<merge_conveyor_node<T>> merge_node = heap<merge_conveyor_node<T>>(data);
SAW_ASSERT(node) { SAW_ASSERT(node) {
return std::make_pair(Conveyor<T>{Own<ConveyorNode>{nullptr}}, return std::make_pair(conveyor<T>{own<conveyor_node>{nullptr}},
MergeConveyor<T>{}); merge_conveyor<T>{});
} }
ConveyorStorage *storage = node->nextStorage(); conveyor_storage *storage = node->next_storage();
SAW_ASSERT(storage) { SAW_ASSERT(storage) {
return std::make_pair(Conveyor<T>{Own<ConveyorNode>{nullptr}}, return std::make_pair(conveyor<T>{own<conveyor_node>{nullptr}},
MergeConveyor<T>{}); merge_conveyor<T>{});
} }
data->attach(Conveyor<T>::toConveyor(std::move(node))); data->attach(conveyor<T>::to_conveyor(std::move(node)));
MergeConveyor<T> node_ref{data}; merge_conveyor<T> node_ref{data};
return std::make_pair(Conveyor<T>{std::move(merge_node)}, return std::make_pair(conveyor<T>{std::move(merge_node)},
std::move(node_ref)); std::move(node_ref));
} }
template <> template <>
template <typename ErrorFunc> template <typename ErrorFunc>
ConveyorSink Conveyor<void>::sink(ErrorFunc &&error_func) { conveyor_sink conveyor<void>::sink(ErrorFunc &&error_func) {
ConveyorStorage *storage = node->nextStorage(); conveyor_storage *storage = node->next_storage();
SAW_ASSERT(storage) { return ConveyorSink{}; } SAW_ASSERT(storage) { return conveyor_sink{}; }
Own<SinkConveyorNode> sink_node = heap<SinkConveyorNode>(std::move(node)); own<sink_conveyor_node> sink_node =
ConveyorStorage *storage_ptr = heap<sink_conveyor_node>(std::move(node));
static_cast<ConveyorStorage *>(sink_node.get()); conveyor_storage *storage_ptr =
static_cast<conveyor_storage *>(sink_node.get());
storage->setParent(storage_ptr); storage->set_parent(storage_ptr);
return ConveyorSink{std::move(sink_node)}; return conveyor_sink{std::move(sink_node)};
} }
void detachConveyor(Conveyor<void> &&conveyor); void detachconveyor(conveyor<void> &&conveyor);
template <typename T> template <typename T>
template <typename ErrorFunc> template <typename ErrorFunc>
void Conveyor<T>::detach(ErrorFunc &&func) { void conveyor<T>::detach(ErrorFunc &&func) {
detachConveyor(std::move(then([](T &&) {}, std::move(func)))); detachconveyor(std::move(then([](T &&) {}, std::move(func))));
} }
template <> template <>
template <typename ErrorFunc> template <typename ErrorFunc>
void Conveyor<void>::detach(ErrorFunc &&func) { void conveyor<void>::detach(ErrorFunc &&func) {
detachConveyor(std::move(then([]() {}, std::move(func)))); detachconveyor(std::move(then([]() {}, std::move(func))));
} }
template <typename T> template <typename T>
Conveyor<T> Conveyor<T>::toConveyor(Own<ConveyorNode> node) { conveyor<T> conveyor<T>::to_conveyor(own<conveyor_node> node) {
return Conveyor<T>{std::move(node)}; return conveyor<T>{std::move(node)};
} }
template <typename T> template <typename T>
Own<ConveyorNode> Conveyor<T>::fromConveyor(Conveyor<T> conveyor) { own<conveyor_node> conveyor<T>::from_conveyor(conveyor<T> conveyor) {
return std::move(conveyor.node); return std::move(conveyor.node);
} }
template <typename T> ErrorOr<FixVoid<T>> Conveyor<T>::take() { template <typename T> error_or<fix_void<T>> conveyor<T>::take() {
SAW_ASSERT(node) { SAW_ASSERT(node) {
return ErrorOr<FixVoid<T>>{criticalError("Conveyor in invalid state")}; return error_or<fix_void<T>>{
critical_error("conveyor in invalid state")};
} }
ConveyorStorage *storage = node->nextStorage(); conveyor_storage *storage = node->next_storage();
if (storage) { if (storage) {
if (storage->queued() > 0) { if (storage->queued() > 0) {
ErrorOr<FixVoid<T>> result; error_or<fix_void<T>> result;
node->getResult(result); node->get_result(result);
return result; return result;
} else { } else {
return ErrorOr<FixVoid<T>>{ return error_or<fix_void<T>>{
recoverableError("Conveyor buffer has no elements")}; recoverable_error("conveyor buffer has no elements")};
} }
} else { } else {
return ErrorOr<FixVoid<T>>{ return error_or<fix_void<T>>{
criticalError("Conveyor node has no child storage")}; critical_error("conveyor node has no child storage")};
} }
} }
template <typename T> ConveyorAndFeeder<T> newConveyorAndFeeder() { template <typename T> conveyor_and_feeder<T> new_conveyor_and_feeder() {
Own<AdaptConveyorFeeder<FixVoid<T>>> feeder = own<adapt_conveyor_feeder<fix_void<T>>> feeder =
heap<AdaptConveyorFeeder<FixVoid<T>>>(); heap<adapt_conveyor_feeder<fix_void<T>>>();
Own<AdaptConveyorNode<FixVoid<T>>> node = own<adapt_conveyor_node<fix_void<T>>> node =
heap<AdaptConveyorNode<FixVoid<T>>>(); heap<adapt_conveyor_node<fix_void<T>>>();
feeder->setFeedee(node.get()); feeder->setFeedee(node.get());
node->setFeeder(feeder.get()); node->setFeeder(feeder.get());
return ConveyorAndFeeder<T>{std::move(feeder), return conveyor_and_feeder<T>{std::move(feeder),
Conveyor<T>::toConveyor(std::move(node))}; conveyor<T>::to_conveyor(std::move(node))};
} }
// QueueBuffer // QueueBuffer
template <typename T> void QueueBufferConveyorNode<T>::fire() { template <typename T> void queue_buffer_conveyor_node<T>::fire() {
if (child_mixin.child) { if (child_mixin.child) {
if (!storage.empty()) { if (!storage.empty()) {
if (storage.front().isError()) { if (storage.front().is_error()) {
if (storage.front().error().isCritical()) { if (storage.front().error().isCritical()) {
child_mixin.child = nullptr; child_mixin.child = nullptr;
} }
@ -193,9 +197,9 @@ template <typename T> void QueueBufferConveyorNode<T>::fire() {
bool has_space_before_fire = space() > 0; bool has_space_before_fire = space() > 0;
if (parent) { if (parent) {
parent->childHasFired(); parent->child_has_fired();
if (!storage.empty() && parent->space() > 0) { if (!storage.empty() && parent->space() > 0) {
armLater(); arm_later();
} }
} }
@ -206,45 +210,45 @@ template <typename T> void QueueBufferConveyorNode<T>::fire() {
return; return;
} }
ConveyorStorage *ch_storage = child_mixin.child->nextStorage(); conveyor_storage *ch_storage = child_mixin.child->next_storage();
if (ch_storage && !has_space_before_fire) { if (ch_storage && !has_space_before_fire) {
ch_storage->parentHasFired(); ch_storage->parent_has_fired();
} }
} }
template <typename T> template <typename T>
void QueueBufferConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept { void queue_buffer_conveyor_node<T>::get_result(error_or_value &eov) noexcept {
ErrorOr<T> &err_or_val = eov.as<T>(); error_or<T> &err_or_val = eov.as<T>();
err_or_val = std::move(storage.front()); err_or_val = std::move(storage.front());
storage.pop(); storage.pop();
} }
template <typename T> size_t QueueBufferConveyorNode<T>::space() const { template <typename T> size_t queue_buffer_conveyor_node<T>::space() const {
return max_store - storage.size(); return max_store - storage.size();
} }
template <typename T> size_t QueueBufferConveyorNode<T>::queued() const { template <typename T> size_t queue_buffer_conveyor_node<T>::queued() const {
return storage.size(); return storage.size();
} }
template <typename T> void QueueBufferConveyorNode<T>::childHasFired() { template <typename T> void queue_buffer_conveyor_node<T>::child_has_fired() {
if (child_mixin.child && storage.size() < max_store) { if (child_mixin.child && storage.size() < max_store) {
ErrorOr<T> eov; error_or<T> eov;
child_mixin.child->getResult(eov); child_mixin.child->get_result(eov);
if (eov.isError()) { if (eov.is_error()) {
if (eov.error().isCritical()) { if (eov.error().isCritical()) {
} }
} }
storage.push(std::move(eov)); storage.push(std::move(eov));
if (!isArmed()) { if (!is_armed()) {
armLater(); arm_later();
} }
} }
} }
template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() { template <typename T> void queue_buffer_conveyor_node<T>::parent_has_fired() {
SAW_ASSERT(parent) { return; } SAW_ASSERT(parent) { return; }
if (parent->space() == 0) { if (parent->space() == 0) {
@ -252,57 +256,57 @@ template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() {
} }
if (queued() > 0) { if (queued() > 0) {
armLater(); arm_later();
} }
} }
template <typename T> template <typename T>
ImmediateConveyorNode<T>::ImmediateConveyorNode(FixVoid<T> &&val) immediate_conveyor_node<T>::immediate_conveyor_node(fix_void<T> &&val)
: value{std::move(val)}, retrieved{0} {} : value{std::move(val)}, retrieved{0} {}
template <typename T> template <typename T>
ImmediateConveyorNode<T>::ImmediateConveyorNode(Error &&error) immediate_conveyor_node<T>::immediate_conveyor_node(error &&error)
: value{std::move(error)}, retrieved{0} {} : value{std::move(error)}, retrieved{0} {}
template <typename T> size_t ImmediateConveyorNode<T>::space() const { template <typename T> size_t immediate_conveyor_node<T>::space() const {
return 0; return 0;
} }
template <typename T> size_t ImmediateConveyorNode<T>::queued() const { template <typename T> size_t immediate_conveyor_node<T>::queued() const {
return retrieved > 1 ? 0 : 1; return retrieved > 1 ? 0 : 1;
} }
template <typename T> void ImmediateConveyorNode<T>::childHasFired() { template <typename T> void immediate_conveyor_node<T>::child_has_fired() {
// Impossible case // Impossible case
assert(false); assert(false);
} }
template <typename T> void ImmediateConveyorNode<T>::parentHasFired() { template <typename T> void immediate_conveyor_node<T>::parent_has_fired() {
SAW_ASSERT(parent) { return; } SAW_ASSERT(parent) { return; }
assert(parent->space() > 0); assert(parent->space() > 0);
if (queued() > 0) { if (queued() > 0) {
armNext(); arm_next();
} }
} }
template <typename T> void ImmediateConveyorNode<T>::fire() { template <typename T> void immediate_conveyor_node<T>::fire() {
if (parent) { if (parent) {
parent->childHasFired(); parent->child_has_fired();
if (queued() > 0 && parent->space() > 0) { if (queued() > 0 && parent->space() > 0) {
armLast(); arm_last();
} }
} }
} }
template <typename T> template <typename T>
MergeConveyor<T>::MergeConveyor(Lent<MergeConveyorNodeData<T>> d) merge_conveyor<T>::merge_conveyor(lent<merge_conveyor_node_data<T>> d)
: data{std::move(d)} {} : data{std::move(d)} {}
template <typename T> MergeConveyor<T>::~MergeConveyor() {} template <typename T> merge_conveyor<T>::~merge_conveyor() {}
template <typename T> void MergeConveyor<T>::attach(Conveyor<T> conveyor) { template <typename T> void merge_conveyor<T>::attach(conveyor<T> conveyor) {
auto sp = data.lock(); auto sp = data.lock();
SAW_ASSERT(sp) { return; } SAW_ASSERT(sp) { return; }
@ -310,26 +314,26 @@ template <typename T> void MergeConveyor<T>::attach(Conveyor<T> conveyor) {
} }
template <typename T> template <typename T>
MergeConveyorNode<T>::MergeConveyorNode(Our<MergeConveyorNodeData<T>> d) merge_conveyor_node<T>::merge_conveyor_node(our<merge_conveyor_node_data<T>> d)
: data{d} { : data{d} {
SAW_ASSERT(data) { return; } SAW_ASSERT(data) { return; }
data->merger = this; data->merger = this;
} }
template <typename T> MergeConveyorNode<T>::~MergeConveyorNode() {} template <typename T> merge_conveyor_node<T>::~merge_conveyor_node() {}
template <typename T> template <typename T>
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
MergeConveyorNode<T>::swapChild(Own<ConveyorNode> &&swapee_) noexcept { merge_conveyor_node<T>::swap_child(own<conveyor_node> &&swapee_) noexcept {
(void)swapee_; (void)swapee_;
return criticalError( return critical_error(
"MergeConveyorNode<T>::Appendage should block calls to this class"); "MergeconveyorNode<T>::Appendage should block calls to this class");
} }
template <typename T> template <typename T>
void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept { void merge_conveyor_node<T>::get_result(error_or_value &eov) noexcept {
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>(); error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
SAW_ASSERT(data) { return; } SAW_ASSERT(data) { return; }
@ -355,24 +359,24 @@ void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept {
} }
} }
err_or_val = criticalError("No value in Merge Appendages"); err_or_val = critical_error("No value in Merge Appendages");
} }
template <typename T> void MergeConveyorNode<T>::fire() { template <typename T> void merge_conveyor_node<T>::fire() {
SAW_ASSERT(queued() > 0) { return; } SAW_ASSERT(queued() > 0) { return; }
if (parent) { if (parent) {
parent->childHasFired(); parent->child_has_fired();
if (queued() > 0 && parent->space() > 0) { if (queued() > 0 && parent->space() > 0) {
armLater(); arm_later();
} }
} }
} }
template <typename T> size_t MergeConveyorNode<T>::space() const { return 0; } template <typename T> size_t merge_conveyor_node<T>::space() const { return 0; }
template <typename T> size_t MergeConveyorNode<T>::queued() const { template <typename T> size_t merge_conveyor_node<T>::queued() const {
SAW_ASSERT(data) { return 0; } SAW_ASSERT(data) { return 0; }
size_t queue_count = 0; size_t queue_count = 0;
@ -384,64 +388,65 @@ template <typename T> size_t MergeConveyorNode<T>::queued() const {
return queue_count; return queue_count;
} }
template <typename T> void MergeConveyorNode<T>::childHasFired() { template <typename T> void merge_conveyor_node<T>::child_has_fired() {
/// This can never happen /// This can never happen
assert(false); assert(false);
} }
template <typename T> void MergeConveyorNode<T>::parentHasFired() { template <typename T> void merge_conveyor_node<T>::parent_has_fired() {
SAW_ASSERT(parent) { return; } SAW_ASSERT(parent) { return; }
if (queued() > 0) { if (queued() > 0) {
if (parent->space() > 0) { if (parent->space() > 0) {
armLater(); arm_later();
} }
} }
} }
/** /**
* MergeConveyorNode<T>::Apendage * MergeconveyorNode<T>::Apendage
*/ */
template <typename T> template <typename T>
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
MergeConveyorNode<T>::Appendage::swapChild(Own<ConveyorNode> &&swapee_) { merge_conveyor_node<T>::appendage::swap_child(own<conveyor_node> &&swapee_) {
Own<ConveyorNode> old_child = std::move(child); own<conveyor_node> old_child = std::move(child);
child = std::move(swapee_); child = std::move(swapee_);
// This case should never happen // This case should never happen
SAW_ASSERT(old_child) { return criticalError("No child exists"); } SAW_ASSERT(old_child) { return critical_error("No child exists"); }
return old_child; return old_child;
} }
template <typename T> template <typename T>
void MergeConveyorNode<T>::Appendage::getResult(ErrorOrValue &eov) { void merge_conveyor_node<T>::appendage::get_result(error_or_value &eov) {
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>(); error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
SAW_ASSERT(queued() > 0) { SAW_ASSERT(queued() > 0) {
err_or_val = criticalError("No element queued in Merge Appendage Node"); err_or_val =
critical_error("No element queued in Merge Appendage Node");
return; return;
} }
err_or_val = std::move(error_or_value.value()); err_or_val = std::move(error_or_value_data.value());
error_or_value = std::nullopt; error_or_value_data = std::nullopt;
} }
template <typename T> size_t MergeConveyorNode<T>::Appendage::space() const { template <typename T> size_t merge_conveyor_node<T>::appendage::space() const {
SAW_ASSERT(merger) { return 0; } SAW_ASSERT(merger) { return 0; }
if (error_or_value.has_value()) { if (error_or_value_data.has_value()) {
return 0; return 0;
} }
return 1; return 1;
} }
template <typename T> size_t MergeConveyorNode<T>::Appendage::queued() const { template <typename T> size_t merge_conveyor_node<T>::appendage::queued() const {
SAW_ASSERT(merger) { return 0; } SAW_ASSERT(merger) { return 0; }
if (error_or_value.has_value()) { if (error_or_value_data.has_value()) {
return 1; return 1;
} }
@ -450,39 +455,43 @@ template <typename T> size_t MergeConveyorNode<T>::Appendage::queued() const {
/// @todo delete this function. Replaced by the regular getResult /// @todo delete this function. Replaced by the regular getResult
template <typename T> template <typename T>
void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) { void merge_conveyor_node<T>::appendage::get_appendage_result(
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>(); error_or_value &eov) {
error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
SAW_ASSERT(queued() > 0) { SAW_ASSERT(queued() > 0) {
err_or_val = criticalError("No element queued in Merge Appendage Node"); err_or_val =
critical_error("No element queued in Merge Appendage Node");
return; return;
} }
err_or_val = std::move(error_or_value.value()); err_or_val = std::move(error_or_value_data.value());
error_or_value = std::nullopt; error_or_value_data = std::nullopt;
} }
template <typename T> void MergeConveyorNode<T>::Appendage::childHasFired() { template <typename T>
SAW_ASSERT(!error_or_value.has_value()) { return; } void merge_conveyor_node<T>::appendage::child_has_fired() {
ErrorOr<FixVoid<T>> eov; SAW_ASSERT(!error_or_value_data.has_value()) { return; }
child->getResult(eov); error_or<fix_void<T>> eov;
child->get_result(eov);
error_or_value = std::move(eov); error_or_value_data = std::move(eov);
if (!merger->isArmed()) { if (!merger->is_armed()) {
merger->armLater(); merger->arm_later();
}
}
template <typename T> void MergeConveyorNode<T>::Appendage::parentHasFired() {
ConveyorStorage *child_storage = child->nextStorage();
if (child_storage) {
child_storage->parentHasFired();
} }
} }
template <typename T> template <typename T>
void MergeConveyorNode<T>::Appendage::setParent(ConveyorStorage *par) { void merge_conveyor_node<T>::appendage::parent_has_fired() {
conveyor_storage *child_storage = child->next_storage();
if (child_storage) {
child_storage->parent_has_fired();
}
}
template <typename T>
void merge_conveyor_node<T>::appendage::set_parent(conveyor_storage *par) {
SAW_ASSERT(merger) { return; } SAW_ASSERT(merger) { return; }
SAW_ASSERT(child) { return; } SAW_ASSERT(child) { return; }
@ -491,38 +500,36 @@ void MergeConveyorNode<T>::Appendage::setParent(ConveyorStorage *par) {
} }
template <typename T> template <typename T>
void MergeConveyorNodeData<T>::attach(Conveyor<T> conveyor) { void merge_conveyor_node_data<T>::attach(conveyor<T> conveyor) {
auto nas = Conveyor<T>::fromConveyor(std::move(conveyor)); auto nas = conveyor<T>::from_conveyor(std::move(conveyor));
SAW_ASSERT(nas) { return; } SAW_ASSERT(nas) { return; }
ConveyorStorage *storage = nas->nextStorage(); conveyor_storage *storage = nas->nextStorage();
SAW_ASSERT(storage) { return; } SAW_ASSERT(storage) { return; }
auto merge_node_appendage = auto merge_node_appendage =
heap<typename MergeConveyorNode<T>::Appendage>(std::move(nas), *merger); heap<typename merge_conveyor_node<T>::Appendage>(std::move(nas),
*merger);
auto merge_node_appendage_ptr = merge_node_appendage.get(); auto merge_node_appendage_ptr = merge_node_appendage.get();
storage->setParent(merge_node_appendage.get()); storage->set_parent(merge_node_appendage.get());
SAW_ASSERT(merger) { return; } SAW_ASSERT(merger) { return; }
ConveyorStorage *mrg_storage = merger->nextStorage(); conveyor_storage *mrg_storage = merger->nextStorage();
SAW_ASSERT(mrg_storage) { return; } SAW_ASSERT(mrg_storage) { return; }
merge_node_appendage->setParent(mrg_storage); merge_node_appendage->setParent(mrg_storage);
appendages.push_back(std::move(merge_node_appendage)); appendages.push_back(std::move(merge_node_appendage));
/// @todo return this. necessary? maybe for the weird linking setup
/// maybe not
// return merge_node_appendage_ptr;
} }
template <typename T> void MergeConveyorNodeData<T>::governingNodeDestroyed() { template <typename T>
void merge_conveyor_node_data<T>::governing_node_destroyed() {
appendages.clear(); appendages.clear();
merger = nullptr; merger = nullptr;
} }
template <typename T> AdaptConveyorFeeder<T>::~AdaptConveyorFeeder() { template <typename T> adapt_conveyor_feeder<T>::~adapt_conveyor_feeder() {
if (feedee) { if (feedee) {
feedee->setFeeder(nullptr); feedee->setFeeder(nullptr);
feedee = nullptr; feedee = nullptr;
@ -530,30 +537,30 @@ template <typename T> AdaptConveyorFeeder<T>::~AdaptConveyorFeeder() {
} }
template <typename T> template <typename T>
void AdaptConveyorFeeder<T>::setFeedee(AdaptConveyorNode<T> *feedee_p) { void adapt_conveyor_feeder<T>::set_feedee(adapt_conveyor_node<T> *feedee_p) {
feedee = feedee_p; feedee = feedee_p;
} }
template <typename T> void AdaptConveyorFeeder<T>::feed(T &&value) { template <typename T> void adapt_conveyor_feeder<T>::feed(T &&value) {
if (feedee) { if (feedee) {
feedee->feed(std::move(value)); feedee->feed(std::move(value));
} }
} }
template <typename T> void AdaptConveyorFeeder<T>::fail(Error &&error) { template <typename T> void adapt_conveyor_feeder<T>::fail(error &&error) {
if (feedee) { if (feedee) {
feedee->fail(std::move(error)); feedee->fail(std::move(error));
} }
} }
template <typename T> size_t AdaptConveyorFeeder<T>::queued() const { template <typename T> size_t adapt_conveyor_feeder<T>::queued() const {
if (feedee) { if (feedee) {
return feedee->queued(); return feedee->queued();
} }
return 0; return 0;
} }
template <typename T> size_t AdaptConveyorFeeder<T>::space() const { template <typename T> size_t adapt_conveyor_feeder<T>::space() const {
if (feedee) { if (feedee) {
return feedee->space(); return feedee->space();
} }
@ -561,20 +568,20 @@ template <typename T> size_t AdaptConveyorFeeder<T>::space() const {
} }
template <typename T> template <typename T>
Error AdaptConveyorFeeder<T>::swap(Conveyor<T> &&conveyor) noexcept { error adapt_conveyor_feeder<T>::swap(conveyor<T> &&conveyor) noexcept {
SAW_ASSERT(feedee) { return criticalError("No feedee connected"); } SAW_ASSERT(feedee) { return critical_error("No feedee connected"); }
auto node = Conveyor<T>::fromConveyor(std::move(conveyor)); auto node = conveyor<T>::from_conveyor(std::move(conveyor));
feedee->swapChild(std::move(node)); feedee->swapChild(std::move(node));
return noError(); return no_error();
} }
template <typename T> template <typename T>
AdaptConveyorNode<T>::AdaptConveyorNode() : ConveyorEventStorage{} {} adapt_conveyor_node<T>::adapt_conveyor_node() : conveyor_event_storage{} {}
template <typename T> AdaptConveyorNode<T>::~AdaptConveyorNode() { template <typename T> adapt_conveyor_node<T>::~adapt_conveyor_node() {
if (feeder) { if (feeder) {
feeder->setFeedee(nullptr); feeder->setFeedee(nullptr);
feeder = nullptr; feeder = nullptr;
@ -582,12 +589,12 @@ template <typename T> AdaptConveyorNode<T>::~AdaptConveyorNode() {
} }
template <typename T> template <typename T>
ErrorOr<Own<ConveyorNode>> error_or<own<conveyor_node>>
AdaptConveyorNode<T>::swapChild(Own<ConveyorNode> &&swapee) noexcept { adapt_conveyor_node<T>::swap_child(own<conveyor_node> &&swapee) noexcept {
// This should return the owning pointer of this instance // This should return the owning pointer of this instance
auto myself_err = parent_node.swapChildOfParent(std::move(swapee)); auto myself_err = parent_node.swap_child_of_parent(std::move(swapee));
if (myself_err.isError()) { if (myself_err.is_error()) {
return myself_err; return myself_err;
} }
@ -599,56 +606,57 @@ AdaptConveyorNode<T>::swapChild(Own<ConveyorNode> &&swapee) noexcept {
} }
template <typename T> template <typename T>
ConveyorStorage *AdaptConveyorNode<T>::nextStorage() noexcept { conveyor_storage *adapt_conveyor_node<T>::next_storage() noexcept {
return static_cast<ConveyorStorage *>(this); return static_cast<conveyor_storage *>(this);
} }
template <typename T> template <typename T>
void AdaptConveyorNode<T>::notifyParentAttached(ConveyorNode &par) noexcept { void adapt_conveyor_node<T>::notify_parent_attached(
parent_node.changeParent(&par); conveyor_node &par) noexcept {
parent_node.change_parent(&par);
} }
template <typename T> template <typename T>
void AdaptConveyorNode<T>::setFeeder(AdaptConveyorFeeder<T> *feeder_p) { void adapt_conveyor_node<T>::set_feeder(adapt_conveyor_feeder<T> *feeder_p) {
feeder = feeder_p; feeder = feeder_p;
} }
template <typename T> void AdaptConveyorNode<T>::feed(T &&value) { template <typename T> void adapt_conveyor_node<T>::feed(T &&value) {
storage.push(std::move(value)); storage.push(std::move(value));
armNext(); arm_next();
} }
template <typename T> void AdaptConveyorNode<T>::fail(Error &&error) { template <typename T> void adapt_conveyor_node<T>::fail(error &&error) {
storage.push(std::move(error)); storage.push(std::move(error));
armNext(); arm_next();
} }
template <typename T> size_t AdaptConveyorNode<T>::queued() const { template <typename T> size_t adapt_conveyor_node<T>::queued() const {
return storage.size(); return storage.size();
} }
template <typename T> size_t AdaptConveyorNode<T>::space() const { template <typename T> size_t adapt_conveyor_node<T>::space() const {
return std::numeric_limits<size_t>::max() - storage.size(); return std::numeric_limits<size_t>::max() - storage.size();
} }
template <typename T> template <typename T>
void AdaptConveyorNode<T>::getResult(ErrorOrValue &err_or_val) { void adapt_conveyor_node<T>::get_result(error_or_value &err_or_val) {
if (!storage.empty()) { if (!storage.empty()) {
err_or_val.as<T>() = std::move(storage.front()); err_or_val.as<T>() = std::move(storage.front());
storage.pop(); storage.pop();
} else { } else {
err_or_val.as<T>() = err_or_val.as<T>() = critical_error(
criticalError("Signal for retrieval of storage sent even though no " "Signal for retrieval of storage sent even though no "
"data is present"); "data is present");
} }
} }
template <typename T> void AdaptConveyorNode<T>::childHasFired() { template <typename T> void adapt_conveyor_node<T>::child_has_fired() {
// Adapt node has no children // Adapt node has no children
assert(false); assert(false);
} }
template <typename T> void AdaptConveyorNode<T>::parentHasFired() { template <typename T> void adapt_conveyor_node<T>::parent_has_fired() {
SAW_ASSERT(parent) { return; } SAW_ASSERT(parent) { return; }
if (parent->space() == 0) { if (parent->space() == 0) {
@ -656,17 +664,17 @@ template <typename T> void AdaptConveyorNode<T>::parentHasFired() {
} }
} }
template <typename T> void AdaptConveyorNode<T>::fire() { template <typename T> void adapt_conveyor_node<T>::fire() {
if (parent) { if (parent) {
parent->childHasFired(); parent->child_has_fired();
if (storage.size() > 0) { if (storage.size() > 0) {
armLater(); arm_later();
} }
} }
} }
template <typename T> OneTimeConveyorFeeder<T>::~OneTimeConveyorFeeder() { template <typename T> one_time_conveyor_feeder<T>::~one_time_conveyor_feeder() {
if (feedee) { if (feedee) {
feedee->setFeeder(nullptr); feedee->setFeeder(nullptr);
feedee = nullptr; feedee = nullptr;
@ -674,37 +682,38 @@ template <typename T> OneTimeConveyorFeeder<T>::~OneTimeConveyorFeeder() {
} }
template <typename T> template <typename T>
void OneTimeConveyorFeeder<T>::setFeedee(OneTimeConveyorNode<T> *feedee_p) { void one_time_conveyor_feeder<T>::set_feedee(
one_time_conveyor_node<T> *feedee_p) {
feedee = feedee_p; feedee = feedee_p;
} }
template <typename T> void OneTimeConveyorFeeder<T>::feed(T &&value) { template <typename T> void one_time_conveyor_feeder<T>::feed(T &&value) {
if (feedee) { if (feedee) {
feedee->feed(std::move(value)); feedee->feed(std::move(value));
} }
} }
template <typename T> void OneTimeConveyorFeeder<T>::fail(Error &&error) { template <typename T> void one_time_conveyor_feeder<T>::fail(error &&error) {
if (feedee) { if (feedee) {
feedee->fail(std::move(error)); feedee->fail(std::move(error));
} }
} }
template <typename T> size_t OneTimeConveyorFeeder<T>::queued() const { template <typename T> size_t one_time_conveyor_feeder<T>::queued() const {
if (feedee) { if (feedee) {
return feedee->queued(); return feedee->queued();
} }
return 0; return 0;
} }
template <typename T> size_t OneTimeConveyorFeeder<T>::space() const { template <typename T> size_t one_time_conveyor_feeder<T>::space() const {
if (feedee) { if (feedee) {
return feedee->space(); return feedee->space();
} }
return 0; return 0;
} }
template <typename T> OneTimeConveyorNode<T>::~OneTimeConveyorNode() { template <typename T> one_time_conveyor_node<T>::~one_time_conveyor_node() {
if (feeder) { if (feeder) {
feeder->setFeedee(nullptr); feeder->setFeedee(nullptr);
feeder = nullptr; feeder = nullptr;
@ -712,43 +721,44 @@ template <typename T> OneTimeConveyorNode<T>::~OneTimeConveyorNode() {
} }
template <typename T> template <typename T>
void OneTimeConveyorNode<T>::setFeeder(OneTimeConveyorFeeder<T> *feeder_p) { void one_time_conveyor_node<T>::set_feeder(
one_time_conveyor_feeder<T> *feeder_p) {
feeder = feeder_p; feeder = feeder_p;
} }
template <typename T> void OneTimeConveyorNode<T>::feed(T &&value) { template <typename T> void one_time_conveyor_node<T>::feed(T &&value) {
storage = std::move(value); storage = std::move(value);
armNext(); arm_next();
} }
template <typename T> void OneTimeConveyorNode<T>::fail(Error &&error) { template <typename T> void one_time_conveyor_node<T>::fail(error &&error) {
storage = std::move(error); storage = std::move(error);
armNext(); arm_next();
} }
template <typename T> size_t OneTimeConveyorNode<T>::queued() const { template <typename T> size_t one_time_conveyor_node<T>::queued() const {
return storage.has_value() ? 1 : 0; return storage.has_value() ? 1 : 0;
} }
template <typename T> size_t OneTimeConveyorNode<T>::space() const { template <typename T> size_t one_time_conveyor_node<T>::space() const {
return passed ? 0 : 1; return passed ? 0 : 1;
} }
template <typename T> template <typename T>
void OneTimeConveyorNode<T>::getResult(ErrorOrValue &err_or_val) { void one_time_conveyor_node<T>::get_result(error_or_value &err_or_val) {
if (storage.has_value()) { if (storage.has_value()) {
err_or_val.as<T>() = std::move(storage.value()); err_or_val.as<T>() = std::move(storage.value());
storage = std::nullopt; storage = std::nullopt;
} else { } else {
err_or_val.as<T>() = err_or_val.as<T>() = critical_error(
criticalError("Signal for retrieval of storage sent even though no " "Signal for retrieval of storage sent even though no "
"data is present"); "data is present");
} }
} }
template <typename T> void OneTimeConveyorNode<T>::fire() { template <typename T> void one_time_conveyor_node<T>::fire() {
if (parent) { if (parent) {
parent->childHasFired(); parent->child_has_fired();
} }
} }

View File

@ -32,43 +32,43 @@ namespace saw {
assert(expression); \ assert(expression); \
if (!(expression)) [[unlikely]] if (!(expression)) [[unlikely]]
template <typename T> using Maybe = std::optional<T>; template <typename T> using maybe = std::optional<T>;
template <typename T> using Own = std::unique_ptr<T>; template <typename T> using own = std::unique_ptr<T>;
template <typename T> using Our = std::shared_ptr<T>; template <typename T> using our = std::shared_ptr<T>;
template <typename T> using Lent = std::weak_ptr<T>; template <typename T> using lent = std::weak_ptr<T>;
template <typename T, class... Args> Own<T> heap(Args &&...args) { template <typename T, class... Args> own<T> heap(Args &&...args) {
return Own<T>(new T(std::forward<Args>(args)...)); return own<T>(new T(std::forward<Args>(args)...));
} }
template <typename T, class... Args> Our<T> share(Args &&...args) { template <typename T, class... Args> our<T> share(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...); return std::make_shared<T>(std::forward<Args>(args)...);
} }
template <typename T> T instance() noexcept; template <typename T> T instance() noexcept;
template <typename Func, typename T> struct ReturnTypeHelper { template <typename Func, typename T> struct return_type_helper {
typedef decltype(instance<Func>()(instance<T>())) Type; typedef decltype(instance<Func>()(instance<T>())) Type;
}; };
template <typename Func> struct ReturnTypeHelper<Func, void> { template <typename Func> struct return_type_helper<Func, void> {
typedef decltype(instance<Func>()()) Type; typedef decltype(instance<Func>()()) Type;
}; };
template <typename Func, typename T> template <typename Func, typename T>
using ReturnType = typename ReturnTypeHelper<Func, T>::Type; using return_type = typename return_type_helper<Func, T>::Type;
struct Void {}; struct Void {};
template <typename T> struct VoidFix { typedef T Type; }; template <typename T> struct void_fix { typedef T Type; };
template <> struct VoidFix<void> { typedef Void Type; }; template <> struct void_fix<void> { typedef Void Type; };
template <typename T> using FixVoid = typename VoidFix<T>::Type; template <typename T> using fix_void = typename void_fix<T>::Type;
template <typename T> struct VoidUnfix { typedef T Type; }; template <typename T> struct void_unfix { typedef T Type; };
template <> struct VoidUnfix<Void> { typedef void Type; }; template <> struct void_unfix<Void> { typedef void Type; };
template <typename T> using UnfixVoid = typename VoidUnfix<T>::Type; template <typename T> using unfix_void = typename void_unfix<T>::Type;
template <typename... T> constexpr bool always_false = false; template <typename... T> constexpr bool always_false = false;

View File

@ -1,19 +1,19 @@
#include "error.h" #include "error.h"
namespace saw { namespace saw {
Error::Error() : error_{static_cast<Error::Code>(0)} {} error::error() : error_{static_cast<error::code>(0)} {}
Error::Error(const std::string_view &msg, Error::Code code) error::error(const std::string_view &msg, error::code code)
: error_message{msg}, error_{static_cast<Error::Code>(code)} {} : error_message{msg}, error_{static_cast<error::code>(code)} {}
Error::Error(std::string &&msg, Error::Code code) error::error(std::string &&msg, error::code code)
: error_message{std::move(msg)}, error_{static_cast<Error::Code>(code)} {} : error_message{std::move(msg)}, error_{static_cast<error::code>(code)} {}
Error::Error(Error &&error) error::error(error &&error)
: error_message{std::move(error.error_message)}, error_{std::move( : error_message{std::move(error.error_message)}, error_{std::move(
error.error_)} {} error.error_)} {}
const std::string_view Error::message() const { const std::string_view error::message() const {
return std::visit( return std::visit(
[this](auto &&arg) -> const std::string_view { [this](auto &&arg) -> const std::string_view {
@ -24,50 +24,50 @@ const std::string_view Error::message() const {
} else if constexpr (std::is_same_v<T, std::string_view>) { } else if constexpr (std::is_same_v<T, std::string_view>) {
return arg; return arg;
} else { } else {
return "Error in class Error. Good luck :)"; return "error in class error. Good luck :)";
} }
}, },
error_message); error_message);
} }
bool Error::failed() const { bool error::failed() const {
return static_cast<std::underlying_type_t<Error::Code>>(error_) != 0; return static_cast<std::underlying_type_t<error::code>>(error_) != 0;
} }
bool Error::isCritical() const { bool error::is_critical() const {
return static_cast<std::underlying_type_t<Error::Code>>(error_) < 0; return static_cast<std::underlying_type_t<error::code>>(error_) < 0;
} }
bool Error::isRecoverable() const { bool error::is_recoverable() const {
return static_cast<std::underlying_type_t<Error::Code>>(error_) > 0; return static_cast<std::underlying_type_t<error::code>>(error_) > 0;
} }
Error Error::copyError() const { error error::copy_error() const {
Error error; error error;
error.error_ = error_; error.error_ = error_;
try { try {
error.error_message = error_message; error.error_message = error_message;
} catch (const std::bad_alloc &) { } catch (const std::bad_alloc &) {
error.error_message = error.error_message =
std::string_view{"Error while copying Error string. Out of memory"}; std::string_view{"error while copying error string. Out of memory"};
} }
return error; return error;
} }
Error::Code Error::code() const { return static_cast<Error::Code>(error_); } error::code error::code() const { return static_cast<error::code>(error_); }
Error makeError(const std::string_view &generic, Error::Code code) { error makeerror(const std::string_view &generic, error::code code) {
return Error{generic, code}; return error{generic, code};
} }
Error criticalError(const std::string_view &generic, Error::Code c) { error critical_error(const std::string_view &generic, error::code c) {
return makeError(generic, c); return makeerror(generic, c);
} }
Error recoverableError(const std::string_view &generic, Error::Code c) { error recoverable_error(const std::string_view &generic, error::code c) {
return makeError(generic, c); return makeerror(generic, c);
} }
Error noError() { return Error{}; } error no_error() { return error{}; }
} // namespace saw } // namespace saw

View File

@ -11,133 +11,140 @@
namespace saw { namespace saw {
/** /**
* Utility class for generating errors. Has a base distinction between * Utility class for generating errors. Has a base distinction between
* critical and recoverable errors. Additional code ids can be provided to the * critical and recoverable_ errors. Additional code ids can be provided to the
* constructor if additional distinctions are necessary. * constructor if additional distinctions are necessary.
*/ */
class Error { class error {
public: public:
enum class Code : int16_t { enum class code : int16_t {
GenericCritical = -1, generic_critical = -1,
GenericRecoverable = 1, generic_recoverable = 1,
Disconnected = -99, disconnected = -99,
Exhausted = -98 exhausted = -98
}; };
private: private:
std::variant<std::string_view, std::string> error_message; std::variant<std::string_view, std::string> error_message;
Code error_; code error_;
public: public:
Error(); error();
Error(const std::string_view &msg, Error::Code code); error(const std::string_view &msg, error::code code);
Error(std::string &&msg, Error::Code code); error(std::string &&msg, error::code code);
Error(Error &&error); error(error &&error);
SAW_FORBID_COPY(Error); SAW_FORBID_COPY(error);
Error &operator=(Error &&) = default; error &operator=(error &&) = default;
const std::string_view message() const; const std::string_view message() const;
bool failed() const; bool failed() const;
bool isCritical() const; bool is_critical() const;
bool isRecoverable() const; bool is_recoverable() const;
Error copyError() const; error copy_error() const;
Code code() const; code error_code() const;
}; };
Error makeError(const std::string_view &generic, Error::Code c); error make_error(const std::string_view &generic, error::code c);
template <typename Formatter> template <typename Formatter>
Error makeError(const Formatter &formatter, Error::Code code, error make_error(const Formatter &formatter, error::code code,
const std::string_view &generic) { const std::string_view &generic) {
/*
try { try {
std::string error_msg = formatter(); std::string error_msg = formatter();
return Error{std::move(error_msg), code}; return error{std::move(error_msg), code};
} catch (std::bad_alloc &) { } catch (std::bad_alloc &) {
return Error{generic, code}; return error{generic, code};
} }
*/
std::string error_msg = formatter();
return error{std::move(error_msg), code};
} }
Error criticalError(const std::string_view &generic, error critical_error(const std::string_view &generic,
Error::Code c = Error::Code::GenericCritical); error::code c = error::code::generic_critical);
template <typename Formatter> template <typename Formatter>
Error criticalError(const Formatter &formatter, const std::string_view &generic, error critical_error(const Formatter &formatter,
Error::Code c = Error::Code::GenericCritical) { const std::string_view &generic,
return makeError(formatter, c, generic); error::code c = error::code::generic_critical) {
return makeerror(formatter, c, generic);
} }
Error recoverableError(const std::string_view &generic, error recoverable_error(const std::string_view &generic,
Error::Code c = Error::Code::GenericRecoverable); error::code c = error::code::generic_recoverable);
template <typename Formatter> template <typename Formatter>
Error recoverableError(const Formatter &formatter, error recoverable_error(const Formatter &formatter,
const std::string_view &generic, const std::string_view &generic,
Error::Code c = Error::Code::GenericRecoverable) { error::code c = error::code::generic_recoverable) {
return makeError(formatter, c, generic); return makeerror(formatter, c, generic);
} }
Error noError(); error no_error();
/** /**
* Exception alternative. Since I code without exceptions this class is * Exception alternative. Since I code without exceptions this class is
* essentially a kind of exception replacement. * essentially a kind of exception replacement.
*/ */
template <typename T> class ErrorOr; template <typename T> class error_or;
class ErrorOrValue { class error_or_value {
public: public:
virtual ~ErrorOrValue() = default; virtual ~error_or_value() = default;
template <typename T> ErrorOr<UnfixVoid<T>> &as() { template <typename T> error_or<unfix_void<T>> &as() {
return static_cast<ErrorOr<UnfixVoid<T>> &>(*this); return static_cast<error_or<unfix_void<T>> &>(*this);
} }
template <typename T> const ErrorOr<UnfixVoid<T>> &as() const { template <typename T> const error_or<unfix_void<T>> &as() const {
return static_cast<const ErrorOr<UnfixVoid<T>> &>(*this); return static_cast<const error_or<unfix_void<T>> &>(*this);
} }
}; };
template <typename T> class ErrorOr final : public ErrorOrValue { template <typename T> class error_or final : public error_or_value {
private: private:
std::variant<Error, FixVoid<T>> value_or_error; std::variant<error, fix_void<T>> value_or_error;
static_assert(!std::is_same_v<T, Void>, "Don't use internal private types"); static_assert(!std::is_same_v<T, Void>, "Don't use internal private types");
public: public:
ErrorOr() = default; error_or() = default;
ErrorOr(const FixVoid<T> &value) : value_or_error{value} {} error_or(const fix_void<T> &value) : value_or_error{value} {}
ErrorOr(FixVoid<T> &&value) : value_or_error{std::move(value)} {} error_or(fix_void<T> &&value) : value_or_error{std::move(value)} {}
ErrorOr(const Error &error) : value_or_error{error} {} error_or(const error &error) : value_or_error{error} {}
ErrorOr(Error &&error) : value_or_error{std::move(error)} {} error_or(error &&error) : value_or_error{std::move(error)} {}
bool isValue() const { bool is_value() const {
return std::holds_alternative<FixVoid<T>>(value_or_error); return std::holds_alternative<fix_void<T>>(value_or_error);
} }
bool isError() const { bool is_error() const {
return std::holds_alternative<Error>(value_or_error); return std::holds_alternative<error>(value_or_error);
} }
Error &error() { return std::get<Error>(value_or_error); } class error &error() {
return std::get<error>(value_or_error);
}
const Error &error() const { return std::get<Error>(value_or_error); } const class error &error() const { return std::get<error>(value_or_error); }
FixVoid<T> &value() { return std::get<FixVoid<T>>(value_or_error); } fix_void<T> &value() { return std::get<fix_void<T>>(value_or_error); }
const FixVoid<T> &value() const { const fix_void<T> &value() const {
return std::get<FixVoid<T>>(value_or_error); return std::get<fix_void<T>>(value_or_error);
} }
}; };
template <typename T> class ErrorOr<ErrorOr<T>> { template <typename T> class error_or<error_or<T>> {
private: private:
ErrorOr() = delete; error_or() = delete;
}; };
} // namespace saw } // namespace saw