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" },
104 test_values<int>(values);
107 void LexicalCastTests::bin_integers()
109 Value<int> values[] =
111 { 0xcf3, "%b", "110011110011" },
112 { 0xcf3, "%#b", "0b110011110011" },
113 { 0xcf3, "%#16b", " 0b110011110011" },
114 { 0xcf3, "%-#16b", "0b110011110011 " },
115 { 0xcf3, "%#016b", "0b00110011110011" },
116 { 0xcf3, "%+#b", "+0b110011110011" },
117 { -0xcf3, "%#b", "-0b110011110011" },
120 test_values<int>(values);
123 void LexicalCastTests::integer_limits()
125 Value<Int32> int32_values[] =
127 { numeric_limits<Int32>::max(), "%d", "2147483647" },
128 { numeric_limits<Int32>::max(), "%x", "7fffffff" },
129 { numeric_limits<Int32>::min(), "%d", "-2147483648" },
130 { numeric_limits<Int32>::min(), "%x", "-80000000" },
133 test_values<Int32>(int32_values);
135 Value<UInt32> uint32_values[] =
137 { numeric_limits<UInt32>::max(), "%d", "4294967295" },
138 { numeric_limits<UInt32>::max(), "%x", "ffffffff" },
141 test_values<UInt32>(uint32_values);
144 void LexicalCastTests::float_fixed()
146 Value<float> float_values[] =
148 { 0, "%f", "0.000000" },
150 { 1, "%#.0f", "1." },
151 { 1, "%06.2f", "001.00" },
152 { 1, "%.1f", "1.0" },
153 { 0.0987, "%f", "0.098700" },
154 { 0.0987, "%.3f", "0.099" },
155 { 0.0987, "%.2f", "0.10" },
158 test_values<float>(float_values);
161 void LexicalCastTests::float_auto()
163 Value<float> float_values[] =
166 { 1, "%#g", "1.00000" },
167 { 100, "%.3g", "100" },
168 { 1000, "%.3g", "1e+03" },
169 { 1100, "%.3g", "1.1e+03" },
170 { 1e-5, "%g", "1e-05" },
171 { 0.0987, "%g", "0.0987" },
172 { 0.0987, "%.3g", "0.0987" },
173 { 0.0987, "%.2g", "0.099" },
176 test_values<float>(float_values);
179 void LexicalCastTests::float_sci()
181 Value<float> float_values[] =
183 { 0, "%e", "0.000000e+00" },
184 { 0.0987, "%e", "9.870000e-02" },
185 { 0.0987, "%.3e", "9.870e-02" },
186 { 0.0987, "%.1e", "9.9e-02" },
189 test_values<float>(float_values);
192 void LexicalCastTests::float_corner_cases()
194 Value<float> float_values[] =
196 { 10, "%.20f", "10.00000000000000000000" },
197 { 10, "%.20g", "10" },
198 { 99.99, "%#.3g", "100." },
199 { 999.9, "%.3g", "1e+03" },
200 { 0.09999999, "%.3g", "0.1" },
201 { 0.09999999, "%.3f", "0.100" },
204 test_values<float>(float_values);
208 void LexicalCastTests::test_values(const Value<T> *values)
210 for(const Value<T> *i=values; i->format; ++i)
212 string result = lexical_cast<string>(i->value, i->format);
213 expect_equal(result, result==i->result, format("result == \"%s\"", c_escape(i->result)));