Chris@16: // Boost.Units - A C++ library for zero-overhead dimensional analysis and Chris@16: // unit/quantity manipulation and conversion Chris@16: // Chris@16: // Copyright (C) 2003-2008 Matthias Christian Schabel Chris@16: // Copyright (C) 2007-2008 Steven Watanabe Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UNITS_DIMENSION_HPP Chris@16: #define BOOST_UNITS_DIMENSION_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /// \file Chris@16: /// \brief Core metaprogramming utilities for compile-time dimensional analysis. Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: /// Reduce dimension list to cardinal form. This algorithm collapses duplicate Chris@16: /// base dimension tags and sorts the resulting list by the tag ordinal value. Chris@16: /// Dimension lists that resolve to the same dimension are guaranteed to be Chris@16: /// represented by an identical type. Chris@16: /// Chris@16: /// The argument should be an MPL forward sequence containing instances Chris@16: /// of the @c dim template. Chris@16: /// Chris@16: /// The result is also an MPL forward sequence. It also supports the Chris@16: /// following metafunctions to allow use as a dimension. Chris@16: /// Chris@16: /// - @c mpl::plus is defined only on two equal dimensions and returns the argument unchanged. Chris@16: /// - @c mpl::minus is defined only for two equal dimensions and returns the argument unchanged. Chris@16: /// - @c mpl::negate will return its argument unchanged. Chris@16: /// - @c mpl::times is defined for any dimensions and adds corresponding exponents. Chris@16: /// - @c mpl::divides is defined for any dimensions and subtracts the exponents of the Chris@16: /// right had argument from the corresponding exponents of the left had argument. Chris@16: /// Missing base dimension tags are assumed to have an exponent of zero. Chris@16: /// - @c static_power takes a dimension and a static_rational and multiplies all Chris@16: /// the exponents of the dimension by the static_rational. Chris@16: /// - @c static_root takes a dimension and a static_rational and divides all Chris@16: /// the exponents of the dimension by the static_rational. Chris@16: template Chris@16: struct make_dimension_list Chris@16: { Chris@16: typedef typename detail::sort_dims::type type; Chris@16: }; Chris@16: Chris@16: /// Raise a dimension list to a scalar power. Chris@16: template Chris@16: struct static_power Chris@16: { Chris@16: typedef typename detail::static_power_impl::template apply< Chris@16: DL, Chris@16: Ex Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: /// Take a scalar root of a dimension list. Chris@16: template Chris@16: struct static_root Chris@16: { Chris@16: typedef typename detail::static_root_impl::template apply< Chris@16: DL, Chris@16: Rt Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: #ifndef BOOST_UNITS_DOXYGEN Chris@16: Chris@16: namespace mpl { Chris@16: Chris@16: template<> Chris@16: struct plus_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: BOOST_STATIC_ASSERT((boost::is_same::value == true)); Chris@16: typedef T0 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct minus_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: BOOST_STATIC_ASSERT((boost::is_same::value == true)); Chris@16: typedef T0 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct times_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename boost::units::detail::merge_dimensions::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct divides_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename boost::units::detail::merge_dimensions< Chris@16: T0, Chris@16: typename boost::units::detail::static_inverse_impl< Chris@16: T1::size::value Chris@16: >::template apply< Chris@16: T1 Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct negate_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef T0 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: } // namespace mpl Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_DIMENSION_HPP