blob: 1e13cfa4561e584ebe314db70dcc8bd768ca65e6 [file] [log] [blame]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Units</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_units.html" title="Chapter&#160;26.&#160;Boost.Units 1.1.0">
<link rel="prev" href="Dimensional_Analysis.html" title="Dimensional Analysis">
<link rel="next" href="Quantities.html" title="Quantities">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="Dimensional_Analysis.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_units.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="Quantities.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_units.Units"></a><a class="link" href="Units.html" title="Units">Units</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="Units.html#boost_units.Units.base_units">Base Units</a></span></dt>
<dt><span class="section"><a href="Units.html#boost_units.Units.scaled_base_units">Scaled Base Units</a></span></dt>
<dt><span class="section"><a href="Units.html#boost_units.Units.scaled_units">Scaled Units</a></span></dt>
</dl></div>
<p>
We define a <span class="bold"><strong>unit</strong></span> as a set of base units each
of which can be raised to an arbitrary rational exponent. Thus, the SI unit
corresponding to the dimension of force is kg m s^-2, where kg, m, and s are
base units. We use the notion of a <span class="bold"><strong>unit system</strong></span>
such as SI to specify the mapping from a dimension to a particular unit so
that instead of specifying the base units explicitly, we can just ask for the
representation of a dimension in a particular system.
</p>
<p>
Units are, like dimensions, purely compile-time variables with no associated
value. Units obey the same algebra as dimensions do; the presence of the unit
system serves to ensure that units having identical reduced dimension in different
systems (like feet and meters) cannot be inadvertently mixed in computations.
</p>
<p>
There are two distinct types of systems that can be envisioned:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<span class="bold"><strong>Homogeneous systems</strong></span> : Systems which hold
a linearly independent set of base units which can be used to represent
many different dimensions. For example, the SI system has seven base dimensions
and seven base units corresponding to them. It can represent any unit which
uses only those seven base dimensions. Thus it is a homogeneous_system.
</li>
<li class="listitem">
<span class="bold"><strong>Heterogeneous systems</strong></span> : Systems which
store the exponents of every base unit involved are termed heterogeneous.
Some units can only be represented in this way. For example, area in m
ft is intrinsically heterogeneous, because the base units of meters and
feet have identical dimensions. As a result, simply storing a dimension
and a set of base units does not yield a unique solution. A practical example
of the need for heterogeneous units, is an empirical equation used in aviation:
H = (r/C)^2 where H is the radar beam height in feet and r is the radar
range in nautical miles. In order to enforce dimensional correctness of
this equation, the constant, C, must be expressed in nautical miles per
foot^(1/2), mixing two distinct base units of length.
</li>
</ul></div>
<p>
Units are implemented by the <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>
template class defined in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.unit_hpp" title="Header &lt;boost/units/unit.hpp&gt;">boost/units/unit.hpp</a></code>
:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Dim</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">System</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">unit</span><span class="special">;</span>
</pre>
<p>
In addition to supporting the compile-time dimensional analysis operations,
the +, -, *, and / runtime operators are provided for <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span> variables. Because the
dimension associated with powers and roots must be computed at compile-time,
it is not possible to provide overloads for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pow</span></code> that
function correctly for <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>s.
These operations are supported through free functions <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/pow_id1445415.html" title="Function template pow">pow</a></code></span> and <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/root.html" title="Function template root">root</a></code></span> that are templated
on integer and <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/static_rational.html" title="Class template static_rational">static_rational</a></code></span>
values and can take as an argument any type for which the utility classes
<span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/power_typeof_helper.html" title="Struct template power_typeof_helper">power_typeof_helper</a></code></span>
and <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/root_typeof_helper.html" title="Struct template root_typeof_helper">root_typeof_helper</a></code></span>
have been defined.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.base_units"></a><a class="link" href="Units.html#boost_units.Units.base_units" title="Base Units">Base Units</a>
</h3></div></div></div>
<p>
Base units are defined much like base dimensions.
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Dimensions</span><span class="special">,</span> <span class="keyword">long</span> <span class="identifier">N</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">base_unit</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span>
</pre>
<p>
Again negative ordinals are reserved.
</p>
<p>
As an example, in the following we will implement a subset of the SI unit
system based on the fundamental dimensions given above, demonstrating all
steps necessary for a completely functional system. First, we simply define
a unit system that includes type definitions for commonly used units:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">meter_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">meter_base_unit</span><span class="special">,</span> <span class="identifier">length_dimension</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">kilogram_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">kilogram_base_unit</span><span class="special">,</span> <span class="identifier">mass_dimension</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">second_base_unit</span> <span class="special">:</span> <span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">second_base_unit</span><span class="special">,</span> <span class="identifier">time_dimension</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">typedef</span> <span class="identifier">make_system</span><span class="special">&lt;</span>
<span class="identifier">meter_base_unit</span><span class="special">,</span>
<span class="identifier">kilogram_base_unit</span><span class="special">,</span>
<span class="identifier">second_base_unit</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">mks_system</span><span class="special">;</span>
<span class="comment">/// unit typedefs
</span><span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">dimensionless_type</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">dimensionless</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">length_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">length</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">mass_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">mass</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">time_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">time</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">area_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">area</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">unit</span><span class="special">&lt;</span><span class="identifier">energy_dimension</span><span class="special">,</span><span class="identifier">mks_system</span><span class="special">&gt;</span> <span class="identifier">energy</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
The macro <span class="underline"><code class="computeroutput"><a class="link" href="../BOOST_UNITS_STATIC_CONSTANT.html" title="Macro BOOST_UNITS_STATIC_CONSTANT">BOOST_UNITS_STATIC_CONSTANT</a></code></span>
is provided in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.static_constant_hpp" title="Header &lt;boost/units/static_constant.hpp&gt;">boost/units/static_constant.hpp</a></code>
to facilitate ODR- and thread-safe constant definition in header files. We
then define some constants for the supported units to simplify variable definitions:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">/// unit constants
</span><span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">meter</span><span class="special">,</span><span class="identifier">length</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">meters</span><span class="special">,</span><span class="identifier">length</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">kilogram</span><span class="special">,</span><span class="identifier">mass</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">kilograms</span><span class="special">,</span><span class="identifier">mass</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">second</span><span class="special">,</span><span class="identifier">time</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">seconds</span><span class="special">,</span><span class="identifier">time</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">square_meter</span><span class="special">,</span><span class="identifier">area</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">square_meters</span><span class="special">,</span><span class="identifier">area</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">joule</span><span class="special">,</span><span class="identifier">energy</span><span class="special">);</span>
<span class="identifier">BOOST_UNITS_STATIC_CONSTANT</span><span class="special">(</span><span class="identifier">joules</span><span class="special">,</span><span class="identifier">energy</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
If support for textual output of units is desired, we can also specialize
the <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/base_unit_info.html" title="Struct template base_unit_info">base_unit_info</a></code></span>
class for each fundamental dimension tag:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">base_unit_info</span><span class="special">&lt;</span><span class="identifier">test</span><span class="special">::</span><span class="identifier">meter_base_unit</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="string">"meter"</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">symbol</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="string">"m"</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
and similarly for <code class="computeroutput"><span class="identifier">kilogram_base_unit</span></code>
and <code class="computeroutput"><span class="identifier">second_base_unit</span></code>. A future
version of the library will provide a more flexible system allowing for internationalization
through a facet/locale-type mechanism. The <code class="computeroutput"><span class="identifier">name</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">symbol</span><span class="special">()</span></code> methods of <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/base_unit_info.html" title="Struct template base_unit_info">base_unit_info</a></code></span>
provide full and short names for the base unit. With these definitions, we
have the rudimentary beginnings of our unit system, which can be used to
determine reduced dimensions for arbitrary unit calculations.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.scaled_base_units"></a><a class="link" href="Units.html#boost_units.Units.scaled_base_units" title="Scaled Base Units">Scaled Base Units</a>
</h3></div></div></div>
<p>
Now, it is also possible to define a base unit as being a multiple of another
base unit. For example, the way that <code class="computeroutput"><span class="identifier">kilogram_base_unit</span></code>
is actually defined by the library is along the following lines
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">gram_base_unit</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">units</span><span class="special">::</span><span class="identifier">base_unit</span><span class="special">&lt;</span><span class="identifier">gram_base_unit</span><span class="special">,</span> <span class="identifier">mass_dimension</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">typedef</span> <span class="identifier">scaled_base_unit</span><span class="special">&lt;</span><span class="identifier">gram_base_unit</span><span class="special">,</span> <span class="identifier">scale</span><span class="special">&lt;</span><span class="number">10</span><span class="special">,</span> <span class="identifier">static_rational</span><span class="special">&lt;</span><span class="number">3</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">kilogram_base_unit</span><span class="special">;</span>
</pre>
<p>
This basically defines a kilogram as being 10^3 times a gram.
</p>
<p>
There are several advantages to this approach.
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
It reflects the real meaning of these units better than treating them
as independent units.
</li>
<li class="listitem">
If a conversion is defined between grams or kilograms and some other
units, it will automatically work for both kilograms and grams, with
only one specialization.
</li>
<li class="listitem">
Similarly, if the symbol for grams is defined as "g", then
the symbol for kilograms will be "kg" without any extra effort.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_units.Units.scaled_units"></a><a class="link" href="Units.html#boost_units.Units.scaled_units" title="Scaled Units">Scaled Units</a>
</h3></div></div></div>
<p>
We can also scale a <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>
as a whole, rather than scaling the individual base units which comprise
it. For this purpose, we use the metafunction <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/make_scaled_unit.html" title="Struct template make_scaled_unit">make_scaled_unit</a></code></span>.
The main motivation for this feature is the metric prefixes defined in <code class="computeroutput"><a class="link" href="Reference.html#header.boost.units.systems.si.prefixes_hpp" title="Header &lt;boost/units/systems/si/prefixes.hpp&gt;">boost/units/systems/si/prefixes.hpp</a></code>.
</p>
<p>
A simple example of its usage would be.
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">make_scaled_unit</span><span class="special">&lt;</span><span class="identifier">si</span><span class="special">::</span><span class="identifier">time</span><span class="special">,</span> <span class="identifier">scale</span><span class="special">&lt;</span><span class="number">10</span><span class="special">,</span> <span class="identifier">static_rational</span><span class="special">&lt;-</span><span class="number">9</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nanosecond</span><span class="special">;</span>
</pre>
<p>
nanosecond is a specialization of <span class="underline"><code class="computeroutput"><a class="link" href="../boost/units/unit.html" title="Class template unit">unit</a></code></span>,
and can be used in a quantity normally.
</p>
<pre class="programlisting"><span class="identifier">quantity</span><span class="special">&lt;</span><span class="identifier">nanosecond</span><span class="special">&gt;</span> <span class="identifier">t</span><span class="special">(</span><span class="number">1.0</span> <span class="special">*</span> <span class="identifier">si</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">t</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 1e9 ns
</span></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003 -2008 Matthias Christian Schabel, 2007-2010 Steven
Watanabe<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="Dimensional_Analysis.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_units.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="Quantities.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>