| 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)#endifnamespace 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 ONLYtemplate<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 ONLYtemplate<class Dim,class System>struct unary_plus_typeof_helper< unit<Dim,System> >{    typedef unit<Dim,System>    type;};/// unit unary minus typeof helper/// INTERNAL ONLYtemplate<class Dim,class System>struct unary_minus_typeof_helper< unit<Dim,System> >{    typedef unit<Dim,System>    type;};/// unit add typeof helper/// INTERNAL ONLYtemplate<class Dim,         class System>struct add_typeof_helper< unit<Dim,System>,unit<Dim,System> >{    typedef unit<Dim,System> type;};/// unit subtract typeof helper/// INTERNAL ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 ONLYtemplate<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 powertemplate<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 unittemplate<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 plustemplate<class Dim,class System>BOOST_CONSTEXPRtypename unary_plus_typeof_helper< unit<Dim,System> >::typeoperator+(const unit<Dim,System>&){     typedef typename unary_plus_typeof_helper< unit<Dim,System> >::type type;        return type();}/// unit runtime unary minustemplate<class Dim,class System>BOOST_CONSTEXPRtypename unary_minus_typeof_helper< unit<Dim,System> >::typeoperator-(const unit<Dim,System>&){     typedef typename unary_minus_typeof_helper< unit<Dim,System> >::type    type;        return type();}/// runtime add two unitstemplate<class Dim1,         class Dim2,         class System1,         class System2>BOOST_CONSTEXPRtypename add_typeof_helper< unit<Dim1,System1>,                            unit<Dim2,System2> >::typeoperator+(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 unitstemplate<class Dim1,         class Dim2,         class System1,         class System2>BOOST_CONSTEXPRtypename subtract_typeof_helper< unit<Dim1,System1>,                                 unit<Dim2,System2> >::typeoperator-(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 unitstemplate<class Dim1,         class Dim2,         class System1,         class System2>BOOST_CONSTEXPRtypename multiply_typeof_helper< unit<Dim1,System1>,                                 unit<Dim2,System2> >::typeoperator*(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 unitstemplate<class Dim1,         class Dim2,         class System1,         class System2>BOOST_CONSTEXPRtypename divide_typeof_helper< unit<Dim1,System1>,                               unit<Dim2,System2> >::typeoperator/(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>inlineBOOST_CONSTEXPRbool 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>inlineBOOST_CONSTEXPRbool 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
 |