123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- // 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;
-
- BOOST_CONSTEXPR unit() { }
- BOOST_CONSTEXPR unit(const this_type&) { }
- //~unit() { }
-
- BOOST_CXX14_CONSTEXPR 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 BOOST_CONSTEXPR 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 BOOST_CONSTEXPR type value(const unit<Dim,System>&)
- {
- return type();
- }
- };
- /// unit runtime unary plus
- template<class Dim,class System>
- BOOST_CONSTEXPR
- 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>
- BOOST_CONSTEXPR
- 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>
- BOOST_CONSTEXPR
- 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>
- BOOST_CONSTEXPR
- 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>
- BOOST_CONSTEXPR
- 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>
- BOOST_CONSTEXPR
- 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
- BOOST_CONSTEXPR
- 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
- BOOST_CONSTEXPR
- 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
|