19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is part of the ustl library, an STL implementation.
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is free software, distributed under the MIT License.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \file uctrstrm.h
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Serialization templates for standard containers.
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Because containers are templates, a single operator>> is impossible.
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Making virtual read/write is also impossible because not all containers
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// contain serializable elements. Therefore, use the macros in this file.
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "mistream.h"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sostream.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "uiosfunc.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace ustl {
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Macros for easily declaring a container streamable.
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Declares container template \p type streamable.
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Use TEMPLATE_TYPE and TEMPLATE_DECL macros to pass in templated
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// type with commas and the template declaration.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define STD_TEMPLATE_CTR_STREAMABLE(type, template_decl)	\
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline istream& operator>> (istream& is, type& v)		\
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (container_read (is, v)); } 			\
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline ostream& operator<< (ostream& os, const type& v)	\
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (container_write (os, v)); } 			\
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline ostringstream& operator<< (ostringstream& os, const type& v)	\
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (container_text_write (os, v)); }			\
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline size_t stream_size_of (const type& v)		\
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (container_stream_size (v)); }
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Declares non-resizable container template \p type streamable.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define STD_TEMPLATE_NR_CTR_STREAMABLE(type, template_decl)	\
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline istream& operator>> (istream& is, type& v)		\
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (nr_container_read (is, v)); } 			\
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline ostream& operator<< (ostream& os, const type& v)	\
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (nr_container_write (os, v)); } 			\
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline ostringstream& operator<< (ostringstream& os, const type& v)	\
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (container_text_write (os, v)); }			\
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    template_decl						\
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    inline size_t stream_size_of (const type& v)		\
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { return (nr_container_stream_size (v)); }
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Fixed size container serialization.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads fixed size container \p v from stream \p is.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline istream& nr_container_read (istream& is, Container& v)
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    foreach (typename Container::iterator, i, v)
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	is >> *i;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (is);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes fixed size container \p v into stream \p os.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ostream& nr_container_write (ostream& os, const Container& v)
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    foreach (typename Container::const_iterator, i, v)
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	os << *i;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (os);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Computes the stream size of a fixed size standard container.
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t nr_container_stream_size (const Container& v)
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::const_iterator vciter_t;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename iterator_traits<vciter_t>::value_type value_type;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t s = 0;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (numeric_limits<value_type>::is_integral)
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	s += v.size() * stream_size_of(value_type());
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	foreach (vciter_t, i, v)
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	    s += stream_size_of(*i);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (s);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Resizable container serialization.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads container \p v from stream \p is.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectistream& container_read (istream& is, Container& v)
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::value_type value_type;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::iterator iterator;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::written_size_type written_size_type;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    written_size_type n;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    is >> n;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t expectedSize = n * stream_size_of(value_type());
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !PLATFORM_ANDROID
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    is.verify_remaining ("read", typeid(v).name(), expectedSize);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (alignof(value_type()) > alignof(n))
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	is >> ios::talign<value_type>();
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    v.resize (n);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nr_container_read (is, v);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    is >> ios::talign<written_size_type>();
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (is);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes the vector to stream \p os.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectostream& container_write (ostream& os, const Container& v)
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::value_type value_type;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::written_size_type written_size_type;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const written_size_type sz (v.size());
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    os << sz;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (alignof(value_type()) > alignof(sz))
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	os << ios::talign<value_type>();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nr_container_write (os, v);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    os << ios::talign<written_size_type>();
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (os);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Computes the stream size of a standard container.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t container_stream_size (const Container& v)
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::value_type value_type;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typedef typename Container::written_size_type written_size_type;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const written_size_type sz (v.size());
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t sizeSize = stream_size_of (sz);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (alignof(value_type()) > alignof(sz))
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	sizeSize = Align (sizeSize, alignof(value_type()));
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (Align (sizeSize + nr_container_stream_size (v), alignof(sz)));
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Writes element \p v into stream \p os as text.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Specialize to custom print elements.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename T>
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ostringstream& container_element_text_write (ostringstream& os, const T& v)
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ return (os << v); }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes container \p v into stream \p os as text.
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container>
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectostringstream& container_text_write (ostringstream& os, const Container& v)
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    typename Container::const_iterator i = v.begin();
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    os << '(';
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (i < v.end()) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	container_element_text_write (os, *i);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	if (++i >= v.end()) break;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	os << ',';
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    os << ')';
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (os);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace ustl
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
178