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>
13{
14 static PolymorphicSaverRegistry oneInstance;
15 return oneInstance;
16}
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(Entry{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>
60{
61 static PolymorphicLoaderRegistry oneInstance;
62 return oneInstance;
63}
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 assert(v);
82 return (*v)(ar, id, args);
83}
84
87
89
90void polyInitError(const char* expected, const char* actual)
91{
92 throw MSXException("Expected type: ", expected, " but got: ", actual, '.');
93}
94
95template<typename Archive>
97{
98 static PolymorphicInitializerRegistry oneInstance;
99 return oneInstance;
100}
101
102template<typename Archive>
104 const char* name, InitFunction initializer)
105{
106 assert(!initializerMap.contains(name));
107 initializerMap.emplace_noDuplicateCheck(name, std::move(initializer));
108}
109
110template<typename Archive>
112 const char* tag, Archive& ar, void* t)
113{
114 ar.beginTag(tag);
115 unsigned id;
116 ar.attribute("id", id);
117 assert(id);
118 std::string type;
119 ar.attribute("type", type);
120
122 auto v = lookup(reg.initializerMap, type);
123 if (!v) {
124 throw MSXException("Deserialize unknown polymorphic type: '", type, "'.");
125 }
126 (*v)(ar, t, id);
127
128 ar.endTag(tag);
129}
130
133
134} // namespace openmsx
uintptr_t id
Definition: Interpreter.cc:27
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
void save(size_t width, std::span< const void * > rowPointers, const PixelFormat &format, const std::string &filename)
Definition: PNG.cc:379
This file implemented 3 utility functions:
Definition: Autofire.cc:9
void polyInitError(const char *expected, const char *actual)
constexpr void sort(RandomAccessRange &&range)
Definition: ranges.hh:49
auto * binary_find(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
Definition: ranges.hh:413
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition: stl.hh:23