openMSX
serialize_meta.cc
Go to the documentation of this file.
1#include "serialize_meta.hh"
2#include "serialize.hh"
3#include "MSXException.hh"
4#include "ranges.hh"
5#include "stl.hh"
6#include <cassert>
7#include <iostream>
8
9namespace openmsx {
10
11template<typename Archive>
17
18template<typename Archive>
20 const std::type_info& type, SaveFunction saver)
21{
22 assert(!initialized);
23 assert(!contains(saverMap, type, &Entry::index)); // not yet sorted
24 saverMap.emplace_back(type, std::move(saver));
25}
26
27template<typename Archive>
29 Archive& ar, const void* t, const std::type_info& typeInfo)
30{
32 if (!reg.initialized) [[unlikely]] {
33 reg.initialized = true;
34 ranges::sort(reg.saverMap, {}, &Entry::index);
35 }
36 auto s = binary_find(reg.saverMap, std::type_index(typeInfo), {}, &Entry::index);
37 if (!s) {
38 std::cerr << "Trying to save an unregistered polymorphic type: "
39 << typeInfo.name() << '\n';
40 assert(false); return;
41 }
42 s->saver(ar, t);
43}
44template<typename Archive>
46 const char* tag, Archive& ar, const void* t, const std::type_info& typeInfo)
47{
48 ar.beginTag(tag);
49 save(ar, t, typeInfo);
50 ar.endTag(tag);
51}
52
53template class PolymorphicSaverRegistry<MemOutputArchive>;
54template class PolymorphicSaverRegistry<XmlOutputArchive>;
55
57
58template<typename Archive>
64
65template<typename Archive>
67 const char* name, LoadFunction loader)
68{
69 assert(!loaderMap.contains(name));
70 loaderMap.emplace_noDuplicateCheck(name, std::move(loader));
71}
72
73template<typename Archive>
75 Archive& ar, unsigned id, const void* args)
76{
77 std::string type;
78 ar.attribute("type", type);
80 auto* v = lookup(reg.loaderMap, type);
81 if (!v) {
82 throw MSXException("Deserialize unknown polymorphic type: '", type, "'.");
83 }
84 return (*v)(ar, id, args);
85}
86
89
91
92void polyInitError(const char* expected, const char* actual)
93{
94 throw MSXException("Expected type: ", expected, " but got: ", actual, '.');
95}
96
97template<typename Archive>
103
104template<typename Archive>
106 const char* name, InitFunction initializer)
107{
108 assert(!initializerMap.contains(name));
109 initializerMap.emplace_noDuplicateCheck(name, std::move(initializer));
110}
111
112template<typename Archive>
114 const char* tag, Archive& ar, void* t)
115{
116 ar.beginTag(tag);
117 unsigned id;
118 ar.attribute("id", id);
119 assert(id);
120 std::string type;
121 ar.attribute("type", type);
122
124 auto v = lookup(reg.initializerMap, type);
125 if (!v) {
126 throw MSXException("Deserialize unknown polymorphic type: '", type, "'.");
127 }
128 (*v)(ar, t, id);
129
130 ar.endTag(tag);
131}
132
135
136} // namespace openmsx
uintptr_t id
TclObject t
static void init(const char *tag, Archive &ar, void *t)
static PolymorphicInitializerRegistry & instance()
static PolymorphicLoaderRegistry & instance()
static void * load(Archive &ar, unsigned id, const void *args)
static PolymorphicSaverRegistry & instance()
static void save(Archive &ar, T *t)
const Value * lookup(const hash_map< Key, Value, Hasher, Equal > &map, const Key2 &key)
Definition hash_map.hh:118
This file implemented 3 utility functions:
Definition Autofire.cc:11
void polyInitError(const char *expected, const char *actual)
constexpr void sort(RandomAccessRange &&range)
Definition ranges.hh:51
auto * binary_find(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
Definition ranges.hh:448
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition stl.hh:32