Skip to content

Commit 9227c53

Browse files
committed
split SerializationOps
1 parent 37ab1c3 commit 9227c53

10 files changed

+535
-293
lines changed

include/gf2/core/Array2D.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "Range.h"
1111
#include "Vec2.h"
12+
#include "gf2/core/Serialization.h"
1213

1314
namespace gf {
1415

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-License-Identifier: Zlib
2+
// Copyright (c) 2023-2025 Julien Bernard
3+
#ifndef GF_SERIALIZATION_ADAPTER_H
4+
#define GF_SERIALIZATION_ADAPTER_H
5+
6+
#include <queue>
7+
8+
#include "Serialization.h"
9+
10+
namespace gf {
11+
12+
/*
13+
* Supported types:
14+
* - std::priority_queue
15+
* - std::queue
16+
*/
17+
18+
namespace details {
19+
20+
template<typename Adapter>
21+
decltype(auto) underlying_container(Adapter& adapter)
22+
{
23+
struct Hack : Adapter {
24+
static decltype(auto) get(Adapter& adapter)
25+
{
26+
return adapter.*&Hack::c;
27+
}
28+
};
29+
30+
return Hack::get(adapter);
31+
}
32+
33+
}
34+
35+
/*
36+
* Serializer
37+
*/
38+
39+
template<typename T>
40+
inline Serializer& operator|(Serializer& ar, const std::queue<T>& queue)
41+
{
42+
return ar | details::underlying_container(queue);
43+
}
44+
45+
template<typename T>
46+
inline Serializer& operator|(Serializer& ar, const std::priority_queue<T>& queue)
47+
{
48+
return ar | details::underlying_container(queue);
49+
}
50+
51+
/*
52+
* Deserializer
53+
*/
54+
55+
template<typename T>
56+
inline Deserializer& operator|(Deserializer& ar, std::queue<T>& queue)
57+
{
58+
details::underlying_container(queue).clear();
59+
return ar | details::underlying_container(queue);
60+
}
61+
62+
template<typename T>
63+
inline Deserializer& operator|(Deserializer& ar, std::priority_queue<T>& queue)
64+
{
65+
details::underlying_container(queue).clear();
66+
return ar | details::underlying_container(queue);
67+
}
68+
69+
}
70+
71+
#endif // GF_SERIALIZATION_ADAPTER_H
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// SPDX-License-Identifier: Zlib
2+
// Copyright (c) 2023-2025 Julien Bernard
3+
#ifndef GF_SERIALIZATION_CONTAINER_H
4+
#define GF_SERIALIZATION_CONTAINER_H
5+
6+
#include <array>
7+
#include <deque>
8+
#include <map>
9+
#include <set>
10+
#include <unordered_map>
11+
#include <unordered_set>
12+
#include <vector>
13+
14+
#include "Serialization.h"
15+
16+
namespace gf {
17+
18+
/*
19+
* Supported types:
20+
* - std::array
21+
* - std::deque
22+
* - std::map
23+
* - std::set
24+
* - std::unordered_map
25+
* - std::unordered_set
26+
* - std::vector
27+
*/
28+
29+
/*
30+
* Serializer
31+
*/
32+
33+
namespace details {
34+
35+
template<typename Iterator>
36+
Serializer& write_container(Serializer& ar, Iterator iterator, std::size_t size)
37+
{
38+
ar.write_raw_size(size);
39+
40+
for (std::size_t i = 0; i < size; ++i) {
41+
ar | *iterator++;
42+
}
43+
44+
return ar;
45+
}
46+
47+
}
48+
49+
template<typename T, std::size_t N>
50+
inline Serializer& operator|(Serializer& ar, const T (&array)[N])
51+
{
52+
return details::write_container(ar, std::begin(array), std::size(array));
53+
}
54+
55+
template<typename T>
56+
inline Serializer& operator|(Serializer& ar, const std::vector<T>& array)
57+
{
58+
return details::write_container(ar, array.begin(), array.size());
59+
}
60+
61+
template<typename T, std::size_t N>
62+
inline Serializer& operator|(Serializer& ar, const std::array<T, N>& array)
63+
{
64+
return details::write_container(ar, array.begin(), array.size());
65+
}
66+
67+
template<typename T>
68+
inline Serializer& operator|(Serializer& ar, const std::deque<T>& deque)
69+
{
70+
return details::write_container(ar, deque.begin(), deque.size());
71+
}
72+
73+
template<typename T>
74+
inline Serializer& operator|(Serializer& ar, const std::set<T>& set)
75+
{
76+
return details::write_container(ar, set.begin(), set.size());
77+
}
78+
79+
template<typename T>
80+
inline Serializer& operator|(Serializer& ar, const std::unordered_set<T>& set)
81+
{
82+
return details::write_container(ar, set.begin(), set.size());
83+
}
84+
85+
template<typename K, typename V, typename C>
86+
inline Serializer& operator|(Serializer& ar, const std::map<K, V, C>& map)
87+
{
88+
return details::write_container(ar, map.begin(), map.size());
89+
}
90+
91+
template<typename K, typename V>
92+
inline Serializer& operator|(Serializer& ar, const std::unordered_map<K, V>& map)
93+
{
94+
return details::write_container(ar, map.begin(), map.size());
95+
}
96+
97+
/*
98+
* Deserializer
99+
*/
100+
101+
namespace details {
102+
103+
template<typename Container>
104+
class EmplaceIterator {
105+
public:
106+
using iterator_category = std::output_iterator_tag;
107+
using value_type = void;
108+
using difference_type = void;
109+
using pointer = void;
110+
using reference = void;
111+
using container_type = Container;
112+
113+
explicit EmplaceIterator(Container& container)
114+
: m_container(std::addressof(container))
115+
{
116+
}
117+
118+
template<typename T>
119+
EmplaceIterator& operator=(T&& value)
120+
{
121+
m_container->emplace(std::forward<T>(value));
122+
return *this;
123+
}
124+
125+
EmplaceIterator& operator*() { return *this; }
126+
EmplaceIterator& operator++() { return *this; }
127+
EmplaceIterator operator++(int) { return *this; }
128+
129+
private:
130+
Container* m_container;
131+
};
132+
133+
template<typename Container>
134+
EmplaceIterator<Container> emplacer(Container& container)
135+
{
136+
return EmplaceIterator<Container>(container);
137+
}
138+
139+
template<typename T, typename Iterator>
140+
Deserializer& read_container(Deserializer& ar, Iterator iterator, std::size_t expected_size = 0)
141+
{
142+
std::size_t size = 0;
143+
ar.read_raw_size(&size);
144+
145+
if (expected_size > 0 && size != expected_size) {
146+
return ar;
147+
}
148+
149+
for (std::size_t i = 0; i < size; ++i) {
150+
T item;
151+
ar | item;
152+
*iterator++ = std::move(item);
153+
}
154+
155+
return ar;
156+
}
157+
158+
}
159+
160+
template<typename T>
161+
inline Deserializer& operator|(Deserializer& ar, Span<T> array)
162+
{
163+
return details::read_container<T>(ar, array.begin(), array.size());
164+
}
165+
166+
template<typename T, std::size_t N>
167+
inline Deserializer& operator|(Deserializer& ar, T (&array)[N])
168+
{
169+
return details::read_container<T>(ar, std::begin(array), std::size(array));
170+
}
171+
172+
template<typename T>
173+
inline Deserializer& operator|(Deserializer& ar, std::vector<T>& array)
174+
{
175+
array.clear();
176+
return details::read_container<T>(ar, std::back_inserter(array));
177+
}
178+
179+
template<typename T, std::size_t N>
180+
inline Deserializer& operator|(Deserializer& ar, std::array<T, N>& array)
181+
{
182+
return details::read_container<T>(ar, array.begin(), array.size());
183+
}
184+
185+
template<typename T>
186+
inline Deserializer& operator|(Deserializer& ar, std::deque<T>& deque)
187+
{
188+
deque.clear();
189+
return details::read_container<T>(ar, std::back_inserter(deque));
190+
}
191+
192+
template<typename T>
193+
inline Deserializer& operator|(Deserializer& ar, std::set<T>& set)
194+
{
195+
set.clear();
196+
return details::read_container<T>(ar, details::emplacer(set));
197+
}
198+
199+
template<typename T>
200+
inline Deserializer& operator|(Deserializer& ar, std::unordered_set<T>& set)
201+
{
202+
set.clear();
203+
return details::read_container<T>(ar, details::emplacer(set));
204+
}
205+
206+
template<typename K, typename V, typename C>
207+
inline Deserializer& operator|(Deserializer& ar, std::map<K, V, C>& map)
208+
{
209+
map.clear();
210+
return details::read_container<std::pair<K, V>>(ar, details::emplacer(map));
211+
}
212+
213+
template<typename K, typename V>
214+
inline Deserializer& operator|(Deserializer& ar, std::unordered_map<K, V>& map)
215+
{
216+
map.clear();
217+
return details::read_container<std::pair<K, V>>(ar, details::emplacer(map));
218+
}
219+
220+
}
221+
222+
#endif // GF_SERIALIZATION_CONTAINER_H

0 commit comments

Comments
 (0)