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