1 | // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
2 | // unit/quantity manipulation and conversion |
3 | // |
4 | // Copyright (C) 2003-2008 Matthias Christian Schabel |
5 | // Copyright (C) 2008 Steven Watanabe |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See |
8 | // accompanying file LICENSE_1_0.txt or copy at |
9 | // http://www.boost.org/LICENSE_1_0.txt) |
10 | |
11 | /// |
12 | /// \file |
13 | /// \brief Absolute units (points rather than vectors). |
14 | /// \details Operations between absolute units, and relative units like temperature differences. |
15 | /// |
16 | |
17 | #ifndef BOOST_UNITS_ABSOLUTE_HPP |
18 | #define BOOST_UNITS_ABSOLUTE_HPP |
19 | |
20 | #include <iosfwd> |
21 | |
22 | #include <boost/units/detail/absolute_impl.hpp> |
23 | |
24 | namespace boost { |
25 | |
26 | namespace units { |
27 | |
28 | /// A wrapper to represent absolute units (points rather than vectors). Intended |
29 | /// originally for temperatures, this class implements operators for absolute units |
30 | /// so that addition of a relative unit to an absolute unit results in another |
31 | /// absolute unit : absolute<T> +/- T -> absolute<T> and subtraction of one absolute |
32 | /// unit from another results in a relative unit : absolute<T> - absolute<T> -> T. |
33 | template<class Y> |
34 | class absolute |
35 | { |
36 | public: |
37 | typedef absolute<Y> this_type; |
38 | typedef Y value_type; |
39 | |
40 | absolute() : val_() { } |
41 | absolute(const value_type& val) : val_(val) { } |
42 | absolute(const this_type& source) : val_(source.val_) { } |
43 | |
44 | this_type& operator=(const this_type& source) { val_ = source.val_; return *this; } |
45 | |
46 | const value_type& value() const { return val_; } |
47 | |
48 | const this_type& operator+=(const value_type& val) { val_ += val; return *this; } |
49 | const this_type& operator-=(const value_type& val) { val_ -= val; return *this; } |
50 | |
51 | private: |
52 | value_type val_; |
53 | }; |
54 | |
55 | /// add a relative value to an absolute one |
56 | template<class Y> |
57 | absolute<Y> operator+(const absolute<Y>& aval,const Y& rval) |
58 | { |
59 | return absolute<Y>(aval.value()+rval); |
60 | } |
61 | |
62 | /// add a relative value to an absolute one |
63 | template<class Y> |
64 | absolute<Y> operator+(const Y& rval,const absolute<Y>& aval) |
65 | { |
66 | return absolute<Y>(aval.value()+rval); |
67 | } |
68 | |
69 | /// subtract a relative value from an absolute one |
70 | template<class Y> |
71 | absolute<Y> operator-(const absolute<Y>& aval,const Y& rval) |
72 | { |
73 | return absolute<Y>(aval.value()-rval); |
74 | } |
75 | |
76 | /// subtracting two absolutes gives a difference |
77 | template<class Y> |
78 | Y operator-(const absolute<Y>& aval1,const absolute<Y>& aval2) |
79 | { |
80 | return Y(aval1.value()-aval2.value()); |
81 | } |
82 | |
83 | /// creates a quantity from an absolute unit and a raw value |
84 | template<class D, class S, class T> |
85 | quantity<absolute<unit<D, S> >, T> operator*(const T& t, const absolute<unit<D, S> >&) |
86 | { |
87 | return(quantity<absolute<unit<D, S> >, T>::from_value(t)); |
88 | } |
89 | |
90 | /// creates a quantity from an absolute unit and a raw value |
91 | template<class D, class S, class T> |
92 | quantity<absolute<unit<D, S> >, T> operator*(const absolute<unit<D, S> >&, const T& t) |
93 | { |
94 | return(quantity<absolute<unit<D, S> >, T>::from_value(t)); |
95 | } |
96 | |
97 | /// Print an absolute unit |
98 | template<class Char, class Traits, class Y> |
99 | std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,const absolute<Y>& aval) |
100 | { |
101 | |
102 | os << "absolute " << aval.value(); |
103 | |
104 | return os; |
105 | } |
106 | |
107 | } // namespace units |
108 | |
109 | } // namespace boost |
110 | |
111 | #if BOOST_UNITS_HAS_BOOST_TYPEOF |
112 | |
113 | #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
114 | |
115 | BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::absolute, (class)) |
116 | |
117 | #endif |
118 | |
119 | namespace boost { |
120 | |
121 | namespace units { |
122 | |
123 | /// Macro to define the offset between two absolute units. |
124 | /// Requires the value to be in the destination units e.g |
125 | /// @code |
126 | /// BOOST_UNITS_DEFINE_CONVERSION_OFFSET(celsius_base_unit, fahrenheit_base_unit, double, 32.0); |
127 | /// @endcode |
128 | /// @c BOOST_UNITS_DEFINE_CONVERSION_FACTOR is also necessary to |
129 | /// specify the conversion factor. Like @c BOOST_UNITS_DEFINE_CONVERSION_FACTOR |
130 | /// this macro defines both forward and reverse conversions so |
131 | /// defining, e.g., the conversion from celsius to fahrenheit as above will also |
132 | /// define the inverse conversion from fahrenheit to celsius. |
133 | #define BOOST_UNITS_DEFINE_CONVERSION_OFFSET(From, To, type_, value_) \ |
134 | namespace boost { \ |
135 | namespace units { \ |
136 | template<> \ |
137 | struct affine_conversion_helper< \ |
138 | reduce_unit<From::unit_type>::type, \ |
139 | reduce_unit<To::unit_type>::type> \ |
140 | { \ |
141 | static const bool is_defined = true; \ |
142 | typedef type_ type; \ |
143 | static type value() { return(value_); } \ |
144 | }; \ |
145 | } \ |
146 | } \ |
147 | void boost_units_require_semicolon() |
148 | |
149 | } // namespace units |
150 | |
151 | } // namespace boost |
152 | |
153 | #endif // BOOST_UNITS_ABSOLUTE_HPP |
154 | |