Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:13

0001 // Boost.Units - A C++ library for zero-overhead dimensional analysis and 
0002 // unit/quantity manipulation and conversion
0003 //
0004 // Copyright (C) 2003-2008 Matthias Christian Schabel
0005 // Copyright (C) 2008 Steven Watanabe
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See
0008 // accompanying file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #ifndef BOOST_UNITS_DETAIL_HETEROGENEOUS_CONVERSION_HPP
0012 #define BOOST_UNITS_DETAIL_HETEROGENEOUS_CONVERSION_HPP
0013 
0014 #include <boost/mpl/minus.hpp>
0015 #include <boost/mpl/times.hpp>
0016 
0017 #include <boost/units/static_rational.hpp>
0018 #include <boost/units/homogeneous_system.hpp>
0019 #include <boost/units/detail/linear_algebra.hpp>
0020 
0021 namespace boost {
0022 
0023 namespace units {
0024 
0025 namespace detail {
0026 
0027 struct solve_end {
0028     template<class Begin, class Y>
0029     struct apply {
0030         typedef dimensionless_type type;
0031     };
0032 };
0033 
0034 struct no_solution {};
0035 
0036 template<class X1, class X2, class Next>
0037 struct solve_normal {
0038     template<class Begin, class Y>
0039     struct apply {
0040         typedef typename Begin::next next;
0041         typedef list<
0042             typename mpl::minus<
0043                 typename mpl::times<X1, Y>::type,
0044                 typename mpl::times<X2, typename Begin::item>::type
0045             >::type,
0046             typename Next::template apply<next, Y>::type
0047         > type;
0048     };
0049 };
0050 
0051 template<class Next>
0052 struct solve_leading_zeroes {
0053     template<class Begin>
0054     struct apply {
0055         typedef list<
0056             typename Begin::item,
0057             typename Next::template apply<typename Begin::next>::type
0058         > type;
0059     };
0060     typedef solve_leading_zeroes type;
0061 };
0062 
0063 template<>
0064 struct solve_leading_zeroes<no_solution> {
0065     typedef no_solution type;
0066 };
0067 
0068 template<class Next>
0069 struct solve_first_non_zero {
0070     template<class Begin>
0071     struct apply {
0072         typedef typename Next::template apply<
0073             typename Begin::next,
0074             typename Begin::item
0075         >::type type;
0076     };
0077 };
0078 
0079 template<class Next>
0080 struct solve_internal_zero {
0081     template<class Begin, class Y>
0082     struct apply {
0083         typedef list<
0084             typename Begin::item,
0085             typename Next::template apply<typename Begin::next, Y>::type
0086         > type;
0087     };
0088 };
0089 
0090 template<class T>
0091 struct make_solve_list_internal_zero {
0092     template<class Next, class X>
0093     struct apply {
0094         typedef solve_normal<T, X, Next> type;
0095     };
0096 };
0097 
0098 template<>
0099 struct make_solve_list_internal_zero<static_rational<0> > {
0100     template<class Next, class X>
0101     struct apply {
0102         typedef solve_internal_zero<Next> type;
0103     };
0104 };
0105 
0106 template<int N>
0107 struct make_solve_list_normal {
0108     template<class Begin, class X>
0109     struct apply {
0110         typedef typename make_solve_list_internal_zero<
0111             typename Begin::item
0112         >::template apply<
0113             typename make_solve_list_normal<N-1>::template apply<typename Begin::next, X>::type,
0114             X
0115         >::type type;
0116     };
0117 };
0118 
0119 template<>
0120 struct make_solve_list_normal<0> {
0121     template<class Begin, class X>
0122     struct apply {
0123         typedef solve_end type;
0124     };
0125 };
0126 
0127 template<int N>
0128 struct make_solve_list_leading_zeroes;
0129 
0130 template<class T>
0131 struct make_solve_list_first_non_zero {
0132     template<class Begin, int N>
0133     struct apply {
0134         typedef solve_first_non_zero<
0135             typename make_solve_list_normal<N-1>::template apply<
0136                 typename Begin::next,
0137                 typename Begin::item
0138             >::type
0139         > type;
0140     };
0141 };
0142 
0143 template<>
0144 struct make_solve_list_first_non_zero<static_rational<0> > {
0145     template<class Begin, int N>
0146     struct apply {
0147         typedef typename solve_leading_zeroes<
0148             typename make_solve_list_leading_zeroes<N-1>::template apply<
0149                 typename Begin::next
0150             >::type
0151         >::type type;
0152     };
0153 };
0154 
0155 template<int N>
0156 struct make_solve_list_leading_zeroes {
0157     template<class Begin>
0158     struct apply {
0159         typedef typename make_solve_list_first_non_zero<typename Begin::item>::template apply<Begin, N>::type type;
0160     };
0161 };
0162 
0163 template<>
0164 struct make_solve_list_leading_zeroes<0> {
0165     template<class Begin>
0166     struct apply {
0167         typedef no_solution type;
0168     };
0169 };
0170 
0171 template<int N>
0172 struct try_add_unit_impl {
0173     template<class Begin, class L>
0174     struct apply {
0175         typedef typename try_add_unit_impl<N-1>::template apply<typename Begin::next, L>::type next;
0176         typedef typename Begin::item::template apply<next>::type type;
0177         BOOST_STATIC_ASSERT((next::size::value - 1 == type::size::value));
0178     };
0179 };
0180 
0181 template<>
0182 struct try_add_unit_impl<0> {
0183     template<class Begin, class L>
0184     struct apply {
0185         typedef L type;
0186     };
0187 };
0188 
0189 template<int N>
0190 struct make_homogeneous_system_impl;
0191 
0192 template<class T, bool is_done>
0193 struct make_homogeneous_system_func;
0194 
0195 template<class T>
0196 struct make_homogeneous_system_func<T, false> {
0197     template<class Begin, class Current, class Units, class Dimensions, int N>
0198     struct apply {
0199         typedef typename make_homogeneous_system_impl<N-1>::template apply<
0200             typename Begin::next,
0201             list<T, Current>,
0202             list<typename Begin::item, Units>,
0203             Dimensions
0204         >::type type;
0205     };
0206 };
0207 
0208 template<class T>
0209 struct make_homogeneous_system_func<T, true> {
0210     template<class Begin, class Current, class Units, class Dimensions, int N>
0211     struct apply {
0212         typedef list<typename Begin::item, Units> type;
0213     };
0214 };
0215 
0216 template<>
0217 struct make_homogeneous_system_func<no_solution, false> {
0218     template<class Begin, class Current, class Units, class Dimensions, int N>
0219     struct apply {
0220         typedef typename make_homogeneous_system_impl<N-1>::template apply<
0221             typename Begin::next,
0222             Current,
0223             Units,
0224             Dimensions
0225         >::type type;
0226     };
0227 };
0228 
0229 template<>
0230 struct make_homogeneous_system_func<no_solution, true> {
0231     template<class Begin, class Current, class Units, class Dimensions, int N>
0232     struct apply {
0233         typedef typename make_homogeneous_system_impl<N-1>::template apply<
0234             typename Begin::next,
0235             Current,
0236             Units,
0237             Dimensions
0238         >::type type;
0239     };
0240 };
0241 
0242 template<int N>
0243 struct make_homogeneous_system_impl {
0244     template<class Begin, class Current, class Units, class Dimensions>
0245     struct apply {
0246         typedef typename expand_dimensions<Dimensions::size::value>::template apply<
0247             Dimensions,
0248             typename Begin::item::dimension_type
0249         >::type dimensions;
0250         typedef typename try_add_unit_impl<Current::size::value>::template apply<Current, dimensions>::type new_element;
0251         typedef typename make_solve_list_leading_zeroes<new_element::size::value>::template apply<new_element>::type new_func;
0252         typedef typename make_homogeneous_system_func<
0253             new_func,
0254             ((Current::size::value)+1) == (Dimensions::size::value)
0255         >::template apply<Begin, Current, Units, Dimensions, N>::type type;
0256     };
0257 };
0258 
0259 template<>
0260 struct make_homogeneous_system_impl<0> {
0261     template<class Begin, class Current, class Units, class Dimensions>
0262     struct apply {
0263         typedef Units type;
0264     };
0265 };
0266 
0267 template<class Units>
0268 struct make_homogeneous_system {
0269     typedef typename find_base_dimensions<Units>::type base_dimensions;
0270     typedef homogeneous_system<
0271         typename insertion_sort<
0272             typename make_homogeneous_system_impl<
0273                 Units::size::value
0274             >::template apply<
0275                 Units,
0276                 dimensionless_type,
0277                 dimensionless_type,
0278                 base_dimensions
0279             >::type
0280         >::type
0281     > type;
0282 };
0283 
0284 template<int N>
0285 struct extract_base_units {
0286     template<class Begin, class T>
0287     struct apply {
0288         typedef list<
0289             typename Begin::item::tag_type,
0290             typename extract_base_units<N-1>::template apply<typename Begin::next, T>::type
0291         > type;
0292     };
0293 };
0294 
0295 template<>
0296 struct extract_base_units<0> {
0297     template<class Begin, class T>
0298     struct apply {
0299         typedef T type;
0300     };
0301 };
0302 
0303 }
0304 
0305 }
0306 
0307 }
0308 
0309 #endif