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
 |