Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/units/heterogeneous_system.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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) 2007-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_HETEROGENEOUS_SYSTEM_HPP
0012 #define BOOST_UNITS_HETEROGENEOUS_SYSTEM_HPP
0013 
0014 /// \file
0015 /// \brief A heterogeneous system is a sorted list of base unit/exponent pairs.
0016 
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/mpl/plus.hpp>
0019 #include <boost/mpl/times.hpp>
0020 #include <boost/mpl/divides.hpp>
0021 #include <boost/mpl/negate.hpp>
0022 #include <boost/mpl/less.hpp>
0023 #include <boost/mpl/size.hpp>
0024 #include <boost/mpl/begin.hpp>
0025 #include <boost/mpl/next.hpp>
0026 #include <boost/mpl/deref.hpp>
0027 #include <boost/mpl/front.hpp>
0028 #include <boost/mpl/push_front.hpp>
0029 #include <boost/mpl/pop_front.hpp>
0030 #include <boost/mpl/assert.hpp>
0031 #include <boost/type_traits/is_same.hpp>
0032 
0033 #include <boost/units/config.hpp>
0034 #include <boost/units/static_rational.hpp>
0035 #include <boost/units/dimension.hpp>
0036 #include <boost/units/units_fwd.hpp>
0037 #include <boost/units/detail/push_front_if.hpp>
0038 #include <boost/units/detail/push_front_or_add.hpp>
0039 #include <boost/units/detail/linear_algebra.hpp>
0040 #include <boost/units/detail/unscale.hpp>
0041 
0042 namespace boost {
0043 
0044 namespace units {
0045 
0046 namespace detail {
0047 
0048 // A normal system is a sorted list of base units.
0049 // A heterogeneous system is a sorted list of base unit/exponent pairs.
0050 // As long as we don't need to convert heterogeneous systems
0051 // directly everything is cool.
0052 
0053 template<class T>
0054 struct is_zero : mpl::false_ {};
0055 
0056 template<>
0057 struct is_zero<static_rational<0> > : mpl::true_ {};
0058 
0059 } // namespace detail
0060 
0061 /// INTERNAL ONLY
0062 template<class L, class Dimensions, class Scale>
0063 struct heterogeneous_system_impl
0064 {
0065     typedef L type;
0066     typedef Dimensions dimensions;
0067     typedef Scale scale;
0068 };
0069 
0070 /// INTERNAL ONLY
0071 typedef dimensionless_type no_scale;
0072 
0073 /// A system that can represent any possible combination
0074 /// of units at the expense of not preserving information
0075 /// about how it was created.  Do not create specializations
0076 /// of this template directly. Instead use @c reduce_unit and
0077 /// @c base_unit<...>::unit_type.
0078 template<class T>
0079 struct heterogeneous_system : T {};
0080 
0081 /// INTERNAL ONLY
0082 struct heterogeneous_system_dim_tag {};
0083 
0084 /// INTERNAL ONLY
0085 template<class Unit, class Exponent>
0086 struct heterogeneous_system_dim
0087 {
0088     typedef heterogeneous_system_dim_tag tag;
0089     typedef heterogeneous_system_dim type;
0090     typedef Unit tag_type;
0091     typedef Exponent value_type;
0092 };
0093 
0094 /// INTERNAL ONLY
0095 #define BOOST_UNITS_MAKE_HETEROGENEOUS_UNIT(BaseUnit, Dimensions)   \
0096     boost::units::unit<                                             \
0097         Dimensions,                                                 \
0098         boost::units::heterogeneous_system<                         \
0099             boost::units::heterogeneous_system_impl<                \
0100                 boost::units::list<                       \
0101                     boost::units::heterogeneous_system_dim<         \
0102                         BaseUnit,                                   \
0103                         boost::units::static_rational<1>            \
0104                     >,                                              \
0105                     boost::units::dimensionless_type                \
0106                 >,                                                  \
0107                 Dimensions,                                         \
0108                 boost::units::no_scale                              \
0109             >                                                       \
0110         >                                                           \
0111     >
0112 
0113 } // namespace units
0114 
0115 } // namespace boost
0116 
0117 
0118 #if BOOST_UNITS_HAS_BOOST_TYPEOF
0119 
0120 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
0121 
0122 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::heterogeneous_system_impl, (class)(class)(class))
0123 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::heterogeneous_system, (class))
0124 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::heterogeneous_system_dim, (class)(class))
0125 
0126 #endif
0127 
0128 namespace boost {
0129 
0130 namespace mpl {
0131 
0132 /// INTERNAL ONLY
0133 template<>
0134 struct less_impl<boost::units::heterogeneous_system_dim_tag, boost::units::heterogeneous_system_dim_tag>
0135 {
0136     template<class T0, class T1>
0137     struct apply : mpl::less<typename T0::tag_type, typename T1::tag_type> {};
0138 };
0139 
0140 }
0141 
0142 namespace units {
0143 
0144 namespace detail {
0145 
0146 template<class Unit1, class Exponent1>
0147 struct is_empty_dim<heterogeneous_system_dim<Unit1,Exponent1> > : detail::is_zero<Exponent1> {};
0148 
0149 } // namespace detail
0150 
0151 } // namespace units
0152 
0153 namespace mpl {
0154 
0155 /// INTERNAL ONLY
0156 template<>
0157 struct plus_impl<boost::units::heterogeneous_system_dim_tag, boost::units::heterogeneous_system_dim_tag>
0158 {
0159     template<class T0, class T1>
0160     struct apply
0161     {
0162         typedef boost::units::heterogeneous_system_dim<
0163             typename T0::tag_type,
0164             typename mpl::plus<typename T0::value_type,typename T1::value_type>::type
0165         > type;
0166     };
0167 };
0168 
0169 /// INTERNAL ONLY
0170 template<>
0171 struct times_impl<boost::units::heterogeneous_system_dim_tag, boost::units::detail::static_rational_tag>
0172 {
0173     template<class T0, class T1>
0174     struct apply
0175     {
0176         typedef boost::units::heterogeneous_system_dim<
0177             typename T0::tag_type,
0178             typename mpl::times<typename T0::value_type,T1>::type
0179         > type;
0180     };
0181 };
0182 
0183 /// INTERNAL ONLY
0184 template<>
0185 struct divides_impl<boost::units::heterogeneous_system_dim_tag, boost::units::detail::static_rational_tag>
0186 {
0187     template<class T0, class T1>
0188     struct apply
0189     {
0190         typedef boost::units::heterogeneous_system_dim<
0191             typename T0::tag_type,
0192             typename mpl::divides<typename T0::value_type,T1>::type
0193         > type;
0194     };
0195 };
0196 
0197 /// INTERNAL ONLY
0198 template<>
0199 struct negate_impl<boost::units::heterogeneous_system_dim_tag>
0200 {
0201     template<class T>
0202     struct apply
0203     {
0204         typedef boost::units::heterogeneous_system_dim<typename T::tag_type, typename mpl::negate<typename T::value_type>::type> type;
0205     };
0206 };
0207 
0208 } // namespace mpl
0209 
0210 namespace units {
0211 
0212 namespace detail {
0213 
0214 template<int N>
0215 struct make_heterogeneous_system_impl
0216 {
0217     template<class UnitsBegin, class ExponentsBegin>
0218     struct apply
0219     {
0220         typedef typename push_front_if<!(is_zero<typename ExponentsBegin::item>::value)>::template apply<
0221             typename make_heterogeneous_system_impl<N-1>::template apply<
0222                 typename UnitsBegin::next,
0223                 typename ExponentsBegin::next
0224             >::type,
0225             heterogeneous_system_dim<typename UnitsBegin::item, typename ExponentsBegin::item>
0226         >::type type;
0227     };
0228 };
0229 
0230 template<>
0231 struct make_heterogeneous_system_impl<0>
0232 {
0233     template<class UnitsBegin, class ExponentsBegin>
0234     struct apply
0235     {
0236         typedef dimensionless_type type;
0237     };
0238 };
0239 
0240 template<class Dimensions, class System>
0241 struct make_heterogeneous_system
0242 {
0243     typedef typename calculate_base_unit_exponents<typename System::type, Dimensions>::type exponents;
0244     BOOST_MPL_ASSERT_MSG((!boost::is_same<exponents, inconsistent>::value), the_specified_dimension_is_not_representible_in_the_given_system, (types<Dimensions, System>));
0245     typedef typename make_heterogeneous_system_impl<System::type::size::value>::template apply<
0246         typename System::type,
0247         exponents
0248     >::type unit_list;
0249     typedef heterogeneous_system<heterogeneous_system_impl<unit_list, Dimensions, no_scale> > type;
0250 };
0251 
0252 template<class Dimensions, class T>
0253 struct make_heterogeneous_system<Dimensions, heterogeneous_system<T> >
0254 {
0255     typedef heterogeneous_system<T> type;
0256 };
0257 
0258 template<class T0, class T1>
0259 struct multiply_systems
0260 {
0261     typedef heterogeneous_system<
0262         heterogeneous_system_impl<
0263             typename mpl::times<typename T0::type, typename T1::type>::type,
0264             typename mpl::times<typename T0::dimensions, typename T1::dimensions>::type,
0265             typename mpl::times<typename T0::scale, typename T1::scale>::type
0266         >
0267     > type;
0268 };
0269 
0270 template<class T0, class T1>
0271 struct divide_systems
0272 {
0273     typedef heterogeneous_system<
0274         heterogeneous_system_impl<
0275             typename mpl::divides<typename T0::type, typename T1::type>::type,
0276             typename mpl::divides<typename T0::dimensions, typename T1::dimensions>::type,
0277             typename mpl::divides<typename T0::scale, typename T1::scale>::type
0278         >
0279     > type;
0280 };
0281 
0282 } // namespace detail
0283 
0284 /// INTERNAL ONLY
0285 template<class S, long N, long D>
0286 struct static_power<heterogeneous_system<S>, static_rational<N,D> >
0287 {
0288     typedef heterogeneous_system<
0289         heterogeneous_system_impl<
0290             typename static_power<typename S::type, static_rational<N,D> >::type,
0291             typename static_power<typename S::dimensions, static_rational<N,D> >::type,
0292             typename static_power<typename S::scale, static_rational<N,D> >::type
0293         >
0294     > type;
0295 };
0296 
0297 /// INTERNAL ONLY
0298 template<class S, long N, long D>
0299 struct static_root<heterogeneous_system<S>, static_rational<N,D> >
0300 {
0301     typedef heterogeneous_system<
0302         heterogeneous_system_impl<
0303             typename static_root<typename S::type, static_rational<N,D> >::type,
0304             typename static_root<typename S::dimensions, static_rational<N,D> >::type,
0305             typename static_root<typename S::scale, static_rational<N,D> >::type
0306         >
0307     > type;
0308 };
0309 
0310 namespace detail {
0311 
0312 template<int N>
0313 struct unscale_heterogeneous_system_impl
0314 {
0315     template<class Begin>
0316     struct apply
0317     {
0318         typedef typename push_front_or_add<
0319             typename unscale_heterogeneous_system_impl<N-1>::template apply<
0320                 typename Begin::next
0321             >::type,
0322             typename unscale<typename Begin::item>::type
0323         >::type type;
0324     };
0325 };
0326 
0327 template<>
0328 struct unscale_heterogeneous_system_impl<0>
0329 {
0330     template<class Begin>
0331     struct apply
0332     {
0333         typedef dimensionless_type type;
0334     };
0335 };
0336 
0337 } // namespace detail
0338 
0339 /// Unscale all the base units. e.g
0340 /// km s -> m s
0341 /// cm km -> m^2
0342 /// INTERNAL ONLY
0343 template<class T>
0344 struct unscale<heterogeneous_system<T> >
0345 {
0346     typedef heterogeneous_system<
0347         heterogeneous_system_impl<
0348             typename detail::unscale_heterogeneous_system_impl<
0349                 T::type::size::value
0350             >::template apply<
0351                 typename T::type
0352             >::type,
0353             typename T::dimensions,
0354             no_scale
0355         >
0356     > type;
0357 };
0358 
0359 /// INTERNAL ONLY
0360 template<class Unit, class Exponent>
0361 struct unscale<heterogeneous_system_dim<Unit, Exponent> >
0362 {
0363     typedef heterogeneous_system_dim<typename unscale<Unit>::type, Exponent> type;
0364 };
0365 
0366 namespace detail {
0367 
0368 template<int N>
0369 struct get_scale_list_of_heterogeneous_system_impl
0370 {
0371     template<class Begin>
0372     struct apply
0373     {
0374         typedef typename mpl::times<
0375             typename get_scale_list_of_heterogeneous_system_impl<N-1>::template apply<
0376                 typename Begin::next
0377             >::type,
0378             typename get_scale_list<typename Begin::item>::type
0379         >::type type;
0380     };
0381 };
0382 
0383 template<>
0384 struct get_scale_list_of_heterogeneous_system_impl<0>
0385 {
0386     template<class Begin>
0387     struct apply
0388     {
0389         typedef dimensionless_type type;
0390     };
0391 };
0392 
0393 } // namespace detail
0394 
0395 /// INTERNAL ONLY
0396 template<class T>
0397 struct get_scale_list<heterogeneous_system<T> >
0398 {
0399     typedef typename mpl::times<
0400         typename detail::get_scale_list_of_heterogeneous_system_impl<
0401             T::type::size::value
0402         >::template apply<typename T::type>::type,
0403         typename T::scale
0404     >::type type;
0405 };
0406 
0407 /// INTERNAL ONLY
0408 template<class Unit, class Exponent>
0409 struct get_scale_list<heterogeneous_system_dim<Unit, Exponent> >
0410 {
0411     typedef typename static_power<typename get_scale_list<Unit>::type, Exponent>::type type;
0412 };
0413 
0414 namespace detail {
0415 
0416 template<class System, class Dimension>
0417 struct check_system : mpl::false_ {};
0418 
0419 template<class System, class Dimension, class Scale>
0420 struct check_system<heterogeneous_system<heterogeneous_system_impl<System, Dimension, Scale> >, Dimension> : mpl::true_ {};
0421 
0422 } // namespace detail
0423 
0424 } // namespace units
0425 
0426 } // namespace boost
0427 
0428 #endif