// 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace units { /// class representing a model-dependent unit with no associated value /// (e.g. meters, Kelvin, feet, etc...) template class unit { public: typedef unit unit_type; typedef unit 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)); BOOST_MPL_ASSERT((is_dimension_list)); } #else private: BOOST_MPL_ASSERT((detail::check_system)); BOOST_MPL_ASSERT((is_dimension_list)); #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 struct reduce_unit > { typedef unit< Dim, typename detail::make_heterogeneous_system< Dim, System >::type > type; }; /// INTERNAL ONLY template struct is_implicitly_convertible : boost::is_same::type, typename reduce_unit::type> { }; /// unit unary plus typeof helper /// INTERNAL ONLY template struct unary_plus_typeof_helper< unit > { typedef unit type; }; /// unit unary minus typeof helper /// INTERNAL ONLY template struct unary_minus_typeof_helper< unit > { typedef unit type; }; /// unit add typeof helper /// INTERNAL ONLY template struct add_typeof_helper< unit,unit > { typedef unit type; }; /// unit subtract typeof helper /// INTERNAL ONLY template struct subtract_typeof_helper< unit,unit > { typedef unit type; }; /// unit multiply typeof helper for two identical homogeneous systems /// INTERNAL ONLY template struct multiply_typeof_helper< unit >, unit > > { typedef unit::type,homogeneous_system > type; }; /// unit multiply typeof helper for two different homogeneous systems /// INTERNAL ONLY template struct multiply_typeof_helper< unit >, unit > > { typedef unit< typename mpl::times::type, typename detail::multiply_systems< typename detail::make_heterogeneous_system::type, typename detail::make_heterogeneous_system::type >::type > type; }; /// unit multiply typeof helper for a heterogeneous and a homogeneous system /// INTERNAL ONLY template struct multiply_typeof_helper< unit >, unit > > { typedef unit< typename mpl::times::type, typename detail::multiply_systems< heterogeneous_system, typename detail::make_heterogeneous_system::type >::type > type; }; /// unit multiply typeof helper for a homogeneous and a heterogeneous system /// INTERNAL ONLY template struct multiply_typeof_helper< unit >, unit > > { typedef unit< typename mpl::times::type, typename detail::multiply_systems< typename detail::make_heterogeneous_system::type, heterogeneous_system >::type > type; }; /// unit multiply typeof helper for two heterogeneous systems /// INTERNAL ONLY template struct multiply_typeof_helper< unit >, unit > > { typedef unit< typename mpl::times::type, typename detail::multiply_systems< heterogeneous_system, heterogeneous_system >::type > type; }; /// unit divide typeof helper for two identical homogeneous systems /// INTERNAL ONLY template struct divide_typeof_helper< unit >, unit > > { typedef unit::type,homogeneous_system > type; }; /// unit divide typeof helper for two different homogeneous systems /// INTERNAL ONLY template struct divide_typeof_helper< unit >, unit > > { typedef unit< typename mpl::divides::type, typename detail::divide_systems< typename detail::make_heterogeneous_system::type, typename detail::make_heterogeneous_system::type >::type > type; }; /// unit divide typeof helper for a heterogeneous and a homogeneous system /// INTERNAL ONLY template struct divide_typeof_helper< unit >, unit > > { typedef unit< typename mpl::divides::type, typename detail::divide_systems< heterogeneous_system, typename detail::make_heterogeneous_system::type >::type > type; }; /// unit divide typeof helper for a homogeneous and a heterogeneous system /// INTERNAL ONLY template struct divide_typeof_helper< unit >, unit > > { typedef unit< typename mpl::divides::type, typename detail::divide_systems< typename detail::make_heterogeneous_system::type, heterogeneous_system >::type > type; }; /// unit divide typeof helper for two heterogeneous systems /// INTERNAL ONLY template struct divide_typeof_helper< unit >, unit > > { typedef unit< typename mpl::divides::type, typename detail::divide_systems< heterogeneous_system, heterogeneous_system >::type > type; }; /// raise unit to a @c static_rational power template struct power_typeof_helper,static_rational > { typedef unit >::type,typename static_power >::type> type; static type value(const unit&) { return type(); } }; /// take the @c static_rational root of a unit template struct root_typeof_helper,static_rational > { typedef unit >::type,typename static_root >::type> type; static type value(const unit&) { return type(); } }; /// unit runtime unary plus template typename unary_plus_typeof_helper< unit >::type operator+(const unit&) { typedef typename unary_plus_typeof_helper< unit >::type type; return type(); } /// unit runtime unary minus template typename unary_minus_typeof_helper< unit >::type operator-(const unit&) { typedef typename unary_minus_typeof_helper< unit >::type type; return type(); } /// runtime add two units template typename add_typeof_helper< unit, unit >::type operator+(const unit&,const unit&) { BOOST_STATIC_ASSERT((boost::is_same::value == true)); typedef System1 system_type; typedef typename add_typeof_helper< unit, unit >::type type; return type(); } /// runtime subtract two units template typename subtract_typeof_helper< unit, unit >::type operator-(const unit&,const unit&) { BOOST_STATIC_ASSERT((boost::is_same::value == true)); typedef System1 system_type; typedef typename subtract_typeof_helper< unit, unit >::type type; return type(); } /// runtime multiply two units template typename multiply_typeof_helper< unit, unit >::type operator*(const unit&,const unit&) { typedef typename multiply_typeof_helper< unit, unit >::type type; return type(); } /// runtime divide two units template typename divide_typeof_helper< unit, unit >::type operator/(const unit&,const unit&) { typedef typename divide_typeof_helper< unit, unit >::type type; return type(); } /// unit runtime @c operator== template inline bool operator==(const unit&,const unit&) { return boost::is_same >::type, typename reduce_unit >::type>::value; } /// unit runtime @c operator!= template inline bool operator!=(const unit&,const unit&) { return !boost::is_same >::type, typename reduce_unit >::type>::value; } } // namespace units } // namespace boost #endif // BOOST_UNITS_UNIT_HPP