File: representing-dimensions.html

package info (click to toggle)
boost 1.34.1-14
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 116,412 kB
  • ctags: 259,566
  • sloc: cpp: 642,395; xml: 56,450; python: 17,612; ansic: 14,520; sh: 2,265; yacc: 858; perl: 481; makefile: 478; lex: 94; sql: 74; csh: 6
file content (156 lines) | stat: -rw-r--r-- 9,784 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- Copyright Aleksey Gurtovoy 2006. 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) -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" />
<title>THE BOOST MPL LIBRARY: Representing Dimensions</title>
<link rel="stylesheet" href="../style.css" type="text/css" />
</head>
<body class="docframe">
<table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./dimensional-analysis.html" class="navigation-link">Prev</a>&nbsp;<a href="./representing-quantities.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./representing-quantities.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./dimensional-analysis.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
<td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./tutorial-metafunctions.html" class="navigation-link">Tutorial: Metafunctions and Higher-Order Metaprogramming</a> / <a href="./dimensional-analysis.html" class="navigation-link">Dimensional Analysis</a> / <a href="./representing-dimensions.html" class="navigation-link">Representing Dimensions</a></td>
</tr></table><div class="header-separator"></div>
<div class="section" id="representing-dimensions">
<h1><a class="toc-backref" href="./dimensional-analysis.html#id42" name="representing-dimensions">Representing Dimensions</a></h1>
<p>An international standard called <em>Système
International d'Unites</em> (SI), breaks every quantity down into a
combination of the dimensions <em>mass</em>, <em>length</em> (or <em>position</em>),
<em>time</em>, <em>charge</em>, <em>temperature</em>, <em>intensity</em>, and <em>angle</em>.  To be
reasonably general, our system would have to be able to
represent seven or more fundamental dimensions.  It also needs
the ability to represent composite dimensions that, like <em>force</em>,
are built through multiplication or division of the fundamental
ones.</p>
<p>In general, a composite dimension is the product of powers of
fundamental dimensions. <a class="footnote-reference" href="#divisor" id="id6" name="id6">[1]</a>  If we were going to represent
these powers for manipulation at runtime, we could use an array of
seven <tt class="literal"><span class="pre">int</span></tt>s, with each position in the array holding the power
of a different fundamental dimension:</p>
<pre class="literal-block">
typedef int dimension[7]; // m  l  t  ...
dimension const mass      = {1, 0, 0, 0, 0, 0, 0};
dimension const length    = {0, 1, 0, 0, 0, 0, 0};
dimension const time      = {0, 0, 1, 0, 0, 0, 0};
...
</pre>
<table class="footnote" frame="void" id="divisor" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id6" name="divisor">[1]</a></td><td>Divisors just contribute negative exponents, since
1/<em>x</em> = <em>x</em><sup>-1</sup>.</td></tr>
</tbody>
</table>
<p>In that representation, force would be:</p>
<pre class="literal-block">
dimension const force  = {1, 1, -2, 0, 0, 0, 0};
</pre>
<!-- @compile(2) -->
<!-- @litre_translator.line_offset -= 7 -->
<p>that is, <em>mlt</em><sup>-2</sup>.  However, if we want to get dimensions into the
type system, these arrays won't do the trick: they're all
the same type!  Instead, we need types that <em>themselves</em> represent
sequences of numbers, so that two masses have the same type and a
mass is a different type from a length.</p>
<p>Fortunately, the MPL provides us with a collection of <strong>type
sequences</strong>.  For example, we can build a sequence of the built-in
signed integral types this way:</p>
<pre class="literal-block">
#include &lt;boost/mpl/vector.hpp&gt;

typedef boost::mpl::vector&lt;
     signed char, short, int, long&gt; signed_types;
</pre>
<p>How can we use a type sequence to represent numbers?  Just as
numerical metafunctions pass and return wrapper <em>types</em> having a
nested <tt class="literal"><span class="pre">::value</span></tt>, so numerical sequences are really sequences of
wrapper types (another example of polymorphism).  To make this sort
of thing easier, MPL supplies the <tt class="literal"><span class="pre">int_&lt;N&gt;</span></tt> class template, which
presents its integral argument as a nested <tt class="literal"><span class="pre">::value</span></tt>:</p>
<pre class="literal-block">
#include &lt;boost/mpl/int.hpp&gt;

namespace mpl = boost::mpl; // namespace alias
static int const five = mpl::int_&lt;5&gt;::value;
</pre>
<div class="sidebar">
<p class="sidebar-title first">Namespace Aliases</p>
<div class="line-block">
<div class="line"><tt class="literal"><span class="pre">namespace</span></tt> <em>alias</em> <tt class="literal"><span class="pre">=</span></tt> <em>namespace-name</em><tt class="literal"><span class="pre">;</span></tt></div>
</div>
<p>declares <em>alias</em> to be a synonym for <em>namespace-name</em>.  Many
examples in this book will use <tt class="literal"><span class="pre">mpl::</span></tt> to indicate
<tt class="literal"><span class="pre">boost::mpl::</span></tt>, but will omit the alias that makes it legal
C++.</p>
</div>
<!-- @ignore() # nonsense isn't worth testing
prefix +=['''
    #include <boost/mpl/int.hpp>
    #include <boost/mpl/vector.hpp>
'''] -->
<p>In fact, the library contains a whole suite of integral constant
wrappers such as <tt class="literal"><span class="pre">long_</span></tt> and <tt class="literal"><span class="pre">bool_</span></tt>, each one wrapping a
different type of integral constant within a class template.</p>
<p>Now we can build our fundamental dimensions:</p>
<pre class="literal-block">
typedef mpl::vector&lt;
   mpl::int_&lt;1&gt;, mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;
 , mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;
&gt; mass;

typedef mpl::vector&lt;
   mpl::int_&lt;0&gt;, mpl::int_&lt;1&gt;, mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;
 , mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;, mpl::int_&lt;0&gt;
&gt; length;
...
</pre>
<!-- @ # We explained about the implicit namespace alias above
prefix.append("""
namespace boost{namespace mpl {}}
namespace mpl = boost::mpl;
""")
compile('all') -->
<p>Whew!  That's going to get tiring pretty quickly.  Worse, it's hard
to read and verify:  The essential information, the powers of each
fundamental dimension, is buried in repetitive syntactic &quot;noise.&quot;
Accordingly, MPL supplies <strong>integral sequence wrappers</strong> that allow
us to write:</p>
<pre class="literal-block">
#include &lt;boost/mpl/vector_c.hpp&gt;

typedef mpl::vector_c&lt;int,1,0,0,0,0,0,0&gt; mass;
typedef mpl::vector_c&lt;int,0,1,0,0,0,0,0&gt; length; // or position 
typedef mpl::vector_c&lt;int,0,0,1,0,0,0,0&gt; time;
typedef mpl::vector_c&lt;int,0,0,0,1,0,0,0&gt; charge;
typedef mpl::vector_c&lt;int,0,0,0,0,1,0,0&gt; temperature;
typedef mpl::vector_c&lt;int,0,0,0,0,0,1,0&gt; intensity;
typedef mpl::vector_c&lt;int,0,0,0,0,0,0,1&gt; angle;
</pre>
<p>Even though they have different types, you can think of these
<tt class="literal"><span class="pre">mpl::vector_c</span></tt> specializations as being equivalent to the more
verbose versions above that use <tt class="literal"><span class="pre">mpl::vector</span></tt>.</p>
<p>If we want, we can also define a few composite dimensions:</p>
<pre class="literal-block">
// base dimension:        m l  t ... 
typedef mpl::vector_c&lt;int,0,1,-1,0,0,0,0&gt; velocity;     // l/t
typedef mpl::vector_c&lt;int,0,1,-2,0,0,0,0&gt; acceleration; // l/(t<sup>2</sup>)
typedef mpl::vector_c&lt;int,1,1,-1,0,0,0,0&gt; momentum;     // ml/t
typedef mpl::vector_c&lt;int,1,1,-2,0,0,0,0&gt; force;        // ml/(t<sup>2</sup>)
</pre>
<p>And, incidentally, the dimensions of scalars (like pi) can be
described as:</p>
<pre class="literal-block">
typedef mpl::vector_c&lt;int,0,0,0,0,0,0,0&gt; scalar;
</pre>
<!-- @stack[0].replace('hpp>', 'hpp>\nnamespace {')
stack[0].append('}')
compile('all', pop = None) -->
</div>

<div class="footer-separator"></div>
<table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./dimensional-analysis.html" class="navigation-link">Prev</a>&nbsp;<a href="./representing-quantities.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./representing-quantities.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./dimensional-analysis.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
</tr></table></body>
</html>