diff options
Diffstat (limited to 'boost/units/unit.hpp')
-rw-r--r-- | boost/units/unit.hpp | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/boost/units/unit.hpp b/boost/units/unit.hpp new file mode 100644 index 0000000000..7d3a8ad46f --- /dev/null +++ b/boost/units/unit.hpp @@ -0,0 +1,440 @@ +// 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 |