// 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_DIMENSION_HPP #define BOOST_UNITS_DIMENSION_HPP #include #include #include #include #include #include /// \file /// \brief Core metaprogramming utilities for compile-time dimensional analysis. namespace boost { namespace units { /// Reduce dimension list to cardinal form. This algorithm collapses duplicate /// base dimension tags and sorts the resulting list by the tag ordinal value. /// Dimension lists that resolve to the same dimension are guaranteed to be /// represented by an identical type. /// /// The argument should be an MPL forward sequence containing instances /// of the @c dim template. /// /// The result is also an MPL forward sequence. It also supports the /// following metafunctions to allow use as a dimension. /// /// - @c mpl::plus is defined only on two equal dimensions and returns the argument unchanged. /// - @c mpl::minus is defined only for two equal dimensions and returns the argument unchanged. /// - @c mpl::negate will return its argument unchanged. /// - @c mpl::times is defined for any dimensions and adds corresponding exponents. /// - @c mpl::divides is defined for any dimensions and subtracts the exponents of the /// right had argument from the corresponding exponents of the left had argument. /// Missing base dimension tags are assumed to have an exponent of zero. /// - @c static_power takes a dimension and a static_rational and multiplies all /// the exponents of the dimension by the static_rational. /// - @c static_root takes a dimension and a static_rational and divides all /// the exponents of the dimension by the static_rational. template struct make_dimension_list { typedef typename detail::sort_dims::type type; }; /// Raise a dimension list to a scalar power. template struct static_power { typedef typename detail::static_power_impl::template apply< DL, Ex >::type type; }; /// Take a scalar root of a dimension list. template struct static_root { typedef typename detail::static_root_impl::template apply< DL, Rt >::type type; }; } // namespace units #ifndef BOOST_UNITS_DOXYGEN namespace mpl { template<> struct plus_impl { template struct apply { BOOST_STATIC_ASSERT((boost::is_same::value == true)); typedef T0 type; }; }; template<> struct minus_impl { template struct apply { BOOST_STATIC_ASSERT((boost::is_same::value == true)); typedef T0 type; }; }; template<> struct times_impl { template struct apply { typedef typename boost::units::detail::merge_dimensions::type type; }; }; template<> struct divides_impl { template struct apply { typedef typename boost::units::detail::merge_dimensions< T0, typename boost::units::detail::static_inverse_impl< T1::size::value >::template apply< T1 >::type >::type type; }; }; template<> struct negate_impl { template struct apply { typedef T0 type; }; }; } // namespace mpl #endif } // namespace boost #endif // BOOST_UNITS_DIMENSION_HPP