Skip to content

Commit eeacc90

Browse files
committed
Add StringBuilder formatters
1 parent f864f81 commit eeacc90

File tree

2 files changed

+92
-3
lines changed

2 files changed

+92
-3
lines changed

src/common/Format.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#pragma once
2+
3+
#include <functional>
4+
#include <ios>
5+
6+
#include "common/String.h"
7+
8+
template<typename T> class FormatProxy
9+
{
10+
T const &value;
11+
inline FormatProxy(T const &_value): value(_value) {}
12+
public:
13+
inline void Write(StringBuilder &b) { b << value; }
14+
};
15+
16+
class Format
17+
{
18+
std::function<void(StringBuilder &)> writer;
19+
public:
20+
template<typename T, typename... Ts> inline Format(T const &value, Ts... args):
21+
writer([value, args...](StringBuilder &b) { FormatProxy<T>(value, args...).Write(b); })
22+
{}
23+
24+
friend StringBuilder &operator<<(StringBuilder &, Format const &);
25+
26+
enum Base { Dec, Oct, Hex };
27+
enum Float { Default, Fixed, Scientific };
28+
};
29+
30+
inline StringBuilder &operator<<(StringBuilder &b, Format const &f)
31+
{
32+
f.writer(b);
33+
return b;
34+
}
35+
36+
template<typename T> class IntegralFormatProxy
37+
{
38+
T value;
39+
Format::Base base;
40+
size_t width;
41+
public:
42+
inline IntegralFormatProxy(T _value, Format::Base _base = Format::Dec, size_t _width = 0): value(_value), base(_base), width(_width) {}
43+
inline void Write(StringBuilder &b)
44+
{
45+
std::ios_base::fmtflags oldflags = b.flags;
46+
b.flags &= ~std::ios_base::basefield;
47+
b.flags |= base == Format::Hex ? std::ios_base::hex : base == Format::Oct ? std::ios_base::oct : std::ios_base::dec;
48+
size_t oldwidth = b.width;
49+
b.width = width;
50+
b << value;
51+
b.flags = oldflags;
52+
b.width = oldwidth;
53+
}
54+
};
55+
56+
template<> class FormatProxy<short int>: public IntegralFormatProxy<short int> { using IntegralFormatProxy::IntegralFormatProxy; };
57+
template<> class FormatProxy<int>: public IntegralFormatProxy<int> { using IntegralFormatProxy::IntegralFormatProxy; };
58+
template<> class FormatProxy<long int>: public IntegralFormatProxy<long int> { using IntegralFormatProxy::IntegralFormatProxy; };
59+
template<> class FormatProxy<long long int>: public IntegralFormatProxy<long long int> { using IntegralFormatProxy::IntegralFormatProxy; };
60+
template<> class FormatProxy<unsigned short int>: public IntegralFormatProxy<unsigned short int> { using IntegralFormatProxy::IntegralFormatProxy; };
61+
template<> class FormatProxy<unsigned int>: public IntegralFormatProxy<unsigned int> { using IntegralFormatProxy::IntegralFormatProxy; };
62+
template<> class FormatProxy<unsigned long int>: public IntegralFormatProxy<unsigned long int> { using IntegralFormatProxy::IntegralFormatProxy; };
63+
template<> class FormatProxy<unsigned long long int>: public IntegralFormatProxy<unsigned long long int> { using IntegralFormatProxy::IntegralFormatProxy; };
64+
65+
template<typename T> class FloatingFormatProxy
66+
{
67+
T value;
68+
size_t precision;
69+
Format::Float style;
70+
size_t width;
71+
public:
72+
inline FloatingFormatProxy(T _value, size_t _precision, Format::Float _style = Format::Default, size_t _width = 0): value(_value), precision(_precision), style(_style), width(_width) {}
73+
inline void Write(StringBuilder &b)
74+
{
75+
std::ios_base::fmtflags oldflags = b.flags;
76+
b.flags &= ~std::ios_base::floatfield;
77+
b.flags |= style == Format::Fixed ? std::ios_base::fixed : style == Format::Scientific ? std::ios_base::scientific : std::ios_base::fmtflags();
78+
size_t oldwidth = b.width;
79+
b.width = width;
80+
size_t oldprecision = b.precision;
81+
b.precision = precision;
82+
b << value;
83+
b.flags = oldflags;
84+
b.width = oldwidth;
85+
b.precision = oldprecision;
86+
}
87+
};
88+
89+
template<> class FormatProxy<float>: public FloatingFormatProxy<float> { using FloatingFormatProxy::FloatingFormatProxy; };
90+
template<> class FormatProxy<double>: public FloatingFormatProxy<double> { using FloatingFormatProxy::FloatingFormatProxy; };

src/common/String.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#ifndef TPT_STRING
2-
#define TPT_STRING
1+
#pragma once
32

43
#include <stdexcept>
54
#include <sstream>
@@ -285,4 +284,4 @@ StringBuilder &operator<<(StringBuilder &, float);
285284
StringBuilder &operator<<(StringBuilder &, double);
286285
template<size_t N> StringBuilder &operator<<(StringBuilder &b, ByteString::value_type const (&data)[N]) { return b << ByteString(data).FromUtf8(); }
287286

288-
#endif
287+
#include "common/Format.h"

0 commit comments

Comments
 (0)