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_DIMENSION_IMPL_HPP
0012 #define BOOST_UNITS_DIMENSION_IMPL_HPP
0013 
0014 #include <boost/mpl/begin_end.hpp>
0015 #include <boost/mpl/deref.hpp>
0016 #include <boost/mpl/if.hpp>
0017 #include <boost/mpl/list.hpp>
0018 #include <boost/mpl/next.hpp>
0019 #include <boost/mpl/size.hpp>
0020 #include <boost/mpl/less.hpp>
0021 
0022 #include <boost/units/config.hpp>
0023 #include <boost/units/dimensionless_type.hpp>
0024 #include <boost/units/static_rational.hpp>
0025 #include <boost/units/units_fwd.hpp>
0026 #include <boost/units/detail/dimension_list.hpp>
0027 #include <boost/units/detail/push_front_if.hpp>
0028 #include <boost/units/detail/push_front_or_add.hpp>
0029 
0030 /// \file 
0031 /// \brief Core class and metaprogramming utilities for compile-time dimensional analysis.
0032 
0033 namespace boost {
0034 
0035 namespace units {
0036 
0037 namespace detail {
0038 
0039 template<int N>
0040 struct insertion_sort_dims_insert;
0041 
0042 template<bool is_greater>
0043 struct insertion_sort_dims_comparison_impl;
0044 
0045 // have to recursively add the element to the next sequence.
0046 template<>
0047 struct insertion_sort_dims_comparison_impl<true> {
0048     template<class Begin, int N, class T>
0049     struct apply {
0050         typedef list<
0051             typename Begin::item,
0052             typename insertion_sort_dims_insert<N - 1>::template apply<
0053                 typename Begin::next,
0054                 T
0055             >::type
0056         > type;
0057     };
0058 };
0059 
0060 // either prepend the current element or join it to
0061 // the first remaining element of the sequence.
0062 template<>
0063 struct insertion_sort_dims_comparison_impl<false> {
0064     template<class Begin, int N, class T>
0065     struct apply {
0066         typedef typename push_front_or_add<Begin, T>::type type;
0067     };
0068 };
0069 
0070 template<int N>
0071 struct insertion_sort_dims_insert {
0072     template<class Begin, class T>
0073     struct apply {
0074         typedef typename insertion_sort_dims_comparison_impl<mpl::less<typename Begin::item, T>::value>::template apply<
0075             Begin,
0076             N,
0077             T
0078         >::type type;
0079     };
0080 };
0081 
0082 template<>
0083 struct insertion_sort_dims_insert<0> {
0084     template<class Begin, class T>
0085     struct apply {
0086         typedef list<T, dimensionless_type> type;
0087     };
0088 };
0089 
0090 template<int N>
0091 struct insertion_sort_dims_mpl_sequence {
0092     template<class Begin>
0093     struct apply {
0094         typedef typename insertion_sort_dims_mpl_sequence<N - 1>::template apply<typename mpl::next<Begin>::type>::type next;
0095         typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename mpl::deref<Begin>::type>::type type;
0096     };
0097 };
0098 
0099 template<>
0100 struct insertion_sort_dims_mpl_sequence<0> {
0101     template<class Begin>
0102     struct apply {
0103         typedef dimensionless_type type;
0104     };
0105 };
0106 
0107 template<int N>
0108 struct insertion_sort_dims_impl {
0109     template<class Begin>
0110     struct apply {
0111         typedef typename insertion_sort_dims_impl<N - 1>::template apply<typename Begin::next>::type next;
0112         typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename Begin::item>::type type;
0113     };
0114 };
0115 
0116 template<>
0117 struct insertion_sort_dims_impl<0> {
0118     template<class Begin>
0119     struct apply {
0120         typedef dimensionless_type type;
0121     };
0122 };
0123 
0124 template<class T>
0125 struct sort_dims
0126 {
0127     typedef typename insertion_sort_dims_mpl_sequence<mpl::size<T>::value>::template apply<typename mpl::begin<T>::type>::type type;
0128 };
0129 
0130 
0131 template<class T, class Next>
0132 struct sort_dims<list<T, Next> >
0133 {
0134     typedef typename insertion_sort_dims_impl<list<T, Next>::size::value>::template apply<list<T, Next> >::type type;
0135 };
0136 
0137 /// sorted sequences can be merged in linear time
0138 template<bool less, bool greater>
0139 struct merge_dimensions_func;
0140 
0141 template<int N1, int N2>
0142 struct merge_dimensions_impl;
0143 
0144 template<>
0145 struct merge_dimensions_func<true, false>
0146 {
0147     template<typename Begin1, typename Begin2, int N1, int N2>
0148     struct apply
0149     {
0150         typedef list<
0151             typename Begin1::item,
0152             typename merge_dimensions_impl<N1 - 1, N2>::template apply<
0153                 typename Begin1::next,
0154                 Begin2
0155             >::type
0156         > type;
0157     };
0158 };
0159 
0160 template<>
0161 struct merge_dimensions_func<false, true> {
0162     template<typename Begin1, typename Begin2, int N1, int N2>
0163     struct apply
0164     {
0165         typedef list<
0166             typename Begin2::item,
0167             typename merge_dimensions_impl<N2 - 1, N1>::template apply<
0168                 typename Begin2::next,
0169                 Begin1
0170             >::type
0171         > type;
0172     };
0173 };
0174 
0175 template<>
0176 struct merge_dimensions_func<false, false> {
0177     template<typename Begin1, typename Begin2, int N1, int N2>
0178     struct apply
0179     {
0180         typedef typename mpl::plus<typename Begin1::item, typename Begin2::item>::type combined;
0181         typedef typename push_front_if<!is_empty_dim<combined>::value>::template apply<
0182             typename merge_dimensions_impl<N1 - 1, N2 - 1>::template apply<
0183                 typename Begin1::next,
0184                 typename Begin2::next
0185             >::type,
0186             combined
0187         >::type type;
0188     };
0189 };
0190 
0191 template<int N1, int N2>
0192 struct merge_dimensions_impl {
0193     template<typename Begin1, typename Begin2>
0194     struct apply
0195     {
0196         typedef typename Begin1::item dim1;
0197         typedef typename Begin2::item dim2;
0198 
0199         typedef typename merge_dimensions_func<(mpl::less<dim1,dim2>::value == true),
0200                 (mpl::less<dim2,dim1>::value == true)>::template apply<
0201             Begin1,
0202             Begin2,
0203             N1,
0204             N2
0205         >::type type;
0206     };
0207 };
0208 
0209 template<typename Sequence1, typename Sequence2>
0210 struct merge_dimensions
0211 {
0212     typedef typename detail::merge_dimensions_impl<Sequence1::size::value, 
0213                                                    Sequence2::size::value>::template 
0214         apply<
0215             Sequence1,
0216             Sequence2
0217         >::type type;
0218 };
0219 
0220 template<int N>
0221 struct iterator_to_list
0222 {
0223     template<typename Begin>
0224     struct apply
0225     {
0226         typedef list<
0227             typename Begin::item,
0228             typename iterator_to_list<N - 1>::template apply<
0229                 typename Begin::next
0230             >::type
0231         > type;
0232     };
0233 };
0234 
0235 template<>
0236 struct iterator_to_list<0>
0237 {
0238     template<typename Begin>
0239     struct apply {
0240         typedef dimensionless_type type;
0241     };
0242 };
0243 
0244 template<int N>
0245 struct merge_dimensions_impl<N, 0>
0246 {
0247     template<typename Begin1, typename Begin2>
0248     struct apply
0249     {
0250         typedef typename iterator_to_list<N>::template apply<Begin1>::type type;
0251     };
0252 };
0253 
0254 template<int N>
0255 struct merge_dimensions_impl<0, N>
0256 {
0257     template<typename Begin1, typename Begin2>
0258     struct apply
0259     {
0260         typedef typename iterator_to_list<N>::template apply<Begin2>::type type;
0261     };
0262 };
0263 
0264 template<>
0265 struct merge_dimensions_impl<0, 0>
0266 {
0267     template<typename Begin1, typename Begin2>
0268     struct apply
0269     {
0270         typedef dimensionless_type type;
0271     };
0272 };
0273 
0274 template<int N>
0275 struct static_inverse_impl
0276 {
0277     template<typename Begin>
0278     struct apply {
0279         typedef list<
0280             typename mpl::negate<typename Begin::item>::type,
0281             typename static_inverse_impl<N - 1>::template apply<
0282                 typename Begin::next
0283             >::type
0284         > type;
0285     };
0286 };
0287 
0288 template<>
0289 struct static_inverse_impl<0>
0290 {
0291     template<typename Begin>
0292     struct apply
0293     {
0294         typedef dimensionless_type type;
0295     };
0296 };
0297 
0298 template<int N>
0299 struct static_power_impl
0300 {
0301     template<typename Begin, typename Ex>
0302     struct apply
0303     {
0304         typedef list<
0305             typename mpl::times<typename Begin::item, Ex>::type,
0306             typename detail::static_power_impl<N - 1>::template apply<typename Begin::next, Ex>::type
0307         > type;
0308     };
0309 };
0310 
0311 template<>
0312 struct static_power_impl<0>
0313 {
0314     template<typename Begin, typename Ex>
0315     struct apply
0316     {
0317         typedef dimensionless_type type;
0318     };
0319 };
0320 
0321 template<int N>
0322 struct static_root_impl {
0323     template<class Begin, class Ex>
0324     struct apply {
0325         typedef list<
0326             typename mpl::divides<typename Begin::item, Ex>::type,
0327             typename detail::static_root_impl<N - 1>::template apply<typename Begin::next, Ex>::type
0328         > type;
0329     };
0330 };
0331 
0332 template<>
0333 struct static_root_impl<0> {
0334     template<class Begin, class Ex>
0335     struct apply 
0336     {
0337         typedef dimensionless_type type;
0338     };
0339 };
0340 
0341 } // namespace detail
0342 
0343 } // namespace units
0344 
0345 } // namespace boost
0346 
0347 #endif // BOOST_UNITS_DIMENSION_IMPL_HPP