Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:56

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_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 /// class representing a model-dependent unit with no associated value
0034 
0035 /// (e.g. meters, Kelvin, feet, etc...)
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         //~unit() { }  
0048        
0049         BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type&) { return *this; }
0050         
0051         // sun will ignore errors resulting from templates
0052         // instantiated in the return type of a function.
0053         // Make sure that we get an error anyway by putting.
0054         // the check in the destructor.
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 /// Returns a unique type for every unit.
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 /// INTERNAL ONLY
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 /// unit unary plus typeof helper
0103 /// INTERNAL ONLY
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 /// unit unary minus typeof helper
0111 /// INTERNAL ONLY
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 /// unit add typeof helper
0119 /// INTERNAL ONLY
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 /// unit subtract typeof helper
0128 /// INTERNAL ONLY
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 /// unit multiply typeof helper for two identical homogeneous systems
0137 /// INTERNAL ONLY
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 /// unit multiply typeof helper for two different homogeneous systems
0148 /// INTERNAL ONLY
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 /// unit multiply typeof helper for a heterogeneous and a homogeneous system
0166 /// INTERNAL ONLY
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 /// unit multiply typeof helper for a homogeneous and a heterogeneous system
0184 /// INTERNAL ONLY
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 /// unit multiply typeof helper for two heterogeneous systems
0202 /// INTERNAL ONLY
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 /// unit divide typeof helper for two identical homogeneous systems
0220 /// INTERNAL ONLY
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 /// unit divide typeof helper for two different homogeneous systems
0231 /// INTERNAL ONLY
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 /// unit divide typeof helper for a heterogeneous and a homogeneous system
0249 /// INTERNAL ONLY
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 /// unit divide typeof helper for a homogeneous and a heterogeneous system
0267 /// INTERNAL ONLY
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 /// unit divide typeof helper for two heterogeneous systems
0285 /// INTERNAL ONLY
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 /// raise unit to a @c static_rational power
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 /// take the @c static_rational root of a unit
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 /// unit runtime unary plus
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 /// unit runtime unary minus
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 /// runtime add two units
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 /// runtime subtract two units
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 /// runtime multiply two units
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 /// runtime divide two units
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 /// unit runtime @c operator==
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 /// unit runtime @c operator!=
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 } // namespace units
0445 
0446 } // namespace boost
0447 
0448 #endif // BOOST_UNITS_UNIT_HPP