Build system improvements
[ustl.git] / sostream.h
blob6f57d8dbbac1f0d6ebf4c8e40e03e56dd8a1ed54
1 // This file is part of the ustl library, an STL implementation.
2 //
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
5 //
6 // sostream.h
7 //
9 #ifndef SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F
10 #define SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F
12 #include "ustring.h"
13 #include "mostream.h"
15 namespace ustl {
17 class string;
19 /// \class ostringstream sostream.h ustl.h
20 /// \ingroup TextStreams
21 ///
22 /// \brief This stream writes textual data into a memory block.
23 ///
24 class ostringstream : public ostream {
25 public:
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); }
36 void iwrite (bool 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);
40 #if HAVE_LONG_LONG
41 inline void iwrite (long long v) { iformat (v); }
42 inline void iwrite (unsigned long long v) { iformat (v); }
43 #endif
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"); }
60 void flush (void);
61 virtual size_type overflow (size_type n = 1);
62 protected:
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()); }
66 private:
67 inline char* encode_dec (char* fmt, uint32_t n) const;
68 void fmtstring (char* fmt, const char* typestr, bool bInteger) const;
69 template <typename T>
70 void iformat (T v);
71 private:
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 //----------------------------------------------------------------------
81 template <typename T>
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")
91 #if HAVE_LONG_LONG
92 PRINTF_TYPESTRING_SPEC (long long, "lld")
93 PRINTF_TYPESTRING_SPEC (unsigned long long, "llu")
94 #endif
95 #undef PRINTF_TYPESTRING_SPEC
97 template <typename T>
98 void ostringstream::iformat (T v)
100 char fmt [16];
101 fmtstring (fmt, printf_typestring(v), numeric_limits<T>::is_integer);
102 format (fmt, v);
105 /// Sets the flag \p f in the stream.
106 inline void ostringstream::iwrite (fmtflags f)
108 switch (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);
131 return (os);
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)
157 #endif
158 #undef OSTRSTREAM_CAST_OPERATOR
160 //----------------------------------------------------------------------
162 } // namespace ustl
164 #endif