forked from andrewprock/ustl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuctrstrm.h
134 lines (120 loc) · 4.28 KB
/
uctrstrm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <[email protected]>
// This file is free software, distributed under the MIT License.
//
/// \file uctrstrm.h
///
/// \brief Serialization templates for standard containers.
/// Because containers are templates, a single operator>> is impossible.
/// Making virtual read/write is also impossible because not all containers
/// contain serializable elements. Therefore, use the macros in this file.
#pragma once
#include "mistream.h"
#include "sostream.h"
#include "typeinfo.h"
#include "uiosfunc.h"
namespace ustl {
//----------------------------------------------------------------------
// Fixed size container serialization.
//----------------------------------------------------------------------
/// Reads fixed size container \p v from stream \p is.
template <typename Container>
inline istream& nr_container_read (istream& is, Container& v)
{
foreach (typename Container::iterator, i, v)
is >> *i;
return is;
}
/// Writes fixed size container \p v into stream \p os.
template <typename Container>
inline ostream& nr_container_write (ostream& os, const Container& v)
{
foreach (typename Container::const_iterator, i, v)
os << *i;
return os;
}
/// Computes the stream size of a fixed size standard container.
template <typename Container>
inline size_t nr_container_stream_size (const Container& v)
{
typedef typename Container::const_iterator vciter_t;
if (!v.size())
return 0;
size_t s = 0, dvs;
vciter_t i = v.begin();
do {
dvs = stream_size_of(*i);
s += dvs;
} while (++i != v.end() && !__builtin_constant_p(dvs));
if (__builtin_constant_p(dvs))
s *= v.size();
return s;
}
//----------------------------------------------------------------------
// Resizable container serialization.
//----------------------------------------------------------------------
/// Reads container \p v from stream \p is.
template <typename Container>
istream& container_read (istream& is, Container& v)
{
typedef typename Container::value_type value_type;
typedef typename Container::written_size_type written_size_type;
written_size_type n = 0;
is >> n;
const size_t expectedSize = n * stream_size_of(value_type());
if (!is.verify_remaining ("read", typeid(v).name(), expectedSize))
return is;
if (stream_align_of(NullValue<value_type>()) > stream_align_of(n))
is >> ios::talign<value_type>();
v.resize (n);
nr_container_read (is, v);
is >> ios::talign<written_size_type>();
return is;
}
/// Writes the vector to stream \p os.
template <typename Container>
ostream& container_write (ostream& os, const Container& v)
{
typedef typename Container::value_type value_type;
typedef typename Container::written_size_type written_size_type;
const written_size_type sz (v.size());
os << sz;
if (stream_align_of(NullValue<value_type>()) > stream_align_of(sz))
os << ios::talign<value_type>();
nr_container_write (os, v);
os << ios::talign<written_size_type>();
return os;
}
/// Computes the stream size of a standard container.
template <typename Container>
size_t container_stream_size (const Container& v)
{
typedef typename Container::value_type value_type;
typedef typename Container::written_size_type written_size_type;
const written_size_type sz (v.size());
size_t sizeSize = stream_size_of (sz);
if (stream_align_of(NullValue<value_type>()) > stream_align_of(sz))
sizeSize = Align (sizeSize, stream_align_of(NullValue<value_type>()));
return Align (sizeSize + nr_container_stream_size (v), stream_align_of(sz));
}
/// \brief Writes element \p v into stream \p os as text.
/// Specialize to custom print elements.
template <typename T>
inline ostringstream& container_element_text_write (ostringstream& os, const T& v)
{ return os << v; }
/// Writes container \p v into stream \p os as text.
template <typename Container>
ostringstream& container_text_write (ostringstream& os, const Container& v)
{
os << '(';
for (typename Container::const_iterator i = v.begin(); i < v.end(); ++i) {
if (i != v.begin())
os << ',';
container_element_text_write (os, *i);
}
os << ')';
return os;
}
//----------------------------------------------------------------------
} // namespace ustl