Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r60521 - branches/units/autoprefix/boost/units
From: steven_at_[hidden]
Date: 2010-03-12 11:24:38


Author: steven_watanabe
Date: 2010-03-12 11:24:37 EST (Fri, 12 Mar 2010)
New Revision: 60521
URL: http://svn.boost.org/trac/boost/changeset/60521

Log:
Cut the number of template instantiations
Text files modified:
   branches/units/autoprefix/boost/units/io.hpp | 113 +++++++++++++++++++++++++++++++--------
   1 files changed, 88 insertions(+), 25 deletions(-)

Modified: branches/units/autoprefix/boost/units/io.hpp
==============================================================================
--- branches/units/autoprefix/boost/units/io.hpp (original)
+++ branches/units/autoprefix/boost/units/io.hpp 2010-03-12 11:24:37 EST (Fri, 12 Mar 2010)
@@ -639,51 +639,51 @@
 
 // For automatically applying the appropriate prefixes.
 
-template<class End, class Prev, class T, class F, class TooLarge>
-void find_matching_scale_impl(End, End, Prev, T, F, TooLarge l)
+template<class End, class Prev, class T, class F>
+bool find_matching_scale_impl(End, End, Prev, T, F)
 {
- l();
+ return false;
 }
 
-template<class Begin, class End, class Prev, class T, class F, class TooLarge>
-void find_matching_scale_impl(Begin, End end, Prev prev, T t, F f, TooLarge l)
+template<class Begin, class End, class Prev, class T, class F>
+bool find_matching_scale_impl(Begin, End end, Prev prev, T t, F f)
 {
     using std::abs;
     if(Begin::item::value() > abs(t)) {
         f(prev, t);
+ return true;
     } else {
- detail::find_matching_scale_impl(
+ return detail::find_matching_scale_impl(
             typename Begin::next(),
             end,
             typename Begin::item(),
             t,
- f,
- l
+ f
         );
     }
 }
 
-template<class End, class T, class F, class Default>
-void find_matching_scale_i(End, End, T, F, Default d)
+template<class End, class T, class F>
+bool find_matching_scale_i(End, End, T, F)
 {
- d();
+ return false;
 }
 
-template<class Begin, class End, class T, class F, class Default>
-void find_matching_scale_i(Begin, End end, T t, F f, Default d)
+template<class Begin, class End, class T, class F>
+bool find_matching_scale_i(Begin, End end, T t, F f)
 {
     using std::abs;
     if(Begin::item::value() > abs(t)) {
- d();
+ return false;
     } else {
- detail::find_matching_scale_impl(typename Begin::next(), end, typename Begin::item(), t, f, d);
+ return detail::find_matching_scale_impl(typename Begin::next(), end, typename Begin::item(), t, f);
     }
 }
 
-template<class Scales, class T, class F, class Default>
-void find_matching_scale(T t, F f, Default d)
+template<class Scales, class T, class F>
+bool find_matching_scale(T t, F f)
 {
- detail::find_matching_scale_i(Scales(), dimensionless_type(), t, f, d);
+ return detail::find_matching_scale_i(Scales(), dimensionless_type(), t, f);
 }
 
 typedef list<scale<10, static_rational<-24> >,
@@ -733,28 +733,91 @@
     return result;
 }
 
-template<class Os, class Unit>
-struct print_scaled_t {
+template<class Os>
+struct print_scale_t {
     typedef void result_type;
     template<class Prefix, class T>
     void operator()(Prefix, const T& t) const
     {
- *os << t / Prefix::value() << ' ' << typename make_scaled_unit<Unit, Prefix>::type();
+ *prefixed = true;
+ *os << t / Prefix::value() << ' ';
+ switch(units::get_format(*os)) {
+ case name_fmt: do_print(*os, Prefix::name()); break;
+ case raw_fmt:
+ case symbol_fmt: do_print(*os, Prefix::symbol()); break;
+ case typename_fmt: do_print(*os, units::simplify_typename(Prefix())); *os << ' '; break;
+ }
+ }
+ template<long N, class T>
+ void operator()(scale<N, static_rational<0> >, const T& t) const
+ {
+ *prefixed = false;
+ *os << t << ' ';
     }
     Os* os;
+ bool* prefixed;
 };
 
-template<class Unit, class Os>
-print_scaled_t<Os, Unit> print_scaled(Os& os)
+template<class Os>
+print_scale_t<Os> print_scale(Os& os, bool& prefixed)
 {
- print_scaled_t<Os, Unit> result = { &os };
+ print_scale_t<Os> result = { &os, &prefixed };
     return result;
 }
 
+// puts parentheses around a unit
+/// INTERNAL ONLY
+template<class Dimension,class Units,class Scale, class Subformatter>
+inline std::string
+maybe_parenthesize(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, Scale> > >&, Subformatter f)
+{
+ std::string str;
+
+ std::string without_scale = f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >());
+
+ if (f.is_default_string(without_scale, unit<Dimension, heterogeneous_system<heterogeneous_system_impl<Units, Dimension, dimensionless_type> > >()))
+ {
+ str += "(";
+ str += without_scale;
+ str += ")";
+ }
+ else
+ {
+ str += without_scale;
+ }
+
+ return(str);
+}
+
+// This overload catches scaled units that have a single base unit
+// raised to the first power. It causes si::nano * si::meters to not
+// put parentheses around the meters. i.e. nm rather than n(m)
+/// INTERNAL ONLY
+template<class Dimension,class Unit,class Scale, class Subformatter>
+inline std::string
+maybe_parenthesize(const unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >,dimensionless_type>, Dimension, Scale> > >&, Subformatter f)
+{
+ return f(unit<Dimension, heterogeneous_system<heterogeneous_system_impl<list<heterogeneous_system_dim<Unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >());
+}
+
 template<class Prefixes, class CharT, class Traits, class Unit, class T, class F>
 void do_print_prefixed_impl(std::basic_ostream<CharT, Traits>& os, const quantity<Unit, T>& q, F default_)
 {
- detail::find_matching_scale<Prefixes>(q.value(), detail::print_scaled<Unit>(os), default_);
+ bool prefixed;
+ if(detail::find_matching_scale<Prefixes>(q.value(), detail::print_scale(os, prefixed))) {
+ if(prefixed) {
+ switch(units::get_format(os)) {
+ case symbol_fmt: do_print(os, maybe_parenthesize(Unit(), format_symbol_impl())); break;
+ case raw_fmt: do_print(os, maybe_parenthesize(Unit(), format_raw_symbol_impl())); break;
+ case name_fmt: do_print(os, maybe_parenthesize(Unit(), format_name_impl())); break;
+ case typename_fmt: do_print(os, simplify_typename(Unit())); break;
+ }
+ } else {
+ os << Unit();
+ }
+ } else {
+ default_();
+ }
 }
 
 // Handle units like si::kilograms that have a scale embedded in the


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk