2 #include <msp/core/inttypes.h>
3 #include <msp/strings/utils.h>
4 #include <msp/test/test.h>
9 class LexicalCastTests: public Test::RegisteredTest<LexicalCastTests>
23 static const char *get_name() { return "lexical_cast"; }
26 void basic_integers();
30 void integer_limits();
34 void float_corner_cases();
37 void test_values(const Value<T> *);
40 LexicalCastTests::LexicalCastTests()
42 add(&LexicalCastTests::basic_integers, "Basic integers");
43 add(&LexicalCastTests::hex_integers, "Hexadecimal integers");
44 add(&LexicalCastTests::oct_integers, "Octal integers");
45 add(&LexicalCastTests::bin_integers, "Binary integers");
46 add(&LexicalCastTests::integer_limits, "Integer limits");
47 add(&LexicalCastTests::float_fixed, "Fixed-precision floats");
48 add(&LexicalCastTests::float_auto, "Automatic floats");
49 add(&LexicalCastTests::float_sci, "Scientific floats");
50 add(&LexicalCastTests::float_corner_cases, "Float corner cases");
53 void LexicalCastTests::basic_integers()
59 { 1, "%04d", "0001" },
62 { 1, "%+04d", "+001" },
63 { 1, "%+-4d", "+1 " },
65 { -1, "%04d", "-001" },
66 { 999999999, "%d", "999999999" },
67 { 1000000000, "%d", "1000000000" },
68 { 1234567890, "%d", "1234567890" },
71 test_values<int>(values);
74 void LexicalCastTests::hex_integers()
78 { 0xabcd, "%x", "abcd" },
79 { 0xabcd, "%#x", "0xabcd" },
80 { 0xabcd, "%#8x", " 0xabcd" },
81 { 0xabcd, "%-#8x", "0xabcd " },
82 { 0xabcd, "%#08x", "0x00abcd" },
83 { 0xabcd, "%#X", "0XABCD" },
84 { 0xabcd, "%+#x", "+0xabcd" },
85 { -0xabcd, "%#x", "-0xabcd" },
88 test_values<int>(values);
91 void LexicalCastTests::oct_integers()
95 { 012345, "%o", "12345" },
96 { 012345, "%#o", "012345" },
97 { 012345, "%#8o", " 012345" },
98 { 012345, "%-#8o", "012345 " },
99 { 012345, "%#08o", "00012345" },
100 { 012345, "%+#o", "+012345" },
101 { -012345, "%#o", "-012345" },
103 test_values<int>(values);
106 void LexicalCastTests::bin_integers()
108 Value<int> values[] =
110 { 0xcf3, "%b", "110011110011" },
111 { 0xcf3, "%#b", "0b110011110011" },
112 { 0xcf3, "%#16b", " 0b110011110011" },
113 { 0xcf3, "%-#16b", "0b110011110011 " },
114 { 0xcf3, "%#016b", "0b00110011110011" },
115 { 0xcf3, "%+#b", "+0b110011110011" },
116 { -0xcf3, "%#b", "-0b110011110011" },
118 test_values<int>(values);
121 void LexicalCastTests::integer_limits()
123 Value<Int32> int32_values[] =
125 { numeric_limits<Int32>::max(), "%d", "2147483647" },
126 { numeric_limits<Int32>::max(), "%x", "7fffffff" },
127 { numeric_limits<Int32>::min(), "%d", "-2147483648" },
128 { numeric_limits<Int32>::min(), "%x", "-80000000" },
131 test_values<Int32>(int32_values);
133 Value<UInt32> uint32_values[] =
135 { numeric_limits<UInt32>::max(), "%d", "4294967295" },
136 { numeric_limits<UInt32>::max(), "%x", "ffffffff" },
139 test_values<UInt32>(uint32_values);
142 void LexicalCastTests::float_fixed()
144 Value<float> float_values[] =
146 { 0, "%f", "0.000000" },
148 { 1, "%#.0f", "1." },
149 { 1, "%06.2f", "001.00" },
150 { 1, "%.1f", "1.0" },
151 { 0.0987, "%f", "0.098700" },
152 { 0.0987, "%.3f", "0.099" },
153 { 0.0987, "%.2f", "0.10" },
156 test_values<float>(float_values);
159 void LexicalCastTests::float_auto()
161 Value<float> float_values[] =
164 { 1, "%#g", "1.00000" },
165 { 100, "%.3g", "100" },
166 { 1000, "%.3g", "1e+03" },
167 { 1100, "%.3g", "1.1e+03" },
168 { 1e-5, "%g", "1e-05" },
169 { 0.0987, "%g", "0.0987" },
170 { 0.0987, "%.3g", "0.0987" },
171 { 0.0987, "%.2g", "0.099" },
174 test_values<float>(float_values);
177 void LexicalCastTests::float_sci()
179 Value<float> float_values[] =
181 { 0, "%e", "0.000000e+00" },
182 { 0.0987, "%e", "9.870000e-02" },
183 { 0.0987, "%.3e", "9.870e-02" },
184 { 0.0987, "%.1e", "9.9e-02" },
187 test_values<float>(float_values);
190 void LexicalCastTests::float_corner_cases()
192 Value<float> float_values[] =
194 { 10, "%.20f", "10.00000000000000000000" },
195 { 10, "%.20g", "10" },
196 { 99.99, "%#.3g", "100." },
197 { 999.9, "%.3g", "1e+03" },
198 { 0.09999999, "%.3g", "0.1" },
199 { 0.09999999, "%.3f", "0.100" },
202 test_values<float>(float_values);
206 void LexicalCastTests::test_values(const Value<T> *values)
208 for(const Value<T> *i=values; i->format; ++i)
210 string result = lexical_cast<string>(i->value, i->format);
211 expect_equal(result, result==i->result, format("result == \"%s\"", c_escape(i->result)));