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