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: /// Chris@16: /// \file Chris@16: /// \brief Absolute units (points rather than vectors). Chris@16: /// \details Operations between absolute units, and relative units like temperature differences. Chris@16: /// Chris@16: Chris@16: #ifndef BOOST_UNITS_ABSOLUTE_HPP Chris@16: #define BOOST_UNITS_ABSOLUTE_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: /// A wrapper to represent absolute units (points rather than vectors). Intended Chris@16: /// originally for temperatures, this class implements operators for absolute units Chris@16: /// so that addition of a relative unit to an absolute unit results in another Chris@16: /// absolute unit : absolute +/- T -> absolute and subtraction of one absolute Chris@16: /// unit from another results in a relative unit : absolute - absolute -> T. Chris@16: template Chris@16: class absolute Chris@16: { Chris@16: public: Chris@16: typedef absolute this_type; Chris@16: typedef Y value_type; Chris@16: Chris@16: absolute() : val_() { } Chris@16: absolute(const value_type& val) : val_(val) { } Chris@16: absolute(const this_type& source) : val_(source.val_) { } Chris@16: Chris@16: this_type& operator=(const this_type& source) { val_ = source.val_; return *this; } Chris@16: Chris@16: const value_type& value() const { return val_; } Chris@16: Chris@16: const this_type& operator+=(const value_type& val) { val_ += val; return *this; } Chris@16: const this_type& operator-=(const value_type& val) { val_ -= val; return *this; } Chris@16: Chris@16: private: Chris@16: value_type val_; Chris@16: }; Chris@16: Chris@16: /// add a relative value to an absolute one Chris@16: template Chris@16: absolute operator+(const absolute& aval,const Y& rval) Chris@16: { Chris@16: return absolute(aval.value()+rval); Chris@16: } Chris@16: Chris@16: /// add a relative value to an absolute one Chris@16: template Chris@16: absolute operator+(const Y& rval,const absolute& aval) Chris@16: { Chris@16: return absolute(aval.value()+rval); Chris@16: } Chris@16: Chris@16: /// subtract a relative value from an absolute one Chris@16: template Chris@16: absolute operator-(const absolute& aval,const Y& rval) Chris@16: { Chris@16: return absolute(aval.value()-rval); Chris@16: } Chris@16: Chris@16: /// subtracting two absolutes gives a difference Chris@16: template Chris@16: Y operator-(const absolute& aval1,const absolute& aval2) Chris@16: { Chris@16: return Y(aval1.value()-aval2.value()); Chris@16: } Chris@16: Chris@16: /// creates a quantity from an absolute unit and a raw value Chris@16: template Chris@16: quantity >, T> operator*(const T& t, const absolute >&) Chris@16: { Chris@16: return(quantity >, T>::from_value(t)); Chris@16: } Chris@16: Chris@16: /// creates a quantity from an absolute unit and a raw value Chris@16: template Chris@16: quantity >, T> operator*(const absolute >&, const T& t) Chris@16: { Chris@16: return(quantity >, T>::from_value(t)); Chris@16: } Chris@16: Chris@16: /// Print an absolute unit Chris@16: template Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os,const absolute& aval) Chris@16: { Chris@16: Chris@16: os << "absolute " << aval.value(); Chris@16: Chris@16: return os; Chris@16: } Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost 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::absolute, (class)) Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: /// Macro to define the offset between two absolute units. Chris@16: /// Requires the value to be in the destination units e.g Chris@16: /// @code Chris@16: /// BOOST_UNITS_DEFINE_CONVERSION_OFFSET(celsius_base_unit, fahrenheit_base_unit, double, 32.0); Chris@16: /// @endcode Chris@16: /// @c BOOST_UNITS_DEFINE_CONVERSION_FACTOR is also necessary to Chris@16: /// specify the conversion factor. Like @c BOOST_UNITS_DEFINE_CONVERSION_FACTOR Chris@16: /// this macro defines both forward and reverse conversions so Chris@16: /// defining, e.g., the conversion from celsius to fahrenheit as above will also Chris@16: /// define the inverse conversion from fahrenheit to celsius. Chris@16: #define BOOST_UNITS_DEFINE_CONVERSION_OFFSET(From, To, type_, value_) \ Chris@16: namespace boost { \ Chris@16: namespace units { \ Chris@16: template<> \ Chris@16: struct affine_conversion_helper< \ Chris@16: reduce_unit::type, \ Chris@16: reduce_unit::type> \ Chris@16: { \ Chris@16: static const bool is_defined = true; \ Chris@16: typedef type_ type; \ Chris@16: static type value() { return(value_); } \ Chris@16: }; \ Chris@16: } \ Chris@16: } \ Chris@16: void boost_units_require_semicolon() Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_ABSOLUTE_HPP