Warning, file /include/boost/units/io.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_IO_HPP
0012 #define BOOST_UNITS_IO_HPP
0013
0014
0015
0016
0017
0018
0019
0020 #include <cassert>
0021 #include <cmath>
0022 #include <string>
0023 #include <iosfwd>
0024 #include <ios>
0025 #include <sstream>
0026
0027 #include <boost/assert.hpp>
0028 #include <boost/core/nvp.hpp>
0029
0030 #include <boost/units/units_fwd.hpp>
0031 #include <boost/units/heterogeneous_system.hpp>
0032 #include <boost/units/make_scaled_unit.hpp>
0033 #include <boost/units/quantity.hpp>
0034 #include <boost/units/scale.hpp>
0035 #include <boost/units/static_rational.hpp>
0036 #include <boost/units/unit.hpp>
0037 #include <boost/units/detail/utility.hpp>
0038
0039 namespace boost {
0040
0041 namespace serialization {
0042
0043
0044 template<class Archive,class System,class Dim>
0045 inline void serialize(Archive& ,boost::units::unit<Dim,System>&,const unsigned int )
0046 { }
0047
0048
0049 template<class Archive,class Unit,class Y>
0050 inline void serialize(Archive& ar,boost::units::quantity<Unit,Y>& q,const unsigned int )
0051 {
0052 ar & boost::serialization::make_nvp("value", units::quantity_cast<Y&>(q));
0053 }
0054
0055 }
0056
0057 namespace units {
0058
0059
0060 template<class T> std::string to_string(const T& t)
0061 {
0062 std::stringstream sstr;
0063
0064 sstr << t;
0065
0066 return sstr.str();
0067 }
0068
0069
0070 template<integer_type N> std::string to_string(const static_rational<N>&)
0071 {
0072 return to_string(N);
0073 }
0074
0075
0076 template<integer_type N, integer_type D> std::string to_string(const static_rational<N,D>&)
0077 {
0078 return '(' + to_string(N) + '/' + to_string(D) + ')';
0079 }
0080
0081
0082 template<class Char, class Traits, integer_type N, integer_type D>
0083 inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,const static_rational<N,D>& r)
0084 {
0085 os << to_string(r);
0086 return os;
0087 }
0088
0089
0090 template<class BaseUnit>
0091 struct base_unit_info
0092 {
0093
0094 typedef void base_unit_info_primary_template;
0095
0096 static std::string name()
0097 {
0098 return(BaseUnit::name());
0099 }
0100
0101 static std::string symbol()
0102 {
0103 return(BaseUnit::symbol());
0104 }
0105 };
0106
0107
0108 enum format_mode
0109 {
0110 symbol_fmt = 0,
0111 name_fmt = 1,
0112 raw_fmt = 2,
0113 typename_fmt = 3,
0114 fmt_mask = 3
0115 };
0116
0117
0118 enum autoprefix_mode
0119 {
0120 autoprefix_none = 0,
0121 autoprefix_engineering = 4,
0122 autoprefix_binary = 8,
0123 autoprefix_mask = 12
0124 };
0125
0126 namespace detail {
0127
0128 template<bool>
0129 struct xalloc_key_holder
0130 {
0131 static int value;
0132 static bool initialized;
0133 };
0134
0135 template<bool b>
0136 int xalloc_key_holder<b>::value = 0;
0137
0138 template<bool b>
0139 bool xalloc_key_holder<b>::initialized = 0;
0140
0141 struct xalloc_key_initializer_t
0142 {
0143 xalloc_key_initializer_t()
0144 {
0145 if (!xalloc_key_holder<true>::initialized)
0146 {
0147 xalloc_key_holder<true>::value = std::ios_base::xalloc();
0148 xalloc_key_holder<true>::initialized = true;
0149 }
0150 }
0151 };
0152
0153 namespace {
0154
0155 xalloc_key_initializer_t xalloc_key_initializer;
0156
0157 }
0158
0159 }
0160
0161
0162 inline long get_flags(std::ios_base& ios, long mask)
0163 {
0164 return(ios.iword(detail::xalloc_key_holder<true>::value) & mask);
0165 }
0166
0167
0168 inline void set_flags(std::ios_base& ios, long new_flags, long mask)
0169 {
0170 BOOST_ASSERT((~mask & new_flags) == 0);
0171 long& flags = ios.iword(detail::xalloc_key_holder<true>::value);
0172 flags = (flags & ~mask) | new_flags;
0173 }
0174
0175
0176 inline format_mode get_format(std::ios_base& ios)
0177 {
0178 return(static_cast<format_mode>((get_flags)(ios, fmt_mask)));
0179 }
0180
0181
0182 inline void set_format(std::ios_base& ios, format_mode new_mode)
0183 {
0184 (set_flags)(ios, new_mode, fmt_mask);
0185 }
0186
0187
0188 inline std::ios_base& typename_format(std::ios_base& ios)
0189 {
0190 (set_format)(ios, typename_fmt);
0191 return(ios);
0192 }
0193
0194
0195 inline std::ios_base& raw_format(std::ios_base& ios)
0196 {
0197 (set_format)(ios, raw_fmt);
0198 return(ios);
0199 }
0200
0201
0202 inline std::ios_base& symbol_format(std::ios_base& ios)
0203 {
0204 (set_format)(ios, symbol_fmt);
0205 return(ios);
0206 }
0207
0208
0209 inline std::ios_base& name_format(std::ios_base& ios)
0210 {
0211 (set_format)(ios, name_fmt);
0212 return(ios);
0213 }
0214
0215
0216 inline autoprefix_mode get_autoprefix(std::ios_base& ios)
0217 {
0218 return static_cast<autoprefix_mode>((get_flags)(ios, autoprefix_mask));
0219 }
0220
0221
0222 inline void set_autoprefix(std::ios_base& ios, autoprefix_mode new_mode)
0223 {
0224 (set_flags)(ios, new_mode, autoprefix_mask);
0225 }
0226
0227
0228 inline std::ios_base& no_prefix(std::ios_base& ios)
0229 {
0230 (set_autoprefix)(ios, autoprefix_none);
0231 return ios;
0232 }
0233
0234
0235 inline std::ios_base& engineering_prefix(std::ios_base& ios)
0236 {
0237 (set_autoprefix)(ios, autoprefix_engineering);
0238 return ios;
0239 }
0240
0241
0242 inline std::ios_base& binary_prefix(std::ios_base& ios)
0243 {
0244 (set_autoprefix)(ios, autoprefix_binary);
0245 return ios;
0246 }
0247
0248 namespace detail {
0249
0250
0251 template<integer_type N, integer_type D>
0252 inline std::string exponent_string(const static_rational<N,D>& r)
0253 {
0254 return '^' + to_string(r);
0255 }
0256
0257
0258 template<>
0259 inline std::string exponent_string(const static_rational<1>&)
0260 {
0261 return "";
0262 }
0263
0264 template<class T>
0265 inline std::string base_unit_symbol_string(const T&)
0266 {
0267 return base_unit_info<typename T::tag_type>::symbol() + exponent_string(typename T::value_type());
0268 }
0269
0270 template<class T>
0271 inline std::string base_unit_name_string(const T&)
0272 {
0273 return base_unit_info<typename T::tag_type>::name() + exponent_string(typename T::value_type());
0274 }
0275
0276
0277 template<int N>
0278 struct symbol_string_impl
0279 {
0280 template<class Begin>
0281 struct apply
0282 {
0283 typedef typename symbol_string_impl<N-1>::template apply<typename Begin::next> next;
0284 static void value(std::string& str)
0285 {
0286 str += base_unit_symbol_string(typename Begin::item()) + ' ';
0287 next::value(str);
0288 }
0289 };
0290 };
0291
0292 template<>
0293 struct symbol_string_impl<1>
0294 {
0295 template<class Begin>
0296 struct apply
0297 {
0298 static void value(std::string& str)
0299 {
0300 str += base_unit_symbol_string(typename Begin::item());
0301 }
0302 };
0303 };
0304
0305 template<>
0306 struct symbol_string_impl<0>
0307 {
0308 template<class Begin>
0309 struct apply
0310 {
0311 static void value(std::string& str)
0312 {
0313
0314 str += "dimensionless";
0315 }
0316 };
0317 };
0318
0319 template<int N>
0320 struct scale_symbol_string_impl
0321 {
0322 template<class Begin>
0323 struct apply
0324 {
0325 static void value(std::string& str)
0326 {
0327 str += Begin::item::symbol();
0328 scale_symbol_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
0329 }
0330 };
0331 };
0332
0333 template<>
0334 struct scale_symbol_string_impl<0>
0335 {
0336 template<class Begin>
0337 struct apply
0338 {
0339 static void value(std::string&) { }
0340 };
0341 };
0342
0343
0344 template<int N>
0345 struct name_string_impl
0346 {
0347 template<class Begin>
0348 struct apply
0349 {
0350 typedef typename name_string_impl<N-1>::template apply<typename Begin::next> next;
0351 static void value(std::string& str)
0352 {
0353 str += base_unit_name_string(typename Begin::item()) + ' ';
0354 next::value(str);
0355 }
0356 };
0357 };
0358
0359 template<>
0360 struct name_string_impl<1>
0361 {
0362 template<class Begin>
0363 struct apply
0364 {
0365 static void value(std::string& str)
0366 {
0367 str += base_unit_name_string(typename Begin::item());
0368 }
0369 };
0370 };
0371
0372 template<>
0373 struct name_string_impl<0>
0374 {
0375 template<class Begin>
0376 struct apply
0377 {
0378 static void value(std::string& str)
0379 {
0380 str += "dimensionless";
0381 }
0382 };
0383 };
0384
0385 template<int N>
0386 struct scale_name_string_impl
0387 {
0388 template<class Begin>
0389 struct apply
0390 {
0391 static void value(std::string& str)
0392 {
0393 str += Begin::item::name();
0394 scale_name_string_impl<N - 1>::template apply<typename Begin::next>::value(str);
0395 }
0396 };
0397 };
0398
0399 template<>
0400 struct scale_name_string_impl<0>
0401 {
0402 template<class Begin>
0403 struct apply
0404 {
0405 static void value(std::string&) { }
0406 };
0407 };
0408
0409 }
0410
0411 namespace detail {
0412
0413
0414
0415
0416 template<class Dimension,class System, class SubFormatter>
0417 inline std::string
0418 to_string_impl(const unit<Dimension,System>&, SubFormatter f)
0419 {
0420 return f(typename reduce_unit<unit<Dimension, System> >::type());
0421 }
0422
0423
0424
0425 template<class Dimension,class Units, class Subformatter>
0426 inline std::string
0427 to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >&, Subformatter f)
0428 {
0429 std::string str;
0430 f.template append_units_to<Units>(str);
0431 return(str);
0432 }
0433
0434
0435
0436
0437 template<class Subformatter>
0438 inline std::string
0439 to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, dimensionless_type> > >&, Subformatter)
0440 {
0441 return("dimensionless");
0442 }
0443
0444
0445
0446
0447 template<class Scale, class Subformatter>
0448 inline std::string
0449 to_string_impl(const unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, Scale> > >&, Subformatter f)
0450 {
0451 std::string str;
0452 f.template append_scale_to<Scale>(str);
0453 return(str);
0454 }
0455
0456
0457
0458 template<class Dimension,class Units,class Scale, class Subformatter>
0459 inline std::string
0460 to_string_impl(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, Scale> > >&, Subformatter f)
0461 {
0462 std::string str;
0463
0464 f.template append_scale_to<Scale>(str);
0465
0466 std::string without_scale = f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >());
0467
0468 if (f.is_default_string(without_scale, unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >()))
0469 {
0470 str += "(";
0471 str += without_scale;
0472 str += ")";
0473 }
0474 else
0475 {
0476 str += without_scale;
0477 }
0478
0479 return(str);
0480 }
0481
0482
0483
0484
0485
0486 template<class Dimension,class Unit,class Scale, class Subformatter>
0487 inline std::string
0488 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)
0489 {
0490 std::string str;
0491
0492 f.template append_scale_to<Scale>(str);
0493 str += f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >());
0494
0495 return(str);
0496 }
0497
0498
0499
0500
0501
0502
0503 template<class Dimension,class Unit,class Subformatter>
0504 inline std::string
0505 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)
0506 {
0507 std::string str;
0508 f.template append_units_to<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type> >(str);
0509 return(str);
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521 template<class Dimension,class Unit,class UnitScale, class Scale, class Subformatter>
0522 inline std::string
0523 to_string_impl(
0524 const unit<
0525 Dimension,
0526 heterogeneous_system<
0527 heterogeneous_system_impl<
0528 list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>,
0529 Dimension,
0530 Scale
0531 >
0532 >
0533 >&,
0534 Subformatter f,
0535 typename base_unit_info<scaled_base_unit<Unit, UnitScale> >::base_unit_info_primary_template* = 0)
0536 {
0537 return(f(
0538 unit<
0539 Dimension,
0540 heterogeneous_system<
0541 heterogeneous_system_impl<
0542 list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>,
0543 Dimension,
0544 typename mpl::times<Scale, list<scale_list_dim<UnitScale>, dimensionless_type> >::type
0545 >
0546 >
0547 >()));
0548 }
0549
0550
0551
0552
0553 template<class Dimension,class Unit,class UnitScale,class Subformatter>
0554 inline std::string
0555 to_string_impl(
0556 const unit<
0557 Dimension,
0558 heterogeneous_system<
0559 heterogeneous_system_impl<
0560 list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type>,
0561 Dimension,
0562 dimensionless_type
0563 >
0564 >
0565 >&,
0566 Subformatter f,
0567 typename base_unit_info<scaled_base_unit<Unit, UnitScale> >::base_unit_info_primary_template* = 0)
0568 {
0569 std::string str;
0570 f.template append_units_to<list<heterogeneous_system_dim<scaled_base_unit<Unit, UnitScale>, static_rational<1> >, dimensionless_type> >(str);
0571 return(str);
0572 }
0573
0574 struct format_raw_symbol_impl {
0575 template<class Units>
0576 void append_units_to(std::string& str) {
0577 detail::symbol_string_impl<Units::size::value>::template apply<Units>::value(str);
0578 }
0579 template<class Scale>
0580 void append_scale_to(std::string& str) {
0581 detail::scale_symbol_string_impl<Scale::size::value>::template apply<Scale>::value(str);
0582 }
0583 template<class Unit>
0584 std::string operator()(const Unit& u) {
0585 return(to_string_impl(u, *this));
0586 }
0587 template<class Unit>
0588 bool is_default_string(const std::string&, const Unit&) {
0589 return(true);
0590 }
0591 };
0592
0593 struct format_symbol_impl : format_raw_symbol_impl {
0594 template<class Unit>
0595 std::string operator()(const Unit& u) {
0596 return(symbol_string(u));
0597 }
0598 template<class Unit>
0599 bool is_default_string(const std::string& str, const Unit& u) {
0600 return(str == to_string_impl(u, format_raw_symbol_impl()));
0601 }
0602 };
0603
0604 struct format_raw_name_impl {
0605 template<class Units>
0606 void append_units_to(std::string& str) {
0607 detail::name_string_impl<(Units::size::value)>::template apply<Units>::value(str);
0608 }
0609 template<class Scale>
0610 void append_scale_to(std::string& str) {
0611 detail::scale_name_string_impl<Scale::size::value>::template apply<Scale>::value(str);
0612 }
0613 template<class Unit>
0614 std::string operator()(const Unit& u) {
0615 return(to_string_impl(u, *this));
0616 }
0617 template<class Unit>
0618 bool is_default_string(const std::string&, const Unit&) {
0619 return(true);
0620 }
0621 };
0622
0623 struct format_name_impl : format_raw_name_impl {
0624 template<class Unit>
0625 std::string operator()(const Unit& u) {
0626 return(name_string(u));
0627 }
0628 template<class Unit>
0629 bool is_default_string(const std::string& str, const Unit& u) {
0630 return(str == to_string_impl(u, format_raw_name_impl()));
0631 }
0632 };
0633
0634 template<class Char, class Traits>
0635 inline void do_print(std::basic_ostream<Char, Traits>& os, const std::string& s)
0636 {
0637 os << s.c_str();
0638 }
0639
0640 inline void do_print(std::ostream& os, const std::string& s)
0641 {
0642 os << s;
0643 }
0644
0645 template<class Char, class Traits>
0646 inline void do_print(std::basic_ostream<Char, Traits>& os, const char* s)
0647 {
0648 os << s;
0649 }
0650
0651
0652
0653 }
0654
0655 #ifdef BOOST_UNITS_DOXYGEN
0656
0657
0658
0659
0660 template<class T>
0661 double autoprefix_norm(const T& arg);
0662
0663 #else
0664
0665 template<class T, bool C = boost::is_arithmetic<T>::value>
0666 struct autoprefix_norm_impl;
0667
0668 template<class T>
0669 struct autoprefix_norm_impl<T, true>
0670 {
0671 typedef double type;
0672 static BOOST_CONSTEXPR double call(const T& arg) { return std::abs(arg); }
0673 };
0674
0675 template<class T>
0676 struct autoprefix_norm_impl<T, false>
0677 {
0678 typedef one type;
0679 static BOOST_CONSTEXPR one call(const T&) { return one(); }
0680 };
0681
0682 template<class T>
0683 BOOST_CONSTEXPR
0684 typename autoprefix_norm_impl<T>::type autoprefix_norm(const T& arg)
0685 {
0686 return autoprefix_norm_impl<T>::call(arg);
0687 }
0688
0689 #endif
0690
0691 namespace detail {
0692
0693 template<class End, class Prev, class T, class F>
0694 BOOST_CONSTEXPR
0695 bool find_matching_scale_impl(End, End, Prev, T, double, F)
0696 {
0697 return false;
0698 }
0699
0700 template<class Begin, class End, class Prev, class T, class F>
0701 BOOST_CXX14_CONSTEXPR
0702 bool find_matching_scale_impl(Begin, End end, Prev prev, T t, double x, F f)
0703 {
0704 if(Begin::item::value() > x) {
0705 f(prev, t);
0706 return true;
0707 } else {
0708 return detail::find_matching_scale_impl(
0709 typename Begin::next(),
0710 end,
0711 typename Begin::item(),
0712 t,
0713 x,
0714 f
0715 );
0716 }
0717 }
0718
0719 template<class End, class T, class F>
0720 BOOST_CONSTEXPR
0721 bool find_matching_scale_i(End, End, T, double, F)
0722 {
0723 return false;
0724 }
0725
0726 template<class Begin, class End, class T, class F>
0727 BOOST_CXX14_CONSTEXPR
0728 bool find_matching_scale_i(Begin, End end, T t, double x, F f)
0729 {
0730 if(Begin::item::value() > x) {
0731 return false;
0732 } else {
0733 return detail::find_matching_scale_impl(typename Begin::next(), end, typename Begin::item(), t, x, f);
0734 }
0735 }
0736
0737 template<class Scales, class T, class F>
0738 BOOST_CXX14_CONSTEXPR
0739 bool find_matching_scale(T t, double x, F f)
0740 {
0741 return detail::find_matching_scale_i(Scales(), dimensionless_type(), t, x, f);
0742 }
0743
0744 typedef list<scale<10, static_rational<-24> >,
0745 list<scale<10, static_rational<-21> >,
0746 list<scale<10, static_rational<-18> >,
0747 list<scale<10, static_rational<-15> >,
0748 list<scale<10, static_rational<-12> >,
0749 list<scale<10, static_rational<-9> >,
0750 list<scale<10, static_rational<-6> >,
0751 list<scale<10, static_rational<-3> >,
0752 list<scale<10, static_rational<0> >,
0753 list<scale<10, static_rational<3> >,
0754 list<scale<10, static_rational<6> >,
0755 list<scale<10, static_rational<9> >,
0756 list<scale<10, static_rational<12> >,
0757 list<scale<10, static_rational<15> >,
0758 list<scale<10, static_rational<18> >,
0759 list<scale<10, static_rational<21> >,
0760 list<scale<10, static_rational<24> >,
0761 list<scale<10, static_rational<27> >,
0762 dimensionless_type> > > > > > > > > > > > > > > > > > engineering_prefixes;
0763
0764 typedef list<scale<2, static_rational<10> >,
0765 list<scale<2, static_rational<20> >,
0766 list<scale<2, static_rational<30> >,
0767 list<scale<2, static_rational<40> >,
0768 list<scale<2, static_rational<50> >,
0769 list<scale<2, static_rational<60> >,
0770 list<scale<2, static_rational<70> >,
0771 list<scale<2, static_rational<80> >,
0772 list<scale<2, static_rational<90> >,
0773 dimensionless_type> > > > > > > > > binary_prefixes;
0774
0775 template<class Os, class Quantity>
0776 struct print_default_t {
0777 typedef void result_type;
0778 void operator()() const
0779 {
0780 *os << q->value() << ' ' << typename Quantity::unit_type();
0781 }
0782 Os* os;
0783 const Quantity* q;
0784 };
0785
0786 template<class Os, class Quantity>
0787 print_default_t<Os, Quantity> print_default(Os& os, const Quantity& q)
0788 {
0789 print_default_t<Os, Quantity> result = { &os, &q };
0790 return result;
0791 }
0792
0793 template<class Os>
0794 struct print_scale_t {
0795 typedef void result_type;
0796 template<class Prefix, class T>
0797 void operator()(Prefix, const T& t) const
0798 {
0799 *prefixed = true;
0800 *os << t / Prefix::value() << ' ';
0801 switch(units::get_format(*os)) {
0802 case name_fmt: do_print(*os, Prefix::name()); break;
0803 case raw_fmt:
0804 case symbol_fmt: do_print(*os, Prefix::symbol()); break;
0805 case typename_fmt: do_print(*os, units::simplify_typename(Prefix())); *os << ' '; break;
0806 }
0807 }
0808 template<long N, class T>
0809 void operator()(scale<N, static_rational<0> >, const T& t) const
0810 {
0811 *prefixed = false;
0812 *os << t << ' ';
0813 }
0814 Os* os;
0815 bool* prefixed;
0816 };
0817
0818 template<class Os>
0819 print_scale_t<Os> print_scale(Os& os, bool& prefixed)
0820 {
0821 print_scale_t<Os> result = { &os, &prefixed };
0822 return result;
0823 }
0824
0825
0826
0827 template<class Dimension,class Units,class Scale, class Subformatter>
0828 inline std::string
0829 maybe_parenthesize(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, Scale> > >&, Subformatter f)
0830 {
0831 std::string str;
0832
0833 std::string without_scale = f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >());
0834
0835 if (f.is_default_string(without_scale, unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >()))
0836 {
0837 str += "(";
0838 str += without_scale;
0839 str += ")";
0840 }
0841 else
0842 {
0843 str += without_scale;
0844 }
0845
0846 return(str);
0847 }
0848
0849
0850
0851
0852
0853 template<class Dimension,class Unit,class Scale, class Subformatter>
0854 inline std::string
0855 maybe_parenthesize(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
0856 {
0857 return f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >());
0858 }
0859
0860 template<class Prefixes, class CharT, class Traits, class Unit, class T, class F>
0861 void do_print_prefixed_impl(std::basic_ostream<CharT, Traits>& os, const quantity<Unit, T>& q, F default_)
0862 {
0863 bool prefixed;
0864 if(detail::find_matching_scale<Prefixes>(q.value(), autoprefix_norm(q.value()), detail::print_scale(os, prefixed))) {
0865 if(prefixed) {
0866 switch(units::get_format(os)) {
0867 case symbol_fmt: do_print(os, maybe_parenthesize(Unit(), format_symbol_impl())); break;
0868 case raw_fmt: do_print(os, maybe_parenthesize(Unit(), format_raw_symbol_impl())); break;
0869 case name_fmt: do_print(os, maybe_parenthesize(Unit(), format_name_impl())); break;
0870 case typename_fmt: do_print(os, simplify_typename(Unit())); break;
0871 }
0872 } else {
0873 os << Unit();
0874 }
0875 } else {
0876 default_();
0877 }
0878 }
0879
0880
0881
0882
0883 template<class Prefixes, class CharT, class Traits, class Dimension, class BaseUnit, class BaseScale, class Scale, class T>
0884 typename base_unit_info<
0885 scaled_base_unit<BaseUnit, Scale>
0886 >::base_unit_info_primary_template
0887 do_print_prefixed(
0888 std::basic_ostream<CharT, Traits>& os,
0889 const quantity<
0890 unit<
0891 Dimension,
0892 heterogeneous_system<
0893 heterogeneous_system_impl<
0894 list<
0895 heterogeneous_system_dim<
0896 scaled_base_unit<BaseUnit, BaseScale>,
0897 static_rational<1>
0898 >,
0899 dimensionless_type
0900 >,
0901 Dimension,
0902 Scale
0903 >
0904 >
0905 >,
0906 T
0907 >& q)
0908 {
0909 quantity<
0910 unit<
0911 Dimension,
0912 heterogeneous_system<
0913 heterogeneous_system_impl<
0914 list<
0915 heterogeneous_system_dim<BaseUnit, static_rational<1> >,
0916 dimensionless_type
0917 >,
0918 Dimension,
0919 dimensionless_type
0920 >
0921 >
0922 >,
0923 T
0924 > unscaled(q);
0925 detail::do_print_prefixed_impl<Prefixes>(os, unscaled, detail::print_default(os, q));
0926 }
0927
0928 template<class Prefixes, class CharT, class Traits, class Dimension, class L, class Scale, class T>
0929 void do_print_prefixed(
0930 std::basic_ostream<CharT, Traits>& os,
0931 const quantity<
0932 unit<
0933 Dimension,
0934 heterogeneous_system<
0935 heterogeneous_system_impl<
0936 L,
0937 Dimension,
0938 Scale
0939 >
0940 >
0941 >,
0942 T
0943 >& q)
0944 {
0945 quantity<
0946 unit<
0947 Dimension,
0948 heterogeneous_system<
0949 heterogeneous_system_impl<
0950 L,
0951 Dimension,
0952 dimensionless_type
0953 >
0954 >
0955 >,
0956 T
0957 > unscaled(q);
0958 detail::do_print_prefixed_impl<Prefixes>(os, unscaled, detail::print_default(os, q));
0959 }
0960
0961 template<class Prefixes, class CharT, class Traits, class Dimension, class System, class T>
0962 void do_print_prefixed(std::basic_ostream<CharT, Traits>& os, const quantity<unit<Dimension, System>, T>& q)
0963 {
0964 detail::do_print_prefixed<Prefixes>(os, quantity<unit<Dimension, typename make_heterogeneous_system<Dimension, System>::type>, T>(q));
0965 }
0966
0967 template<class Prefixes, class CharT, class Traits, class Unit, class T>
0968 void do_print_prefixed(std::basic_ostream<CharT, Traits>& os, const quantity<Unit, T>& q)
0969 {
0970 detail::print_default(os, q)();
0971 }
0972
0973 template<class Prefixes, class CharT, class Traits, class Unit, class T>
0974 void maybe_print_prefixed(std::basic_ostream<CharT, Traits>& os, const quantity<Unit, T>& q, mpl::true_)
0975 {
0976 detail::do_print_prefixed<Prefixes>(os, q);
0977 }
0978
0979 template<class Prefixes, class CharT, class Traits, class Unit, class T>
0980 void maybe_print_prefixed(std::basic_ostream<CharT, Traits>& os, const quantity<Unit, T>& q, mpl::false_)
0981 {
0982 detail::print_default(os, q)();
0983 }
0984
0985 inline BOOST_CONSTEXPR mpl::true_ test_norm(double) { return mpl::true_(); }
0986 inline BOOST_CONSTEXPR mpl::false_ test_norm(one) { return mpl::false_(); }
0987
0988 }
0989
0990 template<class Dimension,class System>
0991 inline std::string
0992 typename_string(const unit<Dimension, System>&)
0993 {
0994 return simplify_typename(typename reduce_unit< unit<Dimension,System> >::type());
0995 }
0996
0997 template<class Dimension,class System>
0998 inline std::string
0999 symbol_string(const unit<Dimension, System>&)
1000 {
1001 return detail::to_string_impl(unit<Dimension,System>(), detail::format_symbol_impl());
1002 }
1003
1004 template<class Dimension,class System>
1005 inline std::string
1006 name_string(const unit<Dimension, System>&)
1007 {
1008 return detail::to_string_impl(unit<Dimension,System>(), detail::format_name_impl());
1009 }
1010
1011
1012
1013
1014
1015
1016
1017 template<class Char, class Traits, class Dimension, class System>
1018 inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const unit<Dimension, System>& u)
1019 {
1020 if (units::get_format(os) == typename_fmt)
1021 {
1022 detail::do_print(os, typename_string(u));
1023 }
1024 else if (units::get_format(os) == raw_fmt)
1025 {
1026 detail::do_print(os, detail::to_string_impl(u, detail::format_raw_symbol_impl()));
1027 }
1028 else if (units::get_format(os) == symbol_fmt)
1029 {
1030 detail::do_print(os, symbol_string(u));
1031 }
1032 else if (units::get_format(os) == name_fmt)
1033 {
1034 detail::do_print(os, name_string(u));
1035 }
1036 else
1037 {
1038 BOOST_ASSERT_MSG(false, "The format mode must be one of: typename_format, raw_format, name_format, symbol_format");
1039 }
1040
1041 return(os);
1042 }
1043
1044
1045
1046
1047
1048
1049
1050 template<class Char, class Traits, class Unit, class T>
1051 inline std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, const quantity<Unit, T>& q)
1052 {
1053 if (units::get_autoprefix(os) == autoprefix_none)
1054 {
1055 os << q.value() << ' ' << Unit();
1056 }
1057 else if (units::get_autoprefix(os) == autoprefix_engineering)
1058 {
1059 detail::maybe_print_prefixed<detail::engineering_prefixes>(os, q, detail::test_norm(autoprefix_norm(q.value())));
1060 }
1061 else if (units::get_autoprefix(os) == autoprefix_binary)
1062 {
1063 detail::maybe_print_prefixed<detail::binary_prefixes>(os, q, detail::test_norm(autoprefix_norm(q.value())));
1064 }
1065 else
1066 {
1067 BOOST_ASSERT_MSG(false, "Autoprefixing must be one of: no_prefix, engineering_prefix, binary_prefix");
1068 }
1069 return(os);
1070 }
1071
1072 }
1073
1074 }
1075
1076 #endif