From 5b1887367680c494e27794252fee8d1aacf088ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sun, 8 Jan 2023 13:20:26 +0100 Subject: Property lookup helpers --- include/erebos/merge.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/merge.cpp | 26 +++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 src/merge.cpp diff --git a/include/erebos/merge.h b/include/erebos/merge.h index bef8212..9705e94 100644 --- a/include/erebos/merge.h +++ b/include/erebos/merge.h @@ -2,9 +2,16 @@ #include +#include +#include + namespace erebos { +using std::nullopt; +using std::optional; +using std::vector; + template struct Mergeable { }; @@ -17,4 +24,50 @@ template<> struct Mergeable>> static vector> merge(const vector> & x) { return x; } }; +vector> findPropertyObjects(const vector> & leaves, const string & prop); + +template +optional::Component>> findPropertyComponent(const vector::Component>> & components, const string & prop) +{ + vector> leaves; + leaves.reserve(components.size()); + + for (const auto & c : components) + leaves.push_back(Stored::load(c.ref())); + + auto candidates = findPropertyObjects(leaves, prop); + if (!candidates.empty()) + return Stored::Component>::load(candidates[0].ref()); + return nullopt; +} + +template +optional::Component>> findPropertyComponent(const T & x, const string & prop) +{ + return findPropertyComponent(x.components(), prop); +} + +template +vector::Component>> findPropertyComponents(const vector::Component>> & components, const string & prop) +{ + vector> leaves; + leaves.reserve(components.size()); + + for (const auto & c : components) + leaves.push_back(Stored::load(c.ref())); + + auto candidates = findPropertyObjects(leaves, prop); + vector::Component>> result; + result.reserve(candidates.size()); + for (const auto & obj : candidates) + result.push_back(Stored::Component>::load(obj.ref())); + return result; +} + +template +vector::Component>> findPropertyComponents(const T & x, const string & prop) +{ + return findPropertyComponents(x.components(), prop); +} + } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72094b8..cb0db6d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(erebos contact.cpp frp.cpp identity.cpp + merge.cpp message.cpp network.cpp pairing.cpp diff --git a/src/merge.cpp b/src/merge.cpp new file mode 100644 index 0000000..040ebb4 --- /dev/null +++ b/src/merge.cpp @@ -0,0 +1,26 @@ +#include + +namespace erebos { + +static void findPropertyObjects(vector> & candidates, const Stored & obj, const string & prop) +{ + if (auto rec = obj->asRecord()) { + if (rec->item(prop)) { + candidates.push_back(obj); + } else { + for (const auto & r : obj.ref().previous()) + findPropertyObjects(candidates, Stored::load(r), prop); + } + } +} + +vector> findPropertyObjects(const vector> & leaves, const string & prop) +{ + vector> candidates; + for (const auto & obj : leaves) + findPropertyObjects(candidates, obj, prop); + filterAncestors(candidates); + return candidates; +} + +} -- cgit v1.2.3