1 // This file is part of the ustl library, an STL implementation.
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
8 /// \brief Serialization templates for standard containers.
9 /// Because containers are templates, a single operator>> is impossible.
10 /// Making virtual read/write is also impossible because not all containers
11 /// contain serializable elements. Therefore, use the macros in this file.
14 #ifndef UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC
15 #define UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC
24 //----------------------------------------------------------------------
25 // Macros for easily declaring a container streamable.
26 //----------------------------------------------------------------------
28 /// \brief Declares container template \p type streamable.
30 /// Use TEMPLATE_TYPE and TEMPLATE_DECL macros to pass in templated
31 /// type with commas and the template declaration.
33 #define STD_TEMPLATE_CTR_STREAMABLE(type, template_decl) \
35 inline istream& operator>> (istream& is, type& v) \
36 { return (container_read (is, v)); } \
38 inline ostream& operator<< (ostream& os, const type& v) \
39 { return (container_write (os, v)); } \
41 inline ostringstream& operator<< (ostringstream& os, const type& v) \
42 { return (container_text_write (os, v)); } \
44 struct object_stream_size<type > { \
45 inline size_t operator()(const type& v) const \
46 { return (container_stream_size (v)); } \
49 /// \brief Declares non-resizable container template \p type streamable.
50 #define STD_TEMPLATE_NR_CTR_STREAMABLE(type, template_decl) \
52 inline istream& operator>> (istream& is, type& v) \
53 { return (nr_container_read (is, v)); } \
55 inline ostream& operator<< (ostream& os, const type& v) \
56 { return (nr_container_write (os, v)); } \
58 inline ostringstream& operator<< (ostringstream& os, const type& v) \
59 { return (container_text_write (os, v)); } \
61 struct object_stream_size<type > { \
62 inline size_t operator()(const type& v) const \
63 { return (nr_container_stream_size (v)); } \
66 //----------------------------------------------------------------------
67 // Fixed size container serialization.
68 //----------------------------------------------------------------------
70 /// Reads fixed size container \p v from stream \p is.
71 template <typename Container
>
72 inline istream
& nr_container_read (istream
& is
, Container
& v
)
74 foreach (typename
Container::iterator
, i
, v
)
79 /// Writes fixed size container \p v into stream \p os.
80 template <typename Container
>
81 inline ostream
& nr_container_write (ostream
& os
, const Container
& v
)
83 foreach (typename
Container::const_iterator
, i
, v
)
88 /// Computes the stream size of a fixed size standard container.
89 template <typename Container
>
90 inline size_t nr_container_stream_size (const Container
& v
)
92 typedef typename
Container::const_iterator vciter_t
;
93 typedef typename iterator_traits
<vciter_t
>::value_type value_type
;
97 vciter_t i
= v
.begin();
99 dvs
= stream_size_of(*i
);
101 } while (++i
!= v
.end() && !__builtin_constant_p(dvs
));
102 if (__builtin_constant_p(dvs
))
107 //----------------------------------------------------------------------
108 // Resizable container serialization.
109 //----------------------------------------------------------------------
111 /// Reads container \p v from stream \p is.
112 template <typename Container
>
113 istream
& container_read (istream
& is
, Container
& v
)
115 typedef typename
Container::value_type value_type
;
116 typedef typename
Container::iterator iterator
;
117 typedef typename
Container::written_size_type written_size_type
;
120 const size_t expectedSize
= n
* stream_size_of(value_type());
121 is
.verify_remaining ("read", typeid(v
).name(), expectedSize
);
122 if (alignof(NullValue
<value_type
>()) > alignof(n
))
123 is
>> ios::talign
<value_type
>();
125 nr_container_read (is
, v
);
126 is
>> ios::talign
<written_size_type
>();
130 /// Writes the vector to stream \p os.
131 template <typename Container
>
132 ostream
& container_write (ostream
& os
, const Container
& v
)
134 typedef typename
Container::value_type value_type
;
135 typedef typename
Container::written_size_type written_size_type
;
136 const written_size_type
sz (v
.size());
138 if (alignof(NullValue
<value_type
>()) > alignof(sz
))
139 os
<< ios::talign
<value_type
>();
140 nr_container_write (os
, v
);
141 os
<< ios::talign
<written_size_type
>();
145 /// Computes the stream size of a standard container.
146 template <typename Container
>
147 size_t container_stream_size (const Container
& v
)
149 typedef typename
Container::value_type value_type
;
150 typedef typename
Container::written_size_type written_size_type
;
151 const written_size_type
sz (v
.size());
152 size_t sizeSize
= stream_size_of (sz
);
153 if (alignof(NullValue
<value_type
>()) > alignof(sz
))
154 sizeSize
= Align (sizeSize
, alignof(NullValue
<value_type
>()));
155 return (Align (sizeSize
+ nr_container_stream_size (v
), alignof(sz
)));
158 /// \brief Writes element \p v into stream \p os as text.
159 /// Specialize to custom print elements.
160 template <typename T
>
161 inline ostringstream
& container_element_text_write (ostringstream
& os
, const T
& v
)
162 { return (os
<< v
); }
164 /// Writes container \p v into stream \p os as text.
165 template <typename Container
>
166 ostringstream
& container_text_write (ostringstream
& os
, const Container
& v
)
168 typename
Container::const_iterator i
= v
.begin();
170 while (i
< v
.end()) {
171 container_element_text_write (os
, *i
);
172 os
<< ",)"[++i
== v
.end()];
177 //----------------------------------------------------------------------