diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 6d08271..d74172c 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -28,6 +28,7 @@ rule run_doxygen ( target : files * : name ) # Horribly ugly, but then macros usually are :( "PREDEFINED= \\ + \"BOOST_MPL_ASSERT(expr)=\" \\ \"BOOST_UNITS_STATIC_CONSTANT(a,b)=static const b a\" \\ \"BOOST_UNITS_AUTO_STATIC_CONSTANT(a,b)=static const auto a = b\" \\ \"BOOST_UNITS_TYPEOF(a)=typeof(a)\" \\ @@ -54,7 +55,8 @@ rule run_doxygen ( target : files * : name ) run_doxygen units_reference : - [ glob $(here)/../../../boost/units/*.hpp ] + [ glob $(here)/../../../boost/units/*.hpp : + $(here)/../../../boost/units/physical_dimensions.hpp ] : "Units Reference" ; @@ -166,10 +168,7 @@ rule generate-qbk ( target : sources * : properties * ) local dir-name = [ path.basename [ path.parent $(file) ] ] ; base_unit = "$(base_unit) ($(dir-name))" ; } - # this looks better, but it won't work until my boostbook patch for - # annotation.xsl gets applied. - # print.text "[headerref $(output_filename) $(base_unit)]\\n" : overwrite ; - print.text "[headerref $(output_filename)]\\n" : overwrite ; + print.text "[headerref $(output_filename) $(base_unit)]\\n" : overwrite ; } } diff --git a/doc/units.qbk b/doc/units.qbk index 7a95854..3e8ed18 100644 --- a/doc/units.qbk +++ b/doc/units.qbk @@ -1,9 +1,9 @@ [library Boost.Units - [quickbook 1.3] - [version 1.0.0] + [quickbook 1.5] + [version 1.1.0] [authors [Schabel, Matthias C.]] [authors [Watanabe, Steven]] - [copyright 2003-2008 Matthias Christian Schabel, 2007-2008 Steven Watanabe] + [copyright 2003-2008 Matthias Christian Schabel, 2007-2010 Steven Watanabe] [license Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -12,10 +12,15 @@ [purpose zero-overhead compile-time dimensional analysis and unit computations] ] +[/ Some links to external sources.] +[def __boost [@http://www.boost.org/ Boost]] +[def __boostroot [@boost: Boost root]] +[def __boostlicense [@http://www.boost.org/LICENSE_1_0.txt Boost License]] [def __boost_mpl [@http://www.boost.org/libs/mpl/doc/index.html Boost Metaprogramming Library]] [def __mpl_forward_sequence [@http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html MPL Forward Sequence]] +[/Links within this document.] [def __ordinal [classref boost::units::ordinal ordinal]] [def __dim [classref boost::units::dim dim]] [def __static_rational [classref boost::units::static_rational static_rational]] @@ -61,7 +66,6 @@ [def __unscale [classref boost::units::unscale unscale]] [def __BOOST_UNITS_STATIC_CONSTANT [macroref BOOST_UNITS_STATIC_CONSTANT]] - [def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR]] [def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE]] [def __BOOST_UNITS_DEFAULT_CONVERSION [macroref BOOST_UNITS_DEFAULT_CONVERSION]] @@ -113,13 +117,14 @@ in the following : no specific restriction on what base dimensions can be used. Base dimensions are essentially a tag type and provide no dimensional analysis functionality themselves. * *Dimension* : A collection of zero or more base dimensions, each - potentially raised to a different rational power. For example, area = \[L\]^2, velocity = \[L\]^1/\[T\]^1, and + potentially raised to a different rational power. + For example, length = \[L\]^1, area = \[L\]^2, velocity = \[L\]^1/\[T\]^1, and energy = \[M\]^1 \[L\]^2/\[T\]^2 are all dimensions. * *Base unit* : A base unit represents a specific measure of a dimension. For example, while length is an abstract measure of distance, the meter is a concrete base unit of distance. Conversions are defined using base units. Much like base dimensions, base units are a tag type used solely to define units and do not support dimensional analysis algebra. -* *Unit* : A set of base units raised to rational exponents, e.g. kg^1 m^1/s^2. +* *Unit* : A set of base units raised to rational exponents, e.g. m^1, kg^1, m^1/s^2. * *System* : A unit system is a collection of base units representing all the measurable entities of interest for a specific problem. For example, the SI unit system defines seven base units : length (\[L\]) in meters, mass (\[M\]) in kilograms, time (\[T\]) in seconds, current (\[I\]) in amperes, temperature (\[theta\]) in kelvin, @@ -150,8 +155,8 @@ The intent and function of the above code should be obvious; the output produced While this library attempts to make simple dimensional computations easy to code, it is in no way tied to any particular unit system (SI or otherwise). Instead, it provides a highly flexible compile-time system for dimensional analysis, supporting arbitrary collections of base dimensions, rational -powers of units, and explicit quantity conversions. It accomplishes all of this via template metaprogramming techniques. With -modern optimizing compilers, this results in zero runtime overhead for quantity computations relative to the +powers of units, and explicit quantity conversions. It accomplishes all of this via template metaprogramming techniques. +With modern optimizing compilers, this results in zero runtime overhead for quantity computations relative to the same code without unit checking. [endsect] @@ -319,7 +324,7 @@ The `name()` and `symbol()` methods of [___base_unit_info] provide full and shor we have the rudimentary beginnings of our unit system, which can be used to determine reduced dimensions for arbitrary unit calculations. -[endsect] +[endsect] [/section Base Units] [section Scaled Base Units] @@ -340,7 +345,7 @@ There are several advantages to this approach. * Similarly, if the symbol for grams is defined as "g", then the symbol for kilograms will be "kg" without any extra effort. -[endsect] +[endsect] [/section Scaled Base Units] [section Scaled Units] @@ -353,15 +358,14 @@ A simple example of its usage would be. typedef make_scaled_unit > >::type nanosecond; -nanosecond is a specialization of [___unit], and can be -used in a quantity normally. +nanosecond is a specialization of [___unit], and can be used in a quantity normally. quantity t(1.0 * si::seconds); std::cout << t << std::endl; // prints 1e9 ns -[endsect] +[endsect] [/section Scaled Units] -[endsect] +[endsect] [/section:Units Units] [section:Quantities Quantities] @@ -507,7 +511,8 @@ to produce new composite dimensions : [dimension_snippet_1] -outputting (with symbol demangling, implemented in [headerref boost/units/detail/utility.hpp]) +outputting (with symbol demangling, implemented in +[@boost:/boost/units/detail/utility.hpp utility.hpp]) [dimension_output] @@ -518,7 +523,7 @@ outputting (with symbol demangling, implemented in [headerref boost/units/detail ([@../../libs/units/example/unit.cpp unit.cpp]) This example demonstrates the use of the simple but functional unit system implemented in -[headerref libs/units/example/test_system.hpp] : +[@boost:/libs/units/example/test_system.hpp test_system.hpp] [import ../example/unit.cpp] @@ -557,7 +562,7 @@ to `std::complex` and performing the appropriate dimensional analysis : [endsect] -[section:KitchenSinkExample Kitchen Sink Example] +[section:KitchenSinkExample Kitchen Sink Example using SI units] ([@../../libs/units/example/kitchen_sink.cpp kitchen_sink.cpp]) @@ -958,6 +963,60 @@ unit is also done correctly. [endsect] +[section:autoscale Automatically Scaled Units] + +It is often desirable to scale a [___unit] automatically, depending on its value, +to keep the integral part in a limited range, usually between 1 and 999. + +For example, using [@http://en.wikipedia.org/wiki/Engineering_notation engineering notation prefixes], + + "1234.5 m" is more helpfully displayed as "1.234 km" + "0.000000001234 m" is more clearly displayed as "1.2345 nanometer". + +The iostream manipulators `engineering_prefixes` or `binary_prefixes` make this easy. + +[import ../example/autoprefixes.cpp] + +[autoprefixes_snippet_1] + +(The complete set of [@http://physics.nist.gov/cuu/Units/prefixes.html engineering and scientific multiples] +is not used (not centi or deci for example), but only powers of ten that are multiples of three, 10^3). + +Similarly, the equivalent [@http://en.wikipedia.org/wiki/Binary_prefixes binary prefixes] +used for displaying computing kilobytes, megabytes, gigabytes... + +These are the 2^10 = 1024, 2^20 = 1 048 576, 2^30 ... multiples. + +(See also [@http://physics.nist.gov/cuu/Units/binary.html Prefixes for binary multiples] + +This scale is specified in IEC 60027-2, Second edition, 2000-11, +Letter symbols to be used in electrical technology - +Part 2: Telecommunications and electronics). + +[autoprefixes_snippet_2] + +But note that scalar dimensionless values, like int, float and double, +are *not* prefixed automatically by the engineering_prefix or binary_prefix iostream manipulators. + +[autoprefixes_snippet_3] + +You can output the name or symbol of a unit (rather than the most common quantity of a unit). + +[autoprefixes_snippet_4] + +Note too that all the formatting flags are persistent, +so that if you set engineering_prefix, then it applies to all future outputs, +until you select binary_prefix, or explicitly switch autoprefix off. +You can specify no prefix (the default of course) in two ways: + +[autoprefixes_snippet_5] + +And you can get the format flags for diagnosing problems. + +[autoprefixes_snippet_6] + +[endsect] [/section:autoscale Automatically Scaled Units] + [section:ConversionFactor Conversion Factor] This code demonstrates the use of the `conversion_factor` free function to determine @@ -1233,7 +1292,7 @@ Thanks to: and all the members of the Boost mailing list who provided their input into the design and implementation of this library. -[endsect] +[endsect] [/section:Acknowledgements Acknowledgements] [section:HelpWanted Help Wanted] @@ -1245,29 +1304,46 @@ the design and implementation of this library. [endsect] +[section:version_id Version Info] + +__boostroot + +Last edit to Quickbook file __FILENAME__ was at __TIME__ on __DATE__. + +[tip This should appear on the pdf version (but may be redundant on html).] +[/ Useful on pdf version. See also Last revised timestamp on first page of html version.] +[/See also Adobe Reader pdf File Properties for creation date, and PDF producer, version and page count.] + +[endsect] [/section:version_id Version Info] + [section:ReleaseNotes Release Notes] +1.2 (March 2010) + +* Added autoprefix ready for Boost 1.43 + 1.0.0 (August 1, 2008) : * Initial release with Boost 1.36 0.7.1 (March 14, 2007) : -* Boost.Typeof emulation support +* Boost.Typeof emulation support. * attempting to rebind a heterogeneous_system to a different set of dimensions now fails. -* cmath.hpp now works with como-win32 -* minor changes to the tests and examples to make msvc 7.1 happy +* cmath.hpp now works with como-win32. +* minor changes to the tests and examples to make msvc 7.1 happy. 0.7.0 (March 13, 2007) : -* heterogeneous and mixed system functionality added -* added fine-grained implicit unit conversion on a per fundamental dimension basis -* added a number of utility metafunction classes and predicates -* [headerref boost/units/operators.hpp] now uses `BOOST_TYPEOF` when possible -* angular units added in [headerref boost/units/systems/trig.hpp] - implicit conversion - of radians between trigonometric, SI, and CGS systems allowed -* a variety of [___unit] and [___quantity] tests added -* examples now provide self-tests +* heterogeneous and mixed system functionality added. +* added fine-grained implicit unit conversion on a per fundamental dimension basis. +* added a number of utility metafunction classes and predicates. +* [headerref boost/units/operators.hpp] now uses `BOOST_TYPEOF` when possible. +* angular units added in [headerref boost/units/systems/angle/gradians.hpp] + and [headerref boost/units/systems/angle/gradians.hpp]. + Implicit conversion of radians between trigonometric, SI, and CGS systems is allowed. +* a variety of [___unit] and [___quantity] tests added. +* examples now provide self-tests. 0.6.2 (February 22, 2007) : @@ -1395,4 +1471,4 @@ in 2003. * Implementation of I/O is rudimentary; consider methods of i18n using facets * Consider runtime variant, perhaps using overload like `quantity` -[endsect] +[endsect] [/section:TODO TODO] diff --git a/example/autoprefixes.cpp b/example/autoprefixes.cpp new file mode 100644 index 0000000..8b2bc43 --- /dev/null +++ b/example/autoprefixes.cpp @@ -0,0 +1,148 @@ +// Boost.Units - A C++ library for zero-overhead dimensional analysis and +// unit/quantity manipulation and conversion +// +// Copyright (C) 2003-2008 Matthias Christian Schabel +// Copyright (C) 2008 Steven Watanabe +// +// 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) + +/** +\file + +\brief Example of using autoprefixes. + +\details +Example of using engineering (10^3) and binary (2^10) autoprefixes. + +Output: +@verbatim +autoprefixes.cpp +using native typeof +Linking... +Embedding manifest... +Autorun "j:\Cpp\Misc\debug\autoprefixes.exe" +2.345 m +2.345 km +5.49902 MJ +5.49902 megajoule +2.048 kb +2 Kib +2345.6 +23456 +2345.6 +23456 +m +meter +0 +1 +@endverbatim +//[autoprefixes_output + +//] [/autoprefixes_output + +**/ + +#include + +#include +#include +#include +#include +#include + +struct byte_base_unit : boost::units::base_unit +{ + static const char* name() { return("byte"); } + static const char* symbol() { return("b"); } +}; + +struct thing_base_unit : boost::units::base_unit +{ + static const char* name() { return("thing"); } + static const char* symbol() { return(""); } +}; + +struct euro_base_unit : boost::units::base_unit +{ + static const char* name() { return("EUR"); } + static const char* symbol() { return("€"); } +}; + +int main() +{ + using std::cout; + using std::endl; + + using namespace boost::units; + using namespace boost::units::si; + + //[autoprefixes_snippet_1 + using boost::units::binary_prefix; + using boost::units::engineering_prefix; + using boost::units::no_prefix; + + quantity l = 2.345 * meters; // A quantity of length, in units of meters. + cout << engineering_prefix << l << endl; // Outputs "2.345 m". + l = 1000.0 * l; // Increase it by 1000, so expect a k prefix. + // Note that a double 1000.0 is required - an integer will fail to compile. + cout << engineering_prefix << l << endl; // Output autoprefixed with k to "2.345 km". + + quantity e = kilograms * pow<2>(l / seconds); // A quantity of energy. + cout << engineering_prefix << e << endl; // 5.49902 MJ + cout << name_format << engineering_prefix << e << endl; // 5.49902 megaJoule + //] [/autoprefixes_snippet_1] + + //[autoprefixes_snippet_2 + // Don't forget that the units name or symbol format specification is persistent. + cout << symbol_format << endl; // Resets the format to the default symbol format. + + quantity b = 2048. * byte_base_unit::unit_type(); + cout << engineering_prefix << b << endl; // 2.048 kb + cout << symbol_format << binary_prefix << b << endl; // "2 Kib" + //] [/autoprefixes_snippet_2] + + // Note that scalar dimensionless values are *not* prefixed automatically by the engineering_prefix or binary_prefix iostream manipulators. + //[autoprefixes_snippet_3 + const double s1 = 2345.6; + const long x1 = 23456; + cout << engineering_prefix << s1 << endl; // 2345.6 + cout << engineering_prefix << x1 << endl; // 23456 + + cout << binary_prefix << s1 << endl; // 2345.6 + cout << binary_prefix << x1 << endl; // 23456 + //] [/autoprefixes_snippet_3] + + //[autoprefixes_snippet_4 + const length L; // A unit of length (but not a quantity of length). + cout << L << endl; // Default length unit is meter, + // but default is symbol format so output is just "m". + cout << name_format << L << endl; // default length name is "meter". + //] [/autoprefixes_snippet_4] + + //[autoprefixes_snippet_5 + no_prefix(cout); // Clear any prefix flag. + cout << no_prefix << endl; // Clear any prefix flag using `no_prefix` manipulator. + //] [/autoprefixes_snippet_5] + + //[autoprefixes_snippet_6 + cout << boost::units::get_autoprefix(cout) << endl; // 8 is `autoprefix_binary` from `enum autoprefix_mode`. + cout << boost::units::get_format(cout) << endl; // 1 is `name_fmt` from `enum format_mode`. + //] [/autoprefixes_snippet_6] + + + quantity t = 2048. * thing_base_unit::unit_type(); + cout << name_format << engineering_prefix << t << endl; // 2.048 kilothing + cout << symbol_format << engineering_prefix << t << endl; // 2.048 k + + cout << binary_prefix << t << endl; // "2 Ki" + + quantity ce = 2048. * euro_base_unit::unit_type(); + cout << name_format << engineering_prefix << ce << endl; // 2.048 kiloEUR + cout << symbol_format << engineering_prefix << ce << endl; // 2.048 k€ + + + return 0; +} // int main() + diff --git a/example/complex.cpp b/example/complex.cpp index 0f501bb..d03eb3d 100644 --- a/example/complex.cpp +++ b/example/complex.cpp @@ -13,7 +13,7 @@ \brief complex.cpp -\detailed +\details Demonstrate a complex number class that functions correctly with quantities. Output: diff --git a/example/composite_output.cpp b/example/composite_output.cpp index ae88a23..022ea4e 100644 --- a/example/composite_output.cpp +++ b/example/composite_output.cpp @@ -13,7 +13,7 @@ \brief composite_output.cpp -\detailed An example of textual representations of units. +\details An example of textual representations of units. Output: @verbatim diff --git a/example/conversion.cpp b/example/conversion.cpp index 3c58c2d..0299dfd 100644 --- a/example/conversion.cpp +++ b/example/conversion.cpp @@ -13,7 +13,7 @@ \brief conversion.cpp -\detailed +\details Test explicit and implicit unit conversion. Output: diff --git a/example/conversion_factor.cpp b/example/conversion_factor.cpp index f72d855..4401e47 100644 --- a/example/conversion_factor.cpp +++ b/example/conversion_factor.cpp @@ -13,7 +13,7 @@ \brief conversion_factor.cpp -\detailed An example of using conversion_factor. +\details An example of using conversion_factor. Output: @verbatim diff --git a/example/dimension.cpp b/example/dimension.cpp index 70e274b..7f7ffb6 100644 --- a/example/dimension.cpp +++ b/example/dimension.cpp @@ -13,7 +13,7 @@ \brief dimension.cpp -\detailed +\details Test dimension list manipulation. Output: diff --git a/example/heterogeneous_unit.cpp b/example/heterogeneous_unit.cpp index 98ae0a2..7a4f112 100644 --- a/example/heterogeneous_unit.cpp +++ b/example/heterogeneous_unit.cpp @@ -13,7 +13,7 @@ \brief heterogeneous_unit.cpp -\detailed +\details Test heterogeneous units and quantities. Output: diff --git a/example/kitchen_sink.cpp b/example/kitchen_sink.cpp index 31031b8..211d981 100644 --- a/example/kitchen_sink.cpp +++ b/example/kitchen_sink.cpp @@ -13,7 +13,7 @@ \brief kitchen_sink.cpp -\detailed +\details More extensive quantity tests. Output: diff --git a/example/non_base_dimension.cpp b/example/non_base_dimension.cpp index b158e16..4476a34 100644 --- a/example/non_base_dimension.cpp +++ b/example/non_base_dimension.cpp @@ -13,7 +13,7 @@ \brief non_base_dimension.cpp -\detailed +\details Another example of user-defined units with conversions. Output: diff --git a/example/performance.cpp b/example/performance.cpp index f8b39a0..0dce3ce 100644 --- a/example/performance.cpp +++ b/example/performance.cpp @@ -13,7 +13,7 @@ \brief performance.cpp -\detailed +\details Test runtime performance. Output: diff --git a/example/quantity.cpp b/example/quantity.cpp index 15e4a61..e3d3f18 100644 --- a/example/quantity.cpp +++ b/example/quantity.cpp @@ -13,7 +13,7 @@ \brief quantity.cpp -\detailed +\details Test quantity algebra. Output: diff --git a/example/quaternion.cpp b/example/quaternion.cpp index f25307c..a2e3e91 100644 --- a/example/quaternion.cpp +++ b/example/quaternion.cpp @@ -13,7 +13,7 @@ \brief quaternion.cpp -\detailed +\details Demonstrate interoperability with Boost.Quaternion. Output: diff --git a/example/radar_beam_height.cpp b/example/radar_beam_height.cpp index cf5fbf8..63752f7 100644 --- a/example/radar_beam_height.cpp +++ b/example/radar_beam_height.cpp @@ -13,7 +13,7 @@ \brief radar_beam_height.cpp -\detailed +\details Demonstrate library usage for user test cases suggested by Michael Fawcett. Output: diff --git a/example/systems.cpp b/example/systems.cpp index 2f7df04..9c34804 100644 --- a/example/systems.cpp +++ b/example/systems.cpp @@ -13,7 +13,7 @@ \brief systems.cpp -\detailed +\details Test various non-si units Output: diff --git a/example/temperature.cpp b/example/temperature.cpp index 834f33f..f6b4342 100644 --- a/example/temperature.cpp +++ b/example/temperature.cpp @@ -13,7 +13,7 @@ \brief temperature.cpp -\detailed +\details Conversions between Fahrenheit and Kelvin for absolute temperatures and temperature differences. diff --git a/example/tutorial.cpp b/example/tutorial.cpp index b10d104..855cce6 100644 --- a/example/tutorial.cpp +++ b/example/tutorial.cpp @@ -8,17 +8,22 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -/** -\file +/** +\file tutorial.cpp -\brief tutorial.cpp +\brief Basic tutorial using SI units. -\detailed -Basic tutorial using si units. +\details +Tutorial +Defines a function that computes the work, in joules, +done by exerting a force in newtons over a specified distance +in meters and outputs the result to std::cout. + +Also code for computing the complex impedance +using std::complex as the value type. Output: @verbatim - //[tutorial_output F = 2 N dx = 2 m @@ -30,9 +35,8 @@ Z = (1.5,-2) Ohm I*Z = (12.5,0) V I*Z == V? true //] - @endverbatim -**/ +*/ //[tutorial_code #include @@ -52,37 +56,39 @@ using namespace boost::units; using namespace boost::units::si; quantity -work(const quantity& F,const quantity& dx) +work(const quantity& F, const quantity& dx) { - return F*dx; + return F * dx; // Defines the relation: work = force * distance. } int main() { - /// test calcuation of work - quantity F(2.0*newton); - quantity dx(2.0*meter); - quantity E(work(F,dx)); + /// Test calculation of work. + quantity F(2.0 * newton); // Define a quantity of force. + quantity dx(2.0 * meter); // and a distance, + quantity E(work(F,dx)); // and calculate the work done. std::cout << "F = " << F << std::endl << "dx = " << dx << std::endl << "E = " << E << std::endl << std::endl; - /// check complex quantities - typedef std::complex complex_type; + /// Test and check complex quantities. + typedef std::complex complex_type; // double real and imaginary parts. - quantity v = complex_type(12.5,0.0)*volts; - quantity i = complex_type(3.0,4.0)*amperes; - quantity z = complex_type(1.5,-2.0)*ohms; + // Define some complex electrical quantities. + quantity v = complex_type(12.5, 0.0) * volts; + quantity i = complex_type(3.0, 4.0) * amperes; + quantity z = complex_type(1.5, -2.0) * ohms; std::cout << "V = " << v << std::endl << "I = " << i << std::endl - << "Z = " << z << std::endl - << "I*Z = " << i*z << std::endl - << "I*Z == V? " << std::boolalpha << (i*z == v) << std::endl + << "Z = " << z << std::endl + // Calculate from Ohm's law voltage = current * resistance. + << "I * Z = " << i * z << std::endl + // Check defined V is equal to calculated. + << "I * Z == V? " << std::boolalpha << (i * z == v) << std::endl << std::endl; - return 0; } //] diff --git a/example/unit.cpp b/example/unit.cpp index b8a8fc3..934d557 100644 --- a/example/unit.cpp +++ b/example/unit.cpp @@ -13,7 +13,7 @@ \brief unit.cpp -\detailed +\details Test unit algebra. Output: diff --git a/include/boost/units/absolute.hpp b/include/boost/units/absolute.hpp index 9f36019..c035475 100644 --- a/include/boost/units/absolute.hpp +++ b/include/boost/units/absolute.hpp @@ -8,6 +8,12 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +/// +/// \file +/// \brief Absolute units (points rather than vectors). +/// \details Operations between absolute units, and relative units like temperature differences. +/// + #ifndef BOOST_UNITS_ABSOLUTE_HPP #define BOOST_UNITS_ABSOLUTE_HPP @@ -23,7 +29,7 @@ namespace units { /// originally for temperatures, this class implements operators for absolute units /// so that addition of a relative unit to an absolute unit results in another /// absolute unit : absolute +/- T -> absolute and subtraction of one absolute -/// unit from another results in a relative unit : absolute - absolute -> T +/// unit from another results in a relative unit : absolute - absolute -> T. template class absolute { diff --git a/include/boost/units/base_dimension.hpp b/include/boost/units/base_dimension.hpp index 57b4d27..8d02de7 100644 --- a/include/boost/units/base_dimension.hpp +++ b/include/boost/units/base_dimension.hpp @@ -8,6 +8,10 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +/// \file +/// \brief base dimensions (mass, length, time...). +/// \details base dimension definition registration. + #ifndef BOOST_UNITS_BASE_DIMENSION_HPP #define BOOST_UNITS_BASE_DIMENSION_HPP diff --git a/include/boost/units/base_unit.hpp b/include/boost/units/base_unit.hpp index 975da57..7d7aca2 100644 --- a/include/boost/units/base_unit.hpp +++ b/include/boost/units/base_unit.hpp @@ -8,6 +8,10 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +/// \file +/// \brief base unit (meter, kg, sec...). +/// \details base unit definition registration. + #ifndef BOOST_UNITS_BASE_UNIT_HPP #define BOOST_UNITS_BASE_UNIT_HPP diff --git a/include/boost/units/cmath.hpp b/include/boost/units/cmath.hpp index 393aa5d..238b31c 100644 --- a/include/boost/units/cmath.hpp +++ b/include/boost/units/cmath.hpp @@ -24,22 +24,22 @@ #include #include #include +#include #include -/// \file -/// \brief Overloads of functions in \ for quantities -/// -/// \detailed Only functions for which a dimensionally-correct result type -/// can be determined are overloaded. All functions work with dimensionless -/// quantities. +/// \file +/// \brief Overloads of functions in \ for quantities. +/// \details Only functions for which a dimensionally-correct result type +/// can be determined are overloaded. +/// All functions work with dimensionless quantities. // BOOST_PREVENT_MACRO_SUBSTITUTION is needed on certain compilers that define // some functions as macros; it is used for all functions even though it // isn't necessary -- I didn't want to think :) // // the form using namespace detail; return(f(x)); is used -// to enable ADL for UDTs +// to enable ADL for UDTs. namespace boost { @@ -604,6 +604,15 @@ acos(const quantity >,Y>& va return quantity >,Y>(acos(val.value())*si::radians); } +/// acos of dimensionless quantity returning angle in radians +template +quantity +acos(const quantity,Y>& val) +{ + using std::acos; + return quantity::from_value(acos(val.value())); +} + /// asin of dimensionless quantity returning angle in same system template quantity >,Y> @@ -613,6 +622,15 @@ asin(const quantity >,Y>& va return quantity >,Y>(asin(val.value())*si::radians); } +/// asin of dimensionless quantity returning angle in radians +template +quantity +asin(const quantity,Y>& val) +{ + using std::asin; + return quantity::from_value(asin(val.value())); +} + /// atan of dimensionless quantity returning angle in same system template quantity >,Y> @@ -622,6 +640,15 @@ atan(const quantity >, Y>& v return quantity >,Y>(atan(val.value())*si::radians); } +/// atan of dimensionless quantity returning angle in radians +template +quantity +atan(const quantity, Y>& val) +{ + using std::atan; + return quantity::from_value(atan(val.value())); +} + /// atan2 of @c value_type returning angle in radians template quantity >, Y> @@ -632,6 +659,16 @@ atan2(const quantity >, Y>& y, return quantity >, Y>(atan2(y.value(),x.value())*si::radians); } +/// atan2 of @c value_type returning angle in radians +template +quantity +atan2(const quantity >, Y>& y, + const quantity >, Y>& x) +{ + using std::atan2; + return quantity::from_value(atan2(y.value(),x.value())); +} + } // namespace units } // namespace boost diff --git a/include/boost/units/config.hpp b/include/boost/units/config.hpp index e381213..9e8a74f 100644 --- a/include/boost/units/config.hpp +++ b/include/boost/units/config.hpp @@ -91,7 +91,7 @@ /// is not layout compatible with T #define BOOST_UNITS_REQUIRE_LAYOUT_COMPATIBILITY -/// If defined will diasable a preprocessor check that the +/// If defined will disable a preprocessor check that the /// compiler is able to handle the library. #define BOOST_UNITS_NO_COMPILER_CHECK diff --git a/include/boost/units/conversion.hpp b/include/boost/units/conversion.hpp index a486895..5f739aa 100644 --- a/include/boost/units/conversion.hpp +++ b/include/boost/units/conversion.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_CONVERSION_HPP #define BOOST_UNITS_CONVERSION_HPP +/// \file +/// \brief Template for defining conversions between quantities. + #include namespace boost { diff --git a/include/boost/units/detail/dimensionless_unit.hpp b/include/boost/units/detail/dimensionless_unit.hpp index bc3223b..291bec4 100644 --- a/include/boost/units/detail/dimensionless_unit.hpp +++ b/include/boost/units/detail/dimensionless_unit.hpp @@ -26,6 +26,14 @@ struct homogeneous_system; template struct heterogeneous_system_impl; +typedef boost::units::heterogeneous_system< + boost::units::heterogeneous_system_impl< + boost::units::dimensionless_type, + boost::units::dimensionless_type, + boost::units::dimensionless_type + > +> heterogeneous_dimensionless_system; + namespace detail { template @@ -39,15 +47,7 @@ struct void_if_dimensionless > { }; template<> -struct void_if_dimensionless< - boost::units::heterogeneous_system< - boost::units::heterogeneous_system_impl< - boost::units::dimensionless_type, - boost::units::dimensionless_type, - boost::units::dimensionless_type - > - > -> { +struct void_if_dimensionless { typedef void type; }; diff --git a/include/boost/units/detail/one.hpp b/include/boost/units/detail/one.hpp index 15bc7a4..4cadc2c 100644 --- a/include/boost/units/detail/one.hpp +++ b/include/boost/units/detail/one.hpp @@ -97,6 +97,11 @@ inline one operator/(const one&, const one&) return(result); } +template +inline bool operator>(const boost::units::one&, const T& t) { + return(1 > t); +} + } // namespace units } // namespace boost diff --git a/include/boost/units/dim.hpp b/include/boost/units/dim.hpp index 53372cf..eb28131 100644 --- a/include/boost/units/dim.hpp +++ b/include/boost/units/dim.hpp @@ -21,7 +21,7 @@ #include #include -/// \file +/// \file dim.hpp /// \brief Handling of fundamental dimension/exponent pairs. namespace boost { @@ -36,7 +36,7 @@ struct dim_tag { }; /// \brief Dimension tag/exponent pair for a single fundamental dimension. /// -/// \detailed +/// \details /// The dim class represents a single dimension tag/dimension exponent pair. /// That is, @c dim is a pair where @c tag_type represents the /// fundamental dimension being represented and @c value_type represents the diff --git a/include/boost/units/dimensionless_quantity.hpp b/include/boost/units/dimensionless_quantity.hpp index 1d39296..7ac6bfb 100644 --- a/include/boost/units/dimensionless_quantity.hpp +++ b/include/boost/units/dimensionless_quantity.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_DIMENSIONLESS_QUANTITY_HPP #define BOOST_UNITS_DIMENSIONLESS_QUANTITY_HPP +/// +/// \file +/// \brief Utility class to simplify construction of dimensionless quantities. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// utility class to simplify construction of dimensionless quantities +/// Utility class to simplify construction of dimensionless quantities. template struct dimensionless_quantity { diff --git a/include/boost/units/dimensionless_type.hpp b/include/boost/units/dimensionless_type.hpp index ba8230a..c8dae9f 100644 --- a/include/boost/units/dimensionless_type.hpp +++ b/include/boost/units/dimensionless_type.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_DIMENSIONLESS_TYPE_HPP #define BOOST_UNITS_DIMENSIONLESS_TYPE_HPP +/// +/// \file +/// \brief Dimension lists in which all exponents resolve to zero reduce to @c dimensionless_type. +/// + #include #include #include diff --git a/include/boost/units/dimensionless_unit.hpp b/include/boost/units/dimensionless_unit.hpp index 448e9d3..8e6368f 100644 --- a/include/boost/units/dimensionless_unit.hpp +++ b/include/boost/units/dimensionless_unit.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_DIMENSIONLESS_UNIT_HPP #define BOOST_UNITS_DIMENSIONLESS_UNIT_HPP +/// +/// \file +/// \brief Utility class to simplify construction of dimensionless units in a system. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// utility class to simplify construction of dimensionless units in a system +/// Utility class to simplify construction of dimensionless units in a system. template struct dimensionless_unit { diff --git a/include/boost/units/get_dimension.hpp b/include/boost/units/get_dimension.hpp index e057f79..c0a7ab9 100644 --- a/include/boost/units/get_dimension.hpp +++ b/include/boost/units/get_dimension.hpp @@ -11,6 +11,12 @@ #ifndef BOOST_UNITS_GET_DIMENSION_HPP #define BOOST_UNITS_GET_DIMENSION_HPP +/// +/// \file +/// \brief Get the dimension of a unit, absolute unit and quantity. +/// \details +/// + #include namespace boost { @@ -20,21 +26,21 @@ namespace units { template struct get_dimension {}; -/// get the dimension of a unit +/// Get the dimension of a unit. template struct get_dimension< unit > { typedef Dim type; }; -/// get the dimension of an absolute unit +/// Get the dimension of an absolute unit. template struct get_dimension< absolute > { typedef typename get_dimension::type type; }; -/// get the dimension of a quantity +/// Get the dimension of a quantity. template struct get_dimension< quantity > { diff --git a/include/boost/units/get_system.hpp b/include/boost/units/get_system.hpp index 9e5bd5e..ce4e59f 100644 --- a/include/boost/units/get_system.hpp +++ b/include/boost/units/get_system.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_GET_SYSTEM_HPP #define BOOST_UNITS_GET_SYSTEM_HPP +/// \file +/// \brief Get the system of a unit, absolute unit or quantity. + #include namespace boost { @@ -20,21 +23,21 @@ namespace units { template struct get_system {}; -/// get the system of a unit +/// Get the system of a unit. template struct get_system< unit > { typedef System type; }; -/// get the system of an absolute unit +/// Get the system of an absolute unit. template struct get_system< absolute > { typedef typename get_system::type type; }; -/// get the system of a quantity +/// Get the system of a quantity. template struct get_system< quantity > { diff --git a/include/boost/units/heterogeneous_system.hpp b/include/boost/units/heterogeneous_system.hpp index 57ed820..966797a 100644 --- a/include/boost/units/heterogeneous_system.hpp +++ b/include/boost/units/heterogeneous_system.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_HETEROGENEOUS_SYSTEM_HPP #define BOOST_UNITS_HETEROGENEOUS_SYSTEM_HPP +/// \file +/// \brief A heterogeneous system is a sorted list of base unit/exponent pairs. + #include #include #include @@ -45,7 +48,7 @@ namespace detail { // A normal system is a sorted list of base units. // A heterogeneous system is a sorted list of base unit/exponent pairs. // As long as we don't need to convert heterogeneous systems -// directly everything is cool +// directly everything is cool. template struct is_zero : mpl::false_ {}; diff --git a/include/boost/units/io.hpp b/include/boost/units/io.hpp index 8ce1212..67e9163 100644 --- a/include/boost/units/io.hpp +++ b/include/boost/units/io.hpp @@ -2,7 +2,7 @@ // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel -// Copyright (C) 2007-2008 Steven Watanabe +// Copyright (C) 2007-2010 Steven Watanabe // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,20 +11,24 @@ #ifndef BOOST_UNITS_IO_HPP #define BOOST_UNITS_IO_HPP +/// \file +/// \brief Stream input and output for rationals, units and quantities. +/// \details Functions and manipulators for output and input of units and quantities. +/// symbol and name format, and engineering and binary autoprefix. +/// Serialization output is also supported. + #include +#include #include #include #include #include -#include -#include -#include -#include #include #include #include +#include #include #include #include @@ -51,7 +55,7 @@ inline void serialize(Archive& ar,boost::units::quantity& q,const unsign namespace units { -// get string representation of arbitrary type +// get string representation of arbitrary type. template std::string to_string(const T& t) { std::stringstream sstr; @@ -61,13 +65,13 @@ template std::string to_string(const T& t) return sstr.str(); } -// get string representation of integral-valued @c static_rational +/// get string representation of integral-valued @c static_rational. template std::string to_string(const static_rational&) { return to_string(N); } -// get string representation of @c static_rational +/// get string representation of @c static_rational. template std::string to_string(const static_rational&) { return '(' + to_string(N) + '/' + to_string(D) + ')'; @@ -81,29 +85,41 @@ inline std::basic_ostream& operator<<(std::basic_ostream struct base_unit_info { + /// INTERNAL ONLY + typedef void base_unit_info_primary_template; /// The full name of the unit (returns BaseUnit::name() by default) static std::string name() { return(BaseUnit::name()); } - /// The symbol for the base unit (Returns BaseUnit::symbol() by default) static std::string symbol() { - return(BaseUnit::symbol()); + return(BaseUnit::symbol()); /// \returns BaseUnit::symbol(), for example "m" } }; -enum format_mode +/// \enum format_mode format of output of units, for example "m" or "meter". +enum format_mode { - symbol_fmt = 0, // default - reduces unit names to known symbols for both base and derived units - name_fmt, // output full unit names for base and derived units - raw_fmt, // output only symbols for base units - typename_fmt // output demangled typenames + symbol_fmt = 0, /// default - reduces unit names to known symbols for both base and derived units. + name_fmt = 1, /// output full unit names for base and derived units, for example "meter". + raw_fmt = 2, /// output only symbols for base units (but not derived units), for example "m". + typename_fmt = 3, /// output demangled typenames (useful only for diagnosis). + fmt_mask = 3 /// Bits used for format. +}; + +/// \enum autoprefix_mode automatic scaling and prefix (controlled by value of quantity) a, if any, +enum autoprefix_mode +{ + autoprefix_none = 0, /// No automatic prefix. + autoprefix_engineering = 4, /// Scale and prefix with 10^3 multiples, 1234.5 m output as 1.2345 km. + autoprefix_binary = 8, /// Scale and prefix with 2^10 (1024) multiples, 1024 as 1 kb. + autoprefix_mask = 12 /// Bits used for autoprefix. }; namespace detail { @@ -141,48 +157,103 @@ xalloc_key_initializer_t xalloc_key_initializer; } // namespace detail +/// returns flags controlling output. +inline long get_flags(std::ios_base& ios, long mask) +{ + return(ios.iword(detail::xalloc_key_holder::value) & mask); +} + +/// Set new flags controlling output format. +inline void set_flags(std::ios_base& ios, long new_flags, long mask) +{ + assert((~mask & new_flags) == 0); + long& flags = ios.iword(detail::xalloc_key_holder::value); + flags = (flags & ~mask) | new_flags; +} + +/// returns flags controlling output format. inline format_mode get_format(std::ios_base& ios) { - return(static_cast(ios.iword(detail::xalloc_key_holder::value))); + return(static_cast((get_flags)(ios, fmt_mask))); } +/// Set new flags controlling output format. inline void set_format(std::ios_base& ios, format_mode new_mode) { - ios.iword(detail::xalloc_key_holder::value) = static_cast(new_mode); + (set_flags)(ios, new_mode, fmt_mask); } +/// Set new flags for type_name output format. inline std::ios_base& typename_format(std::ios_base& ios) { (set_format)(ios, typename_fmt); return(ios); } +/// set new flag for raw format output, for example "m". inline std::ios_base& raw_format(std::ios_base& ios) { (set_format)(ios, raw_fmt); return(ios); } +/// set new format flag for symbol output, for example "m". inline std::ios_base& symbol_format(std::ios_base& ios) { (set_format)(ios, symbol_fmt); return(ios); } +/// set new format for name output, for example "meter". inline std::ios_base& name_format(std::ios_base& ios) { (set_format)(ios, name_fmt); return(ios); } +/// get autoprefix flags for output. +inline autoprefix_mode get_autoprefix(std::ios_base& ios) +{ + return static_cast((get_flags)(ios, autoprefix_mask)); +} + +/// Get format for output. +inline void set_autoprefix(std::ios_base& ios, autoprefix_mode new_mode) +{ + (set_flags)(ios, new_mode, autoprefix_mask); +} + +/// Clear autoprefix flags. +inline std::ios_base& no_prefix(std::ios_base& ios) +{ + (set_autoprefix)(ios, autoprefix_none); + return ios; +} + +/// Set flag for engineering prefix, so 1234.5 m displays as "1.2345 km". +inline std::ios_base& engineering_prefix(std::ios_base& ios) +{ + (set_autoprefix)(ios, autoprefix_engineering); + return ios; +} + +/// Set flag for binary prefix, so 1024 byte displays as "1 Kib". +inline std::ios_base& binary_prefix(std::ios_base& ios) +{ + (set_autoprefix)(ios, autoprefix_binary); + return ios; +} + namespace detail { +/// \return exponent string like "^1/2". template inline std::string exponent_string(const static_rational& r) { return '^' + to_string(r); } +/// \return empty exponent string for integer rational like 2. template<> inline std::string exponent_string(const static_rational<1>&) { @@ -201,7 +272,7 @@ inline std::string base_unit_name_string(const T&) return base_unit_info::name() + exponent_string(typename T::value_type()); } -// stringify with symbols +// stringify with symbols. template struct symbol_string_impl { @@ -268,7 +339,7 @@ struct scale_symbol_string_impl<0> }; }; -// stringify with names +// stringify with names. template struct name_string_impl { @@ -407,7 +478,7 @@ to_string_impl(const unit inline std::string -to_string_impl(const unit, static_rational<1> >, dimensionless_type>, Dimension, Scale> > >&, Subformatter f) +to_string_impl( + const unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + list, static_rational<1> >, dimensionless_type>, + Dimension, + Scale + > + > + >&, + Subformatter f, + typename base_unit_info >::base_unit_info_primary_template* = 0) { return(f( unit< @@ -455,7 +540,7 @@ to_string_impl(const unit >, dimensionless_type>, Dimension, - typename mpl::times >::type + typename mpl::times, dimensionless_type> >::type > > >())); @@ -466,7 +551,19 @@ to_string_impl(const unit inline std::string -to_string_impl(const unit, static_rational<1> >, dimensionless_type>, Dimension, dimensionless_type> > >&, Subformatter f) +to_string_impl( + const unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + list, static_rational<1> >, dimensionless_type>, + Dimension, + dimensionless_type + > + > + >&, + Subformatter f, + typename base_unit_info >::base_unit_info_primary_template* = 0) { std::string str; f.template append_units_to, static_rational<1> >, dimensionless_type> >(str); @@ -483,8 +580,8 @@ struct format_raw_symbol_impl { detail::scale_symbol_string_impl::template apply::value(str); } template - std::string operator()(const Unit& unit) { - return(to_string_impl(unit, *this)); + std::string operator()(const Unit& u) { + return(to_string_impl(u, *this)); } template bool is_default_string(const std::string&, const Unit&) { @@ -494,12 +591,12 @@ struct format_raw_symbol_impl { struct format_symbol_impl : format_raw_symbol_impl { template - std::string operator()(const Unit& unit) { - return(symbol_string(unit)); + std::string operator()(const Unit& u) { + return(symbol_string(u)); } template - bool is_default_string(const std::string& str, const Unit& unit) { - return(str == to_string_impl(unit, format_raw_symbol_impl())); + bool is_default_string(const std::string& str, const Unit& u) { + return(str == to_string_impl(u, format_raw_symbol_impl())); } }; @@ -513,8 +610,8 @@ struct format_raw_name_impl { detail::scale_name_string_impl::template apply::value(str); } template - std::string operator()(const Unit& unit) { - return(to_string_impl(unit, *this)); + std::string operator()(const Unit& u) { + return(to_string_impl(u, *this)); } template bool is_default_string(const std::string&, const Unit&) { @@ -524,29 +621,308 @@ struct format_raw_name_impl { struct format_name_impl : format_raw_name_impl { template - std::string operator()(const Unit& unit) { - return(name_string(unit)); + std::string operator()(const Unit& u) { + return(name_string(u)); } template - bool is_default_string(const std::string& str, const Unit& unit) { - return(str == to_string_impl(unit, format_raw_name_impl())); + bool is_default_string(const std::string& str, const Unit& u) { + return(str == to_string_impl(u, format_raw_name_impl())); } }; template -inline void do_print(std::basic_ostream& os, const std::string& s) { +inline void do_print(std::basic_ostream& os, const std::string& s) +{ os << s.c_str(); } -inline void do_print(std::ostream& os, const std::string& s) { +inline void do_print(std::ostream& os, const std::string& s) +{ os << s; } template -inline void do_print(std::basic_ostream& os, const char* s) { +inline void do_print(std::basic_ostream& os, const char* s) +{ os << s; } +// For automatically applying the appropriate prefixes. + +template +bool find_matching_scale_impl(End, End, Prev, T, F) +{ + return false; +} + +template +bool find_matching_scale_impl(Begin, End end, Prev prev, T t, F f) +{ + using std::abs; + if(Begin::item::value() > abs(t)) { + f(prev, t); + return true; + } else { + return detail::find_matching_scale_impl( + typename Begin::next(), + end, + typename Begin::item(), + t, + f + ); + } +} + +template +bool find_matching_scale_i(End, End, T, F) +{ + return false; +} + +template +bool find_matching_scale_i(Begin, End end, T t, F f) +{ + using std::abs; + if(Begin::item::value() > abs(t)) { + return false; + } else { + return detail::find_matching_scale_impl(typename Begin::next(), end, typename Begin::item(), t, f); + } +} + +template +bool find_matching_scale(T t, F f) +{ + return detail::find_matching_scale_i(Scales(), dimensionless_type(), t, f); +} + +typedef list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + list >, + dimensionless_type> > > > > > > > > > > > > > > > > > engineering_prefixes; + +typedef list >, + list >, + list >, + list >, + list >, + list >, + list >, + dimensionless_type> > > > > > > binary_prefixes; + +template +struct print_default_t { + typedef void result_type; + void operator()() const + { + *os << q->value() << ' ' << typename Quantity::unit_type(); + } + Os* os; + const Quantity* q; +}; + +template +print_default_t print_default(Os& os, const Quantity& q) +{ + print_default_t result = { &os, &q }; + return result; +} + +template +struct print_scale_t { + typedef void result_type; + template + void operator()(Prefix, const T& t) const + { + *prefixed = true; + *os << t / Prefix::value() << ' '; + switch(units::get_format(*os)) { + case name_fmt: do_print(*os, Prefix::name()); break; + case raw_fmt: + case symbol_fmt: do_print(*os, Prefix::symbol()); break; + case typename_fmt: do_print(*os, units::simplify_typename(Prefix())); *os << ' '; break; + } + } + template + void operator()(scale >, const T& t) const + { + *prefixed = false; + *os << t << ' '; + } + Os* os; + bool* prefixed; +}; + +template +print_scale_t print_scale(Os& os, bool& prefixed) +{ + print_scale_t result = { &os, &prefixed }; + return result; +} + +// puts parentheses around a unit +/// INTERNAL ONLY +template +inline std::string +maybe_parenthesize(const unit > >&, Subformatter f) +{ + std::string str; + + std::string without_scale = f(unit > >()); + + if (f.is_default_string(without_scale, unit > >())) + { + str += "("; + str += without_scale; + str += ")"; + } + else + { + str += without_scale; + } + + return(str); +} + +// This overload catches scaled units that have a single base unit +// raised to the first power. It causes si::nano * si::meters to not +// put parentheses around the meters. i.e. nm rather than n(m) +/// INTERNAL ONLY +template +inline std::string +maybe_parenthesize(const unit >,dimensionless_type>, Dimension, Scale> > >&, Subformatter f) +{ + return f(unit >, dimensionless_type>, Dimension, dimensionless_type> > >()); +} + +template +void do_print_prefixed_impl(std::basic_ostream& os, const quantity& q, F default_) +{ + bool prefixed; + if(detail::find_matching_scale(q.value(), detail::print_scale(os, prefixed))) { + if(prefixed) { + switch(units::get_format(os)) { + case symbol_fmt: do_print(os, maybe_parenthesize(Unit(), format_symbol_impl())); break; + case raw_fmt: do_print(os, maybe_parenthesize(Unit(), format_raw_symbol_impl())); break; + case name_fmt: do_print(os, maybe_parenthesize(Unit(), format_name_impl())); break; + case typename_fmt: do_print(os, simplify_typename(Unit())); break; + } + } else { + os << Unit(); + } + } else { + default_(); + } +} + +// Handle units like si::kilograms that have a scale embedded in the +// base unit. This overload is disabled if the scaled base unit has +// a user-defined string representation. +template +typename base_unit_info< + scaled_base_unit +>::base_unit_info_primary_template +do_print_prefixed( + std::basic_ostream& os, + const quantity< + unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + list< + heterogeneous_system_dim< + scaled_base_unit, + static_rational<1> + >, + dimensionless_type + >, + Dimension, + Scale + > + > + >, + T + >& q) +{ + quantity< + unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + list< + heterogeneous_system_dim >, + dimensionless_type + >, + Dimension, + dimensionless_type + > + > + >, + T + > unscaled(q); + detail::do_print_prefixed_impl(os, unscaled, detail::print_default(os, q)); +} + +template +void do_print_prefixed( + std::basic_ostream& os, + const quantity< + unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + L, + Dimension, + Scale + > + > + >, + T + >& q) +{ + quantity< + unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + L, + Dimension, + dimensionless_type + > + > + >, + T + > unscaled(q); + detail::do_print_prefixed_impl(os, unscaled, detail::print_default(os, q)); +} + +template +void do_print_prefixed(std::basic_ostream& os, const quantity, T>& q) +{ + detail::do_print_prefixed(os, quantity::type>, T>(q)); +} + +template +void do_print_prefixed(std::basic_ostream& os, const quantity& q) +{ + detail::print_default(os, q)(); +} + } // namespace detail template @@ -570,18 +946,18 @@ name_string(const unit&) return detail::to_string_impl(unit(), detail::format_name_impl()); } -/// Print an @c unit as a list of base units and exponents +/// Print a @c unit as a list of base units and their exponents. /// -/// for @c symbol_format this gives e.g. "m s^-1" or "J" -/// for @c name_format this gives e.g. "meter second^-1" or "joule" -/// for @c raw_format this gives e.g. "m s^-1" or "meter kilogram^2 second^-2" -/// for @c typename_format this gives the typename itself (currently demangled only on GCC) +/// for @c symbol_format outputs e.g. "m s^-1" or "J". +/// for @c name_format outputs e.g. "meter second^-1" or "joule". +/// for @c raw_format outputs e.g. "m s^-1" or "meter kilogram^2 second^-2". +/// for @c typename_format outputs the typename itself (currently demangled only on GCC). template inline std::basic_ostream& operator<<(std::basic_ostream& os, const unit& u) { if (units::get_format(os) == typename_fmt) { - detail::do_print(os , typename_string(u)); + detail::do_print(os, typename_string(u)); } else if (units::get_format(os) == raw_fmt) { @@ -603,12 +979,31 @@ inline std::basic_ostream& operator<<(std::basic_ostream inline std::basic_ostream& operator<<(std::basic_ostream& os, const quantity& q) { - os << q.value() << ' ' << Unit(); + if (units::get_autoprefix(os) == autoprefix_none) + { + os << q.value() << ' ' << Unit(); + } + else if (units::get_autoprefix(os) == autoprefix_engineering) + { + detail::do_print_prefixed(os, q); + } + else if (units::get_autoprefix(os) == autoprefix_binary) + { + detail::do_print_prefixed(os, q); + } + else + { + assert(!"Autoprefixing must be one of: no_prefix, engineering_prefix, binary_prefix"); + } return(os); } diff --git a/include/boost/units/is_dim.hpp b/include/boost/units/is_dim.hpp index 42297c5..d6a6b54 100644 --- a/include/boost/units/is_dim.hpp +++ b/include/boost/units/is_dim.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_DIM_HPP #define BOOST_UNITS_IS_DIM_HPP +/// +/// \file +/// \brief Check that a type is a valid @c dim. +/// + #include #include diff --git a/include/boost/units/is_dimension_list.hpp b/include/boost/units/is_dimension_list.hpp index 47caaa0..b2494d7 100644 --- a/include/boost/units/is_dimension_list.hpp +++ b/include/boost/units/is_dimension_list.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_DIMENSION_LIST_HPP #define BOOST_UNITS_IS_DIMENSION_LIST_HPP +/// +/// \file +/// \brief Check that a type is a valid dimension list. +/// + #include #include diff --git a/include/boost/units/is_dimensionless.hpp b/include/boost/units/is_dimensionless.hpp index 60d1292..158a420 100644 --- a/include/boost/units/is_dimensionless.hpp +++ b/include/boost/units/is_dimensionless.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_DIMENSIONLESS_HPP #define BOOST_UNITS_IS_DIMENSIONLESS_HPP +/// +/// \file +/// \brief Check if a unit or quantity is dimensionless. +/// + #include #include @@ -23,13 +28,13 @@ struct is_dimensionless : public mpl::false_ { }; -/// check if a unit is dimensionless +/// Check if a unit is dimensionless. template struct is_dimensionless< unit > : public mpl::true_ { }; -/// check if a quantity is dimensionless +/// Check if a quantity is dimensionless. template struct is_dimensionless< quantity > : public is_dimensionless diff --git a/include/boost/units/is_dimensionless_quantity.hpp b/include/boost/units/is_dimensionless_quantity.hpp index c946b0a..fa0dbce 100644 --- a/include/boost/units/is_dimensionless_quantity.hpp +++ b/include/boost/units/is_dimensionless_quantity.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_IS_DIMENSIONLESS_QUANTITY_HPP #define BOOST_UNITS_IS_DIMENSIONLESS_QUANTITY_HPP +/// \file +/// \brief check that a type is a dimensionless quantity + #include #include @@ -18,7 +21,7 @@ namespace boost { namespace units { -/// check that a type is a dimensionless quantity +/// Check that a type is a dimensionless quantity. template struct is_dimensionless_quantity : public is_quantity_of_dimension diff --git a/include/boost/units/is_dimensionless_unit.hpp b/include/boost/units/is_dimensionless_unit.hpp index ce69a03..09d4da5 100644 --- a/include/boost/units/is_dimensionless_unit.hpp +++ b/include/boost/units/is_dimensionless_unit.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_IS_DIMENSIONLESS_UNIT_HPP #define BOOST_UNITS_IS_DIMENSIONLESS_UNIT_HPP +/// \file +/// \brief Check that a type is a dimensionless unit. + #include #include @@ -18,7 +21,7 @@ namespace boost { namespace units { -/// check that a type is a dimensionless unit +/// Check that a type is a dimensionless unit. template struct is_dimensionless_unit : public is_unit_of_dimension diff --git a/include/boost/units/is_quantity.hpp b/include/boost/units/is_quantity.hpp index 6e09080..dd0ae08 100644 --- a/include/boost/units/is_quantity.hpp +++ b/include/boost/units/is_quantity.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_QUANTITY_HPP #define BOOST_UNITS_IS_QUANTITY_HPP +/// +/// \file +/// \brief Check that a type is a quantity. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// check that a type is a quantity +/// Check that a type is a quantity. template struct is_quantity : public mpl::false_ diff --git a/include/boost/units/is_quantity_of_dimension.hpp b/include/boost/units/is_quantity_of_dimension.hpp index 3c8c002..f3ec409 100644 --- a/include/boost/units/is_quantity_of_dimension.hpp +++ b/include/boost/units/is_quantity_of_dimension.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_QUANTITY_OF_DIMENSION_HPP #define BOOST_UNITS_IS_QUANTITY_OF_DIMENSION_HPP +/// +/// \file +/// \brief Check that a type is a quantity of the specified dimension. +/// + #include #include #include @@ -19,7 +24,7 @@ namespace boost { namespace units { -/// check that a type is a quantity of the specified dimension +/// Check that a type is a quantity of the specified dimension. template struct is_quantity_of_dimension : public mpl::false_ diff --git a/include/boost/units/is_quantity_of_system.hpp b/include/boost/units/is_quantity_of_system.hpp index 3f10255..18546eb 100644 --- a/include/boost/units/is_quantity_of_system.hpp +++ b/include/boost/units/is_quantity_of_system.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_QUANTITY_OF_SYSTEM_HPP #define BOOST_UNITS_IS_QUANTITY_OF_SYSTEM_HPP +/// +/// \file +/// \brief Check that a type is a quantity in a specified system. +/// + #include #include #include @@ -19,7 +24,7 @@ namespace boost { namespace units { -/// check that a type is a quantity in a specified system +/// Check that a type is a quantity in a specified system. template struct is_quantity_of_system : public mpl::false_ diff --git a/include/boost/units/is_unit.hpp b/include/boost/units/is_unit.hpp index 59fb99e..195c42f 100644 --- a/include/boost/units/is_unit.hpp +++ b/include/boost/units/is_unit.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_UNIT_HPP #define BOOST_UNITS_IS_UNIT_HPP +/// +/// \file +/// \brief Check that a type is a unit. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// check that a type is a unit +/// Check that a type is a unit. template struct is_unit : public mpl::false_ diff --git a/include/boost/units/is_unit_of_dimension.hpp b/include/boost/units/is_unit_of_dimension.hpp index 0bc2147..4fc878b 100644 --- a/include/boost/units/is_unit_of_dimension.hpp +++ b/include/boost/units/is_unit_of_dimension.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_UNIT_OF_DIMENSION_HPP #define BOOST_UNITS_IS_UNIT_OF_DIMENSION_HPP +/// +/// \file +/// \brief Check that a type is a unit of the specified dimension. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// check that a type is a unit of the specified dimension +/// Check that a type is a unit of the specified dimension. template struct is_unit_of_dimension : public mpl::false_ diff --git a/include/boost/units/is_unit_of_system.hpp b/include/boost/units/is_unit_of_system.hpp index 8bd7d64..3c3eaa7 100644 --- a/include/boost/units/is_unit_of_system.hpp +++ b/include/boost/units/is_unit_of_system.hpp @@ -11,6 +11,11 @@ #ifndef BOOST_UNITS_IS_UNIT_OF_SYSTEM_HPP #define BOOST_UNITS_IS_UNIT_OF_SYSTEM_HPP +/// +/// \file +/// \brief Check that a type is a unit in a specified system. +/// + #include #include @@ -18,7 +23,7 @@ namespace boost { namespace units { -/// check that a type is a unit in a specified system +/// Check that a type is a unit in a specified system. template struct is_unit_of_system : public mpl::false_ diff --git a/include/boost/units/limits.hpp b/include/boost/units/limits.hpp index d248774..2c8a0bf 100644 --- a/include/boost/units/limits.hpp +++ b/include/boost/units/limits.hpp @@ -7,9 +7,15 @@ // 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) + #ifndef BOOST_UNITS_LIMITS_HPP #define BOOST_UNITS_LIMITS_HPP +/// +/// \file +/// \brief specialize std::numeric_limits for units. +/// + #include #include diff --git a/include/boost/units/make_scaled_unit.hpp b/include/boost/units/make_scaled_unit.hpp index 084b362..d9740ff 100644 --- a/include/boost/units/make_scaled_unit.hpp +++ b/include/boost/units/make_scaled_unit.hpp @@ -11,6 +11,7 @@ #ifndef BOOST_UNITS_MAKE_SCALED_UNIT_HPP_INCLUDED #define BOOST_UNITS_MAKE_SCALED_UNIT_HPP_INCLUDED +#include #include #include @@ -39,6 +40,20 @@ struct make_scaled_unit type; }; +template +struct make_scaled_unit > >, scale > > { + typedef unit< + Dimension, + heterogeneous_system< + heterogeneous_system_impl< + UnitList, + Dimension, + OldScale + > + > + > type; +}; + } } diff --git a/include/boost/units/make_system.hpp b/include/boost/units/make_system.hpp index 444ae22..1918268 100644 --- a/include/boost/units/make_system.hpp +++ b/include/boost/units/make_system.hpp @@ -11,6 +11,16 @@ #ifndef BOOST_UNITS_MAKE_SYSTEM_HPP #define BOOST_UNITS_MAKE_SYSTEM_HPP +/// \file +/// \brief Metafunction returning a homogeneous system that can +/// represent any combination of the base units. +/// \details +/// Metafunction make_system returning a homogeneous system that can +/// represent any combination of the base units. There must +/// be no way to represent any of the base units in terms +/// of the others. make_system::type +/// is not allowed, for example. + #include #include #include diff --git a/include/boost/units/operators.hpp b/include/boost/units/operators.hpp index c162610..19b8aac 100644 --- a/include/boost/units/operators.hpp +++ b/include/boost/units/operators.hpp @@ -11,29 +11,30 @@ #ifndef BOOST_UNITS_OPERATORS_HPP #define BOOST_UNITS_OPERATORS_HPP + +/// +/// \file +/// \brief Compile time operators and typeof helper classes. +/// \details +/// These operators declare the compile-time operators needed to support dimensional +/// analysis algebra. They require the use of Boost.Typeof, emulation or native. +/// Typeof helper classes define result type for heterogeneous operators on value types. +/// These must be defined through specialization for powers and roots. +/// + #include #include #include -/// \file -/// \brief Compile time operators and typeof helper classes. -/// -/// \detailed -/// These operators declare the compile-time operators needed to support dimensional -/// analysis algebra. They require the use of Boost.Typeof. -/// Typeof helper classes define result type for heterogeneous operators on value types. -/// These must be defined through specialization for powers and roots. - namespace boost { - namespace units { #if BOOST_UNITS_HAS_TYPEOF #ifndef BOOST_UNITS_DOXYGEN -// to avoid need for default constructor and eliminate divide by zero errors +// to avoid need for default constructor and eliminate divide by zero errors. namespace typeof_ { /// INTERNAL ONLY diff --git a/include/boost/units/physical_dimensions.hpp b/include/boost/units/physical_dimensions.hpp index e115898..4137e1e 100644 --- a/include/boost/units/physical_dimensions.hpp +++ b/include/boost/units/physical_dimensions.hpp @@ -2,7 +2,7 @@ // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel -// Copyright (C) 2007-2008 Steven Watanabe +// Copyright (C) 2007-2010 Steven Watanabe // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,25 +11,29 @@ #ifndef BOOST_UNITS_PHYSICAL_UNITS_HPP #define BOOST_UNITS_PHYSICAL_UNITS_HPP -/// \file Includes all of the physical_dimension headers. /// -/// \brief Physical dimensions according to the SI system -/// -/// \detail This header includes all physical dimension headers for both base -/// derived dimensions. Base dimensions are extended to include plane and -/// solid angle for convenience. +/// \file +/// \brief Physical dimensions according to the SI system. +/// \details This header includes all physical dimension headers for both base +/// and derived dimensions. /// +// Include all of the physical_dimension headers. + +// SI seven fundamental dimensions. #include #include #include #include #include -#include -#include #include #include +// Base dimensions are extended to include plane and solid angle for convenience. +#include +#include + +// Derived dimensions. #include #include #include diff --git a/include/boost/units/pow.hpp b/include/boost/units/pow.hpp index ed0b3e4..1d856a5 100644 --- a/include/boost/units/pow.hpp +++ b/include/boost/units/pow.hpp @@ -19,13 +19,13 @@ #include /// \file -/// \brief Raise values to exponents known at compile-time +/// \brief Raise values to exponents known at compile-time. namespace boost { namespace units { -/// raise a value to a @c static_rational power +/// raise a value to a @c static_rational power. template inline typename power_typeof_helper::type pow(const Y& x) @@ -33,7 +33,7 @@ pow(const Y& x) return power_typeof_helper::value(x); } -/// raise a value to an integer power +/// raise a value to an integer power. template inline typename power_typeof_helper >::type pow(const Y& x) @@ -43,7 +43,7 @@ pow(const Y& x) #ifndef BOOST_UNITS_DOXYGEN -/// raise @c T to a @c static_rational power +/// raise @c T to a @c static_rational power. template struct power_typeof_helper > { @@ -57,11 +57,11 @@ struct power_typeof_helper > } }; -/// raise @c float to a @c static_rational power +/// raise @c float to a @c static_rational power. template struct power_typeof_helper > { - // N.B. pathscale doesn't accept inheritence for some reason. + // N.B. pathscale doesn't accept inheritance for some reason. typedef power_typeof_helper > base; typedef typename base::type type; static type value(const double& x) @@ -72,7 +72,7 @@ struct power_typeof_helper > #endif -/// take the @c static_rational root of a value +/// take the @c static_rational root of a value. template typename root_typeof_helper::type root(const Y& x) @@ -80,7 +80,7 @@ root(const Y& x) return root_typeof_helper::value(x); } -/// take the integer root of a value +/// take the integer root of a value. template typename root_typeof_helper >::type root(const Y& x) @@ -94,7 +94,7 @@ root(const Y& x) template struct root_typeof_helper > { - // N.B. pathscale doesn't accept inheritence for some reason. + // N.B. pathscale doesn't accept inheritance for some reason. typedef power_typeof_helper > base; typedef typename base::type type; static type value(const T& x) diff --git a/include/boost/units/reduce_unit.hpp b/include/boost/units/reduce_unit.hpp index 5c6742b..fe0050a 100644 --- a/include/boost/units/reduce_unit.hpp +++ b/include/boost/units/reduce_unit.hpp @@ -11,6 +11,9 @@ #ifndef BOOST_UNITS_REDUCE_UNIT_HPP_INCLUDED #define BOOST_UNITS_REDUCE_UNIT_HPP_INCLUDED +/// \file +/// \brief Returns a unique type for every unit. + namespace boost { namespace units { diff --git a/include/boost/units/scale.hpp b/include/boost/units/scale.hpp index 05a389f..513d3a1 100644 --- a/include/boost/units/scale.hpp +++ b/include/boost/units/scale.hpp @@ -11,6 +11,12 @@ #ifndef BOOST_UNITS_SCALE_HPP_INCLUDED #define BOOST_UNITS_SCALE_HPP_INCLUDED +/// +/// \file +/// \brief 10^3 Engineering & 2^10 binary scaling factors for autoprefixing. +/// \details +/// + #include #include @@ -27,7 +33,7 @@ template struct scaled_base_unit; /// class representing a scaling factor such as 10^3 -/// The exponent should be a static rational. +/// The exponent must be a static rational. template struct scale { diff --git a/include/boost/units/static_rational.hpp b/include/boost/units/static_rational.hpp index 2a630ec..5263e75 100644 --- a/include/boost/units/static_rational.hpp +++ b/include/boost/units/static_rational.hpp @@ -46,7 +46,7 @@ struct static_abs BOOST_STATIC_CONSTANT(integer_type,value = Value < 0 ? -Value : Value); }; -/// Compile time rational number. +// Compile time rational number. /** This is an implementation of a compile time rational number, where @c static_rational represents a rational number with numerator @c N and denominator @c D. Because of the potential for ambiguity arising diff --git a/include/boost/units/systems/si/codata/electromagnetic_constants.hpp b/include/boost/units/systems/si/codata/electromagnetic_constants.hpp index 9cc6f49..b2ffe26 100644 --- a/include/boost/units/systems/si/codata/electromagnetic_constants.hpp +++ b/include/boost/units/systems/si/codata/electromagnetic_constants.hpp @@ -11,6 +11,13 @@ #ifndef BOOST_UNITS_CODATA_ELECTROMAGNETIC_CONSTANTS_HPP #define BOOST_UNITS_CODATA_ELECTROMAGNETIC_CONSTANTS_HPP +/// +/// \file +/// \brief CODATA recommended values of fundamental electromagnetic constants. +/// \details CODATA recommended values of the fundamental physical constants: NIST SP 961 +/// CODATA 2006 values as of 2007/03/30 +/// + #include #include @@ -26,10 +33,6 @@ #include -/// \file -/// CODATA recommended values of fundamental electromagnetic constants -/// CODATA 2006 values as of 2007/03/30 - namespace boost { namespace units { @@ -40,8 +43,6 @@ namespace constants { namespace codata { -/// CODATA recommended values of the fundamental physical constants: NIST SP 961 - // ELECTROMAGNETIC /// elementary charge BOOST_UNITS_PHYSICAL_CONSTANT(e,quantity,1.602176487e-19*coulombs,4.0e-27*coulombs); diff --git a/include/boost/units/units_fwd.hpp b/include/boost/units/units_fwd.hpp index 886e9ae..e97c46e 100644 --- a/include/boost/units/units_fwd.hpp +++ b/include/boost/units/units_fwd.hpp @@ -11,8 +11,11 @@ #ifndef BOOST_UNITS_UNITS_FWD_HPP #define BOOST_UNITS_UNITS_FWD_HPP +/// /// \file -/// Forward declarations of library components. +/// \brief Forward declarations of library components. +/// \details Forward declarations of units library - dimensions, systems, quantity and string components. +/// #ifndef BOOST_UNITS_DOXYGEN @@ -38,6 +41,8 @@ template class absolute; template class unit; +template struct scale; + template struct base_unit_info; template struct dimensionless_unit; template struct is_unit; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 3bd63df..77f0c05 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -7,13 +7,26 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt -project boost/units/test : - requirements $(BOOST_ROOT) ../../.. msvc:on -; - import testing ; -alias test_framework : $(BOOST_ROOT)/libs/test/build//boost_unit_test_framework ; +warning-options = all on ; +warning-compilers = + msvc +; + +project boost/units/test : + requirements + /boost//headers + ../../.. + msvc:on + $(warning-compilers):$(warning-options) + # This warning comes from the test library. + msvc:"/wd4701" + # The comes from the exception library + msvc,7.1:"/wd4800" +; + +alias test_framework : /boost//unit_test_framework/off ; compile test_predicates.cpp ; compile test_negative_denominator.cpp ; diff --git a/test/fail_add_temperature.cpp b/test/fail_add_temperature.cpp index a3a02ab..979b236 100644 --- a/test/fail_add_temperature.cpp +++ b/test/fail_add_temperature.cpp @@ -13,7 +13,7 @@ \brief fail_add_temperature.cpp -\detailed +\details Verify that adding two absolute temeratures fails miserably. Output: diff --git a/test/fail_adl_detail.cpp b/test/fail_adl_detail.cpp index 6cc9cc7..b44788d 100644 --- a/test/fail_adl_detail.cpp +++ b/test/fail_adl_detail.cpp @@ -13,7 +13,7 @@ \brief fail_adl_detail.cpp -\detailed +\details make sure that namespace detail is not pulled in by ADL. Output: diff --git a/test/fail_base_dimension.cpp b/test/fail_base_dimension.cpp index be511b4..1dd7a4a 100644 --- a/test/fail_base_dimension.cpp +++ b/test/fail_base_dimension.cpp @@ -13,7 +13,7 @@ \brief fail_base_dimension.cpp -\detailed +\details make sure that trying to use the same ordinal for multiple base dimensions fails. diff --git a/test/fail_heterogeneous_unit.cpp b/test/fail_heterogeneous_unit.cpp index 626feae..c0f7692 100644 --- a/test/fail_heterogeneous_unit.cpp +++ b/test/fail_heterogeneous_unit.cpp @@ -13,7 +13,7 @@ \brief fail_heterogeneous_unit.cpp -\detailed +\details make sure that trying to bind a heterogeneous system to a different dimension fails. Output: diff --git a/test/fail_implicit_conversion.cpp b/test/fail_implicit_conversion.cpp index 467932d..bedef1b 100644 --- a/test/fail_implicit_conversion.cpp +++ b/test/fail_implicit_conversion.cpp @@ -13,7 +13,7 @@ \brief fail_implicit_conversion.cpp -\detailed +\details Test implicit conversions for quantity. Output: diff --git a/test/fail_quantity_add.cpp b/test/fail_quantity_add.cpp index a78c3f2..e7e37d4 100644 --- a/test/fail_quantity_add.cpp +++ b/test/fail_quantity_add.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_add.cpp -\detailed +\details Test addition of quantities with different dimensions. Output: diff --git a/test/fail_quantity_add_assign.cpp b/test/fail_quantity_add_assign.cpp index 900e0af..f31df61 100644 --- a/test/fail_quantity_add_assign.cpp +++ b/test/fail_quantity_add_assign.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_add_assign.cpp -\detailed +\details Test += of quantity from different dimensions. Output: diff --git a/test/fail_quantity_assign.cpp b/test/fail_quantity_assign.cpp index d936729..0f48bf2 100644 --- a/test/fail_quantity_assign.cpp +++ b/test/fail_quantity_assign.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_assign.cpp -\detailed +\details Test assignment of quantity from different dimensions. Output: diff --git a/test/fail_quantity_construct.cpp b/test/fail_quantity_construct.cpp index df78966..9450658 100644 --- a/test/fail_quantity_construct.cpp +++ b/test/fail_quantity_construct.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_construct.cpp -\detailed +\details Test construction of quantity from different dimensions. Output: diff --git a/test/fail_quantity_non_unit.cpp b/test/fail_quantity_non_unit.cpp index 4aea068..646160d 100644 --- a/test/fail_quantity_non_unit.cpp +++ b/test/fail_quantity_non_unit.cpp @@ -12,7 +12,7 @@ \brief fail_quantity_non_unit.cpp -\detailed +\details Make sure that trying to use a base_unit as though it were a unit fails. diff --git a/test/fail_quantity_scalar_add.cpp b/test/fail_quantity_scalar_add.cpp index 56f5162..94cc8f2 100644 --- a/test/fail_quantity_scalar_add.cpp +++ b/test/fail_quantity_scalar_add.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_scalar_add.cpp -\detailed +\details Test addition of quantity and scalar. Output: diff --git a/test/fail_quantity_scalar_sub.cpp b/test/fail_quantity_scalar_sub.cpp index 24ddfec..a4b93f1 100644 --- a/test/fail_quantity_scalar_sub.cpp +++ b/test/fail_quantity_scalar_sub.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_scalar_sub.cpp -\detailed +\details Test subtraction of quantity and scalar. Output: diff --git a/test/fail_quantity_sub_assign.cpp b/test/fail_quantity_sub_assign.cpp index 8b4963d..65ea62f 100644 --- a/test/fail_quantity_sub_assign.cpp +++ b/test/fail_quantity_sub_assign.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_sub_assign.cpp -\detailed +\details Test -= of quantity from different dimensions. Output: diff --git a/test/fail_quantity_subtract.cpp b/test/fail_quantity_subtract.cpp index 8ec21aa..65f71e9 100644 --- a/test/fail_quantity_subtract.cpp +++ b/test/fail_quantity_subtract.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_subtract.cpp -\detailed +\details Test subtraction of quantities with different dimensions. Output: diff --git a/test/fail_quantity_unit_add.cpp b/test/fail_quantity_unit_add.cpp index 19f2698..537656b 100644 --- a/test/fail_quantity_unit_add.cpp +++ b/test/fail_quantity_unit_add.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_unit_add.cpp -\detailed +\details Test addition of quantity and unit. Output: diff --git a/test/fail_quantity_unit_subtract.cpp b/test/fail_quantity_unit_subtract.cpp index 98dba07..bcd9260 100644 --- a/test/fail_quantity_unit_subtract.cpp +++ b/test/fail_quantity_unit_subtract.cpp @@ -13,7 +13,7 @@ \brief fail_quantity_unit_subtract.cpp -\detailed +\details Test subtraction of quantity and unit. Output: diff --git a/test/fail_scalar_quantity_add.cpp b/test/fail_scalar_quantity_add.cpp index 789a5e7..0722524 100644 --- a/test/fail_scalar_quantity_add.cpp +++ b/test/fail_scalar_quantity_add.cpp @@ -13,7 +13,7 @@ \brief fail_scalar_quantity_add.cpp -\detailed +\details Test addition of scalar and quantity. Output: diff --git a/test/fail_scalar_quantity_sub.cpp b/test/fail_scalar_quantity_sub.cpp index 7c19565..44e6a7d 100644 --- a/test/fail_scalar_quantity_sub.cpp +++ b/test/fail_scalar_quantity_sub.cpp @@ -13,7 +13,7 @@ \brief fail_scalar_quantity_sub.cpp -\detailed +\details Test subtraction of scalar and quantity. Output: diff --git a/test/fail_unit_quantity_add.cpp b/test/fail_unit_quantity_add.cpp index cc9da5e..512d332 100644 --- a/test/fail_unit_quantity_add.cpp +++ b/test/fail_unit_quantity_add.cpp @@ -13,7 +13,7 @@ \brief fail_unit_quantity_add.cpp -\detailed +\details Test addition of unit and quantity. Output: diff --git a/test/fail_unit_quantity_subtract.cpp b/test/fail_unit_quantity_subtract.cpp index cc9da5e..512d332 100644 --- a/test/fail_unit_quantity_subtract.cpp +++ b/test/fail_unit_quantity_subtract.cpp @@ -13,7 +13,7 @@ \brief fail_unit_quantity_add.cpp -\detailed +\details Test addition of unit and quantity. Output: diff --git a/test/test_absolute.cpp b/test/test_absolute.cpp index c7edff3..3b83173 100644 --- a/test/test_absolute.cpp +++ b/test/test_absolute.cpp @@ -13,7 +13,7 @@ \brief test_absolute.cpp -\detailed +\details Test absolute units. Output: diff --git a/test/test_base_dimension.cpp b/test/test_base_dimension.cpp index 867879e..27cc6dc 100644 --- a/test/test_base_dimension.cpp +++ b/test/test_base_dimension.cpp @@ -13,7 +13,7 @@ \brief test_base_dimension.cpp -\detailed +\details Test base_dimension class. Output: diff --git a/test/test_cmath.cpp b/test/test_cmath.cpp index e4a385a..ac2b715 100644 --- a/test/test_cmath.cpp +++ b/test/test_cmath.cpp @@ -13,7 +13,7 @@ \brief test_units_1.cpp -\detailed +\details Test unit class. Output: diff --git a/test/test_constants.cpp b/test/test_constants.cpp index f0a8829..081aae2 100644 --- a/test/test_constants.cpp +++ b/test/test_constants.cpp @@ -13,7 +13,7 @@ \brief test_constants.cpp -\detailed +\details Test all combinations of operators with the constants. **/ diff --git a/test/test_conversion.cpp b/test/test_conversion.cpp index 9ae1c1a..0f54952 100644 --- a/test/test_conversion.cpp +++ b/test/test_conversion.cpp @@ -13,7 +13,7 @@ \brief test_conversion.cpp -\detailed +\details Test conversion between quantities. Output: diff --git a/test/test_custom_unit.cpp b/test/test_custom_unit.cpp index cde7929..42e7d6e 100644 --- a/test/test_custom_unit.cpp +++ b/test/test_custom_unit.cpp @@ -13,7 +13,7 @@ \brief test_custom_unit.cpp -\detailed +\details Make sure that a minimal + - * / unit class is fully functional. Output: @@ -34,11 +34,17 @@ BOOST_TYPEOF_REGISTER_TEMPLATE(simple_unit, (int)(int)(int)) template simple_unit operator+(const simple_unit&, - const simple_unit&) {} + const simple_unit&) +{ + return simple_unit(); +} template simple_unit operator-(const simple_unit&, - const simple_unit&) {} + const simple_unit&) +{ + return simple_unit(); +} template simple_unit diff --git a/test/test_dimensionless_quantity.cpp b/test/test_dimensionless_quantity.cpp index 3c6014e..6937d9e 100644 --- a/test/test_dimensionless_quantity.cpp +++ b/test/test_dimensionless_quantity.cpp @@ -13,7 +13,7 @@ \brief test_dimensionless_quantity.cpp -\detailed +\details Test unit class. Output: diff --git a/test/test_header.hpp b/test/test_header.hpp index b6a0c22..bc2ec43 100644 --- a/test/test_header.hpp +++ b/test/test_header.hpp @@ -13,7 +13,7 @@ \brief test_header.hpp -\detailed +\details Unit system for test purposes. Output: diff --git a/test/test_implicit_conversion.cpp b/test/test_implicit_conversion.cpp index eafb800..350a7c4 100644 --- a/test/test_implicit_conversion.cpp +++ b/test/test_implicit_conversion.cpp @@ -13,7 +13,7 @@ \brief test_implicit_conversion.cpp -\detailed +\details Test implicit conversions for quantity. Output: diff --git a/test/test_limits.cpp b/test/test_limits.cpp index e548ad2..458feef 100644 --- a/test/test_limits.cpp +++ b/test/test_limits.cpp @@ -13,7 +13,7 @@ \brief test_limits.cpp -\detailed +\details Test numeric_limits specialization. Output: diff --git a/test/test_negative_denominator.cpp b/test/test_negative_denominator.cpp index e927f1c..e9b638a 100644 --- a/test/test_negative_denominator.cpp +++ b/test/test_negative_denominator.cpp @@ -13,7 +13,7 @@ \brief test_negative_denominator.cpp -\detailed +\details Test negative denominator for static_rational class. Output: diff --git a/test/test_output.cpp b/test/test_output.cpp index 7ebb47f..8d97021 100644 --- a/test/test_output.cpp +++ b/test/test_output.cpp @@ -2,19 +2,19 @@ // unit/quantity manipulation and conversion // // Copyright (C) 2009 Steven Watanabe +// Copyright Paul A. Bristow 2010 // // 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) /** -\file +\file test_output.cpp -\brief test_output.cpp - -\detailed +\brief Test unit and quantity printing - +\details +Tests for output from various units, name, symbol and raw formats, and automatic prefixing in engineering and binary units. **/ #include @@ -35,6 +35,7 @@ Test unit and quantity printing #include #include +#include #define BOOST_TEST_MAIN #include @@ -44,11 +45,16 @@ struct meter_base_unit : boost::units::base_unit { +struct second_base_unit : boost::units::base_unit { static const char* name() { return("second"); } static const char* symbol() { return("s"); } }; +struct byte_base_unit : boost::units::base_unit { + static const char* name() { return("byte"); } + static const char* symbol() { return("b"); } +}; + typedef boost::units::make_system::type my_system; typedef boost::units::unit length; @@ -120,7 +126,8 @@ typedef boost::units::make_scaled_unit(), "1.5 absolute m"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 10) * byte_base_unit::unit_type(), "1024 b"); + #undef FORMATTERS } -BOOST_AUTO_TEST_CASE(test_output_quantity_raw) { +BOOST_AUTO_TEST_CASE(test_output_quantity_raw) +{ // quantity symbols using raw format. #define FORMATTERS << boost::units::raw_format BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m"); BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 m s^-1"); @@ -228,7 +241,8 @@ BOOST_AUTO_TEST_CASE(test_output_quantity_raw) { #undef FORMATTERS } -BOOST_AUTO_TEST_CASE(test_output_quantity_name) { +BOOST_AUTO_TEST_CASE(test_output_quantity_name) +{ // // quantity symbols using name format. #define FORMATTERS << boost::units::name_format BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter"); BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 meter second^-1"); @@ -249,3 +263,170 @@ BOOST_AUTO_TEST_CASE(test_output_quantity_name) { #undef FORMATTERS } +BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_name) +{ // Engineering autoprefix, with name format. +#define FORMATTERS << boost::units::name_format << boost::units::engineering_prefix + // Single base unit like meter. + BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter"); + BOOST_UNITS_TEST_OUTPUT(1500.0*meter_base_unit::unit_type(), "1.5 kilometer"); + BOOST_UNITS_TEST_OUTPUT(1.5e7*meter_base_unit::unit_type(), "15 megameter"); + BOOST_UNITS_TEST_OUTPUT(1.5e-3*meter_base_unit::unit_type(), "1.5 millimeter"); + BOOST_UNITS_TEST_OUTPUT(1.5e-9*meter_base_unit::unit_type(), "1.5 nanometer"); + BOOST_UNITS_TEST_OUTPUT(1.5e-8*meter_base_unit::unit_type(), "15 nanometer"); + BOOST_UNITS_TEST_OUTPUT(1.5e-10*meter_base_unit::unit_type(), "150 picometer"); + BOOST_UNITS_TEST_OUTPUT(0.0000000012345 * meter_base_unit::unit_type(), "1.2345 nanometer"); + + // Too small or large for a multiple name. + BOOST_UNITS_TEST_OUTPUT(9.99999e-25 * meter_base_unit::unit_type(), "9.99999e-025 meter"); // Just too small for multiple. + BOOST_UNITS_TEST_OUTPUT(1e+28 * meter_base_unit::unit_type(), "1e+028 meter"); // Just too large for multiple. + BOOST_UNITS_TEST_OUTPUT(1.5e-25 * meter_base_unit::unit_type(), "1.5e-025 meter"); // Too small for multiple. + BOOST_UNITS_TEST_OUTPUT(1.5e+28 * meter_base_unit::unit_type(), "1.5e+028 meter"); // Too large for multiple. + // Too 'biggest or too smallest'. + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::max()*meter_base_unit::unit_type(), "3.40282e+038 meter"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::min()*meter_base_unit::unit_type(), "1.17549e-038 meter"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::max()*meter_base_unit::unit_type(), "1.79769e+308 meter"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::min()*meter_base_unit::unit_type(), "2.22507e-308 meter"); + // Infinity and NaN +#if defined(_MSC_VER) + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::infinity()*meter_base_unit::unit_type(), "1.#INF meter"); + BOOST_UNITS_TEST_OUTPUT(-std::numeric_limits::infinity()*meter_base_unit::unit_type(), "-1.#INF meter"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::quiet_NaN()*meter_base_unit::unit_type(), "1.#QNAN meter"); + BOOST_UNITS_TEST_OUTPUT(-std::numeric_limits::quiet_NaN()*meter_base_unit::unit_type(), "-1.#IND meter"); +#elif defined(__GLIBCXX__) + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::infinity()*meter_base_unit::unit_type(), "inf meter"); + BOOST_UNITS_TEST_OUTPUT(-std::numeric_limits::infinity()*meter_base_unit::unit_type(), "-inf meter"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::quiet_NaN()*meter_base_unit::unit_type(), "nan meter"); + BOOST_UNITS_TEST_OUTPUT(-std::numeric_limits::quiet_NaN()*meter_base_unit::unit_type(), "nan meter"); +#else + // TODO infinity on other platforms? +#endif + BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 meter second^-1"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 kilometer"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 kilo(meter second^-1)"); + BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 millisecond"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 millisecond"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 meter millisecond^-1"); + BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 meter^2"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 kilo(meter^2)"); + BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.536 megameter"); // 1.5 * 2^10 = 1.5 * 1024 = 1.536 + BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kiloscaled_meter"); + BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 custom1"); + BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 custom2"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kilocustom1"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kilocustom2"); + BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute(), "1.5 absolute meter"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 10) * byte_base_unit::unit_type(), "1.024 kilobyte"); + + BOOST_UNITS_TEST_OUTPUT(1.5, "1.5"); // scalar. + BOOST_UNITS_TEST_OUTPUT(1567., "1567"); // scalars are *not* autoprefixed. + BOOST_UNITS_TEST_OUTPUT(0.00015, "0.00015"); // scalars are *not* autoprefixed. + BOOST_UNITS_TEST_OUTPUT(-1.5, "-1.5"); // scalar. + BOOST_UNITS_TEST_OUTPUT(-1567., "-1567"); // scalars are *not* autoprefixed. + BOOST_UNITS_TEST_OUTPUT(-0.00015, "-0.00015"); // scalars are *not* autoprefixed. +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_autoprefixed_quantity_symbol) +{ // Engineering autoprefix, with symbol format. +#define FORMATTERS << boost::units::symbol_format << boost::units::engineering_prefix + // Single base unit like m. + BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m"); + BOOST_UNITS_TEST_OUTPUT(1500.0*meter_base_unit::unit_type(), "1.5 km"); + BOOST_UNITS_TEST_OUTPUT(1.5e7*meter_base_unit::unit_type(), "15 Mm"); + BOOST_UNITS_TEST_OUTPUT(1.5e-3*meter_base_unit::unit_type(), "1.5 mm"); + BOOST_UNITS_TEST_OUTPUT(1.5e-9*meter_base_unit::unit_type(), "1.5 nm"); + BOOST_UNITS_TEST_OUTPUT(1.5e-8*meter_base_unit::unit_type(), "15 nm"); + BOOST_UNITS_TEST_OUTPUT(1.5e-10*meter_base_unit::unit_type(), "150 pm"); + // Too small or large for a multiple name. + BOOST_UNITS_TEST_OUTPUT(9.99999e-25 * meter_base_unit::unit_type(), "9.99999e-025 m"); // Just too small for multiple. + BOOST_UNITS_TEST_OUTPUT(1e+28 * meter_base_unit::unit_type(), "1e+028 m"); // Just too large for multiple. + BOOST_UNITS_TEST_OUTPUT(1.5e-25 * meter_base_unit::unit_type(), "1.5e-025 m"); // Too small for multiple. + BOOST_UNITS_TEST_OUTPUT(1.5e+28 * meter_base_unit::unit_type(), "1.5e+028 m"); // Too large for multiple. + // + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::max()*meter_base_unit::unit_type(), "3.40282e+038 m"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::min()*meter_base_unit::unit_type(), "1.17549e-038 m"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::max()*meter_base_unit::unit_type(), "1.79769e+308 m"); + BOOST_UNITS_TEST_OUTPUT(std::numeric_limits::min()*meter_base_unit::unit_type(), "2.22507e-308 m"); + + BOOST_UNITS_TEST_OUTPUT(1.5*velocity(), "1.5 m s^-1"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_length(), "1.5 km"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity1(), "1.5 k(m s^-1)"); + BOOST_UNITS_TEST_OUTPUT(1.5*millisecond_base_unit::unit_type(), "1.5 ms"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_time(), "1.5 ms"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_velocity2(), "1.5 m ms^-1"); + BOOST_UNITS_TEST_OUTPUT(1.5*area(), "1.5 m^2"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_area(), "1.5 k(m^2)"); + BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length(), "1.536 Mm"); // 1.5 * 2^10 = 1.5 * 1024 = 1.536 + BOOST_UNITS_TEST_OUTPUT(1.5*double_scaled_length2(), "1.5 kscm"); + BOOST_UNITS_TEST_OUTPUT(1.5*custom1(), "1.5 c1"); + BOOST_UNITS_TEST_OUTPUT(1.5*custom2(), "1.5 c2"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom1(), "1.5 kc1"); + BOOST_UNITS_TEST_OUTPUT(1.5*scaled_custom2(), "1.5 kc2"); + BOOST_UNITS_TEST_OUTPUT(1.5*boost::units::absolute(), "1.5 absolute m"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 10) * byte_base_unit::unit_type(), "1.024 kb"); + +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol) +{ // Binary prefix with symbol format. +#define FORMATTERS << boost::units::symbol_format << boost::units::binary_prefix + BOOST_UNITS_TEST_OUTPUT(1024 * byte_base_unit::unit_type(), "1 Kib"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 20) * byte_base_unit::unit_type(), "1 Mib"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 30) * byte_base_unit::unit_type(), "1 Gib"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 40) * byte_base_unit::unit_type(), "1 Tib"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 50) * byte_base_unit::unit_type(), "1 Pib"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 60) * byte_base_unit::unit_type(), "1 Eib"); + BOOST_UNITS_TEST_OUTPUT(42, "42"); // integer scalar. + BOOST_UNITS_TEST_OUTPUT(-42, "-42"); // integer scalar. + BOOST_UNITS_TEST_OUTPUT(1567, "1567"); // scalars are *not* autoprefixed. + BOOST_UNITS_TEST_OUTPUT(-1567, "-1567"); // scalars are *not* autoprefixed. +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name) +{ // Binary prefix with name format. + // http://physics.nist.gov/cuu/Units/binary.html + // 1998 the International Electrotechnical Commission (IEC) approved + // IEC 60027-2, Second edition, 2000-11, Letter symbols to be used in electrical technology + // - Part 2: Telecommunications and electronics. +#define FORMATTERS << boost::units::name_format << boost::units::binary_prefix + BOOST_UNITS_TEST_OUTPUT(2048 * byte_base_unit::unit_type(), "2 kibibyte"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 32) *byte_base_unit::unit_type(), "4 gibibyte"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 41) *byte_base_unit::unit_type(), "2 tebibyte"); // http://en.wikipedia.org/wiki/Tebibyte + BOOST_UNITS_TEST_OUTPUT(pow(2., 50) *byte_base_unit::unit_type(), "1 pebibyte"); + BOOST_UNITS_TEST_OUTPUT(pow(2., 60) *byte_base_unit::unit_type(), "1 exbibyte"); + BOOST_UNITS_TEST_OUTPUT(2048, "2048"); // scalars are *not* autoprefixed. + BOOST_UNITS_TEST_OUTPUT(-4096, "-4096"); // scalars are *not* autoprefixed. +#undef FORMATTERS +} + +// Tests on using more than one format or prefix - only the last specified should be used. +// (This may indicate a programming mistake, but it is ignored). +BOOST_AUTO_TEST_CASE(test_output_quantity_name_duplicate) +{ // Ensure that if more than one format specified, only the last is used. +#define FORMATTERS << boost::units::symbol_format << boost::units::name_format + BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 meter"); +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_quantity_symbol_duplicate) +{ // Ensure that if more than one format specified, only the last is used. +#define FORMATTERS << boost::units::name_format << boost::units::symbol_format + BOOST_UNITS_TEST_OUTPUT(1.5*meter_base_unit::unit_type(), "1.5 m"); +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_name_duplicate) +{ // Ensure that if more than one auto prefix specified, only the last is used. +#define FORMATTERS << boost::units::name_format << boost::units::binary_prefix << boost::units::engineering_prefix + BOOST_UNITS_TEST_OUTPUT(2048 * byte_base_unit::unit_type(), "2.048 kilobyte"); +#undef FORMATTERS +} + +BOOST_AUTO_TEST_CASE(test_output_auto_binary_prefixed_quantity_symbol_duplicate) +{ // Ensure that if more than one auto prefix specified, only the last is used. +#define FORMATTERS << boost::units::symbol_format << boost::units::engineering_prefix << boost::units::binary_prefix + BOOST_UNITS_TEST_OUTPUT(2048 * byte_base_unit::unit_type(), "2 Kib"); +#undef FORMATTERS +} diff --git a/test/test_predicates.cpp b/test/test_predicates.cpp index 8033acf..d05c4ea 100644 --- a/test/test_predicates.cpp +++ b/test/test_predicates.cpp @@ -13,7 +13,7 @@ \brief test_predicates.cpp -\detailed +\details Test metafunctions is_unit, is_quantity, is_dimension_list .... Output: diff --git a/test/test_quantity.cpp b/test/test_quantity.cpp index 512b6a0..28eee7c 100644 --- a/test/test_quantity.cpp +++ b/test/test_quantity.cpp @@ -13,7 +13,7 @@ \brief test_units_1.cpp -\detailed +\details Test unit class. Output: diff --git a/test/test_reduce_unit.cpp b/test/test_reduce_unit.cpp index eb382b0..c9daed0 100644 --- a/test/test_reduce_unit.cpp +++ b/test/test_reduce_unit.cpp @@ -13,7 +13,7 @@ \brief test_reduce_unit.cpp -\detailed +\details Test that reduce_unit works correctly by itself to try to isolate problems. Output: diff --git a/test/test_scaled_conversion.cpp b/test/test_scaled_conversion.cpp index a13463a..b8e2088 100644 --- a/test/test_scaled_conversion.cpp +++ b/test/test_scaled_conversion.cpp @@ -13,7 +13,7 @@ \brief test_scaled_conversion.cpp -\detailed +\details Test unit scaling Output: diff --git a/test/test_scaled_unit.cpp b/test/test_scaled_unit.cpp index ad79f75..89cd818 100644 --- a/test/test_scaled_unit.cpp +++ b/test/test_scaled_unit.cpp @@ -13,7 +13,7 @@ \brief test_scaled_conversion.cpp -\detailed +\details Test unit scaling Output: diff --git a/test/test_trig.cpp b/test/test_trig.cpp index 164d794..5ae16da 100644 --- a/test/test_trig.cpp +++ b/test/test_trig.cpp @@ -12,7 +12,7 @@ \brief test_trig.cpp -\detailed +\details Test trigonometric functions. Output: @@ -35,6 +35,7 @@ using boost::units::si::si_dimensionless; using boost::units::degree::degrees; BOOST_UNITS_STATIC_CONSTANT(degree_dimensionless, boost::units::degree::dimensionless); using boost::units::si::meters; +BOOST_UNITS_STATIC_CONSTANT(heterogeneous_dimensionless, boost::units::reduce_unit::type); BOOST_AUTO_TEST_CASE(test_sin) { BOOST_CHECK_EQUAL(boost::units::sin(2.0 * radians), std::sin(2.0) * si_dimensionless); @@ -54,20 +55,24 @@ BOOST_AUTO_TEST_CASE(test_tan) { BOOST_AUTO_TEST_CASE(test_asin) { BOOST_CHECK_EQUAL(boost::units::asin(0.2 * si_dimensionless), std::asin(0.2) * radians); BOOST_CHECK_CLOSE_FRACTION(boost::units::asin(0.5 * degree_dimensionless).value(), 30.0, 0.0001); + BOOST_CHECK_EQUAL(boost::units::asin(0.2 * heterogeneous_dimensionless).value(), std::asin(0.2)); } BOOST_AUTO_TEST_CASE(test_acos) { BOOST_CHECK_EQUAL(boost::units::acos(0.2 * si_dimensionless), std::acos(0.2) * radians); BOOST_CHECK_CLOSE_FRACTION(boost::units::acos(0.5 * degree_dimensionless).value(), 60.0, 0.0001); + BOOST_CHECK_EQUAL(boost::units::acos(0.2 * heterogeneous_dimensionless).value(), std::acos(0.2)); } BOOST_AUTO_TEST_CASE(test_atan) { BOOST_CHECK_EQUAL(boost::units::atan(0.2 * si_dimensionless), std::atan(0.2) * radians); BOOST_CHECK_CLOSE_FRACTION(boost::units::atan(1.0 * degree_dimensionless).value(), 45.0, 0.0001); + BOOST_CHECK_EQUAL(boost::units::atan(0.2 * heterogeneous_dimensionless).value(), std::atan(0.2)); } BOOST_AUTO_TEST_CASE(test_atan2) { BOOST_CHECK_EQUAL(boost::units::atan2(0.2 * si_dimensionless, 0.3 * si_dimensionless), std::atan2(0.2, 0.3) * radians); BOOST_CHECK_EQUAL(boost::units::atan2(0.2 * meters, 0.3 * meters), std::atan2(0.2, 0.3) * radians); BOOST_CHECK_CLOSE_FRACTION(boost::units::atan2(0.8660*degree_dimensionless,0.5*degree_dimensionless).value(), 60., 0.0002); + BOOST_CHECK_EQUAL(boost::units::atan2(0.2 * heterogeneous_dimensionless, 0.3 * heterogeneous_dimensionless).value(), std::atan2(0.2, 0.3)); } diff --git a/test/test_unit.cpp b/test/test_unit.cpp index ee3f334..49748c5 100644 --- a/test/test_unit.cpp +++ b/test/test_unit.cpp @@ -13,7 +13,7 @@ \brief test_units_1.cpp -\detailed +\details Test unit class. Output: diff --git a/test/test_unscale.cpp b/test/test_unscale.cpp index 7d41423..d81a144 100644 --- a/test/test_unscale.cpp +++ b/test/test_unscale.cpp @@ -1,4 +1,4 @@ -// Boost.Units - A C++ library for zero-overhead dimensional analysis and +// Boost.Units - A C++ library for zero-overhead dimensional analysis and // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel @@ -13,7 +13,7 @@ \brief test_unscale.cpp -\detailed +\details Test that unscale works in an attempt to isolate the sun problems. Output: