summaryrefslogtreecommitdiff
path: root/lib/persistence.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/persistence.h')
-rw-r--r--lib/persistence.h65
1 files changed, 62 insertions, 3 deletions
diff --git a/lib/persistence.h b/lib/persistence.h
index c53ff99..3c95a00 100644
--- a/lib/persistence.h
+++ b/lib/persistence.h
@@ -81,11 +81,11 @@ namespace Persistence {
return make_s<SelectionT<T>>(value);
}
- template<typename S>
+ template<typename S, typename... Extra>
[[nodiscard]] static SelectionPtr
- make_s(T & value)
+ make_s(T & value, Extra &&... extra)
{
- return std::make_unique<S>(value);
+ return std::make_unique<S>(value, std::forward<Extra>(extra)...);
}
T & v;
@@ -331,6 +331,65 @@ namespace Persistence {
}
};
+ template<typename... T> struct SelectionT<std::tuple<T...>> : public SelectionV<std::tuple<T...>> {
+ using V = std::tuple<T...>;
+ using SelectionV<V>::SelectionV;
+
+ struct Members : public SelectionV<V> {
+ template<size_t... Idx>
+ explicit Members(V & v, std::integer_sequence<size_t, Idx...>) :
+ SelectionV<V> {v}, members {SelectionV<std::tuple_element_t<Idx, V>>::make(std::get<Idx>(v))...}
+ {
+ }
+
+ void
+ beforeValue(Stack & stk) override
+ {
+ stk.push(std::move(members[idx++]));
+ }
+
+ std::size_t idx {0};
+ std::array<SelectionPtr, std::tuple_size_v<V>> members;
+ };
+
+ void
+ beginArray(Stack & stk) override
+ {
+ stk.push(this->template make_s<Members>(
+ this->v, std::make_integer_sequence<size_t, std::tuple_size_v<V>>()));
+ }
+ };
+
+ template<typename T, typename U> struct SelectionT<std::pair<T, U>> : public SelectionV<std::pair<T, U>> {
+ using V = std::pair<T, U>;
+ using SelectionV<V>::SelectionV;
+
+ struct Members : public SelectionV<V> {
+ explicit Members(V & v) :
+ SelectionV<V> {v}, members {
+ SelectionV<T>::make(v.first),
+ SelectionV<U>::make(v.second),
+ }
+ {
+ }
+
+ void
+ beforeValue(Stack & stk) override
+ {
+ stk.push(std::move(members[idx++]));
+ }
+
+ std::size_t idx {0};
+ std::array<SelectionPtr, 2> members;
+ };
+
+ void
+ beginArray(Stack & stk) override
+ {
+ stk.push(this->template make_s<Members>(this->v));
+ }
+ };
+
template<typename Map, typename Type = typename Map::mapped_type, auto Key = &Type::element_type::id>
struct MapByMember : public Persistence::SelectionT<Type> {
MapByMember(Map & m) : Persistence::SelectionT<Type> {s}, map {m} { }