merge working. added some noexcept cases

This commit is contained in:
keldu.magnus 2021-10-05 16:40:24 +02:00
parent 23982922d4
commit 9f78b64731
4 changed files with 78 additions and 58 deletions

View File

@ -36,7 +36,7 @@ void ConveyorEventStorage::setParent(ConveyorStorage *p) {
if (/*!parent && */ p && !isArmed() && queued() > 0) {
assert(!parent);
if (p->space() > 0) {
armNext();
armLater();
}
}
@ -333,7 +333,7 @@ void ConvertConveyorNodeBase::getResult(ErrorOrValue &err_or_val) {
getImpl(err_or_val);
}
void AttachConveyorNodeBase::getResult(ErrorOrValue &err_or_val) {
void AttachConveyorNodeBase::getResult(ErrorOrValue &err_or_val) noexcept {
if (child) {
child->getResult(err_or_val);
}

View File

@ -574,23 +574,13 @@ public:
// Event
void fire() override;
// ConveyorNode
void getResult(ErrorOrValue &eov) override;
void getResult(ErrorOrValue &eov) noexcept override;
// ConveyorStorage
size_t space() const override { return max_store - storage.size(); }
size_t queued() const override { return storage.size(); }
void childHasFired() override {
if (child && storage.size() < max_store) {
ErrorOr<T> eov;
child->getResult(eov);
storage.push(std::move(eov));
if (!isArmed()) {
armLater();
}
}
}
size_t space() const override;
size_t queued() const override;
void childHasFired() override;
void parentHasFired() override;
};
@ -603,7 +593,7 @@ public:
virtual ~AttachConveyorNodeBase() = default;
void getResult(ErrorOrValue &err_or_val) override;
void getResult(ErrorOrValue &err_or_val) noexcept override;
};
template <typename... Args>
@ -856,8 +846,6 @@ public:
public:
void attach(Conveyor<T> conv);
void notifyNextAppendage();
void governingNodeDestroyed();
};

View File

@ -4,6 +4,9 @@
#include <cassert>
// Template inlining
#include <iostream>
namespace gin {
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) {
@ -86,7 +89,10 @@ std::pair<Conveyor<T>, MergeConveyor<T>> Conveyor<T>::merge() {
MergeConveyor<T> node_ref{data};
return std::make_pair(Conveyor<T>{std::move(merge_node), storage},
ConveyorStorage *merge_storage =
static_cast<ConveyorStorage *>(merge_node.get());
return std::make_pair(Conveyor<T>{std::move(merge_node), merge_storage},
std::move(node_ref));
}
@ -189,12 +195,38 @@ template <typename T> void QueueBufferConveyorNode<T>::fire() {
}
template <typename T>
void QueueBufferConveyorNode<T>::getResult(ErrorOrValue &eov) {
void QueueBufferConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept {
ErrorOr<T> &err_or_val = eov.as<T>();
err_or_val = std::move(storage.front());
storage.pop();
}
template <typename T> size_t QueueBufferConveyorNode<T>::space() const {
return max_store - storage.size();
}
template <typename T> size_t QueueBufferConveyorNode<T>::queued() const {
return storage.size();
}
template <typename T> void QueueBufferConveyorNode<T>::childHasFired() {
if (child && storage.size() < max_store) {
ErrorOr<T> eov;
child->getResult(eov);
if (eov.isError()) {
if (eov.error().isCritical()) {
child_storage = nullptr;
}
}
storage.push(std::move(eov));
if (!isArmed()) {
armLater();
}
}
}
template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() {
GIN_ASSERT(parent) { return; }
@ -238,6 +270,7 @@ template <typename T> void ImmediateConveyorNode<T>::parentHasFired() {
}
template <typename T> void ImmediateConveyorNode<T>::fire() {
if (parent) {
parent->childHasFired();
if (queued() > 0 && parent->space() > 0) {
@ -280,10 +313,23 @@ template <typename T> void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) {
next_appendage = std::min(appendages.size(), next_appendage);
for (size_t i = next_appendage; i < appendages.size(); ++i) {
if (appendages[i]->queued()) {
err_or_val = std::move(appendages
if (appendages[i]->queued() > 0) {
err_or_val = std::move(appendages[i]->error_or_value.value());
appendages[i]->error_or_value = std::nullopt;
next_appendage = i + 1;
return;
}
}
for (size_t i = 0; i < next_appendage; ++i) {
if (appendages[i]->queued() > 0) {
err_or_val = std::move(appendages[i]->error_or_value.value());
appendages[i]->error_or_value = std::nullopt;
next_appendage = i + 1;
return;
}
}
err_or_val = criticalError("No value in Merge Appendages");
}
template <typename T> void MergeConveyorNode<T>::fire() {
@ -291,21 +337,25 @@ template <typename T> void MergeConveyorNode<T>::fire() {
if (parent) {
parent->childHasFired();
}
if (queued() > 0 && parent->space() > 0) {
armLater();
} else {
/// @unimplemented search for arm which has remaining elements
if (queued() > 0 && parent->space() > 0) {
armLater();
}
}
}
template <typename T> size_t MergeConveyorNode<T>::space() const {
return error_or_value.has_value() ? 0 : 1;
}
template <typename T> size_t MergeConveyorNode<T>::space() const { return 0; }
template <typename T> size_t MergeConveyorNode<T>::queued() const {
return error_or_value.has_value() ? 1 : 0;
GIN_ASSERT(data) { return 0; }
size_t queue_count = 0;
for (auto &iter : data->appendages) {
queue_count += iter->queued();
}
return queue_count;
}
template <typename T> void MergeConveyorNode<T>::childHasFired() {
@ -344,14 +394,14 @@ template <typename T> size_t MergeConveyorNode<T>::Appendage::queued() const {
template <typename T>
void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) {
ErrorOr<FixVoid<T>> &eov = eov.as<FixVoid<T>>();
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>();
GIN_ASSERT(queued() > 0) {
eov = criticalError("No element queued in Merge Appendage Node");
err_or_val = criticalError("No element queued in Merge Appendage Node");
return;
}
eov = std::move(error_or_value.value());
err_or_val = std::move(error_or_value.value());
error_or_value = std::nullopt;
}
@ -396,26 +446,6 @@ void MergeConveyorNodeData<T>::attach(Conveyor<T> conveyor) {
appendages.push_back(std::move(merge_node_appendage));
}
template <typename T> void MergeConveyorNodeData<T>::notifyNextAppendage() {
next_appendage = std::min(next_appendage, appendages.size());
for (size_t i = next_appendage; i < appendages.size(); ++i) {
if (appendages[i]->childStorageHasElementQueued()) {
appendages[i]->parentHasFired();
next_appendage = i + 1;
return;
}
}
for (size_t i = 0; i < next_appendage; ++i) {
if (appendages[i]->childStorageHasElementQueued()) {
appendages[i]->parentHasFired();
next_appendage = i + 1;
return;
}
}
}
template <typename T> void MergeConveyorNodeData<T>::governingNodeDestroyed() {
appendages.clear();
merger = nullptr;

View File

@ -209,11 +209,13 @@ GIN_TEST("Async Merge"){
cam.second.attach(Conveyor<int>{11});
cam.second.attach(Conveyor<int>{14});
size_t elements_passed = 0;
bool wrong_value = false;
auto sink = cam.first.then([&elements_passed, &wrong_value](int foo){
if(foo == 10 || foo == 11){
if(foo == 10 || foo == 11 || 14){
++elements_passed;
}else{
wrong_value = true;
@ -222,7 +224,7 @@ GIN_TEST("Async Merge"){
wait_scope.poll();
GIN_EXPECT(!wrong_value, "Expected values 10 or 11");
GIN_EXPECT(elements_passed == 2, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
GIN_EXPECT(!wrong_value, std::string{"Expected values 10 or 11"});
GIN_EXPECT(elements_passed == 3, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
}
}