| // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
| // unit/quantity manipulation and conversion |
| // |
| // Copyright (C) 2003-2008 Matthias Christian Schabel |
| // Copyright (C) 2007-2008 Steven Watanabe |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See |
| // accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| #ifndef BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED |
| #define BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED |
| |
| #include <string> |
| |
| #include <boost/mpl/bool.hpp> |
| #include <boost/mpl/size.hpp> |
| #include <boost/mpl/begin.hpp> |
| #include <boost/mpl/next.hpp> |
| #include <boost/mpl/deref.hpp> |
| #include <boost/mpl/plus.hpp> |
| #include <boost/mpl/times.hpp> |
| #include <boost/mpl/negate.hpp> |
| #include <boost/mpl/less.hpp> |
| |
| #include <boost/units/config.hpp> |
| #include <boost/units/dimension.hpp> |
| #include <boost/units/scale.hpp> |
| #include <boost/units/static_rational.hpp> |
| #include <boost/units/units_fwd.hpp> |
| #include <boost/units/detail/one.hpp> |
| |
| namespace boost { |
| |
| namespace units { |
| |
| template<class T> |
| struct heterogeneous_system; |
| |
| template<class T, class D, class Scale> |
| struct heterogeneous_system_impl; |
| |
| template<class T, class E> |
| struct heterogeneous_system_dim; |
| |
| template<class S, class Scale> |
| struct scaled_base_unit; |
| |
| /// removes all scaling from a unit or a base unit. |
| template<class T> |
| struct unscale |
| { |
| #ifndef BOOST_UNITS_DOXYGEN |
| typedef T type; |
| #else |
| typedef detail::unspecified type; |
| #endif |
| }; |
| |
| /// INTERNAL ONLY |
| template<class S, class Scale> |
| struct unscale<scaled_base_unit<S, Scale> > |
| { |
| typedef typename unscale<S>::type type; |
| }; |
| |
| /// INTERNAL ONLY |
| template<class D, class S> |
| struct unscale<unit<D, S> > |
| { |
| typedef unit<D, typename unscale<S>::type> type; |
| }; |
| |
| /// INTERNAL ONLY |
| template<class Scale> |
| struct scale_list_dim; |
| |
| /// INTERNAL ONLY |
| template<class T> |
| struct get_scale_list |
| { |
| typedef dimensionless_type type; |
| }; |
| |
| /// INTERNAL ONLY |
| template<class S, class Scale> |
| struct get_scale_list<scaled_base_unit<S, Scale> > |
| { |
| typedef typename mpl::times<list<scale_list_dim<Scale>, dimensionless_type>, typename get_scale_list<S>::type>::type type; |
| }; |
| |
| /// INTERNAL ONLY |
| template<class D, class S> |
| struct get_scale_list<unit<D, S> > |
| { |
| typedef typename get_scale_list<S>::type type; |
| }; |
| |
| /// INTERNAL ONLY |
| struct scale_dim_tag {}; |
| |
| /// INTERNAL ONLY |
| template<class Scale> |
| struct scale_list_dim : Scale |
| { |
| typedef scale_dim_tag tag; |
| typedef scale_list_dim type; |
| }; |
| |
| } // namespace units |
| |
| #ifndef BOOST_UNITS_DOXYGEN |
| |
| namespace mpl { |
| |
| /// INTERNAL ONLY |
| template<> |
| struct less_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag> |
| { |
| template<class T0, class T1> |
| struct apply : mpl::bool_<((T0::base) < (T1::base))> {}; |
| }; |
| |
| } |
| |
| #endif |
| |
| namespace units { |
| |
| namespace detail { |
| |
| template<class Scale> |
| struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {}; |
| |
| template<long N> |
| struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {}; |
| |
| template<int N> |
| struct eval_scale_list_impl |
| { |
| template<class Begin> |
| struct apply |
| { |
| typedef typename eval_scale_list_impl<N-1>::template apply<typename Begin::next> next_iteration; |
| typedef typename multiply_typeof_helper<typename next_iteration::type, typename Begin::item::value_type>::type type; |
| static type value() |
| { |
| return(next_iteration::value() * Begin::item::value()); |
| } |
| }; |
| }; |
| |
| template<> |
| struct eval_scale_list_impl<0> |
| { |
| template<class Begin> |
| struct apply |
| { |
| typedef one type; |
| static one value() |
| { |
| one result; |
| return(result); |
| } |
| }; |
| }; |
| |
| } |
| |
| /// INTERNAL ONLY |
| template<class T> |
| struct eval_scale_list : detail::eval_scale_list_impl<T::size::value>::template apply<T> {}; |
| |
| } // namespace units |
| |
| #ifndef BOOST_UNITS_DOXYGEN |
| |
| namespace mpl { |
| |
| /// INTERNAL ONLY |
| template<> |
| struct plus_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag> |
| { |
| template<class T0, class T1> |
| struct apply |
| { |
| typedef boost::units::scale_list_dim< |
| boost::units::scale< |
| (T0::base), |
| typename mpl::plus<typename T0::exponent, typename T1::exponent>::type |
| > |
| > type; |
| }; |
| }; |
| |
| /// INTERNAL ONLY |
| template<> |
| struct negate_impl<boost::units::scale_dim_tag> |
| { |
| template<class T0> |
| struct apply |
| { |
| typedef boost::units::scale_list_dim< |
| boost::units::scale< |
| (T0::base), |
| typename mpl::negate<typename T0::exponent>::type |
| > |
| > type; |
| }; |
| }; |
| |
| /// INTERNAL ONLY |
| template<> |
| struct times_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag> |
| { |
| template<class T0, class T1> |
| struct apply |
| { |
| typedef boost::units::scale_list_dim< |
| boost::units::scale< |
| (T0::base), |
| typename mpl::times<typename T0::exponent, T1>::type |
| > |
| > type; |
| }; |
| }; |
| |
| } // namespace mpl |
| |
| #endif |
| |
| } // namespace boost |
| |
| #endif |