1
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
2
// unit/quantity manipulation and conversion
4
// Copyright (C) 2003-2008 Matthias Christian Schabel
5
// Copyright (C) 2007-2008 Steven Watanabe
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)
11
#ifndef BOOST_UNITS_IO_HPP
12
#define BOOST_UNITS_IO_HPP
20
#include <boost/mpl/size.hpp>
21
#include <boost/mpl/begin.hpp>
22
#include <boost/mpl/next.hpp>
23
#include <boost/mpl/deref.hpp>
24
#include <boost/serialization/nvp.hpp>
26
#include <boost/units/units_fwd.hpp>
27
#include <boost/units/heterogeneous_system.hpp>
28
#include <boost/units/quantity.hpp>
29
#include <boost/units/scale.hpp>
30
#include <boost/units/static_rational.hpp>
31
#include <boost/units/unit.hpp>
32
#include <boost/units/detail/utility.hpp>
36
namespace serialization {
38
/// Boost Serialization library support for units.
39
template<class Archive,class System,class Dim>
40
inline void serialize(Archive& ar,boost::units::unit<Dim,System>&,const unsigned int /*version*/)
43
/// Boost Serialization library support for quantities.
44
template<class Archive,class Unit,class Y>
45
inline void serialize(Archive& ar,boost::units::quantity<Unit,Y>& q,const unsigned int /*version*/)
47
ar & boost::serialization::make_nvp("value", units::quantity_cast<Y&>(q));
50
} // namespace serialization
54
// get string representation of arbitrary type
55
template<class T> std::string to_string(const T& t)
57
std::stringstream sstr;
64
// get string representation of integral-valued @c static_rational
65
template<integer_type N> std::string to_string(const static_rational<N>&)
70
// get string representation of @c static_rational
71
template<integer_type N, integer_type D> std::string to_string(const static_rational<N,D>&)
73
return '(' + to_string(N) + '/' + to_string(D) + ')';
76
/// Write @c static_rational to @c std::basic_ostream.
77
template<class Char, class Traits, integer_type N, integer_type D>
78
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,const static_rational<N,D>& r)
84
/// traits template for unit names
85
template<class BaseUnit>
88
/// The full name of the unit (returns BaseUnit::name() by default)
89
static std::string name()
91
return(BaseUnit::name());
94
/// The symbol for the base unit (Returns BaseUnit::symbol() by default)
95
static std::string symbol()
97
return(BaseUnit::symbol());
103
symbol_fmt = 0, // default - reduces unit names to known symbols for both base and derived units
104
name_fmt, // output full unit names for base and derived units
105
raw_fmt, // output only symbols for base units
106
typename_fmt // output demangled typenames
112
struct xalloc_key_holder
115
static bool initialized;
119
int xalloc_key_holder<b>::value = 0;
122
bool xalloc_key_holder<b>::initialized = 0;
124
struct xalloc_key_initializer_t
126
xalloc_key_initializer_t()
128
if (!xalloc_key_holder<true>::initialized)
130
xalloc_key_holder<true>::value = std::ios_base::xalloc();
131
xalloc_key_holder<true>::initialized = true;
138
xalloc_key_initializer_t xalloc_key_initializer;
142
} // namespace detail
144
inline format_mode get_format(std::ios_base& ios)
146
return(static_cast<format_mode>(ios.iword(detail::xalloc_key_holder<true>::value)));
149
inline void set_format(std::ios_base& ios, format_mode new_mode)
151
ios.iword(detail::xalloc_key_holder<true>::value) = static_cast<long>(new_mode);
154
inline std::ios_base& typename_format(std::ios_base& ios)
156
(set_format)(ios, typename_fmt);
160
inline std::ios_base& raw_format(std::ios_base& ios)
162
(set_format)(ios, raw_fmt);
166
inline std::ios_base& symbol_format(std::ios_base& ios)
168
(set_format)(ios, symbol_fmt);
172
inline std::ios_base& name_format(std::ios_base& ios)
174
(set_format)(ios, name_fmt);
180
template<integer_type N, integer_type D>
181
inline std::string exponent_string(const static_rational<N,D>& r)
183
return '^' + to_string(r);
187
inline std::string exponent_string(const static_rational<1>&)
193
inline std::string base_unit_symbol_string(const T&)
195
return base_unit_info<typename T::tag_type>::symbol() + exponent_string(typename T::value_type());
199
inline std::string base_unit_name_string(const T&)
201
return base_unit_info<typename T::tag_type>::name() + exponent_string(typename T::value_type());
204
// stringify with symbols
206
struct symbol_string_impl
208
template<class Begin>
211
typedef typename symbol_string_impl<N-1>::template apply<typename Begin::next> next;
212
static void value(std::string& str)
214
str += base_unit_symbol_string(typename Begin::item()) + ' ';
221
struct symbol_string_impl<1>
223
template<class Begin>
226
static void value(std::string& str)
228
str += base_unit_symbol_string(typename Begin::item());
234
struct symbol_string_impl<0>
236
template<class Begin>
239
static void value(std::string& str)
241
// better shorthand for dimensionless?
242
str += "dimensionless";
248
struct scale_symbol_string_impl
250
template<class Begin>
253
static void value(std::string& str)
255
str += Begin::item::symbol();
256
scale_symbol_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
262
struct scale_symbol_string_impl<0>
264
template<class Begin>
267
static void value(std::string&) { }
271
// stringify with names
273
struct name_string_impl
275
template<class Begin>
278
typedef typename name_string_impl<N-1>::template apply<typename Begin::next> next;
279
static void value(std::string& str)
281
str += base_unit_name_string(typename Begin::item()) + ' ';
288
struct name_string_impl<1>
290
template<class Begin>
293
static void value(std::string& str)
295
str += base_unit_name_string(typename Begin::item());
301
struct name_string_impl<0>
303
template<class Begin>
306
static void value(std::string& str)
308
str += "dimensionless";
314
struct scale_name_string_impl
316
template<class Begin>
319
static void value(std::string& str)
321
str += Begin::item::name();
322
scale_name_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
328
struct scale_name_string_impl<0>
330
template<class Begin>
333
static void value(std::string&) { }
337
} // namespace detail
341
// These two overloads of symbol_string and name_string will
342
// will pick up homogeneous_systems. They simply call the
343
// appropriate function with a heterogeneous_system.
344
template<class Dimension,class System, class SubFormatter>
346
to_string_impl(const unit<Dimension,System>&, SubFormatter f)
348
return f(typename reduce_unit<unit<Dimension, System> >::type());
352
// this overload picks up heterogeneous units that are not scaled.
353
template<class Dimension,class Units, class Subformatter>
355
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >&, Subformatter f)
358
f.template append_units_to<Units>(str);
362
// This overload is a special case for heterogeneous_system which
363
// is really unitless
365
template<class Subformatter>
367
to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, dimensionless_type> > >&, Subformatter)
369
return("dimensionless");
372
// this overload deals with heterogeneous_systems which are unitless
375
template<class Scale, class Subformatter>
377
to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, Scale> > >&, Subformatter f)
380
f.template append_scale_to<Scale>(str);
384
// this overload deals with scaled units.
386
template<class Dimension,class Units,class Scale, class Subformatter>
388
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, Scale> > >&, Subformatter f)
392
f.template append_scale_to<Scale>(str);
394
std::string without_scale = f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >());
396
if (f.is_default_string(without_scale, unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >()))
399
str += without_scale;
404
str += without_scale;
410
// this overload catches scaled units that have a single base unit
411
// raised to the first power. It causes si::nano * si::meters to not
412
// put parentheses around the meters. i.e. nm rather than n(m)
414
template<class Dimension,class Unit,class Scale, class Subformatter>
416
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
420
f.template append_scale_to<Scale>(str);
421
str += f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >());
426
// this overload is necessary to disambiguate.
427
// it catches units that are unscaled and have a single
428
// base unit raised to the first power. It is treated the
429
// same as any other unscaled unit.
431
template<class Dimension,class Unit,class Subformatter>
433
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, dimensionless_type> > >&, Subformatter f)
436
f.template append_units_to<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type> >(str);
441
// this overload catches scaled units that have a single scaled base unit
442
// raised to the first power. It moves that scaling on the base unit
443
// to the unit level scaling and recurses. By doing this we make sure that
444
// si::milli * si::kilograms will print g rather than mkg
447
template<class Dimension,class Unit,class UnitScale, class Scale, class Subformatter>
449
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
454
heterogeneous_system<
455
heterogeneous_system_impl<
456
list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>,
458
typename mpl::times<Scale, list<UnitScale, dimensionless_type> >::type
464
// this overload disambuguates between the overload for an unscaled unit
465
// and the overload for a scaled base unit raised to the first power.
467
template<class Dimension,class Unit,class UnitScale,class Subformatter>
469
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >&, Subformatter f)
472
f.template append_units_to<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type> >(str);
476
struct format_raw_symbol_impl {
477
template<class Units>
478
void append_units_to(std::string& str) {
479
detail::symbol_string_impl<Units::size::value>::template apply<Units>::value(str);
481
template<class Scale>
482
void append_scale_to(std::string& str) {
483
detail::scale_symbol_string_impl<Scale::size::value>::template apply<Scale>::value(str);
486
std::string operator()(const Unit& unit) {
487
return(to_string_impl(unit, *this));
490
bool is_default_string(const std::string&, const Unit&) {
495
struct format_symbol_impl : format_raw_symbol_impl {
497
std::string operator()(const Unit& unit) {
498
return(symbol_string(unit));
501
bool is_default_string(const std::string& str, const Unit& unit) {
502
return(str == to_string_impl(unit, format_raw_symbol_impl()));
506
struct format_raw_name_impl {
507
template<class Units>
508
void append_units_to(std::string& str) {
509
detail::name_string_impl<(Units::size::value)>::template apply<Units>::value(str);
511
template<class Scale>
512
void append_scale_to(std::string& str) {
513
detail::scale_name_string_impl<Scale::size::value>::template apply<Scale>::value(str);
516
std::string operator()(const Unit& unit) {
517
return(to_string_impl(unit, *this));
520
bool is_default_string(const std::string&, const Unit&) {
525
struct format_name_impl : format_raw_name_impl {
527
std::string operator()(const Unit& unit) {
528
return(name_string(unit));
531
bool is_default_string(const std::string& str, const Unit& unit) {
532
return(str == to_string_impl(unit, format_raw_name_impl()));
536
} // namespace detail
538
template<class Dimension,class System>
540
typename_string(const unit<Dimension, System>&)
542
return simplify_typename(typename reduce_unit< unit<Dimension,System> >::type());
545
template<class Dimension,class System>
547
symbol_string(const unit<Dimension, System>&)
549
return detail::to_string_impl(unit<Dimension,System>(), detail::format_symbol_impl());
552
template<class Dimension,class System>
554
name_string(const unit<Dimension, System>&)
556
return detail::to_string_impl(unit<Dimension,System>(), detail::format_name_impl());
559
/// Print an @c unit as a list of base units and exponents
561
/// for @c symbol_format this gives e.g. "m s^-1" or "J"
562
/// for @c name_format this gives e.g. "meter second^-1" or "joule"
563
/// for @c raw_format this gives e.g. "m s^-1" or "meter kilogram^2 second^-2"
564
/// for @c typename_format this gives the typename itself (currently demangled only on GCC)
565
template<class Char, class Traits, class Dimension, class System>
566
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const unit<Dimension, System>& u)
568
if (units::get_format(os) == typename_fmt)
570
os << typename_string(u);
572
else if (units::get_format(os) == raw_fmt)
574
os << detail::to_string_impl(u, detail::format_raw_symbol_impl());
576
else if (units::get_format(os) == symbol_fmt)
578
os << symbol_string(u);
580
else if (units::get_format(os) == name_fmt)
582
os << name_string(u);
586
assert(!"The format mode must be one of: typename_format, raw_format, name_format, symbol_format");
593
/// Print a @c quantity. Prints the value followed by the unit
594
template<class Char, class Traits, class Unit, class T>
595
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const quantity<Unit, T>& q)
597
os << q.value() << ' ' << Unit();
1
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
2
// unit/quantity manipulation and conversion
4
// Copyright (C) 2003-2008 Matthias Christian Schabel
5
// Copyright (C) 2007-2008 Steven Watanabe
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)
11
#ifndef BOOST_UNITS_IO_HPP
12
#define BOOST_UNITS_IO_HPP
20
#include <boost/mpl/size.hpp>
21
#include <boost/mpl/begin.hpp>
22
#include <boost/mpl/next.hpp>
23
#include <boost/mpl/deref.hpp>
24
#include <boost/serialization/nvp.hpp>
26
#include <boost/units/units_fwd.hpp>
27
#include <boost/units/heterogeneous_system.hpp>
28
#include <boost/units/quantity.hpp>
29
#include <boost/units/scale.hpp>
30
#include <boost/units/static_rational.hpp>
31
#include <boost/units/unit.hpp>
32
#include <boost/units/detail/utility.hpp>
36
namespace serialization {
38
/// Boost Serialization library support for units.
39
template<class Archive,class System,class Dim>
40
inline void serialize(Archive& ar,boost::units::unit<Dim,System>&,const unsigned int /*version*/)
43
/// Boost Serialization library support for quantities.
44
template<class Archive,class Unit,class Y>
45
inline void serialize(Archive& ar,boost::units::quantity<Unit,Y>& q,const unsigned int /*version*/)
47
ar & boost::serialization::make_nvp("value", units::quantity_cast<Y&>(q));
50
} // namespace serialization
54
// get string representation of arbitrary type
55
template<class T> std::string to_string(const T& t)
57
std::stringstream sstr;
64
// get string representation of integral-valued @c static_rational
65
template<integer_type N> std::string to_string(const static_rational<N>&)
70
// get string representation of @c static_rational
71
template<integer_type N, integer_type D> std::string to_string(const static_rational<N,D>&)
73
return '(' + to_string(N) + '/' + to_string(D) + ')';
76
/// Write @c static_rational to @c std::basic_ostream.
77
template<class Char, class Traits, integer_type N, integer_type D>
78
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,const static_rational<N,D>& r)
84
/// traits template for unit names
85
template<class BaseUnit>
88
/// The full name of the unit (returns BaseUnit::name() by default)
89
static std::string name()
91
return(BaseUnit::name());
94
/// The symbol for the base unit (Returns BaseUnit::symbol() by default)
95
static std::string symbol()
97
return(BaseUnit::symbol());
103
symbol_fmt = 0, // default - reduces unit names to known symbols for both base and derived units
104
name_fmt, // output full unit names for base and derived units
105
raw_fmt, // output only symbols for base units
106
typename_fmt // output demangled typenames
112
struct xalloc_key_holder
115
static bool initialized;
119
int xalloc_key_holder<b>::value = 0;
122
bool xalloc_key_holder<b>::initialized = 0;
124
struct xalloc_key_initializer_t
126
xalloc_key_initializer_t()
128
if (!xalloc_key_holder<true>::initialized)
130
xalloc_key_holder<true>::value = std::ios_base::xalloc();
131
xalloc_key_holder<true>::initialized = true;
138
xalloc_key_initializer_t xalloc_key_initializer;
142
} // namespace detail
144
inline format_mode get_format(std::ios_base& ios)
146
return(static_cast<format_mode>(ios.iword(detail::xalloc_key_holder<true>::value)));
149
inline void set_format(std::ios_base& ios, format_mode new_mode)
151
ios.iword(detail::xalloc_key_holder<true>::value) = static_cast<long>(new_mode);
154
inline std::ios_base& typename_format(std::ios_base& ios)
156
(set_format)(ios, typename_fmt);
160
inline std::ios_base& raw_format(std::ios_base& ios)
162
(set_format)(ios, raw_fmt);
166
inline std::ios_base& symbol_format(std::ios_base& ios)
168
(set_format)(ios, symbol_fmt);
172
inline std::ios_base& name_format(std::ios_base& ios)
174
(set_format)(ios, name_fmt);
180
template<integer_type N, integer_type D>
181
inline std::string exponent_string(const static_rational<N,D>& r)
183
return '^' + to_string(r);
187
inline std::string exponent_string(const static_rational<1>&)
193
inline std::string base_unit_symbol_string(const T&)
195
return base_unit_info<typename T::tag_type>::symbol() + exponent_string(typename T::value_type());
199
inline std::string base_unit_name_string(const T&)
201
return base_unit_info<typename T::tag_type>::name() + exponent_string(typename T::value_type());
204
// stringify with symbols
206
struct symbol_string_impl
208
template<class Begin>
211
typedef typename symbol_string_impl<N-1>::template apply<typename Begin::next> next;
212
static void value(std::string& str)
214
str += base_unit_symbol_string(typename Begin::item()) + ' ';
221
struct symbol_string_impl<1>
223
template<class Begin>
226
static void value(std::string& str)
228
str += base_unit_symbol_string(typename Begin::item());
234
struct symbol_string_impl<0>
236
template<class Begin>
239
static void value(std::string& str)
241
// better shorthand for dimensionless?
242
str += "dimensionless";
248
struct scale_symbol_string_impl
250
template<class Begin>
253
static void value(std::string& str)
255
str += Begin::item::symbol();
256
scale_symbol_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
262
struct scale_symbol_string_impl<0>
264
template<class Begin>
267
static void value(std::string&) { }
271
// stringify with names
273
struct name_string_impl
275
template<class Begin>
278
typedef typename name_string_impl<N-1>::template apply<typename Begin::next> next;
279
static void value(std::string& str)
281
str += base_unit_name_string(typename Begin::item()) + ' ';
288
struct name_string_impl<1>
290
template<class Begin>
293
static void value(std::string& str)
295
str += base_unit_name_string(typename Begin::item());
301
struct name_string_impl<0>
303
template<class Begin>
306
static void value(std::string& str)
308
str += "dimensionless";
314
struct scale_name_string_impl
316
template<class Begin>
319
static void value(std::string& str)
321
str += Begin::item::name();
322
scale_name_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
328
struct scale_name_string_impl<0>
330
template<class Begin>
333
static void value(std::string&) { }
337
} // namespace detail
341
// These two overloads of symbol_string and name_string will
342
// will pick up homogeneous_systems. They simply call the
343
// appropriate function with a heterogeneous_system.
344
template<class Dimension,class System, class SubFormatter>
346
to_string_impl(const unit<Dimension,System>&, SubFormatter f)
348
return f(typename reduce_unit<unit<Dimension, System> >::type());
352
// this overload picks up heterogeneous units that are not scaled.
353
template<class Dimension,class Units, class Subformatter>
355
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >&, Subformatter f)
358
f.template append_units_to<Units>(str);
362
// This overload is a special case for heterogeneous_system which
363
// is really unitless
365
template<class Subformatter>
367
to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, dimensionless_type> > >&, Subformatter)
369
return("dimensionless");
372
// this overload deals with heterogeneous_systems which are unitless
375
template<class Scale, class Subformatter>
377
to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, Scale> > >&, Subformatter f)
380
f.template append_scale_to<Scale>(str);
384
// this overload deals with scaled units.
386
template<class Dimension,class Units,class Scale, class Subformatter>
388
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, Scale> > >&, Subformatter f)
392
f.template append_scale_to<Scale>(str);
394
std::string without_scale = f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >());
396
if (f.is_default_string(without_scale, unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >()))
399
str += without_scale;
404
str += without_scale;
410
// this overload catches scaled units that have a single base unit
411
// raised to the first power. It causes si::nano * si::meters to not
412
// put parentheses around the meters. i.e. nm rather than n(m)
414
template<class Dimension,class Unit,class Scale, class Subformatter>
416
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
420
f.template append_scale_to<Scale>(str);
421
str += f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >());
426
// this overload is necessary to disambiguate.
427
// it catches units that are unscaled and have a single
428
// base unit raised to the first power. It is treated the
429
// same as any other unscaled unit.
431
template<class Dimension,class Unit,class Subformatter>
433
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, dimensionless_type> > >&, Subformatter f)
436
f.template append_units_to<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type> >(str);
441
// this overload catches scaled units that have a single scaled base unit
442
// raised to the first power. It moves that scaling on the base unit
443
// to the unit level scaling and recurses. By doing this we make sure that
444
// si::milli * si::kilograms will print g rather than mkg
447
template<class Dimension,class Unit,class UnitScale, class Scale, class Subformatter>
449
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
454
heterogeneous_system<
455
heterogeneous_system_impl<
456
list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>,
458
typename mpl::times<Scale, list<UnitScale, dimensionless_type> >::type
464
// this overload disambuguates between the overload for an unscaled unit
465
// and the overload for a scaled base unit raised to the first power.
467
template<class Dimension,class Unit,class UnitScale,class Subformatter>
469
to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >&, Subformatter f)
472
f.template append_units_to<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type> >(str);
476
struct format_raw_symbol_impl {
477
template<class Units>
478
void append_units_to(std::string& str) {
479
detail::symbol_string_impl<Units::size::value>::template apply<Units>::value(str);
481
template<class Scale>
482
void append_scale_to(std::string& str) {
483
detail::scale_symbol_string_impl<Scale::size::value>::template apply<Scale>::value(str);
486
std::string operator()(const Unit& unit) {
487
return(to_string_impl(unit, *this));
490
bool is_default_string(const std::string&, const Unit&) {
495
struct format_symbol_impl : format_raw_symbol_impl {
497
std::string operator()(const Unit& unit) {
498
return(symbol_string(unit));
501
bool is_default_string(const std::string& str, const Unit& unit) {
502
return(str == to_string_impl(unit, format_raw_symbol_impl()));
506
struct format_raw_name_impl {
507
template<class Units>
508
void append_units_to(std::string& str) {
509
detail::name_string_impl<(Units::size::value)>::template apply<Units>::value(str);
511
template<class Scale>
512
void append_scale_to(std::string& str) {
513
detail::scale_name_string_impl<Scale::size::value>::template apply<Scale>::value(str);
516
std::string operator()(const Unit& unit) {
517
return(to_string_impl(unit, *this));
520
bool is_default_string(const std::string&, const Unit&) {
525
struct format_name_impl : format_raw_name_impl {
527
std::string operator()(const Unit& unit) {
528
return(name_string(unit));
531
bool is_default_string(const std::string& str, const Unit& unit) {
532
return(str == to_string_impl(unit, format_raw_name_impl()));
536
template<class Char, class Traits>
537
inline void do_print(std::basic_ostream<Char, Traits>& os, const std::string& s) {
541
inline void do_print(std::ostream& os, const std::string& s) {
545
template<class Char, class Traits>
546
inline void do_print(std::basic_ostream<Char, Traits>& os, const char* s) {
550
} // namespace detail
552
template<class Dimension,class System>
554
typename_string(const unit<Dimension, System>&)
556
return simplify_typename(typename reduce_unit< unit<Dimension,System> >::type());
559
template<class Dimension,class System>
561
symbol_string(const unit<Dimension, System>&)
563
return detail::to_string_impl(unit<Dimension,System>(), detail::format_symbol_impl());
566
template<class Dimension,class System>
568
name_string(const unit<Dimension, System>&)
570
return detail::to_string_impl(unit<Dimension,System>(), detail::format_name_impl());
573
/// Print an @c unit as a list of base units and exponents
575
/// for @c symbol_format this gives e.g. "m s^-1" or "J"
576
/// for @c name_format this gives e.g. "meter second^-1" or "joule"
577
/// for @c raw_format this gives e.g. "m s^-1" or "meter kilogram^2 second^-2"
578
/// for @c typename_format this gives the typename itself (currently demangled only on GCC)
579
template<class Char, class Traits, class Dimension, class System>
580
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const unit<Dimension, System>& u)
582
if (units::get_format(os) == typename_fmt)
584
detail::do_print(os , typename_string(u));
586
else if (units::get_format(os) == raw_fmt)
588
detail::do_print(os, detail::to_string_impl(u, detail::format_raw_symbol_impl()));
590
else if (units::get_format(os) == symbol_fmt)
592
detail::do_print(os, symbol_string(u));
594
else if (units::get_format(os) == name_fmt)
596
detail::do_print(os, name_string(u));
600
assert(!"The format mode must be one of: typename_format, raw_format, name_format, symbol_format");
607
/// Print a @c quantity. Prints the value followed by the unit
608
template<class Char, class Traits, class Unit, class T>
609
inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const quantity<Unit, T>& q)
611
os << q.value() << ' ' << Unit();