151 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			151 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | // 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 <boost/static_assert.hpp> | ||
|  | 
 | ||
|  | #include <boost/type_traits/is_same.hpp> | ||
|  | 
 | ||
|  | #include <boost/mpl/arithmetic.hpp> | ||
|  | 
 | ||
|  | #include <boost/units/static_rational.hpp> | ||
|  | #include <boost/units/detail/dimension_list.hpp> | ||
|  | #include <boost/units/detail/dimension_impl.hpp> | ||
|  | 
 | ||
|  | /// \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<typename Seq> | ||
|  | struct make_dimension_list | ||
|  | { | ||
|  |     typedef typename detail::sort_dims<Seq>::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Raise a dimension list to a scalar power. | ||
|  | template<typename DL,typename Ex>  | ||
|  | struct static_power | ||
|  | { | ||
|  |     typedef typename detail::static_power_impl<DL::size::value>::template apply< | ||
|  |         DL, | ||
|  |         Ex | ||
|  |     >::type type;     | ||
|  | }; | ||
|  | 
 | ||
|  | /// Take a scalar root of a dimension list. | ||
|  | template<typename DL,typename Rt>  | ||
|  | struct static_root | ||
|  | { | ||
|  |     typedef typename detail::static_root_impl<DL::size::value>::template apply< | ||
|  |         DL, | ||
|  |         Rt | ||
|  |     >::type type;     | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace units | ||
|  | 
 | ||
|  | #ifndef BOOST_UNITS_DOXYGEN | ||
|  | 
 | ||
|  | namespace mpl { | ||
|  | 
 | ||
|  | template<> | ||
|  | struct plus_impl<boost::units::detail::dimension_list_tag,boost::units::detail::dimension_list_tag> | ||
|  | { | ||
|  |     template<class T0, class T1> | ||
|  |     struct apply | ||
|  |     { | ||
|  |         BOOST_STATIC_ASSERT((boost::is_same<T0,T1>::value == true)); | ||
|  |         typedef T0 type; | ||
|  |     }; | ||
|  | }; | ||
|  | 
 | ||
|  | template<> | ||
|  | struct minus_impl<boost::units::detail::dimension_list_tag,boost::units::detail::dimension_list_tag> | ||
|  | { | ||
|  |     template<class T0, class T1> | ||
|  |     struct apply | ||
|  |     { | ||
|  |         BOOST_STATIC_ASSERT((boost::is_same<T0,T1>::value == true)); | ||
|  |         typedef T0 type; | ||
|  |     }; | ||
|  | }; | ||
|  | 
 | ||
|  | template<> | ||
|  | struct times_impl<boost::units::detail::dimension_list_tag,boost::units::detail::dimension_list_tag> | ||
|  | { | ||
|  |     template<class T0, class T1> | ||
|  |     struct apply | ||
|  |     { | ||
|  |         typedef typename boost::units::detail::merge_dimensions<T0,T1>::type type; | ||
|  |     }; | ||
|  | }; | ||
|  | 
 | ||
|  | template<> | ||
|  | struct divides_impl<boost::units::detail::dimension_list_tag,boost::units::detail::dimension_list_tag> | ||
|  | { | ||
|  |     template<class T0, class T1> | ||
|  |     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<boost::units::detail::dimension_list_tag> | ||
|  | { | ||
|  |     template<class T0> | ||
|  |     struct apply | ||
|  |     { | ||
|  |         typedef T0 type; | ||
|  |     }; | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace mpl | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #endif // BOOST_UNITS_DIMENSION_HPP |