441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | // Boost.Units - A C++ library for zero-overhead dimensional analysis and  | ||
|  | // unit/quantity manipulation and conversion | ||
|  | // | ||
|  | // Copyright (C) 2003-2008 Matthias Christian Schabel | ||
|  | // Copyright (C) 2008 Steven Watanabe | ||
|  | // | ||
|  | // Distributed under the Boost Software License, Version 1.0. (See | ||
|  | // accompanying file LICENSE_1_0.txt or copy at | ||
|  | // http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | #ifndef BOOST_UNITS_UNIT_HPP | ||
|  | #define BOOST_UNITS_UNIT_HPP | ||
|  | 
 | ||
|  | #include <boost/static_assert.hpp> | ||
|  | #include <boost/mpl/bool.hpp> | ||
|  | #include <boost/mpl/assert.hpp> | ||
|  | #include <boost/type_traits/is_same.hpp> | ||
|  | 
 | ||
|  | #include <boost/units/config.hpp> | ||
|  | #include <boost/units/dimension.hpp> | ||
|  | #include <boost/units/operators.hpp> | ||
|  | #include <boost/units/units_fwd.hpp> | ||
|  | #include <boost/units/homogeneous_system.hpp> | ||
|  | #include <boost/units/heterogeneous_system.hpp> | ||
|  | #include <boost/units/is_dimension_list.hpp> | ||
|  | #include <boost/units/reduce_unit.hpp> | ||
|  | #include <boost/units/static_rational.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | 
 | ||
|  | namespace units {  | ||
|  | 
 | ||
|  | /// class representing a model-dependent unit with no associated value | ||
|  | 
 | ||
|  | /// (e.g. meters, Kelvin, feet, etc...) | ||
|  | template<class Dim,class System, class Enable> | ||
|  | class unit | ||
|  | { | ||
|  |     public: | ||
|  |         typedef unit<Dim, System>   unit_type; | ||
|  |         typedef unit<Dim,System>    this_type; | ||
|  |         typedef Dim                 dimension_type;  | ||
|  |         typedef System              system_type; | ||
|  |          | ||
|  |         unit() { } | ||
|  |         unit(const this_type&) { } | ||
|  |         //~unit() { }   | ||
|  |         | ||
|  |         this_type& operator=(const this_type&) { return *this; } | ||
|  |          | ||
|  |         // sun will ignore errors resulting from templates | ||
|  |         // instantiated in the return type of a function. | ||
|  |         // Make sure that we get an error anyway by putting. | ||
|  |         // the check in the destructor. | ||
|  |         #ifdef __SUNPRO_CC | ||
|  |         ~unit() { | ||
|  |             BOOST_MPL_ASSERT((detail::check_system<System, Dim>)); | ||
|  |             BOOST_MPL_ASSERT((is_dimension_list<Dim>)); | ||
|  |         } | ||
|  |         #else | ||
|  |     private: | ||
|  |         BOOST_MPL_ASSERT((detail::check_system<System, Dim>)); | ||
|  |         BOOST_MPL_ASSERT((is_dimension_list<Dim>)); | ||
|  |         #endif | ||
|  | }; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | #if BOOST_UNITS_HAS_BOOST_TYPEOF | ||
|  | 
 | ||
|  | #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() | ||
|  | 
 | ||
|  | BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::unit, 2) | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | 
 | ||
|  | namespace units { | ||
|  | 
 | ||
|  | /// Returns a unique type for every unit. | ||
|  | template<class Dim, class System> | ||
|  | struct reduce_unit<unit<Dim, System> > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         Dim, | ||
|  |         typename detail::make_heterogeneous_system< | ||
|  |             Dim, | ||
|  |             System | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// INTERNAL ONLY | ||
|  | template<class S1,class S2>  | ||
|  | struct is_implicitly_convertible : | ||
|  |     boost::is_same<typename reduce_unit<S1>::type, typename reduce_unit<S2>::type> | ||
|  | { }; | ||
|  | 
 | ||
|  | /// unit unary plus typeof helper | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim,class System> | ||
|  | struct unary_plus_typeof_helper< unit<Dim,System> > | ||
|  | { | ||
|  |     typedef unit<Dim,System>    type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit unary minus typeof helper | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim,class System> | ||
|  | struct unary_minus_typeof_helper< unit<Dim,System> > | ||
|  | { | ||
|  |     typedef unit<Dim,System>    type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit add typeof helper | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim, | ||
|  |          class System> | ||
|  | struct add_typeof_helper< unit<Dim,System>,unit<Dim,System> > | ||
|  | { | ||
|  |     typedef unit<Dim,System> type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit subtract typeof helper | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim, | ||
|  |          class System> | ||
|  | struct subtract_typeof_helper< unit<Dim,System>,unit<Dim,System> > | ||
|  | { | ||
|  |     typedef unit<Dim,System>   type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit multiply typeof helper for two identical homogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System> | ||
|  | struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System> >, | ||
|  |                                unit<Dim2,homogeneous_system<System> > > | ||
|  | { | ||
|  |     typedef unit<typename mpl::times<Dim1,Dim2>::type,homogeneous_system<System> >    type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit multiply typeof helper for two different homogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >, | ||
|  |                                unit<Dim2,homogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::times<Dim1,Dim2>::type, | ||
|  |         typename detail::multiply_systems< | ||
|  |             typename detail::make_heterogeneous_system<Dim1, System1>::type, | ||
|  |             typename detail::make_heterogeneous_system<Dim2, System2>::type | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit multiply typeof helper for a heterogeneous and a homogeneous system | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >, | ||
|  |                                unit<Dim2,homogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::times<Dim1,Dim2>::type, | ||
|  |         typename detail::multiply_systems< | ||
|  |             heterogeneous_system<System1>, | ||
|  |             typename detail::make_heterogeneous_system<Dim2, System2>::type | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit multiply typeof helper for a homogeneous and a heterogeneous system | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >, | ||
|  |                                unit<Dim2,heterogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::times<Dim1,Dim2>::type, | ||
|  |         typename detail::multiply_systems< | ||
|  |             typename detail::make_heterogeneous_system<Dim1, System1>::type, | ||
|  |             heterogeneous_system<System2> | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit multiply typeof helper for two heterogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >, | ||
|  |                                unit<Dim2,heterogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::times<Dim1,Dim2>::type, | ||
|  |         typename detail::multiply_systems< | ||
|  |             heterogeneous_system<System1>, | ||
|  |             heterogeneous_system<System2> | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit divide typeof helper for two identical homogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System> | ||
|  | struct divide_typeof_helper< unit<Dim1,homogeneous_system<System> >, | ||
|  |                              unit<Dim2,homogeneous_system<System> > > | ||
|  | { | ||
|  |     typedef unit<typename mpl::divides<Dim1,Dim2>::type,homogeneous_system<System> >    type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit divide typeof helper for two different homogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >, | ||
|  |                              unit<Dim2,homogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::divides<Dim1,Dim2>::type, | ||
|  |         typename detail::divide_systems< | ||
|  |             typename detail::make_heterogeneous_system<Dim1, System1>::type, | ||
|  |             typename detail::make_heterogeneous_system<Dim2, System2>::type | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit divide typeof helper for a heterogeneous and a homogeneous system | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >, | ||
|  |                              unit<Dim2,homogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::divides<Dim1,Dim2>::type, | ||
|  |         typename detail::divide_systems< | ||
|  |             heterogeneous_system<System1>, | ||
|  |             typename detail::make_heterogeneous_system<Dim2, System2>::type | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit divide typeof helper for a homogeneous and a heterogeneous system | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >, | ||
|  |                              unit<Dim2,heterogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::divides<Dim1,Dim2>::type, | ||
|  |         typename detail::divide_systems< | ||
|  |             typename detail::make_heterogeneous_system<Dim1, System1>::type, | ||
|  |             heterogeneous_system<System2> | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit divide typeof helper for two heterogeneous systems | ||
|  | /// INTERNAL ONLY | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >, | ||
|  |                              unit<Dim2,heterogeneous_system<System2> > > | ||
|  | { | ||
|  |     typedef unit< | ||
|  |         typename mpl::divides<Dim1,Dim2>::type, | ||
|  |         typename detail::divide_systems< | ||
|  |             heterogeneous_system<System1>, | ||
|  |             heterogeneous_system<System2> | ||
|  |         >::type | ||
|  |     > type; | ||
|  | }; | ||
|  | 
 | ||
|  | /// raise unit to a @c static_rational power | ||
|  | template<class Dim,class System,long N,long D>  | ||
|  | struct power_typeof_helper<unit<Dim,System>,static_rational<N,D> >                 | ||
|  | {  | ||
|  |     typedef unit<typename static_power<Dim,static_rational<N,D> >::type,typename static_power<System, static_rational<N,D> >::type>     type;  | ||
|  |      | ||
|  |     static type value(const unit<Dim,System>&)   | ||
|  |     {  | ||
|  |         return type(); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | /// take the @c static_rational root of a unit | ||
|  | template<class Dim,class System,long N,long D>  | ||
|  | struct root_typeof_helper<unit<Dim,System>,static_rational<N,D> >                 | ||
|  | {  | ||
|  |     typedef unit<typename static_root<Dim,static_rational<N,D> >::type,typename static_root<System, static_rational<N,D> >::type>      type;  | ||
|  |      | ||
|  |     static type value(const unit<Dim,System>&)   | ||
|  |     {  | ||
|  |         return type(); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | /// unit runtime unary plus | ||
|  | template<class Dim,class System> | ||
|  | typename unary_plus_typeof_helper< unit<Dim,System> >::type | ||
|  | operator+(const unit<Dim,System>&) | ||
|  | {  | ||
|  |     typedef typename unary_plus_typeof_helper< unit<Dim,System> >::type type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// unit runtime unary minus | ||
|  | template<class Dim,class System> | ||
|  | typename unary_minus_typeof_helper< unit<Dim,System> >::type | ||
|  | operator-(const unit<Dim,System>&) | ||
|  | {  | ||
|  |     typedef typename unary_minus_typeof_helper< unit<Dim,System> >::type    type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// runtime add two units | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | typename add_typeof_helper< unit<Dim1,System1>, | ||
|  |                             unit<Dim2,System2> >::type | ||
|  | operator+(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true)); | ||
|  |      | ||
|  |     typedef System1                                                     system_type; | ||
|  |     typedef typename add_typeof_helper< unit<Dim1,system_type>, | ||
|  |                                         unit<Dim2,system_type> >::type  type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// runtime subtract two units | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | typename subtract_typeof_helper< unit<Dim1,System1>, | ||
|  |                                  unit<Dim2,System2> >::type | ||
|  | operator-(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true)); | ||
|  |      | ||
|  |     typedef System1                                                         system_type; | ||
|  |     typedef typename subtract_typeof_helper< unit<Dim1,system_type>, | ||
|  |                                              unit<Dim2,system_type> >::type type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// runtime multiply two units | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | typename multiply_typeof_helper< unit<Dim1,System1>, | ||
|  |                                  unit<Dim2,System2> >::type | ||
|  | operator*(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     typedef typename multiply_typeof_helper< unit<Dim1,System1>, | ||
|  |                                              unit<Dim2,System2> >::type type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// runtime divide two units | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | typename divide_typeof_helper< unit<Dim1,System1>, | ||
|  |                                unit<Dim2,System2> >::type | ||
|  | operator/(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     typedef typename divide_typeof_helper< unit<Dim1,System1>, | ||
|  |                                            unit<Dim2,System2> >::type   type; | ||
|  |      | ||
|  |     return type(); | ||
|  | } | ||
|  | 
 | ||
|  | /// unit runtime @c operator== | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | inline | ||
|  | bool  | ||
|  | operator==(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     return boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value; | ||
|  | } | ||
|  | 
 | ||
|  | /// unit runtime @c operator!= | ||
|  | template<class Dim1, | ||
|  |          class Dim2, | ||
|  |          class System1, | ||
|  |          class System2> | ||
|  | inline | ||
|  | bool  | ||
|  | operator!=(const unit<Dim1,System1>&,const unit<Dim2,System2>&) | ||
|  | { | ||
|  |     return !boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value; | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace units | ||
|  | 
 | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #endif // BOOST_UNITS_UNIT_HPP |