Home

Awesome

PhysUnits-CT

A C++ library for compile-time dimensional analysis and unit/quantity manipulation and conversion.

This library is based on the quantity compile-time library by Michael S. Kenniston[1] and expanded and adapted to compile with current compilers by Martin Moene.

This easy to use header-only library is intended to work with a wide range of compilers, including MSVC 6.

Example

#include "phys/units/quantity.hpp"

using namespace phys::units;

int main()
{
    quantity<speed_d> speed = 45 * kilo() * meter() / second();
}

Other libraries

Usage

Definition of terms

Adapted from Boost.Units:

Limitations

This library only supports the use of the <em>SI unit system</em>.

This library only supports <em>integral powers</em> of the dimensions.

The <em>representation or value type</em> in the implementation of quantity is fixed and cannot be defined separately for each quantity. However you can change the type for all uses within a translation unit by defining PHYS_UNITS_REP_TYPE before inclusion of header quantity.hpp. Default this type is double.

Output

The following example shows the quantity type in the computation of work from force and distance and the printing of the result on standard output.

#include <iostream>

#include "phys/units/io.hpp"
#include "phys/units/quantity.hpp"

using namespace phys::units;
using namespace phys::units::io;

quantity<energy_d>
work( const quantity<force_d> & F, const quantity<length_d> & dx )
{
    return F * dx; // Defines the relation: work = force * distance.
}

int main()
{
    /// Test calculation of work.
    quantity<force_d>       F ( 2.0 * newton());  // Define a quantity of force.
    quantity<length_d>      dx( 2.0 * meter() );  // and a distance,
    quantity<energy_d>      E ( work( F, dx ) );  // and calculate the work done.

    std::cout << "F  = " << F  << std::endl
              << "dx = " << dx << std::endl
              << "E  = " << E  << std::endl;
}

The output produced is:

F  = 2 N
dx = 2 m
E  = 4 J

The following example demonstrates printing in default floating point notation and in engineering notation, using metric prefixes.

#include <iostream>

#include "phys/units/io.hpp"
#include "phys/units/quantity.hpp"

using namespace phys::units;

int main()
{
    quantity<electric_resistance_d> R( 4.7 * kilo() * volt() / ampere() );

    {
        using namespace phys::units::io;
        std::cout << "R = " << R << std::endl;
    }
    {
        using namespace phys::units::io::eng;
        std::cout << "R = " << R << std::endl;
    }
}

The output produced is:

R = 4700 Ohm
R = 4.7 kOhm

See namespaces io and io::eng for further information.

Instead of unit names such as J, you can also obtain the unit expressed in base dimensions.

#include <iostream>

#include "phys/units/quantity.hpp"
#include "phys/units/quantity_io.hpp"

using namespace phys::units;
using namespace phys::units::io;

int main()
{
    std::cout << "J = " << joule() << std::endl;
}

The output produced is:

J = m+2 kg s-2

Convenience functions

There are several convenience functions, such as:

In namespace io:

In namespace io::eng:

Error handling

Error handling with respect to mixing incompatible dimensions occurs at compile-time.

Mixing run-time and compile-time libraries

Although this library seems to be in the phys::units namespace, it does so through using the ct namespace in the global namespace. So this library actually lives in the ct::phys::units namespace. When you want to mix this library with its compile-time companion, the ct namespace must be applied. This can be accomplished by defining PHYS_UNITS_IN_CT_NAMESPACE.

Dependencies

This library has no dependencies other than the standard C++ libraries.

Performance

TBD

Relative running time (lower is better)

Compiler        Option : double : quantity
-----------------------+--------+-------------
GCC 4.6.2         -O2  :  1     :  . (1)
MS VC6/VS6        -O2  :  .     :  . (1.x)
MS VC8/VS2005     -O2  :  .     :  . (1.x)
MS VC2010/VS2010  -O2  :  .     :  . (1.x)

Measured on a AMD Athlon 64 X2 Dual Core Processor 5600+, 64kB L1 Data, 64kB L1 Instruction, 512kB L2, 3.2 GB RAM

Compilers known to work

Ideas for improvement

Allow to specify a conversion offset between two units, e.g. to make conversion between 'C and K possible (see Boost.Units).

It may be nice if you can obtain a quantity in a unit representation of your choice, e.g. in kWh in stead of J [m+2 kg s-2]. See G.S. Novak. Conversion of units of measurement (PDF)". 1 August 1997.

References

[1] Michael Kenniston. The Quantity Library. (Rationale, Quantity folder). 16 July 2001, rev 0.4.

[2] Ambler Thompson and Barry N. Taylor. Guide for the Use of the International System of Units (SI). NIST Special Publication 811 2008 Edition.

[3] David B. Newell and Eite Tiesinga, Editors. The International System of Units (SI). NIST Special Publication 330 2019 Edition.