Chris@16: // Boost.Units - A C++ library for zero-overhead dimensional analysis and Chris@16: // unit/quantity manipulation and conversion Chris@16: // Chris@16: // Copyright (C) 2003-2008 Matthias Christian Schabel Chris@16: // Copyright (C) 2008 Steven Watanabe Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UNITS_UNIT_HPP Chris@16: #define BOOST_UNITS_UNIT_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: /// class representing a model-dependent unit with no associated value Chris@16: Chris@16: /// (e.g. meters, Kelvin, feet, etc...) Chris@16: template Chris@16: class unit Chris@16: { Chris@16: public: Chris@16: typedef unit unit_type; Chris@16: typedef unit this_type; Chris@16: typedef Dim dimension_type; Chris@16: typedef System system_type; Chris@16: Chris@16: unit() { } Chris@16: unit(const this_type&) { } Chris@16: //~unit() { } Chris@16: Chris@16: this_type& operator=(const this_type&) { return *this; } Chris@16: Chris@16: // sun will ignore errors resulting from templates Chris@16: // instantiated in the return type of a function. Chris@16: // Make sure that we get an error anyway by putting. Chris@16: // the check in the destructor. Chris@16: #ifdef __SUNPRO_CC Chris@16: ~unit() { Chris@16: BOOST_MPL_ASSERT((detail::check_system)); Chris@16: BOOST_MPL_ASSERT((is_dimension_list)); Chris@16: } Chris@16: #else Chris@16: private: Chris@16: BOOST_MPL_ASSERT((detail::check_system)); Chris@16: BOOST_MPL_ASSERT((is_dimension_list)); Chris@16: #endif Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: } Chris@16: Chris@16: #if BOOST_UNITS_HAS_BOOST_TYPEOF Chris@16: Chris@16: #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() Chris@16: Chris@16: BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::unit, 2) Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: /// Returns a unique type for every unit. Chris@16: template Chris@16: struct reduce_unit > Chris@16: { Chris@16: typedef unit< Chris@16: Dim, Chris@16: typename detail::make_heterogeneous_system< Chris@16: Dim, Chris@16: System Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct is_implicitly_convertible : Chris@16: boost::is_same::type, typename reduce_unit::type> Chris@16: { }; Chris@16: Chris@16: /// unit unary plus typeof helper Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct unary_plus_typeof_helper< unit > Chris@16: { Chris@16: typedef unit type; Chris@16: }; Chris@16: Chris@16: /// unit unary minus typeof helper Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct unary_minus_typeof_helper< unit > Chris@16: { Chris@16: typedef unit type; Chris@16: }; Chris@16: Chris@16: /// unit add typeof helper Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct add_typeof_helper< unit,unit > Chris@16: { Chris@16: typedef unit type; Chris@16: }; Chris@16: Chris@16: /// unit subtract typeof helper Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct subtract_typeof_helper< unit,unit > Chris@16: { Chris@16: typedef unit type; Chris@16: }; Chris@16: Chris@16: /// unit multiply typeof helper for two identical homogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct multiply_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit::type,homogeneous_system > type; Chris@16: }; Chris@16: Chris@16: /// unit multiply typeof helper for two different homogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct multiply_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::times::type, Chris@16: typename detail::multiply_systems< Chris@16: typename detail::make_heterogeneous_system::type, Chris@16: typename detail::make_heterogeneous_system::type Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit multiply typeof helper for a heterogeneous and a homogeneous system Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct multiply_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::times::type, Chris@16: typename detail::multiply_systems< Chris@16: heterogeneous_system, Chris@16: typename detail::make_heterogeneous_system::type Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit multiply typeof helper for a homogeneous and a heterogeneous system Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct multiply_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::times::type, Chris@16: typename detail::multiply_systems< Chris@16: typename detail::make_heterogeneous_system::type, Chris@16: heterogeneous_system Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit multiply typeof helper for two heterogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct multiply_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::times::type, Chris@16: typename detail::multiply_systems< Chris@16: heterogeneous_system, Chris@16: heterogeneous_system Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit divide typeof helper for two identical homogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct divide_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit::type,homogeneous_system > type; Chris@16: }; Chris@16: Chris@16: /// unit divide typeof helper for two different homogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct divide_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::divides::type, Chris@16: typename detail::divide_systems< Chris@16: typename detail::make_heterogeneous_system::type, Chris@16: typename detail::make_heterogeneous_system::type Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit divide typeof helper for a heterogeneous and a homogeneous system Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct divide_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::divides::type, Chris@16: typename detail::divide_systems< Chris@16: heterogeneous_system, Chris@16: typename detail::make_heterogeneous_system::type Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit divide typeof helper for a homogeneous and a heterogeneous system Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct divide_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::divides::type, Chris@16: typename detail::divide_systems< Chris@16: typename detail::make_heterogeneous_system::type, Chris@16: heterogeneous_system Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// unit divide typeof helper for two heterogeneous systems Chris@16: /// INTERNAL ONLY Chris@16: template Chris@16: struct divide_typeof_helper< unit >, Chris@16: unit > > Chris@16: { Chris@16: typedef unit< Chris@16: typename mpl::divides::type, Chris@16: typename detail::divide_systems< Chris@16: heterogeneous_system, Chris@16: heterogeneous_system Chris@16: >::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: /// raise unit to a @c static_rational power Chris@16: template Chris@16: struct power_typeof_helper,static_rational > Chris@16: { Chris@16: typedef unit >::type,typename static_power >::type> type; Chris@16: Chris@16: static type value(const unit&) Chris@16: { Chris@16: return type(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// take the @c static_rational root of a unit Chris@16: template Chris@16: struct root_typeof_helper,static_rational > Chris@16: { Chris@16: typedef unit >::type,typename static_root >::type> type; Chris@16: Chris@16: static type value(const unit&) Chris@16: { Chris@16: return type(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /// unit runtime unary plus Chris@16: template Chris@16: typename unary_plus_typeof_helper< unit >::type Chris@16: operator+(const unit&) Chris@16: { Chris@16: typedef typename unary_plus_typeof_helper< unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// unit runtime unary minus Chris@16: template Chris@16: typename unary_minus_typeof_helper< unit >::type Chris@16: operator-(const unit&) Chris@16: { Chris@16: typedef typename unary_minus_typeof_helper< unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// runtime add two units Chris@16: template Chris@16: typename add_typeof_helper< unit, Chris@16: unit >::type Chris@16: operator+(const unit&,const unit&) Chris@16: { Chris@16: BOOST_STATIC_ASSERT((boost::is_same::value == true)); Chris@16: Chris@16: typedef System1 system_type; Chris@16: typedef typename add_typeof_helper< unit, Chris@16: unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// runtime subtract two units Chris@16: template Chris@16: typename subtract_typeof_helper< unit, Chris@16: unit >::type Chris@16: operator-(const unit&,const unit&) Chris@16: { Chris@16: BOOST_STATIC_ASSERT((boost::is_same::value == true)); Chris@16: Chris@16: typedef System1 system_type; Chris@16: typedef typename subtract_typeof_helper< unit, Chris@16: unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// runtime multiply two units Chris@16: template Chris@16: typename multiply_typeof_helper< unit, Chris@16: unit >::type Chris@16: operator*(const unit&,const unit&) Chris@16: { Chris@16: typedef typename multiply_typeof_helper< unit, Chris@16: unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// runtime divide two units Chris@16: template Chris@16: typename divide_typeof_helper< unit, Chris@16: unit >::type Chris@16: operator/(const unit&,const unit&) Chris@16: { Chris@16: typedef typename divide_typeof_helper< unit, Chris@16: unit >::type type; Chris@16: Chris@16: return type(); Chris@16: } Chris@16: Chris@16: /// unit runtime @c operator== Chris@16: template Chris@16: inline Chris@16: bool Chris@16: operator==(const unit&,const unit&) Chris@16: { Chris@16: return boost::is_same >::type, typename reduce_unit >::type>::value; Chris@16: } Chris@16: Chris@16: /// unit runtime @c operator!= Chris@16: template Chris@16: inline Chris@16: bool Chris@16: operator!=(const unit&,const unit&) Chris@16: { Chris@16: return !boost::is_same >::type, typename reduce_unit >::type>::value; Chris@16: } Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_UNIT_HPP