1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
2 // unit/quantity manipulation and conversion
3 //
4 // Copyright (C) 2009 Steven Watanabe
5 // Copyright Paul A. Bristow 2010
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 /**
12 \file test_output.cpp
13 
14 \brief
15 Test unit and quantity printing
16 \details
17 Tests for output from various units, name, symbol and raw formats, and automatic prefixing in engineering and binary units.
18 **/
19 
20 #include <boost/units/quantity.hpp>
21 #include <boost/units/io.hpp>
22 #include <boost/units/unit.hpp>
23 #include <boost/units/scale.hpp>
24 #include <boost/units/scaled_base_unit.hpp>
25 #include <boost/units/make_scaled_unit.hpp>
26 #include <boost/units/base_unit.hpp>
27 #include <boost/units/make_system.hpp>
28 #include <boost/units/absolute.hpp>
29 #include <boost/units/physical_dimensions/length.hpp>
30 #include <boost/units/physical_dimensions/time.hpp>
31 #include <boost/units/physical_dimensions/velocity.hpp>
32 #include <boost/units/physical_dimensions/volume.hpp>
33 #include <boost/units/physical_dimensions/acceleration.hpp>
34 #include <boost/units/physical_dimensions/area.hpp>
35 
36 #include <boost/regex.hpp>
37 
38 #include <iostream>
39 #include <sstream>
40 #include <boost/config.hpp>
41 #include <limits>
42 
43 #define BOOST_TEST_MAIN
44 #include <boost/test/unit_test.hpp>
45 
46 struct meter_base_unit : boost::units::base_unit<meter_base_unit, boost::units::length_dimension, 1> {
namemeter_base_unit47     static const char* name() { return("meter"); }
symbolmeter_base_unit48     static const char* symbol() { return("m"); }
49 };
50 
51 struct second_base_unit : boost::units::base_unit<second_base_unit, boost::units::time_dimension, 2> {
namesecond_base_unit52     static const char* name() { return("second"); }
symbolsecond_base_unit53     static const char* symbol() { return("s"); }
54 };
55 
56 struct byte_base_unit : boost::units::base_unit<byte_base_unit, boost::units::dimensionless_type, 3> {
namebyte_base_unit57     static const char* name() { return("byte"); }
symbolbyte_base_unit58     static const char* symbol() { return("b"); }
59 };
60 
61 typedef boost::units::make_system<meter_base_unit, second_base_unit>::type my_system;
62 
63 typedef boost::units::unit<boost::units::length_dimension, my_system> length;
64 typedef boost::units::unit<boost::units::velocity_dimension, my_system> velocity;
65 
66 typedef boost::units::make_scaled_unit<length, boost::units::scale<10, boost::units::static_rational<3> > >::type scaled_length;
67 typedef boost::units::make_scaled_unit<velocity, boost::units::scale<10, boost::units::static_rational<3> > >::type scaled_velocity1;
68 
69 typedef boost::units::scaled_base_unit<second_base_unit, boost::units::scale<10, boost::units::static_rational<-3> > > millisecond_base_unit;
70 
71 typedef boost::units::make_system<meter_base_unit, millisecond_base_unit>::type scaled_system;
72 
73 typedef boost::units::unit<boost::units::time_dimension, scaled_system> scaled_time;
74 typedef boost::units::unit<boost::units::velocity_dimension, scaled_system> scaled_velocity2;
75 
76 typedef boost::units::unit<boost::units::area_dimension, my_system> area;
77 typedef boost::units::make_scaled_unit<area, boost::units::scale<10, boost::units::static_rational<3> > >::type scaled_area;
78 
79 typedef boost::units::make_scaled_unit<scaled_length, boost::units::scale<2, boost::units::static_rational<10> > >::type double_scaled_length;
80 
81 typedef boost::units::scaled_base_unit<meter_base_unit, boost::units::scale<100, boost::units::static_rational<1> > > scaled_length_base_unit;
82 namespace boost {
83 namespace units {
84 template<>
85 struct base_unit_info<scaled_length_base_unit> {
symbolboost::units::base_unit_info86     static const char* symbol() { return("scm"); }
nameboost::units::base_unit_info87     static const char* name() { return("scaled_meter"); }
88 };
89 }
90 }
91 typedef boost::units::scaled_base_unit<scaled_length_base_unit, boost::units::scale<10, boost::units::static_rational<3> > > double_scaled_length_base_unit;
92 typedef double_scaled_length_base_unit::unit_type double_scaled_length2;
93 
94 typedef boost::units::reduce_unit<boost::units::unit<boost::units::volume_dimension, my_system> >::type custom1;
95 
name_string(const custom1 &)96 std::string name_string(const custom1&) { return("custom1"); }
symbol_string(const custom1 &)97 std::string symbol_string(const custom1&) { return("c1"); }
98 
99 typedef boost::units::reduce_unit<boost::units::unit<boost::units::acceleration_dimension, my_system> >::type custom2;
100 
name_string(const custom2 &)101 const char* name_string(const custom2&) { return("custom2"); }
symbol_string(const custom2 &)102 const char* symbol_string(const custom2&) { return("c2"); }
103 
104 typedef boost::units::make_scaled_unit<custom1, boost::units::scale<10, boost::units::static_rational<3> > >::type scaled_custom1;
105 typedef boost::units::make_scaled_unit<custom2, boost::units::scale<10, boost::units::static_rational<3> > >::type scaled_custom2;
106 
107 #ifndef BOOST_NO_CWCHAR
108 
109 #define BOOST_UNITS_TEST_OUTPUT(v, expected)                \
110 {                                                           \
111     std::ostringstream ss;                                  \
112     ss FORMATTERS << v;                                     \
113     BOOST_CHECK_EQUAL(ss.str(), expected);                  \
114 }                                                           \
115 {                                                           \
116     std::wostringstream ss;                                 \
117     ss FORMATTERS << v;                                     \
118     BOOST_CHECK(ss.str() == BOOST_PP_CAT(L, expected));     \
119 }
120 
121 #define BOOST_UNITS_TEST_OUTPUT_REGEX(v, expected)          \
122 {                                                           \
123     std::ostringstream ss;                                  \
124     ss FORMATTERS << v;                                     \
125     boost::regex r(expected);                               \
126     BOOST_CHECK_MESSAGE(boost::regex_match(ss.str(), r),    \
127         ss.str() + " does not match " + expected);          \
128 }                                                           \
129 {                                                           \
130     std::wostringstream ss;                                 \
131     ss FORMATTERS << v;                                     \
132     boost::wregex r(BOOST_PP_CAT(L, expected));             \
133     BOOST_CHECK(boost::regex_match(ss.str(), r));           \
134 }
135 
136 #define BOOST_UNITS_TEST_OUTPUT_DISPLAY(v)                  \
137 {                                                           \
138     std::ostringstream ss;                                  \
139     ss FORMATTERS << v;                                     \
140     std::cout << #v << ": " << ss.str() << std::endl;       \
141 }                                                           \
142 {                                                           \
143     std::wostringstream ss;                                 \
144     ss FORMATTERS << v;                                     \
145     std::wcout << #v << ": " << ss.str() << std::endl;      \
146 }
147 
148 #else
149 
150 #define BOOST_UNITS_TEST_OUTPUT(v, expected)                \
151 {                                                           \
152     std::ostringstream ss;                                  \
153     ss FORMATTERS << v;                                     \
154     BOOST_CHECK_EQUAL(ss.str(), expected);                  \
155 }
156 
157 #define BOOST_UNITS_TEST_OUTPUT_REGEX(v, expected)          \
158 {                                                           \
159     std::ostringstream ss;                                  \
160     ss FORMATTERS << v;                                     \
161     boost::regex r(expected);                               \
162     BOOST_CHECK_MESSAGE(boost::regex_match(ss.str(), r),    \
163         ss.str() + " does not match " + expected);          \
164 }
165 
166 #define BOOST_UNITS_TEST_OUTPUT_DISPLAY(v)                  \
167 {                                                           \
168     std::ostringstream ss;                                  \
169     ss FORMATTERS << v;                                     \
170     std::cout << #v << ": " << ss.str() << std::endl;       \
171 }
172 
173 #endif
174 
BOOST_AUTO_TEST_CASE(test_output_unit_symbol)175 BOOST_AUTO_TEST_CASE(test_output_unit_symbol)
176 {  // base units using default symbol_format (no format specified) and no auto prefixing.
177 #define FORMATTERS
178     BOOST_UNITS_TEST_OUTPUT(meter_base_unit::unit_type(), "m");
179     BOOST_UNITS_TEST_OUTPUT(velocity(), "m s^-1");
180     BOOST_UNITS_TEST_OUTPUT(scaled_length(), "km");
181     BOOST_UNITS_TEST_OUTPUT(scaled_velocity1(), "k(m s^-1)");
182     BOOST_UNITS_TEST_OUTPUT(millisecond_base_unit::unit_type(), "ms");
183     BOOST_UNITS_TEST_OUTPUT(scaled_time(), "ms");
184     BOOST_UNITS_TEST_OUTPUT(scaled_velocity2(), "m ms^-1");
185     BOOST_UNITS_TEST_OUTPUT(area(), "m^2");
186     BOOST_UNITS_TEST_OUTPUT(scaled_area(), "k(m^2)");
187     BOOST_UNITS_TEST_OUTPUT(double_scaled_length(), "Kikm");
188     BOOST_UNITS_TEST_OUTPUT(double_scaled_length2(), "kscm");
189     BOOST_UNITS_TEST_OUTPUT(custom1(), "c1");
190     BOOST_UNITS_TEST_OUTPUT(custom2(), "c2");
191     BOOST_UNITS_TEST_OUTPUT(scaled_custom1(), "kc1");
192     BOOST_UNITS_TEST_OUTPUT(scaled_custom2(), "kc2");
193     BOOST_UNITS_TEST_OUTPUT(boost::units::absolute<meter_base_unit::unit_type>(), "absolute m");
194 #undef FORMATTERS
195 }
196 
BOOST_AUTO_TEST_CASE(test_output_unit_raw)197 BOOST_AUTO_TEST_CASE(test_output_unit_raw)
198 {  // raw format specified
199 #define FORMATTERS << boost::units::raw_format
200     BOOST_UNITS_TEST_OUTPUT(meter_base_unit::unit_type(), "m");
201     BOOST_UNITS_TEST_OUTPUT(velocity(), "m s^-1");
202     BOOST_UNITS_TEST_OUTPUT(scaled_length(), "km");
203     BOOST_UNITS_TEST_OUTPUT(scaled_velocity1(), "k(m s^-1)");
204     BOOST_UNITS_TEST_OUTPUT(millisecond_base_unit::unit_type(), "ms");
205     BOOST_UNITS_TEST_OUTPUT(scaled_time(), "ms");
206     BOOST_UNITS_TEST_OUTPUT(scaled_velocity2(), "m ms^-1");
207     BOOST_UNITS_TEST_OUTPUT(area(), "m^2");
208     BOOST_UNITS_TEST_OUTPUT(scaled_area(), "k(m^2)");
209     BOOST_UNITS_TEST_OUTPUT(double_scaled_length(), "Kikm");
210     BOOST_UNITS_TEST_OUTPUT(double_scaled_length2(), "kscm");
211     // when using raw format, we ignore the user defined overloads
212     BOOST_UNITS_TEST_OUTPUT(custom1(), "m^3");
213     BOOST_UNITS_TEST_OUTPUT(custom2(), "m s^-2");
214     BOOST_UNITS_TEST_OUTPUT(scaled_custom1(), "k(m^3)");
215     BOOST_UNITS_TEST_OUTPUT(scaled_custom2(), "k(m s^-2)");
216     BOOST_UNITS_TEST_OUTPUT(boost::units::absolute<meter_base_unit::unit_type>(), "absolute m");
217 #undef FORMATTERS
218 }
219 
BOOST_AUTO_TEST_CASE(test_output_unit_name)220 BOOST_AUTO_TEST_CASE(test_output_unit_name)
221 {  // name format specified.
222 #define FORMATTERS << boost::units::name_format
223     BOOST_UNITS_TEST_OUTPUT(meter_base_unit::unit_type(), "meter");
224     BOOST_UNITS_TEST_OUTPUT(velocity(), "meter second^-1");
225     BOOST_UNITS_TEST_OUTPUT(scaled_length(), "kilometer");
226     BOOST_UNITS_TEST_OUTPUT(scaled_velocity1(), "kilo(meter second^-1)");
227     BOOST_UNITS_TEST_OUTPUT(millisecond_base_unit::unit_type(), "millisecond");
228     BOOST_UNITS_TEST_OUTPUT(scaled_time(), "millisecond");
229     BOOST_UNITS_TEST_OUTPUT(scaled_velocity2(), "meter millisecond^-1");
230     BOOST_UNITS_TEST_OUTPUT(area(), "meter^2");
231     BOOST_UNITS_TEST_OUTPUT(scaled_area(), "kilo(meter^2)");
232     BOOST_UNITS_TEST_OUTPUT(double_scaled_length(), "kibikilometer");
233     BOOST_UNITS_TEST_OUTPUT(double_scaled_length2(), "kiloscaled_meter");
234     BOOST_UNITS_TEST_OUTPUT(custom1(), "custom1");
235     BOOST_UNITS_TEST_OUTPUT(custom2(), "custom2");
236     BOOST_UNITS_TEST_OUTPUT(scaled_custom1(), "kilocustom1");
237     BOOST_UNITS_TEST_OUTPUT(scaled_custom2(), "kilocustom2");
238     BOOST_UNITS_TEST_OUTPUT(boost::units::absolute<meter_base_unit::unit_type>(), "absolute meter");
239 #undef FORMATTERS
240 }
241 
242 
BOOST_AUTO_TEST_CASE(test_output_quantity_symbol)243 BOOST_AUTO_TEST_CASE(test_output_quantity_symbol)
244 { // quantity symbols using default format.
245 #define FORMATTERS
246     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m");
247     BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 m s^-1");
248     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 km");
249     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 k(m s^-1)");
250     BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 ms");
251     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 ms");
252     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 m ms^-1");
253     BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 m^2");
254     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 k(m^2)");
255     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.5 Kikm");
256     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kscm");
257     BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 c1");
258     BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 c2");
259     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kc1");
260     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kc2");
261     BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute<meter_base_unit::unit_type>(), "1.5 absolute m");
262     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 10) * byte_base_unit::unit_type(), "1024 b");
263 
264 #undef FORMATTERS
265 }
266 
BOOST_AUTO_TEST_CASE(test_output_quantity_raw)267 BOOST_AUTO_TEST_CASE(test_output_quantity_raw)
268 { // quantity symbols using raw format.
269 #define FORMATTERS << boost::units::raw_format
270     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m");
271     BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 m s^-1");
272     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 km");
273     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 k(m s^-1)");
274     BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 ms");
275     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 ms");
276     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 m ms^-1");
277     BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 m^2");
278     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 k(m^2)");
279     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.5 Kikm");
280     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kscm");
281     // when using raw format, we ignore the user defined overloads
282     BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 m^3");
283     BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 m s^-2");
284     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 k(m^3)");
285     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 k(m s^-2)");
286     BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute<meter_base_unit::unit_type>(), "1.5 absolute m");
287 #undef FORMATTERS
288 }
289 
BOOST_AUTO_TEST_CASE(test_output_quantity_name)290 BOOST_AUTO_TEST_CASE(test_output_quantity_name)
291 { // // quantity symbols using name format.
292 #define FORMATTERS << boost::units::name_format
293     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter");
294     BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 meter second^-1");
295     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 kilometer");
296     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 kilo(meter second^-1)");
297     BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 millisecond");
298     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 millisecond");
299     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 meter millisecond^-1");
300     BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 meter^2");
301     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 kilo(meter^2)");
302     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.5 kibikilometer");
303     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kiloscaled_meter");
304     BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 custom1");
305     BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 custom2");
306     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kilocustom1");
307     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kilocustom2");
308     BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute<meter_base_unit::unit_type>(), "1.5 absolute meter");
309 #undef FORMATTERS
310 }
311 
BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_name)312 BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_name)
313 { // Engineering autoprefix, with name format.
314 #define FORMATTERS << boost::units::name_format << boost::units::engineering_prefix
315   // Single base unit like meter.
316     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter");
317     BOOST_UNITS_TEST_OUTPUT(1500.0*meter_base_unit::unit_type(), "1.5 kilometer");
318     BOOST_UNITS_TEST_OUTPUT(1.5e7*meter_base_unit::unit_type(), "15 megameter");
319     BOOST_UNITS_TEST_OUTPUT(1.5e-3*meter_base_unit::unit_type(), "1.5 millimeter");
320     BOOST_UNITS_TEST_OUTPUT(1.5e-9*meter_base_unit::unit_type(), "1.5 nanometer");
321     BOOST_UNITS_TEST_OUTPUT(1.5e-8*meter_base_unit::unit_type(), "15 nanometer");
322     BOOST_UNITS_TEST_OUTPUT(1.5e-10*meter_base_unit::unit_type(), "150 picometer");
323     BOOST_UNITS_TEST_OUTPUT(0.0000000012345 * meter_base_unit::unit_type(), "1.2345 nanometer");
324 
325   // Too small or large for a multiple name.
326     BOOST_UNITS_TEST_OUTPUT_REGEX(9.99999e-25 * meter_base_unit::unit_type(), "9\\.99999e-0?25 meter"); // Just too small for multiple.
327     BOOST_UNITS_TEST_OUTPUT_REGEX(1e+28 * meter_base_unit::unit_type(), "1e\\+0?28 meter"); // Just too large for multiple.
328     BOOST_UNITS_TEST_OUTPUT_REGEX(1.5e-25 * meter_base_unit::unit_type(), "1\\.5e-0?25 meter"); // Too small for multiple.
329     BOOST_UNITS_TEST_OUTPUT_REGEX(1.5e+28 * meter_base_unit::unit_type(), "1\\.5e\\+0?28 meter"); // Too large for multiple.
330   // Too 'biggest or too smallest'.
331     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<float>::max()*meter_base_unit::unit_type(), "3\\.40282e\\+0?38 meter");
332     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<float>::min()*meter_base_unit::unit_type(), "1\\.17549e-0?38 meter");
333     BOOST_UNITS_TEST_OUTPUT(std::numeric_limits<double>::max()*meter_base_unit::unit_type(), "1.79769e+308 meter");
334     BOOST_UNITS_TEST_OUTPUT(std::numeric_limits<double>::min()*meter_base_unit::unit_type(), "2.22507e-308 meter");
335    // Infinity and NaN
336     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<float>::infinity()*meter_base_unit::unit_type(), "(1\\.#INF|inf|INF) meter");
337     BOOST_UNITS_TEST_OUTPUT_REGEX(-std::numeric_limits<float>::infinity()*meter_base_unit::unit_type(), "-(1\\.#INF|inf|INF) meter");
338     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<double>::quiet_NaN()*meter_base_unit::unit_type(), "(1\\.#QNAN|nan|NaNQ) meter");
339     BOOST_UNITS_TEST_OUTPUT_REGEX(-std::numeric_limits<double>::quiet_NaN()*meter_base_unit::unit_type(), "-?(1\\.#IND|nan|nan\\(ind\\)|NaNQ) meter");
340 
341     BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 meter second^-1");
342     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 kilometer");
343     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 kilo(meter second^-1)");
344     BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 millisecond");
345     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 millisecond");
346     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 meter millisecond^-1");
347     BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 meter^2");
348     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 kilo(meter^2)");
349     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.536 megameter"); // 1.5 * 2^10 = 1.5 * 1024 = 1.536
350     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kiloscaled_meter");
351     BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 custom1");
352     BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 custom2");
353     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kilocustom1");
354     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kilocustom2");
355     BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute<meter_base_unit::unit_type>(), "1.5 absolute meter");
356     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 10) * byte_base_unit::unit_type(), "1.024 kilobyte");
357 
358     BOOST_UNITS_TEST_OUTPUT(1.5, "1.5"); // scalar.
359     BOOST_UNITS_TEST_OUTPUT(1567., "1567"); // scalars are *not* autoprefixed.
360     BOOST_UNITS_TEST_OUTPUT(0.00015, "0.00015"); // scalars are *not* autoprefixed.
361     BOOST_UNITS_TEST_OUTPUT(-1.5, "-1.5"); // scalar.
362     BOOST_UNITS_TEST_OUTPUT(-1567., "-1567"); // scalars are *not* autoprefixed.
363     BOOST_UNITS_TEST_OUTPUT(-0.00015, "-0.00015"); // scalars are *not* autoprefixed.
364 #undef FORMATTERS
365 }
366 
BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_symbol)367 BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_symbol)
368 { // Engineering autoprefix, with symbol format.
369 #define FORMATTERS << boost::units::symbol_format << boost::units::engineering_prefix
370   // Single base unit like m.
371     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m");
372     BOOST_UNITS_TEST_OUTPUT(1500.0*meter_base_unit::unit_type(), "1.5 km");
373     BOOST_UNITS_TEST_OUTPUT(1.5e7*meter_base_unit::unit_type(), "15 Mm");
374     BOOST_UNITS_TEST_OUTPUT(1.5e-3*meter_base_unit::unit_type(), "1.5 mm");
375     BOOST_UNITS_TEST_OUTPUT(1.5e-9*meter_base_unit::unit_type(), "1.5 nm");
376     BOOST_UNITS_TEST_OUTPUT(1.5e-8*meter_base_unit::unit_type(), "15 nm");
377     BOOST_UNITS_TEST_OUTPUT(1.5e-10*meter_base_unit::unit_type(), "150 pm");
378   // Too small or large for a multiple name.
379     BOOST_UNITS_TEST_OUTPUT_REGEX(9.99999e-25 * meter_base_unit::unit_type(), "9\\.99999e-0?25 m"); // Just too small for multiple.
380     BOOST_UNITS_TEST_OUTPUT_REGEX(1e+28 * meter_base_unit::unit_type(), "1e\\+0?28 m"); // Just too large for multiple.
381     BOOST_UNITS_TEST_OUTPUT_REGEX(1.5e-25 * meter_base_unit::unit_type(), "1\\.5e-0?25 m"); // Too small for multiple.
382     BOOST_UNITS_TEST_OUTPUT_REGEX(1.5e+28 * meter_base_unit::unit_type(), "1\\.5e\\+0?28 m"); // Too large for multiple.
383   //
384     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<float>::max()*meter_base_unit::unit_type(), "3\\.40282e\\+0?38 m");
385     BOOST_UNITS_TEST_OUTPUT_REGEX(std::numeric_limits<float>::min()*meter_base_unit::unit_type(), "1\\.17549e-0?38 m");
386     BOOST_UNITS_TEST_OUTPUT(std::numeric_limits<double>::max()*meter_base_unit::unit_type(), "1.79769e+308 m");
387     BOOST_UNITS_TEST_OUTPUT(std::numeric_limits<double>::min()*meter_base_unit::unit_type(), "2.22507e-308 m");
388 
389     BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 m s^-1");
390     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 km");
391     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 k(m s^-1)");
392     BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 ms");
393     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 ms");
394     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 m ms^-1");
395     BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 m^2");
396     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 k(m^2)");
397     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.536 Mm"); // 1.5 * 2^10 = 1.5 * 1024 = 1.536
398     BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kscm");
399     BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 c1");
400     BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 c2");
401     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kc1");
402     BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kc2");
403     BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute<meter_base_unit::unit_type>(), "1.5 absolute m");
404     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 10) * byte_base_unit::unit_type(), "1.024 kb");
405 
406 #undef FORMATTERS
407 }
408 
BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol)409 BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol)
410 { // Binary prefix with symbol format.
411 #define FORMATTERS << boost::units::symbol_format << boost::units::binary_prefix
412     BOOST_UNITS_TEST_OUTPUT(1024 * byte_base_unit::unit_type(), "1 Kib");
413     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 20) * byte_base_unit::unit_type(), "1 Mib");
414     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 30) * byte_base_unit::unit_type(), "1 Gib");
415     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 40) * byte_base_unit::unit_type(), "1 Tib");
416     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 50) * byte_base_unit::unit_type(), "1 Pib");
417     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 60) * byte_base_unit::unit_type(), "1 Eib");
418     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 70) * byte_base_unit::unit_type(), "1 Zib");
419     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 80) * byte_base_unit::unit_type(), "1 Yib");
420     BOOST_UNITS_TEST_OUTPUT(42, "42"); // integer scalar.
421     BOOST_UNITS_TEST_OUTPUT(-42, "-42"); // integer scalar.
422     BOOST_UNITS_TEST_OUTPUT(1567, "1567"); // scalars are *not* autoprefixed.
423     BOOST_UNITS_TEST_OUTPUT(-1567, "-1567"); // scalars are *not* autoprefixed.
424 #undef FORMATTERS
425 }
426 
BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name)427 BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name)
428 { // Binary prefix with name format.
429   // http://physics.nist.gov/cuu/Units/binary.html
430   // 1998 the International Electrotechnical Commission (IEC) approved
431   // IEC 60027-2, Second edition, 2000-11, Letter symbols to be used in electrical technology
432   // - Part 2: Telecommunications and electronics.
433   // IEC 80000-13:2008, Quantities and units
434   // – Part 13: Information science and technology
435 #define FORMATTERS << boost::units::name_format << boost::units::binary_prefix
436     BOOST_UNITS_TEST_OUTPUT(2048  * byte_base_unit::unit_type(), "2 kibibyte");
437     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 32) *byte_base_unit::unit_type(), "4 gibibyte");
438     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 41) *byte_base_unit::unit_type(), "2 tebibyte"); // http://en.wikipedia.org/wiki/Tebibyte
439     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 50) *byte_base_unit::unit_type(), "1 pebibyte");
440     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 60) *byte_base_unit::unit_type(), "1 exbibyte");
441     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 70) *byte_base_unit::unit_type(), "1 zebibyte");
442     BOOST_UNITS_TEST_OUTPUT(std::pow(2., 80) *byte_base_unit::unit_type(), "1 yobibyte");
443     BOOST_UNITS_TEST_OUTPUT(2048, "2048"); // scalars are *not* autoprefixed.
444     BOOST_UNITS_TEST_OUTPUT(-4096, "-4096"); // scalars are *not* autoprefixed.
445 #undef FORMATTERS
446 }
447 
448 // Tests on using more than one format or prefix - only the last specified should be used.
449 // (This may indicate a programming mistake, but it is ignored).
BOOST_AUTO_TEST_CASE(test_output_quantity_name_duplicate)450 BOOST_AUTO_TEST_CASE(test_output_quantity_name_duplicate)
451 { // Ensure that if more than one format specified, only the last is used.
452 #define FORMATTERS << boost::units::symbol_format << boost::units::name_format
453     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter");
454 #undef FORMATTERS
455 }
456 
BOOST_AUTO_TEST_CASE(test_output_quantity_symbol_duplicate)457 BOOST_AUTO_TEST_CASE(test_output_quantity_symbol_duplicate)
458 { // Ensure that if more than one format specified, only the last is used.
459 #define FORMATTERS << boost::units::name_format << boost::units::symbol_format
460     BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m");
461 #undef FORMATTERS
462 }
463 
BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name_duplicate)464 BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name_duplicate)
465 { // Ensure that if more than one auto prefix specified, only the last is used.
466 #define FORMATTERS << boost::units::name_format << boost::units::binary_prefix << boost::units::engineering_prefix
467     BOOST_UNITS_TEST_OUTPUT(2048 * byte_base_unit::unit_type(), "2.048 kilobyte");
468 #undef FORMATTERS
469 }
470 
BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol_duplicate)471 BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol_duplicate)
472 { // Ensure that if more than one auto prefix specified, only the last is used.
473 #define FORMATTERS << boost::units::symbol_format << boost::units::engineering_prefix << boost::units::binary_prefix
474     BOOST_UNITS_TEST_OUTPUT(2048 * byte_base_unit::unit_type(), "2 Kib");
475 #undef FORMATTERS
476 }
477 
BOOST_AUTO_TEST_CASE(test_output_typename_format)478 BOOST_AUTO_TEST_CASE(test_output_typename_format)
479 {  // Displays typename formatting result. The test doesn't check the formatting result
480    // and thus doesn't fail because the formatting result is platform-dependent.
481 #define FORMATTERS << boost::units::typename_format
482     BOOST_UNITS_TEST_OUTPUT_DISPLAY(meter_base_unit::unit_type());
483     BOOST_UNITS_TEST_OUTPUT_DISPLAY(velocity());
484     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_length());
485     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_velocity1());
486     BOOST_UNITS_TEST_OUTPUT_DISPLAY(millisecond_base_unit::unit_type());
487     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_time());
488     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_velocity2());
489     BOOST_UNITS_TEST_OUTPUT_DISPLAY(area());
490     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_area());
491     BOOST_UNITS_TEST_OUTPUT_DISPLAY(double_scaled_length());
492     BOOST_UNITS_TEST_OUTPUT_DISPLAY(double_scaled_length2());
493     BOOST_UNITS_TEST_OUTPUT_DISPLAY(custom1());
494     BOOST_UNITS_TEST_OUTPUT_DISPLAY(custom2());
495     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_custom1());
496     BOOST_UNITS_TEST_OUTPUT_DISPLAY(scaled_custom2());
497     BOOST_UNITS_TEST_OUTPUT_DISPLAY(boost::units::absolute<meter_base_unit::unit_type>());
498 #undef FORMATTERS
499 }
500