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.
9 #ifndef SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F
10 #define SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F
19 /// \class ostringstream sostream.h ustl.h
20 /// \ingroup TextStreams
22 /// \brief This stream writes textual data into a memory block.
24 class ostringstream
: public ostream
{
26 ostringstream (const string
& v
= string::empty_string
);
27 ostringstream (void* p
, size_t n
);
28 void iwrite (uint8_t v
);
29 void iwrite (wchar_t v
);
30 inline void iwrite (int v
) { iformat (v
); }
31 inline void iwrite (unsigned int v
) { iformat (v
); }
32 inline void iwrite (long int v
) { iformat (v
); }
33 inline void iwrite (unsigned long int v
) { iformat (v
); }
34 inline void iwrite (float v
) { iformat (v
); }
35 inline void iwrite (double v
) { iformat (v
); }
37 inline void iwrite (const char* s
) { write_buffer (s
, strlen(s
)); }
38 inline void iwrite (const string
& v
) { write_buffer (v
.begin(), v
.size()); }
39 inline void iwrite (fmtflags f
);
41 inline void iwrite (long long v
) { iformat (v
); }
42 inline void iwrite (unsigned long long v
) { iformat (v
); }
44 inline size_type
max_size (void) const { return (m_Buffer
.max_size()); }
45 inline void put (char c
) { iwrite (uint8_t(c
)); }
46 int vformat (const char* fmt
, va_list args
);
47 int format (const char* fmt
, ...) __attribute__((__format__(__printf__
, 2, 3)));
48 inline void set_base (uint16_t b
) { m_Base
= b
; }
49 inline void set_width (uint16_t w
) { m_Width
= w
; }
50 inline void set_decimal_separator (char) { }
51 inline void set_thousand_separator (char) { }
52 inline void set_precision (uint16_t v
) { m_Precision
= v
; }
53 void link (void* p
, size_type n
);
54 inline void link (memlink
& l
) { link (l
.data(), l
.writable_size()); }
55 inline const string
& str (void) { flush(); return (m_Buffer
); }
56 void str (const string
& s
);
57 void write (const void* buffer
, size_type size
);
58 void write (const cmemlink
& buf
);
59 inline void write_strz (const char*) { assert (!"Writing nul characters into a text stream is not allowed"); }
61 virtual size_type
overflow (size_type n
= 1);
63 void write_buffer (const char* buf
, size_type bufSize
);
64 inline void reserve (size_type n
) { m_Buffer
.reserve (n
, false); }
65 inline size_type
capacity (void) const { return (m_Buffer
.capacity()); }
67 inline char* encode_dec (char* fmt
, uint32_t n
) const;
68 void fmtstring (char* fmt
, const char* typestr
, bool bInteger
) const;
72 string m_Buffer
; ///< The output buffer.
73 uint32_t m_Flags
; ///< See ios_base::fmtflags.
74 uint16_t m_Width
; ///< Field width.
75 uint8_t m_Base
; ///< Numeric base for writing numbers.
76 uint8_t m_Precision
; ///< Number of digits after the decimal separator.
79 //----------------------------------------------------------------------
82 inline const char* printf_typestring (const T
&) { return (""); }
83 #define PRINTF_TYPESTRING_SPEC(type,str) \
84 template <> inline const char* printf_typestring (const type&) { return (str); }
85 PRINTF_TYPESTRING_SPEC (int, "d")
86 PRINTF_TYPESTRING_SPEC (unsigned int, "u")
87 PRINTF_TYPESTRING_SPEC (long, "ld")
88 PRINTF_TYPESTRING_SPEC (unsigned long, "lu")
89 PRINTF_TYPESTRING_SPEC (float, "f")
90 PRINTF_TYPESTRING_SPEC (double, "lf")
92 PRINTF_TYPESTRING_SPEC (long long, "lld")
93 PRINTF_TYPESTRING_SPEC (unsigned long long, "llu")
95 #undef PRINTF_TYPESTRING_SPEC
98 void ostringstream::iformat (T v
)
101 fmtstring (fmt
, printf_typestring(v
), numeric_limits
<T
>::is_integer
);
105 /// Sets the flag \p f in the stream.
106 inline void ostringstream::iwrite (fmtflags f
)
109 case oct
: set_base (8); break;
110 case dec
: set_base (10); break;
111 case hex
: set_base (16); break;
112 case left
: m_Flags
|= left
; m_Flags
&= ~right
; break;
113 case right
: m_Flags
|= right
; m_Flags
&= ~left
; break;
114 default: m_Flags
|= f
; break;
118 //----------------------------------------------------------------------
120 template <typename T
> struct object_text_writer
{
121 inline void operator()(ostringstream
& os
, const T
& v
) const { v
.text_write (os
); }
123 template <typename T
> struct integral_text_object_writer
{
124 inline void operator()(ostringstream
& os
, const T
& v
) const { os
.iwrite (v
); }
126 template <typename T
>
127 inline ostringstream
& operator<< (ostringstream
& os
, const T
& v
) {
128 typedef typename
tm::Select
<numeric_limits
<T
>::is_integral
,
129 integral_text_object_writer
<T
>, object_text_writer
<T
> >::Result object_writer_t
;
130 object_writer_t()(os
, v
);
133 // Needed because if called with a char[], numeric_limits will not work. Should be removed if I find out how to partial specialize for arrays...
134 inline ostringstream
& operator<< (ostringstream
& os
, const char* v
)
135 { os
.iwrite (v
); return (os
); }
136 inline ostringstream
& operator<< (ostringstream
& os
, char* v
)
137 { os
.iwrite (v
); return (os
); }
139 //----------------------------------------------------------------------
141 template <> struct object_text_writer
<string
> {
142 inline void operator()(ostringstream
& os
, const string
& v
) const { os
.iwrite (v
); }
144 template <typename T
> struct integral_text_object_writer
<T
*> {
145 inline void operator() (ostringstream
& os
, const T
* const& v
) const
146 { os
.iwrite ((uintptr_t)(v
)); }
148 #define OSTRSTREAM_CAST_OPERATOR(RealT, CastT) \
149 template <> inline ostringstream& operator<< (ostringstream& os, const RealT& v) \
150 { os.iwrite ((CastT)(v)); return (os); }
151 OSTRSTREAM_CAST_OPERATOR (uint8_t* const, const char*)
152 OSTRSTREAM_CAST_OPERATOR (int8_t, uint8_t)
153 OSTRSTREAM_CAST_OPERATOR (short int, int)
154 OSTRSTREAM_CAST_OPERATOR (unsigned short, unsigned int)
155 #if HAVE_THREE_CHAR_TYPES
156 OSTRSTREAM_CAST_OPERATOR (char, uint8_t)
158 #undef OSTRSTREAM_CAST_OPERATOR
160 //----------------------------------------------------------------------