https://github.com/martinmoene/physunits-ct-cpp11
A small C++11, C++14 header-only library for compile-time dimensional analysis and unit/quantity manipulation and conversion
https://github.com/martinmoene/physunits-ct-cpp11
compile-time cpp11 cpp14 dimensional-analysis header-only no-dependencies single-file unit-conversion units-of-measure
Last synced: about 1 month ago
JSON representation
A small C++11, C++14 header-only library for compile-time dimensional analysis and unit/quantity manipulation and conversion
- Host: GitHub
- URL: https://github.com/martinmoene/physunits-ct-cpp11
- Owner: martinmoene
- License: bsl-1.0
- Created: 2013-09-07T11:13:08.000Z (about 12 years ago)
- Default Branch: master
- Last Pushed: 2023-02-09T11:52:17.000Z (over 2 years ago)
- Last Synced: 2025-07-03T07:54:35.032Z (3 months ago)
- Topics: compile-time, cpp11, cpp14, dimensional-analysis, header-only, no-dependencies, single-file, unit-conversion, units-of-measure
- Language: C++
- Homepage:
- Size: 145 KB
- Stars: 81
- Watchers: 9
- Forks: 16
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE_1_0.txt
Awesome Lists containing this project
README
PhysUnits C++11 (compile-time)
==============================[](https://isocpp.org/) [](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [](https://opensource.org/licenses/BSL-1.0) [](https://travis-ci.org/martinmoene/PhysUnits-CT-Cpp11/branches) [](https://github.com/martinmoene/PhysUnits-CT-Cpp11/releases) [](https://github.com/martinmoene/PhysUnits-CT-Cpp11/archive/master.zip) [](https://docs.hunter.sh/en/latest/packages/pkg/PhysUnits.html)
A small C++11 header-only 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 for C++11 by Martin Moene.
**Contents**
- [Hello quantity](#hello-quantity)
- [Other libraries](#other-libraries)
- [Dependencies](#dependencies)
- [Limitations](#limitations)
- [Error handling](#error-handling)
- [Definition of terms](#definition-of-terms)
- [Dimensions, units and literals](#dimensions-units-and-literals)
- [Include files](#include-files)
- [Configuration](#configuration)
- [Types and declarations](#types-and-declarations)
- [Operations and expressions](#operations-and-expressions)
- [Convenience functions](#convenience-functions)
- [Output variations](#output-variations)
- [Reported to work with](#reported-to-work-with)
- [Performance](#performance)
- [Ideas for improvement](#ideas-for-improvement)
- [References](#references)Hello quantity
--------------```C++
#include "phys/units/quantity.hpp"using namespace phys::units;
using namespace phys::units::literals;int main()
{
quantity speed = 45_km / hour;
}
```Other libraries
---------------- Search GitHub for [unit dimension language:C++](https://github.com/search?utf8=%E2%9C%93&q=unit+dimension+language%3AC%2B%2B&type=Repositories).
- [PhysUnits-CT](https://github.com/martinmoene/PhysUnits-CT) - C++98 companion of this library.
- [PhysUnits-RT](https://github.com/martinmoene/PhysUnits-RT) - C++98 Run-time companion of this library.
- [Au](https://github.com/aurora-opensource/au) - A C++14-compatible physical units library with no dependencies and a single-file delivery option. Emphasis on safety, accessibility, performance, and developer experience. Aurora Open Source.
- [Boost.Units](http://www.boost.org/doc/libs/1_51_0/libs/units/) - Zero-overhead dimensional analysis and unit/quantity manipulation and conversion in C++.
- [SI](https://github.com/bernedom/SI) - A header only C++ library that provides type safety and user defined literal. Dominik Berner.
- [PQS](https://github.com/kwikius/pqs) - A C++ library for modelling physical quantities. kwikius.
- [quan](https://github.com/kwikius/quan-trunk) - C++ library for physical quantities and much more. kwikius.
- [Quantities](http://www.echem.uni-tuebingen.de/index.shtml/Quantities/quantities.html) - C++ objects with dimensionality and units attached in a way similar to the built-in types float or double. Universität Tübingen.
- [unlib](https://github.com/gitsbi/unlib) - A light-weight, header-only, dependency-free, C++14 library for ISO units. sbi.
- [units](https://github.com/mpusz/units) - A Physical Units Library for C++ providing compile-time dimensional analysis and unit/quantity manipulation. Mateusz Pusz.
- [units](https://github.com/nholthaus/units) - A compile-time, header-only, dimensional analysis and unit conversion library built on C++14 with no dependencies. Nic Holthaus.
- [units](https://github.com/tonypilz/units) - A lightweight compile-time, header-only, dimensional analysis and unit conversion library built on C++11 with no dependencies. Tony Pilz.
- [units](https://github.com/legento/units) - C++ compile time dimensional analysis. Oliver Esser.
- [Units](https://github.com/VincentDucharme/Units) - C++ Library for managing values with units. Vincent Ducharme.
- [DimensionalAnalysis
](https://github.com/njoy/DimensionalAnalysis) - A compact C++ header-only library providing compile-time dimensional analysis and unit awareness. Austin McCartney.
- [units_literals
](https://github.com/acecil/units_literals) - User defined literals for Boost.Units.
- [unitscpp](http://code.google.com/p/unitscpp/) - A lightweight C++ library for physical calculation with units.
- Python packages [Numericalunits](http://pypi.python.org/pypi/numericalunits), [Pint](http://pypi.python.org/pypi/Pint) and [Units](http://pypi.python.org/pypi/units), mentioned in [4].Dependencies
--------------This library has no dependencies other than the standard C++ library.
Limitations
-----------This library only supports the use of the SI unit system.
This library only supports integral powers of the dimensions.
Error handling
--------------Error handling with respect to mixing incompatible dimensions occurs at compile-time.
Definition of terms
-------------------Adapted from Boost.Units:
- Base dimension: A base dimension is loosely defined as a measurable entity of interest; in conventional dimensional analysis, base dimensions include length ([L]), mass ([M]), time ([T]), etc.. 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, 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. 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, amount ([N]) in moles, and luminous intensity ([J]) in candelas. All measurable entities within the SI system can be represented as products of various integer or rational powers of these seven base units.
- Quantity: A quantity represents a concrete amount of a unit. Thus, while the meter is the base unit of length in the SI system, 5.5 meters is a quantity of length in that system.Dimensions, units and literals
------------------------------The seven fundamental SI [2] *dimensions* are length, mass, time interval, electric current, thermodynamic temperature, quantity of substance and luminous intensity. The base *units* are meter (m), kilogram (kg), second (s), ampere (A), mole (mol) and candela (cd).
The library defines dimensions such as `length_d` and `mass_d` and it defines quantities that represent their units as `meter` and `kilogram`. The library also defines [user-defined literal suffixes](https://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals) with prefixes ranging from yocto (1e-24L) through yotta (1e+24). Thus you can write quantity literals such as `1_ns` and ` 42.195_km`.
To use literals of non-base units, include the file `io.hpp` or `io_symbols.hpp`, or one or more of the following files named quantity_io_ *unit* .hpp where *unit* is becquerel, celsius, coulomb, farad, gray, henry, hertz, joule, lumen, lux, newton, ohm, pascal, radian, siemens, sievert, speed, steradian, tesla, volt, watt, weber.
Include files
-------------- io.hpp - include all io-related include files.
- io_output.hpp - provide basic stream output in base dimensions.
- io_output_eng.hpp - provide stream output in [engineering notation](http://en.wikipedia.org/wiki/Engineering_notation), using [metric prefixes](http://en.wikipedia.org/wiki/Metric_prefix).
- io_symbols.hpp - include all files quantity_io_ *unit* .hpp
- other_units.hpp - units that are *not* approved for use with SI.
- physical_constants.hpp - Planck constant, speed of light etc.
- quantity.hpp - quantity, SI dimensions and units, base unit literals.
- quantity_io_ *unit* .hpp - name, symbol and literals for *unit*.Configuration
--------------DPHYS_UNITS_REP_TYPE=double
Define this to the representation or value type for the magnitude of quantity. Default is `double`.
You can change the type for all uses within a translation unit by defining `PHYS_UNITS_REP_TYPE` before inclusion of header quantity.hpp.-DPHYS_UNITS_COLLAPSE_TO_REP=1
The library can collapse dimensionless results to the representation type or continue with type `quantity`. Define `PHYS_UNITS_COLLAPSE_TO_REP` to 0 to allow dimensionless quantities. Default is 1.Types and declarations
----------------------```C++
#include "phys/units/quantity.hpp"using namespace phys::units;
quantity q_rep; // magnitude has type Rep (PHYS_UNITS_REP_TYPE)
quantity q_float; // magnitude has type float
```The default representation or value type `Rep` for the magnitude of quantity is `double`. You can change the type for all uses within a translation unit by defining `PHYS_UNITS_REP_TYPE` before inclusion of header quantity.hpp.
Operations and expressions
--------------------------- `N` is an integer constant
- `num` is an int, long, float, double, etc.
- `quantity1` and `quantity2` have different dimensions
- quantities with different magnitude types can be mixed|Operation |Operand Type(s) |Result Type |
|--------------|---------------------------|------------|
|Construction |`quantity()` |`quantity` |
| |`quantity( quantity )` |`quantity` |
|Assignment |`quantity = quantity` |`quantity &`|
|Addition & |`quantity += quantity` |`quantity &`|
| Subtraction |`quantity -= quantity` |`quantity &`|
| |`+quantity` |`quantity` |
| |`-quantity` |`quantity` |
| |`quantity + quantity` |`quantity` |
| |`quantity - quantity` |`quantity` |
|Multiplication|`quantity *= num` |`quantity &`|
| |`quantity * num` |`quantity` |
| |`num * quantity` |`quantity` |
| |`quantity1 * quantity1` |`quantity2` |
| |`quantity1 * quantity2` |`num` or `quantity3` |
|Division |`quantity /= num` |`quantity &`|
| |`quantity / num` |`quantity` |
| |`num / quantity1` |`quantity2` |
| |`quantity / quantity` |`num` |
| |`quantity1 / quantity2` |`quantity3` |
|Powers |`nth_power( quantity1 )`|`num` if N=0, `quantity1` if N=1, `quantity2` otherwise|
| |`square( quantity1 )` |`quantity2` |
| |`cube( quantity1 )` |`quantity2` |
|Roots |`nth_root( quantity1 )` |`quantity2`, iff dimensions of quantity1 are all even multiples of N|
| |`sqrt( quantity1 )` |`quantity2`, iff dimensions of quantity1 are all even multiples of 2|
|Conversion |`quantity1.to( quantity2 )`|`num` or `quantity3` (quantity1/quantity2)|
|Zero |`quantity.zero()` |`quantity` with magnitude 0|Convenience functions
---------------------The following convenience functions are provided.
In namespace `phys::units`:
- `DX dimension( quantity const & q )` - the quantity's dimension.
- `X magnitude( quantity<..., X> const & q )` - the quantity's magnitude.
- `std::string to_magnitude( quantity<...> const & q )` - the quantity's magnitude represented as string.
- `std::string to_unit_name( quantity<...> const & q )` - the quantity's unit name, e.g. 'hertz'.
- `std::string to_unit_symbol( quantity<...> const & q )` - the quantity's unit symbol, e.g. 'Hz'.
- `std::string to_string( long double const value )` - the value of a long double represented as string.In namespace `phys::units::io`:
- `std::string to_string( quantity<...> const & q )` - the quantity represented as string in scientific notation.
- `std::ostream & operator<<( std::ostream & os, quantity<...> const & q )` - output the quantity to a stream in scientific notation.In namespace `phys::units::io::eng`:
- `std::string to_string( quantity<...> const & q )` - the quantity represented as string in engineering notation.
- `std::ostream & operator<<( std::ostream & os, quantity<...> const & q )` - output the quantity to a stream in engineering notation.Output variations
-----------------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.
```C++
#include#include "phys/units/io.hpp"
#include "phys/units/quantity.hpp"using namespace phys::units;
using namespace phys::units::io;
using namespace phys::units::literals;quantity
work( const quantity & F, const quantity & dx )
{
return F * dx; // Defines the relation: work = force * distance.
}int main()
{
// Test calculation of work.
quantity F { 2_N }; // Define a quantity of force.
quantity dx{ 2_m }; // 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;
}
```The output produced is:
```Text
F = 2 N
dx = 2 m
E = 4 J
```The following example demonstrates printing in default floating point notation and in [engineering notation](http://en.wikipedia.org/wiki/Engineering_notation), using [metric prefixes](http://en.wikipedia.org/wiki/Metric_prefix).
```C++
#include#include "phys/units/io.hpp"
#include "phys/units/quantity.hpp"using namespace phys::units;
using namespace phys::units::literals;int main()
{
quantity R{ 4.7_kV / 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:
```Text
R = 4700 Ohm
R = 4.70 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.
```C++
#include#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:
```Text
J = m+2 kg s-2
```To get the presentation in base dimensions, you should not include `quantity_io_joule`, `io_symbols.hpp` or `io.hpp`.
Reported to work with
---------------------- GCC 4.8.1
- Clang 3.2Performance
-------------```Text
Relative running time (lower is better)Compiler Option : double : quantity
-----------------------+--------+-------------
GCC 4.8.1 -O0 : 1 : 7
GCC 4.8.1 -O2 : 1 : 1
Clang 3.2 -O0 : . : .
Clang 3.2 -O2 : . : .Measured on a AMD Athlon 64 X2 Dual Core Processor 5600+, 64kB L1 Data, 64kB L1 Instruction, 512kB L2, 3.2 GB RAM
```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).
References
----------[1] Michael Kenniston. [The Quantity Library](http://home.xnet.com/~msk/quantity/quantity.html). ([Rationale](http://home.xnet.com/%7Emsk/quantity/quantity.html), Quantity [folder](http://www.xnet.com/%7Emsk/quantity)). 16 July 2001, rev 0.4.
[2] Ambler Thompson and Barry N. Taylor. [Guide for the Use of the International System of Units (SI)](http://physics.nist.gov/cuu/pdf/sp811.pdf). NIST Special Publication 811 2008 Edition.
[3] David B. Newell and Eite Tiesinga, Editors. [The International System of Units (SI)](https://doi.org/10.6028/NIST.SP.330-2019). NIST Special Publication 330 2019 Edition.
[4] Gaston Hillar. [Quantities and Units in Python](http://www.drdobbs.com/jvm/quantities-and-units-in-python/240161101). Dr. Dobb's. 10 September 2013.