]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/units/doc/units.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / units / doc / units.qbk
CommitLineData
7c673cae
FG
1[library Boost.Units
2 [quickbook 1.5]
3 [version 1.1.0]
4 [authors [Schabel, Matthias C.]]
5 [authors [Watanabe, Steven]]
6 [copyright 2003-2008 Matthias Christian Schabel, 2007-2010 Steven Watanabe]
7 [license
8 Distributed under the Boost Software License, Version 1.0.
9 (See accompanying file LICENSE_1_0.txt or copy at
10 [@http://www.boost.org/LICENSE_1_0.txt])
11 ]
12 [purpose zero-overhead compile-time dimensional analysis and unit computations]
13]
14
15[/ Some links to external sources.]
16[def __boost [@http://www.boost.org/ Boost]]
17[def __boostroot [@boost: Boost root]]
18[def __boostlicense [@http://www.boost.org/LICENSE_1_0.txt Boost License]]
19[def __boost_mpl [@http://www.boost.org/libs/mpl/doc/index.html Boost Metaprogramming Library]]
20
21[def __mpl_forward_sequence [@http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html MPL Forward Sequence]]
22
23[/Links within this document.]
24[def __ordinal [classref boost::units::ordinal ordinal]]
25[def __dim [classref boost::units::dim dim]]
26[def __static_rational [classref boost::units::static_rational static_rational]]
27[def __make_dimension_list [classref boost::units::make_dimension_list make_dimension_list]]
28[def __unit [classref boost::units::unit unit]]
29[def __base_unit_info [classref boost::units::base_unit_info base_unit_info]]
30[def __quantity [classref boost::units::quantity quantity]]
31[def __conversion_helper [classref boost::units::conversion_helper conversion_helper]]
32[def __absolute [classref boost::units::absolute absolute]]
33[def __base_unit [classref boost::units::base_unit base_unit]]
34[def __base_dimension [classref boost::units::base_dimension base_dimension]]
35[def __scaled_base_unit [classref boost::units::scaled_base_unit base_unit]]
36[def __make_scaled_unit [classref boost::units::make_scaled_unit make_scaled_unit]]
37
38[def __unary_plus_typeof_helper [classref boost::units::unary_plus_typeof_helper unary_plus_typeof_helper]]
39[def __unary_minus_typeof_helper [classref boost::units::unary_minus_typeof_helper unary_minus_typeof_helper]]
40[def __add_typeof_helper [classref boost::units::add_typeof_helper add_typeof_helper]]
41[def __subtract_typeof_helper [classref boost::units::subtract_typeof_helper subtract_typeof_helper]]
42[def __multiply_typeof_helper [classref boost::units::multiply_typeof_helper multiply_typeof_helper]]
43[def __divide_typeof_helper [classref boost::units::divide_typeof_helper divide_typeof_helper]]
44[def __power_typeof_helper [classref boost::units::power_typeof_helper power_typeof_helper]]
45[def __root_typeof_helper [classref boost::units::root_typeof_helper root_typeof_helper]]
46
47[def __static_negate [classref boost::units::static_negate static_negate]]
48[def __static_add [classref boost::units::static_add static_add]]
49[def __static_subtract [classref boost::units::static_subtract static_subtract]]
50[def __static_multiply [classref boost::units::static_multiply static_multiply]]
51[def __static_divide [classref boost::units::static_divide static_divide]]
52[def __static_power [classref boost::units::static_power static_power]]
53[def __static_root [classref boost::units::static_root static_root]]
54
55[def __get_dimension [classref boost::units::get_dimension get_dimension]]
56[def __get_system [classref boost::units::get_system get_system]]
57
58[def __pow [funcref boost::units::pow pow]]
59[def __root [funcref boost::units::root root]]
60[def __quantity_cast [funcref boost::units::quantity_cast quantity_cast]]
61
62[def __from_value [memberref boost::units::quantity::from_value from_value]]
63[def __value [memberref boost::units::quantity::value value]]
64
65[def __reduce_unit [classref boost::units::reduce_unit reduce_unit]]
66[def __unscale [classref boost::units::unscale unscale]]
67
68[def __BOOST_UNITS_STATIC_CONSTANT [macroref BOOST_UNITS_STATIC_CONSTANT]]
69[def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR]]
70[def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE]]
71[def __BOOST_UNITS_DEFAULT_CONVERSION [macroref BOOST_UNITS_DEFAULT_CONVERSION]]
72
73[section:Introduction Introduction]
74
75The Boost.Units library is a C++ implementation of dimensional analysis in a general
76and extensible manner, treating it as a generic compile-time metaprogramming problem. With appropriate
77compiler optimization, no runtime execution cost is introduced, facilitating the use of this library to
78provide dimension checking in performance-critical code. Support for units
79and quantities (defined as a unit and associated value) for arbitrary unit system models and arbitrary
80value types is provided, as is a fine-grained general facility for unit conversions. Complete SI and CGS unit
81systems are provided, along with systems for
82angles measured in degrees, radians, gradians, and revolutions and
83systems for temperatures measured in Kelvin, degrees Celsius and degrees Fahrenheit.
84The library architecture has been designed with flexibility and extensibility in mind; demonstrations of the ease
85of adding new units and unit conversions are provided in the examples.
86
87In order to enable complex compile-time dimensional analysis calculations with no runtime overhead,
88Boost.Units relies heavily on the [___boost_mpl] (MPL) and on template metaprogramming techniques, and is, as a consequence,
89fairly demanding of compiler compliance to ISO standards. At present, it has been successfully
90compiled and tested on the following compilers/platforms :
91
92# g++ 4.0.1 on Mac OSX 10.4
93# Intel CC 9.1, 10.0, and 10.1 on Mac OSX 10.4
94# g++ 3.4.4, 4.2.3, and 4.3.0 on Windows XP
95# Microsoft Visual C++ 7.1, 8.0, and 9.0 on Windows XP
96# Comeau 4.3.10.1 beta2 on Windows XP
97# Metrowerks CodeWarrior 9.2 on Windows XP.
98# Sun CC 5.9 on Solaris and Linux
99
100The following compilers/platforms are known *not* to work :
101
102# g++ 3.3.x
103# Microsoft Visual C++ 6.0 on Windows XP
104# Microsoft Visual C++ 7.0 on Windows XP
105# Metrowerks CodeWarrior 8.0 on Windows XP.
106# All versions of Borland.
107
108[endsect]
109
110[section:Quick_Start Quick Start]
111
112Before discussing the basics of the library, we first define a few terms that will be used frequently
113in the following :
114
115* *Base dimension* : A base dimension is loosely defined as a measurable entity of interest; in conventional
116 dimensional analysis, base dimensions include length (\[L\]), mass (\[M\]), time (\[T\]), etc... but there is
117 no specific restriction on what base dimensions can be used. Base dimensions are essentially a tag type and
118 provide no dimensional analysis functionality themselves.
119* *Dimension* : A collection of zero or more base dimensions, each
120 potentially raised to a different rational power.
121 For example, length = \[L\]^1, area = \[L\]^2, velocity = \[L\]^1/\[T\]^1, and
122 energy = \[M\]^1 \[L\]^2/\[T\]^2 are all dimensions.
123* *Base unit* : A base unit represents a specific measure of a dimension. For example, while length is an abstract measure of
124 distance, the meter is a concrete base unit of distance. Conversions are defined using base units.
125 Much like base dimensions, base units are a tag type used solely to define units and do not support dimensional
126 analysis algebra.
127* *Unit* : A set of base units raised to rational exponents, e.g. m^1, kg^1, m^1/s^2.
128* *System* : A unit system is a collection of base units representing all the measurable entities of interest for a
129 specific problem. For example, the SI unit system defines seven base units : length (\[L\]) in meters,
130 mass (\[M\]) in kilograms, time (\[T\]) in seconds, current (\[I\]) in amperes, temperature (\[theta\]) in kelvin,
131 amount (\[N\]) in moles, and luminous intensity (\[J\]) in candelas. All measurable entities within the SI system can
132 be represented as products of various integer or rational powers of these seven base units.
133* *Quantity* : A quantity represents a concrete amount of a unit. Thus, while the meter is the base
134 unit of length in the SI system, 5.5 meters is a quantity of length in that system.
135
136To begin, we present two short tutorials. [@../../libs/units/tutorial/tutorial_1.cpp Tutorial1] demonstrates the use of
137[@http://en.wikipedia.org/wiki/SI_units SI] units. After including the appropriate system headers
138and the headers for the various SI units we will need (all SI units can be included with
139[headerref boost/units/systems/si.hpp]) and for quantity I/O ([headerref boost/units/io.hpp]), we define
140a function that computes the work, in joules, done by exerting a force in newtons over a specified distance in meters
141and outputs the result to `std::cout`. The [___quantity] class accepts a second template parameter as its value type;
142this parameter defaults to
143`double` if not otherwise specified. To demonstrate the ease of using user-defined types in dimensional
144calculations, we also present code for computing the complex impedance using `std::complex<double>`
145as the value type :
146
147[import ../example/tutorial.cpp]
148
149[tutorial_code]
150
151The intent and function of the above code should be obvious; the output produced is :
152
153[tutorial_output]
154
155While this library attempts to make simple dimensional computations easy to code, it is in no way
156tied to any particular unit system (SI or otherwise). Instead, it provides a highly flexible compile-time
157system for dimensional analysis, supporting arbitrary collections of base dimensions, rational
158powers of units, and explicit quantity conversions. It accomplishes all of this via template metaprogramming techniques.
159With modern optimizing compilers, this results in zero runtime overhead for quantity computations relative to the
160same code without unit checking.
161
162[endsect]
163
164[section:Dimensional_Analysis Dimensional Analysis]
165
166The concept of
167[@http://en.wikipedia.org/wiki/Dimensional_analysis dimensional analysis]
168is normally presented early on in introductory physics and engineering classes as a means of determining the
169correctness of an equation or computation by propagating the physical measurement
170[@http://en.wikipedia.org/wiki/Units_of_measurement units]
171of various quantities through the equation along with their numerical values. There are a number of standard
172unit systems in common use, the most prominent of which is the
173[@http://en.wikipedia.org/wiki/SI_units Systeme International]
174(also known as SI or MKS (meter-kilogram-second), which was a metric predecessor to the SI system named
175for three of the base units on which the system is based). The SI
176is the only official international standard unit system and is widely utilized in science and engineering.
177Other common systems include the [@http://en.wikipedia.org/wiki/Cgs_units CGS]
178(centimeter-gram-second) system and the
179[@http://en.wikipedia.org/wiki/English_units English]
180system still in use in some problem domains in the United States and elsewhere. In physics,
181there also exist a number of other systems that are in common use in specialized subdisciplines. These are
182collectively referred to as [@http://en.wikipedia.org/wiki/Natural_units natural units]. When
183quantities representing different measurables are combined, dimensional analysis provides the means of
184assessing the consistency of the resulting calculation. For example, the sum of two lengths is also a length,
185while the product of two lengths is an area, and the sum of a length and an area is undefined. The fact that the
186arguments to many functions (such as exp, log, etc...) must be dimensionless quantities can be easily demonstrated by
187examining their series expansions in the context of dimensional analysis. This library facilitates the enforcement
188of this type of restriction in code involving dimensioned quantities where appropriate.
189
190In the following discussion we view dimensional analysis as an abstraction in which an arbitrary set of
191[@http://en.wikipedia.org/wiki/Fundamental_units units] obey the rules of a specific algebra.
192We will refer to a pair of a base dimension and a rational exponent as a *fundamental dimension*,
193and a list composed of an arbitrary number of fundamental dimensions as a *composite dimension* or, simply,
194*dimension*. In particular, given a set of [$../../libs/units/images/form_0.png] fundamental dimensions
195denoted by [$../../libs/units/images/form_1.png] and a set of [$../../libs/units/images/form_0.png]
196rational exponents [$../../libs/units/images/form_2.png], any possible (composite) dimension can be written
197as [$../../libs/units/images/form_3.png].
198
199Composite dimensions obey the algebraic rules for dimensional analysis. In particular, for any scalar value,
200[$../../libs/units/images/form_4.png],
201and composite dimensions [$../../libs/units/images/form_5.png]
202and [$../../libs/units/images/form_6.png], where
203[$../../libs/units/images/form_7.png], we have:
204
205[$../../libs/units/images/form_8.png]
206
207Users of a dimensional analysis library should be able to specify an arbitrary list of base dimensions to
208produce a composite dimension. This potentially includes repeated tags. For example,
209it should be possible to express energy as [$../../libs/units/images/form_9.png], [$../../libs/units/images/form_10.png],
210[$../../libs/units/images/form_11.png], or any other permutation of mass, length, and time having aggregate exponents of
2111, 2, and -2, respectively.
212In order to be able to perform computations on arbitrary sets of dimensions,
213all composite dimensions must be reducible to an unambiguous final composite dimension, which we will refer to as a
214*reduced dimension*, for which
215
216# fundamental dimensions are consistently ordered
217# dimensions with zero exponent are elided. Note that reduced dimensions never have more than
218 [$../../libs/units/images/form_0.png] base dimensions, one for each distinct fundamental dimension, but may have fewer.
219
220In our implementation, base dimensions are associated with tag types. As we will ultimately
221represent composite dimensions as typelists, we must provide some mechanism for sorting
222base dimension tags in order to make it possible to convert an arbitrary composite dimension
223into a reduced dimension. For this purpose, we assign a unique integer to each base dimension.
224The [___base_dimension] class (found in [headerref boost/units/base_dimension.hpp]) uses the
225curiously recurring template pattern (CRTP) technique to ensure that ordinals specified for
226base dimensions are unique:
227
228 template<class Derived, long N> struct base_dimension { ... };
229
230With this, we can define the base dimensions for length, mass, and time as:
231
232[import ../example/test_system.hpp]
233[test_system_snippet_1]
234
235It is important to note that the choice of order is completely arbitrary as long as each tag has a unique enumerable
236value; non-unique ordinals are flagged as errors at compile-time. Negative ordinals are reserved for use by the library.
237To define composite dimensions corresponding to the base dimensions, we
238simply create MPL-conformant typelists of fundamental dimensions by using the [___dim] class to encapsulate pairs of base dimensions
239and [___static_rational] exponents. The [___make_dimension_list] class acts as a wrapper to ensure
240that the resulting type is in the form of a reduced dimension:
241
242[test_system_snippet_2]
243
244This can also be easily accomplished using a convenience typedef provided by [___base_dimension]:
245
246[test_system_snippet_3]
247
248so that the above code is identical to the full typelist definition. Composite dimensions are similarly defined via a typelist:
249
250[test_system_snippet_4]
251
252A convenience class for composite dimensions with integer powers is also provided:
253
254[test_system_snippet_5]
255
256[endsect]
257
258[section:Units Units]
259
260We define a *unit* as a set of base units each of which can be raised to an arbitrary rational
261exponent. Thus, the SI unit corresponding to the dimension of force is kg m s^-2, where kg, m,
262and s are base units. We use the notion of a *unit system* such as SI to specify the mapping
263from a dimension to a particular unit so that instead of specifying the base units explicitly,
264we can just ask for the representation of a dimension in a particular system.
265
266Units are, like dimensions, purely compile-time variables with no associated value.
267Units obey the same algebra as dimensions do; the presence of the unit system serves to ensure that units having identical
268reduced dimension in different systems (like feet and meters) cannot be inadvertently mixed in computations.
269
270There are two distinct types of systems that can be envisioned:
271
272* *Homogeneous systems* : Systems which hold a linearly independent set of base units which
273 can be used to represent many different dimensions. For example, the SI system has seven
274 base dimensions and seven base units corresponding to them. It can represent any unit which
275 uses only those seven base dimensions. Thus it is a homogeneous_system.
276* *Heterogeneous systems* : Systems which store the exponents of every base unit involved
277 are termed heterogeneous. Some units can only be represented in this way. For example,
278 area in m ft is intrinsically heterogeneous, because the base units of meters and feet
279 have identical dimensions. As a result, simply storing a dimension and a set of base
280 units does not yield a unique solution. A practical example of the need for heterogeneous
281 units, is an empirical equation used in aviation: H = (r/C)^2 where H is the radar beam
282 height in feet and r is the radar range in nautical miles. In order to enforce dimensional
283 correctness of this equation, the constant, C, must be expressed in nautical miles per foot^(1/2),
284 mixing two distinct base units of length.
285
286Units are implemented by the [___unit] template class defined in [headerref boost/units/unit.hpp] :
287
288 template<class Dim,class System> class unit;
289
290In addition to supporting the compile-time dimensional analysis operations, the +, -, *, and / runtime operators are provided
291for [___unit] variables. Because the dimension associated with powers and roots must be computed at compile-time, it is not
292possible to provide overloads for `std::pow` that function correctly for [___unit]s. These operations are supported through
293free functions [___pow] and [___root] that are templated on integer and [___static_rational] values and can take as an argument
294any type for which the utility classes [___power_typeof_helper] and [___root_typeof_helper] have been defined.
295
296[section Base Units]
297
298Base units are defined much like base dimensions.
299
300 template<class Derived, class Dimensions, long N> struct base_unit { ... };
301
302Again negative ordinals are reserved.
303
304As an example, in the following we will implement a subset of the SI unit system based on the fundamental dimensions
305given above, demonstrating all steps necessary for a completely functional system. First, we simply define a unit system
306that includes type definitions for commonly used units:
307
308[test_system_snippet_6]
309
310The macro [___BOOST_UNITS_STATIC_CONSTANT] is provided in [headerref boost/units/static_constant.hpp]
311to facilitate ODR- and thread-safe constant definition in header files. We then define some constants for the supported units
312to simplify variable definitions:
313
314[test_system_snippet_7]
315
316If support for textual output of units is desired, we can also specialize the [___base_unit_info] class for each fundamental
317dimension tag:
318
319[test_system_snippet_8]
320
321and similarly for `kilogram_base_unit` and `second_base_unit`. A future version of the library will provide a more flexible system
322allowing for internationalization through a facet/locale-type mechanism.
323The `name()` and `symbol()` methods of [___base_unit_info] provide full and short names for the base unit. With these definitions,
324we have the rudimentary beginnings of our unit system, which can be used to determine reduced dimensions for arbitrary
325unit calculations.
326
327[endsect] [/section Base Units]
328
329[section Scaled Base Units]
330
331Now, it is also possible to define a base unit as being a multiple of
332another base unit. For example, the way that `kilogram_base_unit` is
333actually defined by the library is along the following lines
334
335 struct gram_base_unit : boost::units::base_unit<gram_base_unit, mass_dimension, 1> {};
336 typedef scaled_base_unit<gram_base_unit, scale<10, static_rational<3> > > kilogram_base_unit;
337
338This basically defines a kilogram as being 10^3 times a gram.
339
340There are several advantages to this approach.
341
342* It reflects the real meaning of these units better than treating them as independent units.
343* If a conversion is defined between grams or kilograms and some other units,
344 it will automatically work for both kilograms and grams, with only one specialization.
345* Similarly, if the symbol for grams is defined as "g", then the symbol for kilograms
346 will be "kg" without any extra effort.
347
348[endsect] [/section Scaled Base Units]
349
350[section Scaled Units]
351
352We can also scale a [___unit] as a whole, rather than scaling the individual
353base units which comprise it. For this purpose, we use the metafunction
354[___make_scaled_unit]. The main motivation for this feature is the metric
355prefixes defined in [headerref boost/units/systems/si/prefixes.hpp].
356
357A simple example of its usage would be.
358
359 typedef make_scaled_unit<si::time, scale<10, static_rational<-9> > >::type nanosecond;
360
361nanosecond is a specialization of [___unit], and can be used in a quantity normally.
362
363 quantity<nanosecond> t(1.0 * si::seconds);
364 std::cout << t << std::endl; // prints 1e9 ns
365
366[endsect] [/section Scaled Units]
367
368[endsect] [/section:Units Units]
369
370[section:Quantities Quantities]
371
372A *quantity* is defined as a value of an arbitrary value type that is associated with a specific unit. For example,
373while meter is a unit, 3.0 meters is a quantity. Quantities obey two separate algebras: the native algebra for their
374value type, and the dimensional analysis algebra for the associated unit. In addition, algebraic operations are defined
375between units and quantities to simplify the definition of quantities; it is effectively equivalent to algebra with
376a unit-valued quantity.
377
378Quantities are implemented by the [___quantity] template class defined in [headerref boost/units/quantity.hpp] :
379
380 template<class Unit,class Y = double> class quantity;
381
382This class is templated on both unit type (`Unit`) and value type (`Y`), with the latter defaulting to double-precision
383floating point if not otherwise specified. The value type must have a normal copy constructor and copy
384assignment operator. Operators +, -, *, and / are provided for algebraic operations between
385scalars and units, scalars and quantities, units and quantities, and between quantities. In addition, integral and
386rational powers and roots can be computed using the [___pow]<R> and [___root]<R> functions. Finally,
387the standard set of boolean comparison operators ( `==, !=, <, <=, >, and >=` ) are provided to allow
388comparison of quantities from the same unit system. All operators simply delegate to the
389corresponding operator of the value type if the units permit.
390
391[section:Heterogeneous_Operators Heterogeneous Operators]
392
393For most common value types, the result type of arithmetic operators is the same as the value type itself. For example,
394the sum of two double precision floating point numbers is another double precision floating point number. However, there
395are instances where this is not the case. A simple example is given by the [@http://en.wikipedia.org/wiki/Natural_number
396natural numbers] where the operator arithmetic obeys the following rules (using the standard notation for
397[@http://en.wikipedia.org/wiki/Number number systems]):
398
399* [$../../libs/units/images/form_12.png]
400* [$../../libs/units/images/form_13.png]
401* [$../../libs/units/images/form_14.png]
402* [$../../libs/units/images/form_15.png]
403
404This library is designed to support arbitrary value type algebra for addition, subtraction, multiplication, division, and
405rational powers and roots. It uses Boost.Typeof to deduce the result of these operators. For compilers that
406support `typeof`, the appropriate value type will be automatically deduced. For compilers that do not provide
407language support for `typeof` it is necessary to register all the types used. For the case of natural numbers,
408this would amount to something like the following:
409
410 BOOST_TYPEOF_REGISTER_TYPE(natural);
411 BOOST_TYPEOF_REGISTER_TYPE(integer);
412 BOOST_TYPEOF_REGISTER_TYPE(rational);
413
414[endsect]
415
416[section:Conversions Conversions]
417
418Conversion is only meaningful for quantities as it implies the presence of at
419least a multiplicative scale factor and, possibly, and affine linear offset.
420Macros for simplifying the definition of conversions between units can be found in
421[headerref boost/units/conversion.hpp] and [headerref boost/units/absolute.hpp]
422(for affine conversions with offsets).
423
424The macro [___BOOST_UNITS_DEFINE_CONVERSION_FACTOR] specifies a scale
425factor for conversion from the first unit type to the second. The
426first argument must be a [___base_unit]. The second argument
427can be either a [___base_unit] or a [___unit].
428
429Let's declare a simple base unit:
430
431 struct foot_base_unit : base_unit<foot_base_unit, length_dimension, 10> { };
432
433Now, we want to be able to convert feet to meters and vice versa. The foot
434is defined as exactly 0.3048 meters, so we can write the following
435
436 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, meter_base_unit, double, 0.3048);
437
438Alternately, we could use the SI length `typedef`:
439
440 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, SI::length, double, 0.3048);
441
442Since the SI unit of length is the meter, these two definitions are equivalent.
443If these conversions have been defined, then converting between
444scaled forms of these units will also automatically work.
445
446The macro [___BOOST_UNITS_DEFAULT_CONVERSION] specifies a conversion
447that will be applied to a base unit when no direct conversion is
448possible. This can be used to make arbitrary conversions work
449with a single specialization:
450
451 struct my_unit_tag : boost::units::base_unit<my_unit_tag, boost::units::force_type, 1> {};
452 // define the conversion factor
453 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(my_unit_tag, SI::force, double, 3.14159265358979323846);
454 // make conversion to SI the default.
455 BOOST_UNITS_DEFAULT_CONVERSION(my_unit_tag, SI::force);
456
457[endsect]
458
459[section:Quantity_Construction_and_Conversion Construction and Conversion of Quantities]
460
461This library is designed to emphasize safety above convenience when performing operations with dimensioned quantities.
462Specifically, construction of quantities is required to fully specify both value and unit. Direct construction from a scalar value
463is prohibited (though the static member function [___from_value] is provided to enable
464this functionality where it is necessary. In addition, a [___quantity_cast] to a reference allows direct access to the
465underlying value of a [___quantity] variable. An explicit constructor is provided to enable conversion between
466dimensionally compatible quantities in different unit systems. Implicit conversions between unit systems are
467allowed only when the reduced units are identical, allowing, for example, trivial conversions between
468equivalent units in different systems (such as SI seconds and CGS seconds) while simultaneously enabling
469unintentional unit system mismatches to be caught at compile time and preventing potential loss of precision and
470performance overhead from unintended conversions. Assignment follows the same rules.
471An exception is made for quantities for which the unit reduces to dimensionless; in this case, implicit conversion
472to the underlying value type is allowed via class template specialization. Quantities of different value types are implicitly
473convertible only if the value types are themselves implicitly convertible. The [___quantity] class also defines
474a `value()` member for directly accessing the underlying value.
475
476To summarize, conversions are allowed under the following conditions :
477
478* implicit conversion of `quantity<Unit,Y>` to `quantity<Unit,Z>` is allowed if `Y` and `Z` are implicitly convertible.
479* assignment between `quantity<Unit,Y>` and `quantity<Unit,Z>` is allowed if `Y` and `Z` are implicitly convertible.
480* explicit conversion between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed if `Unit1` and `Unit2` have the same dimensions
481 and if `Y` and `Z` are implicitly convertible.
482* implicit conversion between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed if `Unit1`
483 reduces to exactly the same combination of base units as `Unit2` and if `Y` and `Z` are convertible.
484* assignment between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed under the same
485 conditions as implicit conversion.
486* `quantity<Unit,Y>` can be directly constructed from a value of type `Y` using the static member function [___from_value]. Doing so,
487 naturally, bypasses any type-checking of the newly assigned value, so this method should be used only when absolutely necessary.
488
489Of course, any time implicit conversion is allowed, an explicit conversion is
490also legal.
491
492Because dimensionless quantities have no associated units, they behave as normal scalars, and allow implicit conversion to and from
493the underlying value type or types that are convertible to/from that value type.
494
495[endsect]
496
497[endsect]
498
499[section:Examples Examples]
500
501[section:DimensionExample Dimension Example]
502
503([@../../libs/units/example/dimension.cpp dimension.cpp])
504
505By using MPL metafunctions and the template specializations for operations on composite dimensions
506(defined in [headerref boost/units/dimension.hpp]) it is possible to perform compile time arithmetic
507according to the dimensional analysis rules described [link boost_units.Dimensional_Analysis above]
508to produce new composite dimensions :
509
510[import ../example/dimension.cpp]
511
512[dimension_snippet_1]
513
514outputting (with symbol demangling, implemented in
515[@boost:/boost/units/detail/utility.hpp utility.hpp])
516
517[dimension_output]
518
519[endsect]
520
521[section:UnitExample Unit Example]
522
523([@../../libs/units/example/unit.cpp unit.cpp])
524
525This example demonstrates the use of the simple but functional unit system implemented in
526[@boost:/libs/units/example/test_system.hpp test_system.hpp]
527
528[import ../example/unit.cpp]
529
530[unit_snippet_1]
531
532We can perform various algebraic operations on these units, resulting in the following output:
533
534[unit_output]
535
536[endsect]
537
538[section:QuantityExample Quantity Example]
539
540([@../../libs/units/example/quantity.cpp quantity.cpp])
541
542This example demonstrates how to use quantities of our toy unit system :
543
544[import ../example/quantity.cpp]
545
546[quantity_snippet_1]
547
548giving us the basic quantity functionality :
549
550[quantity_output_double]
551
552As a further demonstration of the flexibility of the system, we replace the `double` value type
553with a `std::complex<double>` value type (ignoring the question of the meaningfulness of
554complex lengths and energies) :
555
556[quantity_snippet_2]
557
558and find that the code functions exactly as expected with no additional work, delegating operations
559to `std::complex<double>` and performing the appropriate dimensional analysis :
560
561[quantity_output_complex]
562
563[endsect]
564
565[section:KitchenSinkExample Kitchen Sink Example using SI units]
566
567([@../../libs/units/example/kitchen_sink.cpp kitchen_sink.cpp])
568
569This example provides a fairly extensive set of tests covering most of the [___quantity] functionality.
570It uses the SI unit system defined in [headerref boost/units/systems/si.hpp].
571
572If we define a few units and associated quantities,
573
574[import ../example/kitchen_sink.cpp]
575
576[kitchen_sink_snippet_1]
577
578the various algebraic operations between scalars, units, and quantities give
579
580[kitchen_sink_output_1]
581
582Scalar/unit operations :
583
584[kitchen_sink_output_2]
585
586Unit/unit operations and integral/rational powers of units :
587
588[kitchen_sink_output_3]
589
590Scalar/quantity operations :
591
592[kitchen_sink_output_4]
593
594Unit/quantity operations :
595
596[kitchen_sink_output_5]
597
598Quantity/quantity operations and integral/rational powers of quantities :
599
600[kitchen_sink_output_6]
601
602Logical comparison operators are also defined between quantities :
603
604[kitchen_sink_snippet_2]
605
606giving
607
608[kitchen_sink_output_7]
609
610Implicit conversion is allowed between dimensionless quantities and their corresponding value types :
611
612[kitchen_sink_snippet_3]
613
614A generic function for computing mechanical work can be defined that takes force and distance arguments
615in an arbitrary unit system and returns energy in the same system:
616
617[kitchen_sink_function_snippet_3]
618
619[kitchen_sink_snippet_4]
620
621which functions as expected for SI quantities :
622
623[kitchen_sink_output_9]
624
625The ideal gas law can also be implemented in SI units :
626
627[kitchen_sink_function_snippet_4]
628
629[kitchen_sink_snippet_5]
630
631with the resulting output :
632
633[kitchen_sink_output_10]
634
635Trigonometric and inverse trigonometric functions can be implemented for any unit system
636that provides an angular base dimension. For radians, these functions are found in
637[headerref boost/units/cmath.hpp] These behave as one expects, with trigonometric functions
638taking an angular quantity and returning a dimensionless quantity, while the inverse trigonometric functions
639take a dimensionless quantity and return an angular quantity :
640
641Defining a few angular quantities,
642
643[kitchen_sink_snippet_6]
644
645yields
646
647[kitchen_sink_output_11]
648
649Dealing with complex quantities is trivial. Here is the calculation of complex impedance :
650
651[kitchen_sink_snippet_7]
652
653giving
654
655[kitchen_sink_output_12]
656
657[section:UDT_Quantities User-defined value types]
658
659User-defined value types that support the appropriate arithmetic operations are automatically supported
660as quantity value types. The operators that are supported by default for quantity value types are unary plus, unary minus,
661addition, subtraction, multiplication, division, equal-to, not-equal-to, less-than, less-or-equal-to,
662greater-than, and greater-or-equal-to. Support for rational powers and roots can be added by overloading
663the [___power_typeof_helper] and [___root_typeof_helper] classes. Here we implement a user-defined `measurement`
664class that models a numerical measurement with an associated measurement error and the appropriate algebra and
665demonstrates its use as a quantity value type; the full code is found in [@../../libs/units/example/measurement.hpp measurement.hpp].
666
667Then, defining some `measurement` [___quantity] variables
668
669[kitchen_sink_snippet_8]
670
671gives
672
673[kitchen_sink_output_13]
674
675If we implement the overloaded helper classes for rational powers and roots
676then we can also compute rational powers of measurement quantities :
677
678[kitchen_sink_output_14]
679
680[endsect]
681
682[endsect]
683
684[section:ConversionExample Conversion Example]
685
686([@../../libs/units/example/conversion.cpp conversion.cpp])
687
688This example demonstrates the various allowed conversions between SI and CGS units. Defining some
689quantities
690
691[import ../example/conversion.cpp]
692
693[conversion_snippet_1]
694
695illustrates implicit conversion of quantities of different value types where implicit conversion
696of the value types themselves is allowed. N.B. The conversion from double to int is treated
697as an explicit conversion because there is no way to emulate the exact behavior of the built-in
698conversion. Explicit constructors allow conversions for two cases:
699
700* explicit casting of a [___quantity] to a different `value_type` :
701
702[conversion_snippet_3]
703
704* and explicit casting of a [___quantity] to a different unit :
705
706[conversion_snippet_4]
707
708giving the following output :
709
710[conversion_output_1]
711
712A few more explicit unit system conversions :
713
714[conversion_snippet_5]
715
716which produces the following output:
717
718[conversion_output_2]
719
720[endsect]
721
722[section:UDTExample User Defined Types]
723
724([@../../libs/units/example/quaternion.cpp quaternion.cpp])
725
726This example demonstrates the use of `boost::math::quaternion` as a value type for [___quantity] and the converse.
727For the first case, we first define specializations of [___power_typeof_helper] and [___root_typeof_helper] for
728powers and roots, respectively:
729
730[import ../example/quaternion.cpp]
731
732[quaternion_class_snippet_1a]
733
734[quaternion_class_snippet_1b]
735
736We can now declare a [___quantity] of a `quaternion` :
737
738[quaternion_snippet_1]
739
740so that all operations that are defined in the `quaternion` class behave correctly. If rational
741powers were defined for this class, it would be possible to compute rational powers and roots with
742no additional changes.
743
744[quaternion_output_1]
745
746Now, if for some reason we preferred the [___quantity] to be the value type of the `quaternion` class we would have :
747
748[quaternion_snippet_2]
749
750Here, the unary plus and minus and addition and subtraction operators function correctly. Unfortunately,
751the multiplication and division operations fail because `quaternion` implements them in terms of the `*=` and
752`/=` operators, respectively, which are incapable of representing the heterogeneous unit algebra needed for
753quantities (an identical problem
754occurs with `std::complex<T>`, for the same reason). In order to compute rational powers and roots, we need to
755specialize [___power_typeof_helper] and [___root_typeof_helper] as follows:
756
757[quaternion_class_snippet_2a]
758
759[quaternion_class_snippet_2b]
760
761giving:
762
763[quaternion_output_2]
764
765[endsect]
766
767[section:ComplexExample Complex Example]
768
769([@../../libs/units/example/complex.cpp complex.cpp])
770
771This example demonstrates how to implement a replacement `complex` class that functions correctly both as a
772quantity value type and as a quantity container class, including heterogeneous multiplication and division
773operations and rational powers and roots. Naturally, heterogeneous operations are only supported on
774compilers that implement `typeof`. The primary differences are that binary operations are not implemented
775using the `op=` operators and use the utility classes [___add_typeof_helper], [___subtract_typeof_helper],
776[___multiply_typeof_helper], and [___divide_typeof_helper]. In addition, [___power_typeof_helper] and
777[___root_typeof_helper] are defined for both cases :
778
779[import ../example/complex.cpp]
780
781[complex_class_snippet_1]
782
783With this replacement `complex` class, we can declare a complex variable :
784
785[complex_snippet_1]
786
787to get the correct behavior for all cases supported by [___quantity] with a `complex` value type :
788
789[complex_output_1]
790
791and, similarly, `complex` with a [___quantity] value type
792
793[complex_snippet_2]
794
795gives
796
797[complex_output_2]
798
799[endsect]
800
801[section:PerformanceExample Performance Example]
802
803([@../../libs/units/example/performance.cpp performance.cpp])
804
805This example provides an ad hoc performance test to verify that zero runtime overhead
806is incurred when using [___quantity] in place of `double`. Note that performance
807optimization and testing is not trivial, so some care must be taken in profiling. It
808is also critical to have a compiler capable of optimizing the many template instantiations
809and inline calls effectively to achieve maximal performance. Zero overhead for this test
810has been verified using gcc 4.0.1, and icc 9.0, 10.0, and 10.1 on Mac OS 10.4 and 10.5, and
811using msvc 8.0 on Windows XP.
812
813[endsect]
814
815[section:RadarBeamHeightExample Radar Beam Height]
816
817([@../../libs/units/example/radar_beam_height.cpp radar_beam_height.cpp])
818
819[import ../example/radar_beam_height.cpp]
820
821This example demonstrates the implementation of two non-SI units of length, the
822nautical mile :
823
824[radar_beam_height_class_snippet_1]
825
826and the imperial foot :
827
828[radar_beam_height_class_snippet_2]
829
830These units include conversions between themselves and the meter. Three functions
831for computing radar beam height from radar range and the local earth radius are
832defined. The first takes arguments in one system and returns a value in the same
833system :
834
835[radar_beam_height_function_snippet_1]
836
837The second is similar, but is templated on return type, so that the arguments are
838converted to the return unit system internally :
839
840[radar_beam_height_function_snippet_2]
841
842Finally, the third function is an empirical approximation that is only valid for
843radar ranges specified in nautical miles, returning beam height in feet. This
844function uses the heterogeneous unit of nautical miles per square root of feet to
845ensure dimensional correctness :
846
847[radar_beam_height_function_snippet_3]
848
849With these, we can compute radar beam height in various unit systems :
850
851[radar_beam_height_snippet_1]
852
853giving
854
855[radar_beam_height_output]
856
857[endsect]
858
859[section:HeterogeneousUnitExample Heterogeneous Unit Example]
860
861([@../../libs/units/example/heterogeneous_unit.cpp heterogeneous_unit.cpp])
862
863[import ../example/heterogeneous_unit.cpp]
864
865Mixed units and mixed unit conversions.
866
867This code:
868
869[heterogeneous_unit_snippet_1]
870
871gives
872
873[heterogeneous_unit_output_1]
874
875Arbitrary conversions also work:
876
877[heterogeneous_unit_snippet_2]
878
879yielding
880
881[heterogeneous_unit_output_2]
882
883[endsect]
884
885[section:AbsoluteRelativeTemperatureExample Absolute and Relative Temperature Example]
886
887([@../../libs/units/example/temperature.cpp temperature.cpp])
888
889[import ../example/temperature.cpp]
890
891This example demonstrates using of absolute temperatures and relative temperature differences in Fahrenheit
892and converting between these and the Kelvin temperature scale. This issue touches on some surprisingly deep mathematical
893concepts (see [@http://en.wikipedia.org/wiki/Affine_space Wikipedia] for a basic review), but for our purposes here, we
894will simply observe that it is important to be able to differentiate between an absolute temperature measurement and a
895measurement of temperature difference. This is accomplished by using the [___absolute] wrapper class.
896
897First we define a system using the predefined fahrenheit base unit:
898
899[temperature_snippet_1]
900
901Now we can create some quantities:
902
903[temperature_snippet_3]
904
905Note the use of [___absolute] to wrap a unit. The resulting output is:
906
907[temperature_output_1]
908
909[endsect]
910
911[section:RuntimeConversionFactorExample Runtime Conversion Factor Example]
912
913([@../../libs/units/example/runtime_conversion_factor.cpp runtime_conversion_factor.cpp])
914
915[import ../example/runtime_conversion_factor.cpp]
916
917The Boost.Units library does not require that the conversion factors be compile time constants,
918as is demonstrated in this example:
919
920[runtime_conversion_factor_snippet_1]
921
922[endsect]
923
924[section:UnitsWithNonbaseDimensions Units with Non-base Dimensions]
925
926([@../../libs/units/example/non_base_dimension.cpp non_base_dimension.cpp])
927
928[import ../example/non_base_dimension.cpp]
929
930It is also possible to define base units that have derived rather than base dimensions:
931
932[non_base_dimension_snippet_1]
933
934[endsect]
935
936[section:OutputForCompositeUnits Output for Composite Units]
937
938([@../../libs/units/example/composite_output.cpp composite_output.cpp])
939
940[import ../example/composite_output.cpp]
941
942If a unit has a special name and/or symbol, the free functions `name_string` and
943`symbol_string` can be overloaded directly.
944
945[composite_output_snippet_1]
946
947In this case, any unit that reduces
948to the overloaded unit will be output with the replacement symbol.
949
950Special names and symbols for the SI and CGS unit systems are found in
951[headerref boost/units/systems/si/io.hpp] and [headerref boost/units/systems/cgs/io.hpp],
952respectively. If these headers are not included, the output will simply follow
953default rules using the appropriate fundamental dimensions.
954Note that neither of these functions is defined for quantities
955because doing so would require making assumptions on how the corresponding value
956type should be formatted.
957
958Three `ostream` formatters, `symbol_format`, `name_format`, and `typename_format`
959are provided for convenience. These select the textual representation of units
960provided by `symbol_string` or `name_string` in the first two cases, while the
961latter returns a demangled typename for debugging purposes. Formatting of scaled
962unit is also done correctly.
963
964[endsect]
965
966[section:autoscale Automatically Scaled Units]
967
968It is often desirable to scale a [___unit] automatically, depending on its value,
969to keep the integral part in a limited range, usually between 1 and 999.
970
971For example, using [@http://en.wikipedia.org/wiki/Engineering_notation engineering notation prefixes],
972
973 "1234.5 m" is more helpfully displayed as "1.234 km"
974 "0.000000001234 m" is more clearly displayed as "1.2345 nanometer".
975
976The iostream manipulators `engineering_prefixes` or `binary_prefixes` make this easy.
977
978[import ../example/autoprefixes.cpp]
979
980[autoprefixes_snippet_1]
981
982(The complete set of [@http://physics.nist.gov/cuu/Units/prefixes.html engineering and scientific multiples]
983is not used (not centi or deci for example), but only powers of ten that are multiples of three, 10^3).
984
985Similarly, the equivalent [@http://en.wikipedia.org/wiki/Binary_prefixes binary prefixes]
986used for displaying computing kilobytes, megabytes, gigabytes...
987
988These are the 2^10 = 1024, 2^20 = 1 048 576, 2^30 ... multiples.
989
990(See also [@http://physics.nist.gov/cuu/Units/binary.html Prefixes for binary multiples]
991
992This scale is specified in IEC 60027-2, Second edition, 2000-11,
993Letter symbols to be used in electrical technology -
994Part 2: Telecommunications and electronics).
995
996[autoprefixes_snippet_2]
997
998But note that scalar dimensionless values, like int, float and double,
999are *not* prefixed automatically by the engineering_prefix or binary_prefix iostream manipulators.
1000
1001[autoprefixes_snippet_3]
1002
1003You can output the name or symbol of a unit (rather than the most common quantity of a unit).
1004
1005[autoprefixes_snippet_4]
1006
1007Note too that all the formatting flags are persistent,
1008so that if you set engineering_prefix, then it applies to all future outputs,
1009until you select binary_prefix, or explicitly switch autoprefix off.
1010You can specify no prefix (the default of course) in two ways:
1011
1012[autoprefixes_snippet_5]
1013
1014And you can get the format flags for diagnosing problems.
1015
1016[autoprefixes_snippet_6]
1017
1018[endsect] [/section:autoscale Automatically Scaled Units]
1019
1020[section:ConversionFactor Conversion Factor]
1021
1022This code demonstrates the use of the `conversion_factor` free function to determine
1023the scale factor between two units.
1024
1025([@../../libs/units/example/conversion_factor.cpp conversion_factor.cpp])
1026
1027[import ../example/conversion_factor.cpp]
1028
1029[conversion_factor_snippet_1]
1030
1031Produces
1032
1033[conversion_factor_output]
1034
1035[endsect]
1036
1037[section:RuntimeUnits Runtime Units]
1038
1039([@../../libs/units/example/runtime_unit.cpp runtime_unit.cpp])
1040
1041[import ../example/runtime_unit.cpp]
1042
1043This example shows how to implement an interface that
1044allow different units at runtime while still maintaining
1045type safety for internal calculations.
1046
1047[runtime_unit_snippet_1]
1048
1049[endsect]
1050
1051[section:lambda Interoperability with Boost.Lambda]
1052
1053([@../../libs/units/example/lambda.cpp lambda.cpp])
1054
1055[import ../example/lambda.cpp]
1056
1057The header [headerref boost/units/lambda.hpp] provides overloads
1058and specializations needed to make Boost.Units usable with the
1059Boost.Lambda library.
1060
1061[lambda_snippet_1]
1062
1063[endsect]
1064
1065[endsect]
1066
1067[section:Utilities Utilities]
1068
1069Relatively complete SI and CGS unit systems are provided in [headerref boost/units/systems/si.hpp] and
1070[headerref boost/units/systems/cgs.hpp], respectively.
1071
1072[section:Metaprogramming_Classes Metaprogramming Classes]
1073
1074 template<long N> struct ordinal<N>;
1075
1076 template<typename T,typename V> struct get_tag< dim<T,V> >;
1077 template<typename T,typename V> struct get_value< dim<T,V> >;
1078 template<class S,class DT> struct get_system_tag_of_dim<S,DT>;
1079 template<typename Seq> struct make_dimension_list<Seq>;
1080 template<class DT> struct fundamental_dimension<DT>;
1081 template<class DT1,int E1,...> struct composite_dimension<DT1,E1,...>;
1082
1083 template<class Dim,class System> struct get_dimension< unit<Dim,System> >;
1084 template<class Unit,class Y> struct get_dimension< quantity<Unit,Y> >;
1085 template<class Dim,class System> struct get_system< unit<Dim,System> >;
1086 template<class Unit,class Y> struct get_system quantity<Unit,Y> >;
1087
1088 struct dimensionless_type;
1089 template<class System> struct dimensionless_unit<System>;
1090 template<class System,class Y> struct dimensionless_quantity<System,Y>;
1091
1092 struct implicitly_convertible;
1093 struct trivial_conversion;
1094 template<class T,class S1,class S2> struct base_unit_converter<T,S1,S2>;
1095
1096 template<class Q1,class Q2> class conversion_helper<Q1,Q2>;
1097
1098[endsect]
1099
1100[section:Metaprogramming_Predicates Metaprogramming Predicates]
1101
1102 template<typename T,typename V> struct is_dim< dim<T,V> >;
1103 template<typename T,typename V> struct is_empty_dim< dim<T,V> >;
1104
1105 template<typename Seq> struct is_dimension_list<Seq>;
1106
1107 template<class S> struct is_system< homogeneous_system<S> >;
1108 template<class S> struct is_system< heterogeneous_system<S> >;
1109 template<class S> struct is_homogeneous_system< homogeneous_system<S> >;
1110 template<class S> struct is_heterogeneous_system< heterogeneous_system<S> >;
1111
1112 template<class Dim,class System> struct is_unit< unit<Dim,System> >;
1113 template<class Dim,class System> struct is_unit_of_system< unit<Dim,System>,System >;
1114 template<class Dim,class System> struct is_unit_of_dimension< unit<Dim,System>,Dim >;
1115
1116 template<class Unit,class Y> struct is_quantity< quantity<Unit,Y> >;
1117 template<class Dim,class System,class Y> struct is_quantity_of_system< quantity<unit<Dim,System>,Y>,System >;
1118 template<class Dim,class System,class Y> struct is_quantity_of_dimension< quantity<unit<Dim,System>,Y>,Dim >;
1119
1120 template<class System> struct is_dimensionless< unit<dimensionless_type,System> >;
1121 template<class System> struct is_dimensionless_unit< unit<dimensionless_type,System> >;
1122 template<class System,class Y> struct is_dimensionless< quantity<unit<dimensionless_type,System>,Y> >;
1123 template<class System,class Y> struct is_dimensionless_quantity< quantity<unit<dimensionless_type,System>,Y> >;
1124
1125[endsect]
1126
1127[endsect]
1128
1129[section:Reference Reference]
1130
1131[xinclude units_reference.xml]
1132
1133[xinclude dimensions_reference.xml]
1134[xinclude si_reference.xml]
1135[xinclude cgs_reference.xml]
1136[xinclude trig_reference.xml]
1137[xinclude temperature_reference.xml]
1138[xinclude information_reference.xml]
1139[xinclude abstract_reference.xml]
1140
1141[section Base Units by Category]
1142
1143[xinclude angle_base_units_reference.xml]
1144[xinclude astronomical_base_units_reference.xml]
1145[xinclude cgs_base_units_reference.xml]
1146[xinclude imperial_base_units_reference.xml]
1147[xinclude metric_base_units_reference.xml]
1148[xinclude si_base_units_reference.xml]
1149[xinclude temperature_base_units_reference.xml]
1150[xinclude us_base_units_reference.xml]
1151
1152[endsect]
1153
1154[section Alphabetical Listing of Base Units]
1155[include base_units.qbk]
1156[endsect]
1157
1158[endsect]
1159
1160[section:Installation Installation]
1161
1162The core header files are located in `boost/units`. Unit system headers are
1163located in `<boost/units/systems>`. There are no source files for the library
1164itself - the library is header-only. Example programs demonstrating various aspects of the library can be found in
1165`boost/libs/units/example`. Programs for unit testing are provided in `boost/libs/units/test`.
1166
1167[endsect]
1168
1169[section:FAQ FAQ]
1170
1171[section:Distinguishing_Quantities_With_Same_Units
1172How does one distinguish between quantities that are physically different but have the same units (such as
1173energy and torque)?]
1174
1175Because Boost.Units includes plane and solid angle units in the SI system, torque and energy
1176are, in fact, distinguishable (see [@http://en.wikipedia.org/wiki/SI_units torque]).
1177In addition, energy is a true
1178[@http://mathworld.wolfram.com/Scalar.html scalar] quantity, while torque, despite
1179having the same units as energy if plane angle is not included, is in fact a
1180[@http://mathworld.wolfram.com/Pseudovector.html pseudovector]. Thus, a value type representing pseudovectors
1181and encapsulating their algebra could also be implemented.
1182
1183There are,
1184however, a few SI units that are dimensionally indistinguishable within the SI system. These
1185include the [@http://en.wikipedia.org/wiki/Becquerel becquerel], which has units identical to
1186frequency (Hz), and the [@http://en.wikipedia.org/wiki/Sievert sievert], which is degenerate
1187with the [@http://en.wikipedia.org/wiki/Gray_%28unit%29 gray]. In cases such as this,
1188the proper way to treat this difference is to recognize that expanding the set of base dimensions
1189can provide disambiguation. For example, adding a base dimension for radioactive decays would
1190allow the becquerel to be written as decays/second, differentiating it from the signature of hertz,
1191which is simply 1/second.
1192
1193[endsect]
1194
1195[section:Angle_Are_Units Angles are treated as units]
1196
1197If you don't like this, you can just ignore the angle units and
1198go on your merry way (periodically screwing up when a routine wants degrees and you give it
1199radians instead...)
1200
1201[endsect]
1202
1203[section:Why_Homogeneous_Systems Why are there homogeneous systems? Aren't heterogeneous systems sufficient?]
1204
1205Consider the following code:
1206
1207 cout << sin(asin(180.0 * degrees));
1208
1209What should this print? If only heterogeneous
1210systems are available it would print 3.14159+ rad
1211Why? Well, `asin` would return a `quantity<dimensionless>`
1212effectively losing the information that degrees
1213are being used. In order to propogate this extra information
1214we need homogeneous systems.
1215
1216[endsect]
1217
1218[section:NoConstructorFromValueType Why can't I construct a quantity directly from the value type?]
1219
1220This only breaks generic code--which ought to break anyway. The only
1221literal value that ought to be converted to a quantity by generic code
1222is zero, which should be handled by the default constructor. In addition,
1223consider the search and replace problem allowing this poses:
1224
1225 quantity<si::length> q(1.0);
1226
1227Here, the intent is clear - we want a length of one in the SI system, which is one meter. However,
1228imagine some well-intentioned coder attempting to reuse this code, but to have it perform the
1229calculations in the CGS unit system instead. After searching for `si::` and replacing it with `cgs::` ,
1230we have:
1231
1232 quantity<cgs::length> q(1.0);
1233
1234Unfortunately, the meaning of this statement has suddenly changed from one meter to one centimeter. In
1235contrast, as implemented, we begin with:
1236
1237 quantity<si::length> q(1.0*si::meter);
1238
1239and, after search and replace:
1240
1241 quantity<cgs::length> q(1.0*cgs::meter);
1242
1243which gives us an error. Even if the code has a @using namespace boost::units::si; declaration, the latter
1244is still safe, with:
1245
1246 using namespace boost::units::si;
1247 quantity<length> q(1.0*meter);
1248
1249going to
1250
1251 using namespace boost::units::cgs;
1252 quantity<length> q(1.0*meter);
1253
1254The latter will involve an explicit conversion from meters to centimeters, but the value remains correct.
1255
1256[endsect]
1257
1258[section:ExplicitConversions Why are conversions explicit by default?]
1259
1260Safety and the potential for unintended conversions leading to precision loss and hidden performance costs.
1261Options are provided for forcing implicit conversions between specific units to be allowed.
1262
1263[endsect]
1264
1265[endsect]
1266
1267[section:Acknowledgements Acknowledgements]
1268
1269Matthias C. Schabel would like to acknowledge the Department of Defense for its support of this work under
1270the Prostate Cancer Research Program New Investigator Award W81XWH-04-1-0042 and the National Institutes of Health for their
1271support of this work under the NIBIB Mentored Quantitative Research Development Award K25EB005077.
1272
1273Thanks to David Walthall for his assistance in debugging and testing on a variety of platforms and Torsten Maehne for
1274his work on interfacing the Boost Units and Boost Lambda libraries.
1275
1276Thanks to:
1277
1278* Paul Bristow,
1279* Michael Fawcett,
1280* Ben FrantzDale,
1281* Ron Garcia,
1282* David Greene,
1283* Peder Holt,
1284* Janek Kozicki,
1285* Andy Little,
1286* Kevin Lynch,
1287* Torsten Maehne
1288* Noah Roberts,
1289* Andrey Semashev,
1290* David Walthall,
1291* Deane Yang,
1292
1293and all the members of the Boost mailing list who provided their input into
1294the design and implementation of this library.
1295
1296[endsect] [/section:Acknowledgements Acknowledgements]
1297
1298[section:HelpWanted Help Wanted]
1299
1300 Any help in the following areas would be much appreciated:
1301
1302* testing on other compilers and operating systems
1303* performance testing on various architectures
1304* tutorials
1305
1306[endsect]
1307
1308[section:version_id Version Info]
1309
1310__boostroot
1311
1312Last edit to Quickbook file __FILENAME__ was at __TIME__ on __DATE__.
1313
1314[tip This should appear on the pdf version (but may be redundant on html).]
1315[/ Useful on pdf version. See also Last revised timestamp on first page of html version.]
1316[/See also Adobe Reader pdf File Properties for creation date, and PDF producer, version and page count.]
1317
1318[endsect] [/section:version_id Version Info]
1319
1320[section:ReleaseNotes Release Notes]
1321
13221.2 (March 2010)
1323
1324* Added autoprefix ready for Boost 1.43
1325
13261.0.0 (August 1, 2008) :
1327
1328* Initial release with Boost 1.36
1329
13300.7.1 (March 14, 2007) :
1331
1332* Boost.Typeof emulation support.
1333* attempting to rebind a heterogeneous_system to a different set of dimensions now fails.
1334* cmath.hpp now works with como-win32.
1335* minor changes to the tests and examples to make msvc 7.1 happy.
1336
13370.7.0 (March 13, 2007) :
1338
1339* heterogeneous and mixed system functionality added.
1340* added fine-grained implicit unit conversion on a per fundamental dimension basis.
1341* added a number of utility metafunction classes and predicates.
1342* [headerref boost/units/operators.hpp] now uses `BOOST_TYPEOF` when possible.
1343* angular units added in [headerref boost/units/systems/angle/gradians.hpp]
1344 and [headerref boost/units/systems/angle/gradians.hpp].
1345 Implicit conversion of radians between trigonometric, SI, and CGS systems is allowed.
1346* a variety of [___unit] and [___quantity] tests added.
1347* examples now provide self-tests.
1348
13490.6.2 (February 22, 2007) :
1350
1351* changed template order in `unit` so dimension precedes unit system
1352* added `homogeneous_system<S>` for unit systems
1353* incorporated changes to [headerref boost/units/dimension.hpp] (compile-time sorting by predicate),
1354 [headerref boost/units/conversion.hpp] (thread-safe implementation of quantity conversions),
1355 and [headerref boost/units/io.hpp] (now works with any `std::basic_ostream`) by SW
1356* added abstract units in [headerref boost/units/systems/abstract.hpp] to allow abstract dimensional
1357 analysis
1358* new example demonstrating implementation of code based on requirements from
1359 Michael Fawcett ([@../../libs/units/example/radar_beam_height.cpp radar_beam_height.cpp])
1360
13610.6.1 (February 13, 2007) :
1362
1363* added metafunctions to test if a type is
1364 * a valid dimension list (`is_dimension_list<D>`)
1365 * a unit (`is_unit<T>` and `is_unit_of_system<U,System>`)
1366 * a quantity (`is_quantity<T>` and `is_quantity_of_system<Q,System>`)
1367* quantity conversion factor is now computed at compile time
1368* static constants now avoid ODR problems
1369* unit_example_14.cpp now uses Boost.Timer
1370* numerous minor fixes suggested by SW
1371
13720.6.0 (February 8, 2007) :
1373
1374* incorporated Steven Watanabe's optimized code for dimension.hpp, leading to *dramatic*
1375 decreases in compilation time (nearly a factor of 10 for unit_example_4.cpp in my tests).
1376
13770.5.8 (February 7, 2007) :
1378
1379* fixed `#include` in [headerref boost/units/systems/si/base.hpp] (thanks to Michael Fawcett and
1380 Steven Watanabe)
1381* removed references to obsolete `base_type` in [___unit_info] (thanks to Michael Fawcett)
1382* moved functions in [headerref boost/units/cmath.hpp] into `boost::units` namespace
1383 (thanks to Steven Watanabe)
1384* fixed `#include` guards to be consistently named `BOOST_UNITS_XXX` (thanks to Steven
1385 Watanabe)
1386
13870.5.7 (February 5, 2007) :
1388
1389* changed quantity conversion helper to increase flexibility
1390* minor documentation changes
1391* submitted for formal review as a Boost library
1392
13930.5.6 (January 22, 2007) :
1394
1395* added IEEE 1541 standard binary prefixes along with SI prefixes to and extended algebra of
1396 `scale` and `scaled_value` classes (thanks to Kevin Lynch)
1397* split SI units into separate header files to minimize the "kitchen sink" include problem
1398 (thanks to Janek Kozicki)
1399* added convenience classes for declaring fundamental dimensions and composite dimensions
1400 with integral powers (`fundamental_dimension` and `composite_dimension` respectively)
1401
14020.5.5 (January 18, 2007) :
1403
1404* template parameter order in `quantity` switched and default `value_type` of `double` added
1405 (thanks to Andrey Semashev and Paul Bristow)
1406* added implicit `value_type` conversion where allowed (thanks to Andrey Semashev)
1407* added `quantity_cast` for three cases (thanks to Andrey Semashev):
1408 * constructing `quantity` from raw `value_type`
1409 * casting from one `value_type` to another
1410 * casting from one `unit` to another (where conversion is allowed)
1411* added` metre` and `metres` and related constants to the SI system for the convenience of
1412 our Commonwealth friends...
1413
14140.5.4 (January 12, 2007) :
1415
1416* completely reimplemented unit conversion to allow for arbitrary unit conversions
1417 between systems
1418* strict quantity construction is default; quantities can be constructed from bare values
1419 by using static member `from_value`
1420
14210.5.3 (December 12, 2006) :
1422
1423* added Boost.Serialization support to `unit` and `quantity` classes
1424* added option to enforce strict construction of quantities (only constructible
1425 by multiplication of scalar by unit or quantity by unit) by preprocessor
1426 `MCS_STRICT_QUANTITY_CONSTRUCTION` switch
1427
14280.5.2 (December 4, 2006) :
1429
1430* added `<cmath>` wrappers in the `std` namespace for functions that can support quantities
1431
14320.5.1 (November 3, 2006) :
1433
1434* converted to Boost Software License
1435* boostified directory structure and file paths
1436
14370.5 (November 2, 2006) :
1438
1439* completely reimplemented SI and CGS unit systems and changed syntax for quantities
1440* significantly streamlined `pow` and `root` so for most applications it is only
1441 necessary to define `power_typeof_helper` and `root_typeof_helper` to gain this
1442 functionality
1443* added a selection of physical constants from the CODATA tables
1444* added a skeleton `complex` class that correctly supports both `complex<quantity<Y,Unit> >`
1445 and `quantity<complex<Y>,Unit>` as an example
1446* investigate using Boost.Typeof for compilers that do not support `typeof`
1447
14480.4 (October 13, 2006) :
1449
1450* `pow<R>` and `root<R>` improved for user-defined types
1451* added unary + and unary - operators
1452* added new example of interfacing with `boost::math::quaternion`
1453* added optional preprocessor switch to enable implicit unit conversions
1454 (`BOOST_UNITS_ENABLE_IMPLICIT_UNIT_CONVERSIONS`)
1455
14560.3 (September 6, 2006) :
1457
1458* Support for `op(X x,Y y)` for g++ added. This is automatically
1459 active when compiling with gcc and can be optionally enabled by defining the preprocessor
1460 constant `BOOST_UNITS_HAS_TYPEOF`
1461
14620.2 (September 4, 2006) : Second alpha release based on slightly modified code from 0.1 release
1463
14640.1 (December 13, 2003) : written as a Boost demonstration of MPL-based dimensional analysis
1465in 2003.
1466
1467[endsect]
1468
1469[section:TODO TODO]
1470
1471* Document concepts
1472* Implementation of I/O is rudimentary; consider methods of i18n using facets
1473* Consider runtime variant, perhaps using overload like `quantity<runtime,Y>`
1474
1475[endsect] [/section:TODO TODO]