You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
150 lines
4.3 KiB
150 lines
4.3 KiB
// 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
|
|
|