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
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_HETEROGENEOUS_SYSTEM_HPP
0012 #define BOOST_UNITS_HETEROGENEOUS_SYSTEM_HPP
0013
0014
0015
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
0049
0050
0051
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 }
0060
0061
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
0071 typedef dimensionless_type no_scale;
0072
0073
0074
0075
0076
0077
0078 template<class T>
0079 struct heterogeneous_system : T {};
0080
0081
0082 struct heterogeneous_system_dim_tag {};
0083
0084
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
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 }
0114
0115 }
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
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 }
0150
0151 }
0152
0153 namespace mpl {
0154
0155
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
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
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
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 }
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 }
0283
0284
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
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 }
0338
0339
0340
0341
0342
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
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 }
0394
0395
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
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 }
0423
0424 }
0425
0426 }
0427
0428 #endif