summaryrefslogtreecommitdiff
path: root/boost/units/detail/unscale.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/units/detail/unscale.hpp')
-rw-r--r--boost/units/detail/unscale.hpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/boost/units/detail/unscale.hpp b/boost/units/detail/unscale.hpp
new file mode 100644
index 0000000..08e51e9
--- /dev/null
+++ b/boost/units/detail/unscale.hpp
@@ -0,0 +1,234 @@
+// 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