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_DIMENSION_IMPL_HPP Chris@16: #define BOOST_UNITS_DIMENSION_IMPL_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /// \file Chris@16: /// \brief Core class and metaprogramming utilities for compile-time dimensional analysis. Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: struct insertion_sort_dims_insert; Chris@16: Chris@16: template Chris@16: struct insertion_sort_dims_comparison_impl; Chris@16: Chris@16: // have to recursively add the element to the next sequence. Chris@16: template<> Chris@16: struct insertion_sort_dims_comparison_impl { Chris@16: template Chris@16: struct apply { Chris@16: typedef list< Chris@16: typename Begin::item, Chris@16: typename insertion_sort_dims_insert::template apply< Chris@16: typename Begin::next, Chris@16: T Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: // either prepend the current element or join it to Chris@16: // the first remaining element of the sequence. Chris@16: template<> Chris@16: struct insertion_sort_dims_comparison_impl { Chris@16: template Chris@16: struct apply { Chris@16: typedef typename push_front_or_add::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct insertion_sort_dims_insert { Chris@16: template Chris@16: struct apply { Chris@16: typedef typename insertion_sort_dims_comparison_impl::value>::template apply< Chris@16: Begin, Chris@16: N, Chris@16: T Chris@16: >::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct insertion_sort_dims_insert<0> { Chris@16: template Chris@16: struct apply { Chris@16: typedef list type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct insertion_sort_dims_mpl_sequence { Chris@16: template Chris@16: struct apply { Chris@16: typedef typename insertion_sort_dims_mpl_sequence::template apply::type>::type next; Chris@16: typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply::type>::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct insertion_sort_dims_mpl_sequence<0> { Chris@16: template Chris@16: struct apply { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct insertion_sort_dims_impl { Chris@16: template Chris@16: struct apply { Chris@16: typedef typename insertion_sort_dims_impl::template apply::type next; Chris@16: typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct insertion_sort_dims_impl<0> { Chris@16: template Chris@16: struct apply { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct sort_dims Chris@16: { Chris@16: typedef typename insertion_sort_dims_mpl_sequence::value>::template apply::type>::type type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct sort_dims > Chris@16: { Chris@16: typedef typename insertion_sort_dims_impl::size::value>::template apply >::type type; Chris@16: }; Chris@16: Chris@16: /// sorted sequences can be merged in linear time Chris@16: template Chris@16: struct merge_dimensions_func; Chris@16: Chris@16: template Chris@16: struct merge_dimensions_impl; Chris@16: Chris@16: template<> Chris@16: struct merge_dimensions_func Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef list< Chris@16: typename Begin1::item, Chris@16: typename merge_dimensions_impl::template apply< Chris@16: typename Begin1::next, Chris@16: Begin2 Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct merge_dimensions_func { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef list< Chris@16: typename Begin2::item, Chris@16: typename merge_dimensions_impl::template apply< Chris@16: typename Begin2::next, Chris@16: Begin1 Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct merge_dimensions_func { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename mpl::plus::type combined; Chris@16: typedef typename push_front_if::value>::template apply< Chris@16: typename merge_dimensions_impl::template apply< Chris@16: typename Begin1::next, Chris@16: typename Begin2::next Chris@16: >::type, Chris@16: combined Chris@16: >::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct merge_dimensions_impl { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename Begin1::item dim1; Chris@16: typedef typename Begin2::item dim2; Chris@16: Chris@16: typedef typename merge_dimensions_func<(mpl::less::value == true), Chris@16: (mpl::less::value == true)>::template apply< Chris@16: Begin1, Chris@16: Begin2, Chris@16: N1, Chris@16: N2 Chris@16: >::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct merge_dimensions Chris@16: { Chris@16: typedef typename detail::merge_dimensions_impl::template Chris@16: apply< Chris@16: Sequence1, Chris@16: Sequence2 Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iterator_to_list Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef list< Chris@16: typename Begin::item, Chris@16: typename iterator_to_list::template apply< Chris@16: typename Begin::next Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_to_list<0> Chris@16: { Chris@16: template Chris@16: struct apply { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct merge_dimensions_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename iterator_to_list::template apply::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct merge_dimensions_impl<0, N> Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename iterator_to_list::template apply::type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct merge_dimensions_impl<0, 0> Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct static_inverse_impl Chris@16: { Chris@16: template Chris@16: struct apply { Chris@16: typedef list< Chris@16: typename mpl::negate::type, Chris@16: typename static_inverse_impl::template apply< Chris@16: typename Begin::next Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct static_inverse_impl<0> Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct static_power_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef list< Chris@16: typename mpl::times::type, Chris@16: typename detail::static_power_impl::template apply::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct static_power_impl<0> Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct static_root_impl { Chris@16: template Chris@16: struct apply { Chris@16: typedef list< Chris@16: typename mpl::divides::type, Chris@16: typename detail::static_root_impl::template apply::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct static_root_impl<0> { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef dimensionless_type type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_DIMENSION_IMPL_HPP