From d563500c915de2f0a652513af03f101c99715db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sun, 9 May 2021 15:20:30 +0200 Subject: SharedType: type trait instead of member functions and typedef --- include/erebos/identity.h | 8 ++++++-- include/erebos/state.h | 50 +++++++++++++++++++++++++++++++---------------- src/identity.cpp | 20 ++++++++++++++++++- src/state.h | 1 + src/sync.cpp | 1 + 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/include/erebos/identity.h b/include/erebos/identity.h index f7b17b8..d0b60d5 100644 --- a/include/erebos/identity.h +++ b/include/erebos/identity.h @@ -1,9 +1,12 @@ #pragma once +#include #include namespace erebos { +using std::optional; + class Identity { public: @@ -14,6 +17,7 @@ public: static std::optional load(const Ref &); static std::optional load(const std::vector &); + std::vector store() const; std::vector store(const Storage & st) const; std::optional name() const; @@ -47,8 +51,6 @@ public: static Builder create(const Storage &); Builder modify() const; - static const UUID sharedTypeId; - private: struct Priv; std::shared_ptr p; @@ -56,4 +58,6 @@ private: Identity(std::shared_ptr && p); }; +DECLARE_SHARED_TYPE(optional) + } diff --git a/include/erebos/state.h b/include/erebos/state.h index cfa9532..16be464 100644 --- a/include/erebos/state.h +++ b/include/erebos/state.h @@ -1,9 +1,11 @@ #pragma once -#include +#include #include +#include #include +#include namespace erebos { @@ -11,6 +13,26 @@ using std::optional; using std::shared_ptr; using std::vector; +template +struct SharedType +{ + static const UUID id; + static T(*const load)(const vector &); + static vector(*const store)(const T &); +}; + +#define DECLARE_SHARED_TYPE(T) \ + template<> const UUID erebos::SharedType::id; \ + template<> T(*const erebos::SharedType::load)(const std::vector &); \ + template<> std::vector(*const erebos::SharedType::store) (const T &); + +#define DEFINE_SHARED_TYPE(T, id_, load_, store_) \ + template<> const UUID erebos::SharedType::id { id_ }; \ + template<> T(*const erebos::SharedType::load)(const vector &) { load_ }; \ + template<> std::vector(*const erebos::SharedType::store) (const T &) { store_ }; + +class Identity; + class LocalState { public: @@ -24,11 +46,8 @@ public: const optional & identity() const; LocalState identity(const Identity &) const; - template optional shared() const; - template LocalState shared(const vector> &) const; - template LocalState shared(const Stored & x) const { return shared({ x }); }; - template LocalState shared(const Storage & st, const T & x) - { return updateShared(T::sharedTypeId, x.store(st)); } + template T shared() const; + template LocalState shared(const T & x) const; vector sharedRefs() const; LocalState sharedRefAdd(const Ref &) const; @@ -46,7 +65,7 @@ private: class SharedState { public: - template optional get() const; + template T get() const; template static T lens(const SharedState &); bool operator==(const SharedState &) const; @@ -62,30 +81,27 @@ private: }; template -optional LocalState::shared() const +T LocalState::shared() const { - return T::load(lookupShared(T::sharedTypeId)); + return SharedType::load(lookupShared(SharedType::id)); } template -LocalState LocalState::shared(const vector> & v) const +LocalState LocalState::shared(const T & x) const { - vector refs; - for (const auto & x : v) - refs.push_back(x.ref()); - return updateShared(T::sharedTypeId, refs); + return updateShared(SharedType::id, SharedType::store(x)); } template -optional SharedState::get() const +T SharedState::get() const { - return T::load(lookup(T::sharedTypeId)); + return SharedType::load(lookup(SharedType::id)); } template T SharedState::lens(const SharedState & x) { - return T::value_type::load(x.lookup(T::value_type::sharedTypeId)); + return x.get(); } } diff --git a/src/identity.cpp b/src/identity.cpp index a4c12f2..f55f6dd 100644 --- a/src/identity.cpp +++ b/src/identity.cpp @@ -1,5 +1,7 @@ #include "identity.h" +#include + #include #include #include @@ -11,7 +13,14 @@ using std::nullopt; using std::runtime_error; using std::set; -const UUID Identity::sharedTypeId { "0c6c1fe0-f2d7-4891-926b-c332449f7871" }; +DEFINE_SHARED_TYPE(optional, + "0c6c1fe0-f2d7-4891-926b-c332449f7871", + &Identity::load, + [](const optional & id) { + if (id) + return id->store(); + return vector(); + }) Identity::Identity(const Priv * p): p(p) {} Identity::Identity(shared_ptr && p): p(std::move(p)) {} @@ -34,6 +43,15 @@ optional Identity::load(const vector & refs) return nullopt; } +vector Identity::store() const +{ + vector res; + res.reserve(p->data.size()); + for (const auto & x : p->data) + res.push_back(x.ref()); + return res; +} + vector Identity::store(const Storage & st) const { vector res; diff --git a/src/state.h b/src/state.h index 91dea94..397a906 100644 --- a/src/state.h +++ b/src/state.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "pubkey.h" diff --git a/src/sync.cpp b/src/sync.cpp index cf423ac..85fed96 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,5 +1,6 @@ #include +#include #include using namespace erebos; -- cgit v1.2.3