// 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) 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_HETEROGENEOUS_CONVERSION_HPP #define BOOST_UNITS_DETAIL_HETEROGENEOUS_CONVERSION_HPP #include #include #include #include #include namespace boost { namespace units { namespace detail { struct solve_end { template struct apply { typedef dimensionless_type type; }; }; struct no_solution {}; template struct solve_normal { template struct apply { typedef typename Begin::next next; typedef list< typename mpl::minus< typename mpl::times::type, typename mpl::times::type >::type, typename Next::template apply::type > type; }; }; template struct solve_leading_zeroes { template struct apply { typedef list< typename Begin::item, typename Next::template apply::type > type; }; typedef solve_leading_zeroes type; }; template<> struct solve_leading_zeroes { typedef no_solution type; }; template struct solve_first_non_zero { template struct apply { typedef typename Next::template apply< typename Begin::next, typename Begin::item >::type type; }; }; template struct solve_internal_zero { template struct apply { typedef list< typename Begin::item, typename Next::template apply::type > type; }; }; template struct make_solve_list_internal_zero { template struct apply { typedef solve_normal type; }; }; template<> struct make_solve_list_internal_zero > { template struct apply { typedef solve_internal_zero type; }; }; template struct make_solve_list_normal { template struct apply { typedef typename make_solve_list_internal_zero< typename Begin::item >::template apply< typename make_solve_list_normal::template apply::type, X >::type type; }; }; template<> struct make_solve_list_normal<0> { template struct apply { typedef solve_end type; }; }; template struct make_solve_list_leading_zeroes; template struct make_solve_list_first_non_zero { template struct apply { typedef solve_first_non_zero< typename make_solve_list_normal::template apply< typename Begin::next, typename Begin::item >::type > type; }; }; template<> struct make_solve_list_first_non_zero > { template struct apply { typedef typename solve_leading_zeroes< typename make_solve_list_leading_zeroes::template apply< typename Begin::next >::type >::type type; }; }; template struct make_solve_list_leading_zeroes { template struct apply { typedef typename make_solve_list_first_non_zero::template apply::type type; }; }; template<> struct make_solve_list_leading_zeroes<0> { template struct apply { typedef no_solution type; }; }; template struct try_add_unit_impl { template struct apply { typedef typename try_add_unit_impl::template apply::type next; typedef typename Begin::item::template apply::type type; BOOST_STATIC_ASSERT((next::size::value - 1 == type::size::value)); }; }; template<> struct try_add_unit_impl<0> { template struct apply { typedef L type; }; }; template struct make_homogeneous_system_impl; template struct make_homogeneous_system_func; template struct make_homogeneous_system_func { template struct apply { typedef typename make_homogeneous_system_impl::template apply< typename Begin::next, list, list, Dimensions >::type type; }; }; template struct make_homogeneous_system_func { template struct apply { typedef list type; }; }; template<> struct make_homogeneous_system_func { template struct apply { typedef typename make_homogeneous_system_impl::template apply< typename Begin::next, Current, Units, Dimensions >::type type; }; }; template<> struct make_homogeneous_system_func { template struct apply { typedef typename make_homogeneous_system_impl::template apply< typename Begin::next, Current, Units, Dimensions >::type type; }; }; template struct make_homogeneous_system_impl { template struct apply { typedef typename expand_dimensions::template apply< Dimensions, typename Begin::item::dimension_type >::type dimensions; typedef typename try_add_unit_impl::template apply::type new_element; typedef typename make_solve_list_leading_zeroes::template apply::type new_func; typedef typename make_homogeneous_system_func< new_func, ((Current::size::value)+1) == (Dimensions::size::value) >::template apply::type type; }; }; template<> struct make_homogeneous_system_impl<0> { template struct apply { typedef Units type; }; }; template struct make_homogeneous_system { typedef typename find_base_dimensions::type base_dimensions; typedef homogeneous_system< typename insertion_sort< typename make_homogeneous_system_impl< Units::size::value >::template apply< Units, dimensionless_type, dimensionless_type, base_dimensions >::type >::type > type; }; template struct extract_base_units { template struct apply { typedef list< typename Begin::item::tag_type, typename extract_base_units::template apply::type > type; }; }; template<> struct extract_base_units<0> { template struct apply { typedef T type; }; }; } } } #endif