File indexing completed on 2025-12-15 10:09:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_UNIT_HPP
0012 #define BOOST_UNITS_UNIT_HPP
0013
0014 #include <boost/static_assert.hpp>
0015 #include <boost/mpl/bool.hpp>
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/type_traits/is_same.hpp>
0018
0019 #include <boost/units/config.hpp>
0020 #include <boost/units/dimension.hpp>
0021 #include <boost/units/operators.hpp>
0022 #include <boost/units/units_fwd.hpp>
0023 #include <boost/units/homogeneous_system.hpp>
0024 #include <boost/units/heterogeneous_system.hpp>
0025 #include <boost/units/is_dimension_list.hpp>
0026 #include <boost/units/reduce_unit.hpp>
0027 #include <boost/units/static_rational.hpp>
0028
0029 namespace boost {
0030
0031 namespace units {
0032
0033
0034
0035
0036 template<class Dim,class System, class Enable>
0037 class unit
0038 {
0039 public:
0040 typedef unit<Dim, System> unit_type;
0041 typedef unit<Dim,System> this_type;
0042 typedef Dim dimension_type;
0043 typedef System system_type;
0044
0045 BOOST_CONSTEXPR unit() { }
0046 BOOST_CONSTEXPR unit(const this_type&) { }
0047
0048
0049 BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type&) { return *this; }
0050
0051
0052
0053
0054
0055 #ifdef __SUNPRO_CC
0056 ~unit() {
0057 BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
0058 BOOST_MPL_ASSERT((is_dimension_list<Dim>));
0059 }
0060 #else
0061 private:
0062 BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
0063 BOOST_MPL_ASSERT((is_dimension_list<Dim>));
0064 #endif
0065 };
0066
0067 }
0068
0069 }
0070
0071 #if BOOST_UNITS_HAS_BOOST_TYPEOF
0072
0073 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
0074
0075 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::unit, 2)
0076
0077 #endif
0078
0079 namespace boost {
0080
0081 namespace units {
0082
0083
0084 template<class Dim, class System>
0085 struct reduce_unit<unit<Dim, System> >
0086 {
0087 typedef unit<
0088 Dim,
0089 typename detail::make_heterogeneous_system<
0090 Dim,
0091 System
0092 >::type
0093 > type;
0094 };
0095
0096
0097 template<class S1,class S2>
0098 struct is_implicitly_convertible :
0099 boost::is_same<typename reduce_unit<S1>::type, typename reduce_unit<S2>::type>
0100 { };
0101
0102
0103
0104 template<class Dim,class System>
0105 struct unary_plus_typeof_helper< unit<Dim,System> >
0106 {
0107 typedef unit<Dim,System> type;
0108 };
0109
0110
0111
0112 template<class Dim,class System>
0113 struct unary_minus_typeof_helper< unit<Dim,System> >
0114 {
0115 typedef unit<Dim,System> type;
0116 };
0117
0118
0119
0120 template<class Dim,
0121 class System>
0122 struct add_typeof_helper< unit<Dim,System>,unit<Dim,System> >
0123 {
0124 typedef unit<Dim,System> type;
0125 };
0126
0127
0128
0129 template<class Dim,
0130 class System>
0131 struct subtract_typeof_helper< unit<Dim,System>,unit<Dim,System> >
0132 {
0133 typedef unit<Dim,System> type;
0134 };
0135
0136
0137
0138 template<class Dim1,
0139 class Dim2,
0140 class System>
0141 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System> >,
0142 unit<Dim2,homogeneous_system<System> > >
0143 {
0144 typedef unit<typename mpl::times<Dim1,Dim2>::type,homogeneous_system<System> > type;
0145 };
0146
0147
0148
0149 template<class Dim1,
0150 class Dim2,
0151 class System1,
0152 class System2>
0153 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
0154 unit<Dim2,homogeneous_system<System2> > >
0155 {
0156 typedef unit<
0157 typename mpl::times<Dim1,Dim2>::type,
0158 typename detail::multiply_systems<
0159 typename detail::make_heterogeneous_system<Dim1, System1>::type,
0160 typename detail::make_heterogeneous_system<Dim2, System2>::type
0161 >::type
0162 > type;
0163 };
0164
0165
0166
0167 template<class Dim1,
0168 class Dim2,
0169 class System1,
0170 class System2>
0171 struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
0172 unit<Dim2,homogeneous_system<System2> > >
0173 {
0174 typedef unit<
0175 typename mpl::times<Dim1,Dim2>::type,
0176 typename detail::multiply_systems<
0177 heterogeneous_system<System1>,
0178 typename detail::make_heterogeneous_system<Dim2, System2>::type
0179 >::type
0180 > type;
0181 };
0182
0183
0184
0185 template<class Dim1,
0186 class Dim2,
0187 class System1,
0188 class System2>
0189 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
0190 unit<Dim2,heterogeneous_system<System2> > >
0191 {
0192 typedef unit<
0193 typename mpl::times<Dim1,Dim2>::type,
0194 typename detail::multiply_systems<
0195 typename detail::make_heterogeneous_system<Dim1, System1>::type,
0196 heterogeneous_system<System2>
0197 >::type
0198 > type;
0199 };
0200
0201
0202
0203 template<class Dim1,
0204 class Dim2,
0205 class System1,
0206 class System2>
0207 struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
0208 unit<Dim2,heterogeneous_system<System2> > >
0209 {
0210 typedef unit<
0211 typename mpl::times<Dim1,Dim2>::type,
0212 typename detail::multiply_systems<
0213 heterogeneous_system<System1>,
0214 heterogeneous_system<System2>
0215 >::type
0216 > type;
0217 };
0218
0219
0220
0221 template<class Dim1,
0222 class Dim2,
0223 class System>
0224 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System> >,
0225 unit<Dim2,homogeneous_system<System> > >
0226 {
0227 typedef unit<typename mpl::divides<Dim1,Dim2>::type,homogeneous_system<System> > type;
0228 };
0229
0230
0231
0232 template<class Dim1,
0233 class Dim2,
0234 class System1,
0235 class System2>
0236 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
0237 unit<Dim2,homogeneous_system<System2> > >
0238 {
0239 typedef unit<
0240 typename mpl::divides<Dim1,Dim2>::type,
0241 typename detail::divide_systems<
0242 typename detail::make_heterogeneous_system<Dim1, System1>::type,
0243 typename detail::make_heterogeneous_system<Dim2, System2>::type
0244 >::type
0245 > type;
0246 };
0247
0248
0249
0250 template<class Dim1,
0251 class Dim2,
0252 class System1,
0253 class System2>
0254 struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
0255 unit<Dim2,homogeneous_system<System2> > >
0256 {
0257 typedef unit<
0258 typename mpl::divides<Dim1,Dim2>::type,
0259 typename detail::divide_systems<
0260 heterogeneous_system<System1>,
0261 typename detail::make_heterogeneous_system<Dim2, System2>::type
0262 >::type
0263 > type;
0264 };
0265
0266
0267
0268 template<class Dim1,
0269 class Dim2,
0270 class System1,
0271 class System2>
0272 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
0273 unit<Dim2,heterogeneous_system<System2> > >
0274 {
0275 typedef unit<
0276 typename mpl::divides<Dim1,Dim2>::type,
0277 typename detail::divide_systems<
0278 typename detail::make_heterogeneous_system<Dim1, System1>::type,
0279 heterogeneous_system<System2>
0280 >::type
0281 > type;
0282 };
0283
0284
0285
0286 template<class Dim1,
0287 class Dim2,
0288 class System1,
0289 class System2>
0290 struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
0291 unit<Dim2,heterogeneous_system<System2> > >
0292 {
0293 typedef unit<
0294 typename mpl::divides<Dim1,Dim2>::type,
0295 typename detail::divide_systems<
0296 heterogeneous_system<System1>,
0297 heterogeneous_system<System2>
0298 >::type
0299 > type;
0300 };
0301
0302
0303 template<class Dim,class System,long N,long D>
0304 struct power_typeof_helper<unit<Dim,System>,static_rational<N,D> >
0305 {
0306 typedef unit<typename static_power<Dim,static_rational<N,D> >::type,typename static_power<System, static_rational<N,D> >::type> type;
0307
0308 static BOOST_CONSTEXPR type value(const unit<Dim,System>&)
0309 {
0310 return type();
0311 }
0312 };
0313
0314
0315 template<class Dim,class System,long N,long D>
0316 struct root_typeof_helper<unit<Dim,System>,static_rational<N,D> >
0317 {
0318 typedef unit<typename static_root<Dim,static_rational<N,D> >::type,typename static_root<System, static_rational<N,D> >::type> type;
0319
0320 static BOOST_CONSTEXPR type value(const unit<Dim,System>&)
0321 {
0322 return type();
0323 }
0324 };
0325
0326
0327 template<class Dim,class System>
0328 BOOST_CONSTEXPR
0329 typename unary_plus_typeof_helper< unit<Dim,System> >::type
0330 operator+(const unit<Dim,System>&)
0331 {
0332 typedef typename unary_plus_typeof_helper< unit<Dim,System> >::type type;
0333
0334 return type();
0335 }
0336
0337
0338 template<class Dim,class System>
0339 BOOST_CONSTEXPR
0340 typename unary_minus_typeof_helper< unit<Dim,System> >::type
0341 operator-(const unit<Dim,System>&)
0342 {
0343 typedef typename unary_minus_typeof_helper< unit<Dim,System> >::type type;
0344
0345 return type();
0346 }
0347
0348
0349 template<class Dim1,
0350 class Dim2,
0351 class System1,
0352 class System2>
0353 BOOST_CONSTEXPR
0354 typename add_typeof_helper< unit<Dim1,System1>,
0355 unit<Dim2,System2> >::type
0356 operator+(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0357 {
0358 BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true));
0359
0360 typedef System1 system_type;
0361 typedef typename add_typeof_helper< unit<Dim1,system_type>,
0362 unit<Dim2,system_type> >::type type;
0363
0364 return type();
0365 }
0366
0367
0368 template<class Dim1,
0369 class Dim2,
0370 class System1,
0371 class System2>
0372 BOOST_CONSTEXPR
0373 typename subtract_typeof_helper< unit<Dim1,System1>,
0374 unit<Dim2,System2> >::type
0375 operator-(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0376 {
0377 BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true));
0378
0379 typedef System1 system_type;
0380 typedef typename subtract_typeof_helper< unit<Dim1,system_type>,
0381 unit<Dim2,system_type> >::type type;
0382
0383 return type();
0384 }
0385
0386
0387 template<class Dim1,
0388 class Dim2,
0389 class System1,
0390 class System2>
0391 BOOST_CONSTEXPR
0392 typename multiply_typeof_helper< unit<Dim1,System1>,
0393 unit<Dim2,System2> >::type
0394 operator*(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0395 {
0396 typedef typename multiply_typeof_helper< unit<Dim1,System1>,
0397 unit<Dim2,System2> >::type type;
0398
0399 return type();
0400 }
0401
0402
0403 template<class Dim1,
0404 class Dim2,
0405 class System1,
0406 class System2>
0407 BOOST_CONSTEXPR
0408 typename divide_typeof_helper< unit<Dim1,System1>,
0409 unit<Dim2,System2> >::type
0410 operator/(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0411 {
0412 typedef typename divide_typeof_helper< unit<Dim1,System1>,
0413 unit<Dim2,System2> >::type type;
0414
0415 return type();
0416 }
0417
0418
0419 template<class Dim1,
0420 class Dim2,
0421 class System1,
0422 class System2>
0423 inline
0424 BOOST_CONSTEXPR
0425 bool
0426 operator==(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0427 {
0428 return boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value;
0429 }
0430
0431
0432 template<class Dim1,
0433 class Dim2,
0434 class System1,
0435 class System2>
0436 inline
0437 BOOST_CONSTEXPR
0438 bool
0439 operator!=(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
0440 {
0441 return !boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value;
0442 }
0443
0444 }
0445
0446 }
0447
0448 #endif