summaryrefslogtreecommitdiff
path: root/lib/persistence.h
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2021-05-01 18:29:26 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2021-11-07 16:41:37 +0000
commit9923219ce7e1f791b079ecaf21cb20d0938f8d6a (patch)
treeb1bacec57623c81f19d361a23a4d6287b802199c /lib/persistence.h
parentLots of test cases, few minor fixes (diff)
downloadilt-9923219ce7e1f791b079ecaf21cb20d0938f8d6a.tar.bz2
ilt-9923219ce7e1f791b079ecaf21cb20d0938f8d6a.tar.xz
ilt-9923219ce7e1f791b079ecaf21cb20d0938f8d6a.zip
Common implementation for shared and unique pointers
Diffstat (limited to 'lib/persistence.h')
-rw-r--r--lib/persistence.h173
1 files changed, 55 insertions, 118 deletions
diff --git a/lib/persistence.h b/lib/persistence.h
index ed21ec8..5ef1400 100644
--- a/lib/persistence.h
+++ b/lib/persistence.h
@@ -179,93 +179,12 @@ namespace Persistence {
return true;
}
- template<typename T> struct SelectionT<std::unique_ptr<T>> : public SelectionV<std::unique_ptr<T>> {
- using Ptr = std::unique_ptr<T>;
- struct SelectionObj : public SelectionV<Ptr> {
- struct MakeObjectByTypeName : public SelectionV<Ptr> {
- using SelectionV<Ptr>::SelectionV;
-
- void
- setValue(std::string & type) override
- {
- auto no = Persistable::callFactory(type);
- if (dynamic_cast<T *>(no.get())) {
- this->v.reset(static_cast<T *>(no.release()));
- }
- }
- };
-
- using SelectionV<Ptr>::SelectionV;
-
- SelectionPtr
- select(const std::string & mbr) override
- {
- using namespace std::literals;
- if (mbr == "@typeid"sv) {
- if (this->v) {
- throw std::runtime_error("cannot set object type after creation");
- }
- return this->template make_s<MakeObjectByTypeName>(this->v);
- }
- else {
- if (!this->v) {
- if constexpr (std::is_abstract_v<T>) {
- throw std::runtime_error("cannot select member of null object");
- }
- else {
- this->v = std::make_unique<T>();
- }
- }
- PersistenceStore ps {mbr};
- if (this->v->persist(ps)) {
- throw std::runtime_error("cannot find member: " + mbr);
- }
- return std::move(ps.sel);
- }
- }
-
- void
- endObject(Stack & stk) override
- {
- if (!this->v) {
- if constexpr (std::is_abstract_v<T>) {
- throw std::runtime_error("cannot default create abstract object");
- }
- else {
- this->v = std::make_unique<T>();
- }
- }
- stk.pop();
- }
- };
-
- using SelectionV<Ptr>::SelectionV;
-
- void
- setValue(const std::nullptr_t &) override
- {
- this->v.reset();
- }
-
- void
- beginObject(Stack & stk) override
- {
- stk.push(this->template make_s<SelectionObj>(this->v));
- }
-
- void
- endObject(Stack & stk) override
- {
- stk.pop();
- }
- };
-
// TODO Move this
using SharedObjects = std::map<std::string, std::shared_ptr<Persistable>>;
inline SharedObjects sharedObjects;
- template<typename T> struct SelectionT<std::shared_ptr<T>> : public SelectionV<std::shared_ptr<T>> {
- using Ptr = std::shared_ptr<T>;
+ template<typename Ptr, bool shared> struct SelectionPtrBase : public SelectionV<Ptr> {
+ using T = typename Ptr::element_type;
struct SelectionObj : public SelectionV<Ptr> {
struct MakeObjectByTypeName : public SelectionV<Ptr> {
using SelectionV<Ptr>::SelectionV;
@@ -273,9 +192,17 @@ namespace Persistence {
void
setValue(std::string & type) override
{
- auto no = Persistable::callSharedFactory(type);
- if (auto tno = std::dynamic_pointer_cast<T>(no)) {
- this->v = std::move(tno);
+ if constexpr (shared) {
+ auto no = Persistable::callSharedFactory(type);
+ if (auto tno = std::dynamic_pointer_cast<T>(no)) {
+ this->v = std::move(tno);
+ }
+ }
+ else {
+ auto no = Persistable::callFactory(type);
+ if (dynamic_cast<T *>(no.get())) {
+ this->v.reset(static_cast<T *>(no.release()));
+ }
}
}
};
@@ -302,41 +229,43 @@ namespace Persistence {
}
return this->template make_s<MakeObjectByTypeName>(this->v);
}
- else if (mbr == "@id"sv) {
- return this->template make_s<RememberObjectById>(this->v);
- }
- else {
- if (!this->v) {
- if constexpr (std::is_abstract_v<T>) {
- throw std::runtime_error("cannot select member of null object");
- }
- else {
- this->v = std::make_shared<T>();
- }
- }
- PersistenceStore ps {mbr};
- if (this->v->persist(ps)) {
- throw std::runtime_error("cannot find member: " + mbr);
+ if constexpr (shared) {
+ if (mbr == "@id"sv) {
+ return this->template make_s<RememberObjectById>(this->v);
}
- return std::move(ps.sel);
}
+ make_default_as_needed(this->v);
+ PersistenceStore ps {mbr};
+ if (this->v->persist(ps)) {
+ throw std::runtime_error("cannot find member: " + mbr);
+ }
+ return std::move(ps.sel);
}
void
endObject(Stack & stk) override
{
- if (!this->v) {
- if constexpr (std::is_abstract_v<T>) {
- throw std::runtime_error("cannot default create abstract object");
- }
- else {
- this->v = std::make_shared<T>();
- }
- }
+ make_default_as_needed(this->v);
stk.pop();
}
};
+ static inline void
+ make_default_as_needed(Ptr & v)
+ {
+ if (!v) {
+ if constexpr (std::is_abstract_v<T>) {
+ throw std::runtime_error("cannot select member of null abstract object");
+ }
+ else if constexpr (shared) {
+ v = std::make_shared<T>();
+ }
+ else {
+ v = std::make_unique<T>();
+ }
+ }
+ }
+
using SelectionV<Ptr>::SelectionV;
void
@@ -346,14 +275,6 @@ namespace Persistence {
}
void
- setValue(std::string & id) override
- {
- if (auto teo = std::dynamic_pointer_cast<T>(sharedObjects.at(id))) {
- this->v = std::move(teo);
- }
- }
-
- void
beginObject(Stack & stk) override
{
stk.push(this->template make_s<SelectionObj>(this->v));
@@ -365,6 +286,22 @@ namespace Persistence {
stk.pop();
}
};
+
+ template<typename T> struct SelectionT<std::unique_ptr<T>> : public SelectionPtrBase<std::unique_ptr<T>, false> {
+ using SelectionPtrBase<std::unique_ptr<T>, false>::SelectionPtrBase;
+ };
+
+ template<typename T> struct SelectionT<std::shared_ptr<T>> : public SelectionPtrBase<std::shared_ptr<T>, true> {
+ using SelectionPtrBase<std::shared_ptr<T>, true>::SelectionPtrBase;
+
+ void
+ setValue(std::string & id) override
+ {
+ if (auto teo = std::dynamic_pointer_cast<T>(sharedObjects.at(id))) {
+ this->v = std::move(teo);
+ }
+ }
+ };
}
#define STORE_TYPE store.persistType<std::decay_t<decltype(*this)>>()