Add a method to set autobase in Fmt
[libs/core.git] / source / strings / fmt.h
1 #ifndef MSP_STRINGS_FMT_H_
2 #define MSP_STRINGS_FMT_H_
3
4 #include <ostream>
5 #include <stdexcept>
6 #include <string>
7
8 namespace Msp {
9
10 class format_error: public std::logic_error
11 {
12 public:
13         format_error(const std::string &w): std::logic_error(w) { }
14         virtual ~format_error() throw() { }
15 };
16
17
18 /**
19 Stores formatting information for converting variables into strings.  Can be
20 applied to an std::ostream or fed to lexical_cast.  Also used internally by
21 Formatter.
22
23 Formats can be constructed from printf-style conversion specifications, by
24 chaining calls to the various setter functions, or with a mixture of both.
25
26 Since type information for conversions is acquired through templates, the
27 meaning of the conversion specifier character is reduced to only specifying
28 what the conversion should look like.  Of special note is the s conversion,
29 which will result in a default conversion for any data type.  Size modifiers
30 are not supported and there is no difference between signed and unsigned
31 conversions.
32
33 Some new conversions are supported:
34
35   b/B  Binary integer conversion
36   P    Uppercase pointer conversion (like %#X)
37 */
38 class Fmt
39 {
40 public:
41         enum Type
42         {
43                 NUM,
44                 CHAR,
45                 STR
46         };
47
48         enum Base
49         {
50                 AUTOBASE = 0,
51                 DEC = 10,
52                 HEX = 16,
53                 OCT = 8,
54                 BIN = 2
55         };
56
57         enum FloatMode
58         {
59                 FIXED,
60                 AUTOFLT,
61                 SCI
62         };
63
64         enum Align
65         {
66                 LEFT,
67                 RIGHT
68         };
69
70 private:
71         unsigned wd;
72         unsigned prec;
73         bool spos;
74         wchar_t fillc;
75         Base base;
76         bool sbase;
77         FloatMode fmode;
78         bool spoint;
79         Align align;
80         bool ucase;
81         Type type;
82
83 public:
84         Fmt() { reset(); }
85         Fmt(const char *f) { reset(); parse(f); }
86         Fmt(const std::string &f) { reset(); parse(f.c_str()); }
87
88 private:
89         void parse(const char *);
90
91 public:
92         Fmt &width(unsigned w) { wd = w; return *this; }
93         Fmt &precision(unsigned p) { prec = p; return *this; }
94         Fmt &showpos(bool s = true) { spos = s; return *this; }
95         Fmt &fill(wchar_t f) { fillc = f; return *this; }
96         Fmt &fixed() { fmode = FIXED; return *this; }
97         Fmt &scientific() { fmode = SCI; return *this; }
98         Fmt &showpoint(bool s = true) { spoint = s; return *this; }
99         Fmt &showbase(bool s = true) { sbase = s; return *this; }
100         Fmt &left() { align = LEFT; return *this; }
101         Fmt &right() { align = RIGHT; return *this; }
102         Fmt &dec() { base = DEC; return *this; }
103         Fmt &hex() { base = HEX; return *this; }
104         Fmt &oct() { base = OCT; return *this; }
105         Fmt &bin() { base = BIN; return *this; }
106         Fmt &autobase() { base = AUTOBASE; return *this; }
107         Fmt &uppercase(bool u = true) { ucase = u; return *this; }
108         Fmt &numeric() { type = NUM; return *this; }
109         Fmt &character() { type = CHAR; return *this; }
110         Fmt &string() { type = STR; return *this; }
111         Fmt &reset();
112
113         unsigned get_width() const { return wd; }
114         unsigned get_precision() const { return prec; }
115         bool get_showpos() const { return spos; }
116         wchar_t get_fill() const { return fillc; }
117         Base get_base() const { return base; }
118         bool get_showbase() const { return sbase; }
119         FloatMode get_floatmode() const { return fmode; }
120         bool get_showpoint() const { return spoint; }
121         Align get_align() const { return align; }
122         bool get_uppercase() const { return ucase; }
123         Type get_type() const { return type; }
124
125         void apply(std::ostream &) const;
126 };
127
128 inline std::ostream &operator<<(std::ostream &o, const Fmt &f)
129 { f.apply(o); return o; }
130
131 } // namespace Msp
132
133 #endif