forked from mpusz/mp-units
coherent_derived_unit and custom prefixes support added
This commit is contained in:
@@ -63,6 +63,8 @@ NOTE: This library as of now compiles correctly only with gcc-9.1 and newer.
|
|||||||
- Downcasting facility refactored so the user does not have to write the boilerplate code anymore
|
- Downcasting facility refactored so the user does not have to write the boilerplate code anymore
|
||||||
- From now on base dimensions should inherit from `base_dimension` class template
|
- From now on base dimensions should inherit from `base_dimension` class template
|
||||||
- Added unit symbols definitions to `base_dimension` and `derived_unit`
|
- Added unit symbols definitions to `base_dimension` and `derived_unit`
|
||||||
|
- Added `coherent_derived_unit` helper
|
||||||
|
- Added support for `operator<<` on `quantity`
|
||||||
|
|
||||||
- 0.3.1 Sep 18, 2019
|
- 0.3.1 Sep 18, 2019
|
||||||
- cmcstl2 dependency changed to range-v3 0.9.1
|
- cmcstl2 dependency changed to range-v3 0.9.1
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
# `mp-units` - A Units Library for C++
|
# `mp-units` - A Units Library for C++
|
||||||
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
`Units` is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
`Units` is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
||||||
@@ -71,6 +72,7 @@ constexpr units::Velocity auto avg_speed(units::Length auto d, units::Time auto
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Basic Concepts
|
## Basic Concepts
|
||||||
|
|
||||||
Below UML diagram shows the most important entities in the library design and how they relate to
|
Below UML diagram shows the most important entities in the library design and how they relate to
|
||||||
@@ -256,35 +258,35 @@ struct unit : downcast_base<unit<D, R>> {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
All units are created with a `derived_unit` helper:
|
Coherent derived units (units with `ratio<1>`) are created with a `coherent_derived_unit` helper:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<typename Child, fixed_string Symbol, Dimension D, typename Prefix = no_prefix>
|
||||||
|
struct coherent_derived_unit;
|
||||||
|
```
|
||||||
|
|
||||||
|
The above type exposes public `symbol` and `prefix` member types used to print unit symbol names.
|
||||||
|
|
||||||
|
For example to define the base unit of `length`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct metre : coherent_derived_unit<metre, "m", length, si_prefix> {};
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, similarly to `derived_dimension`, the first class template parameter is a CRTP idiom used
|
||||||
|
to provide downcasting facility (described below).
|
||||||
|
|
||||||
|
All other units are created with a `derived_unit` helper:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename Child, fixed_string Symbol, typename...>
|
template<typename Child, fixed_string Symbol, typename...>
|
||||||
struct derived_unit;
|
struct derived_unit;
|
||||||
```
|
```
|
||||||
|
|
||||||
For example to define the base unit of `length`:
|
The above type exposes public `symbol` member type used to print unit symbol names.
|
||||||
|
|
||||||
```cpp
|
`derived_unit` has a few useful partial specializations:
|
||||||
struct metre : derived_unit<metre, "m", length> {};
|
- helper to create non-coherent units for a specified dimension
|
||||||
```
|
|
||||||
|
|
||||||
Again, similarly to `derived_dimension`, the first class template parameter is a CRTP idiom used
|
|
||||||
to provide downcasting facility (described below).
|
|
||||||
|
|
||||||
`derived_unit` has a few partial useful specializations:
|
|
||||||
- helper to create a base unit of a specified dimension
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
template<typename Child, fixed_string Symbol, Dimension D>
|
|
||||||
struct derived_unit<Child, Symbol, D>;
|
|
||||||
```
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
struct metre : derived_unit<metre, "m", length> {};
|
|
||||||
```
|
|
||||||
|
|
||||||
- helper to create other units for a specified dimension
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename Child, fixed_string Symbol, Dimension D, Ratio R>
|
template<typename Child, fixed_string Symbol, Dimension D, Ratio R>
|
||||||
@@ -295,7 +297,7 @@ struct derived_unit<Child, Symbol, D, R>;
|
|||||||
struct yard : derived_unit<yard, "yd", length, ratio<9'144, 10'000>> {};
|
struct yard : derived_unit<yard, "yd", length, ratio<9'144, 10'000>> {};
|
||||||
```
|
```
|
||||||
|
|
||||||
- helper to create a unit with a SI prefix
|
- helper to create a named unit with a SI prefix
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename Child, fixed_string Symbol, Unit U>
|
template<typename Child, fixed_string Symbol, Unit U>
|
||||||
@@ -428,6 +430,22 @@ template<Scalar ToRep, typename U, typename Rep>
|
|||||||
[[nodiscard]] constexpr quantity<U, ToRep> quantity_cast(const quantity<U, Rep>& q);
|
[[nodiscard]] constexpr quantity<U, ToRep> quantity_cast(const quantity<U, Rep>& q);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `operator<<`
|
||||||
|
|
||||||
|
The library tries its best to print a correct unit of the quantity. This is why it performs a series
|
||||||
|
of checks:
|
||||||
|
1. If the user predefined a unit with a `coherent_derived_unit` or `derived_unit` class templates,
|
||||||
|
the symbol provided by the user will be used (i.e. `60 W`).
|
||||||
|
2. If a quantity has an unknown unit for a dimension predefined by the user with `derived_dimension`,
|
||||||
|
the symbol of a coherent unit of this dimension will be used. Additionally:
|
||||||
|
- if `Prefix` template parameter of a `coherent_derived_unit` is different than `no_prefix` then
|
||||||
|
the prefix symbol (i.e. `8 cJ`) defined by the specialization of `units::prefix_symbol` will be
|
||||||
|
aded wherever possible (`Ratio` matches the prefix ratio),
|
||||||
|
- otherwise, non-standard ratio (i.e. `2 [60]Hz`) will be printed.
|
||||||
|
3. If a quantity has an unknown dimension, the symbols of base dimensions will be used to construct
|
||||||
|
a unit symbol (i.e. `2 m/kg^2`). In this case no prefix symbols are added.
|
||||||
|
|
||||||
|
|
||||||
## Strong types instead of aliases, and type downcasting facility
|
## Strong types instead of aliases, and type downcasting facility
|
||||||
|
|
||||||
Most of the important design decisions in the library are dictated by the requirement of providing
|
Most of the important design decisions in the library are dictated by the requirement of providing
|
||||||
@@ -658,14 +676,24 @@ In order to extend the library with custom dimensions the user has to:
|
|||||||
concept DigitalInformation = units::QuantityOf<T, digital_information>;
|
concept DigitalInformation = units::QuantityOf<T, digital_information>;
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Define units and register them to a downcasting facility:
|
4. If non-SI prefixes should be applied to the unit symbol, define a new prefix tag and provide
|
||||||
|
`prefix_symbol` specializations to provide their text representation:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct bit : units::derived_unit<bit, "b", digital_information> {};
|
struct data_prefix;
|
||||||
|
|
||||||
|
template<> inline constexpr std::string_view units::prefix_symbol<data_prefix, units::ratio< 1'024>> = "Ki";
|
||||||
|
template<> inline constexpr std::string_view units::prefix_symbol<data_prefix, units::ratio<1'048'576>> = "Mi";
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Define units and register them to a downcasting facility:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct bit : units::coherent_derived_unit<bit, "b", digital_information, data_prefix> {};
|
||||||
struct byte : units::derived_unit<byte, "B", digital_information, units::ratio<8>> {};
|
struct byte : units::derived_unit<byte, "B", digital_information, units::ratio<8>> {};
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Provide user-defined literals for the most important units:
|
6. Provide user-defined literals for the most important units:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
@@ -31,7 +31,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Acceleration = QuantityOf<T, acceleration>;
|
concept Acceleration = QuantityOf<T, acceleration>;
|
||||||
|
|
||||||
struct metre_per_second_sq : derived_unit<metre_per_second_sq, decltype("m/s^2"_fs), acceleration, metre, second> {};
|
struct metre_per_second_sq : coherent_derived_unit<metre_per_second_sq, decltype("m/s^2"_fs), acceleration> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -31,14 +31,18 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Area = QuantityOf<T, area>;
|
concept Area = QuantityOf<T, area>;
|
||||||
|
|
||||||
|
struct square_metre : coherent_derived_unit<square_metre, decltype("m^2"_fs), area> {};
|
||||||
struct square_millimetre : derived_unit<square_millimetre, decltype("mm^2"_fs), area, millimetre> {};
|
struct square_millimetre : derived_unit<square_millimetre, decltype("mm^2"_fs), area, millimetre> {};
|
||||||
struct square_centimetre : derived_unit<square_centimetre, decltype("cm^2"_fs), area, centimetre> {};
|
struct square_centimetre : derived_unit<square_centimetre, decltype("cm^2"_fs), area, centimetre> {};
|
||||||
struct square_metre : derived_unit<square_metre, decltype("m^2"_fs), area, metre> {};
|
|
||||||
struct square_kilometre : derived_unit<square_kilometre, decltype("km^2"_fs), area, kilometre> {};
|
struct square_kilometre : derived_unit<square_kilometre, decltype("km^2"_fs), area, kilometre> {};
|
||||||
struct square_foot : derived_unit<square_foot, decltype("ft^2"_fs), area, foot> {};
|
struct square_foot : derived_unit<square_foot, decltype("ft^2"_fs), area, foot> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
// sq_m
|
||||||
|
constexpr auto operator""sq_m(unsigned long long l) { return quantity<square_metre, std::int64_t>(l); }
|
||||||
|
constexpr auto operator""sq_m(long double l) { return quantity<square_metre, long double>(l); }
|
||||||
|
|
||||||
// sq_mm
|
// sq_mm
|
||||||
constexpr auto operator""sq_mm(unsigned long long l) { return quantity<square_millimetre, std::int64_t>(l); }
|
constexpr auto operator""sq_mm(unsigned long long l) { return quantity<square_millimetre, std::int64_t>(l); }
|
||||||
constexpr auto operator""sq_mm(long double l) { return quantity<square_millimetre, long double>(l); }
|
constexpr auto operator""sq_mm(long double l) { return quantity<square_millimetre, long double>(l); }
|
||||||
@@ -47,10 +51,6 @@ namespace units {
|
|||||||
constexpr auto operator""sq_cm(unsigned long long l) { return quantity<square_centimetre, std::int64_t>(l); }
|
constexpr auto operator""sq_cm(unsigned long long l) { return quantity<square_centimetre, std::int64_t>(l); }
|
||||||
constexpr auto operator""sq_cm(long double l) { return quantity<square_centimetre, long double>(l); }
|
constexpr auto operator""sq_cm(long double l) { return quantity<square_centimetre, long double>(l); }
|
||||||
|
|
||||||
// sq_m
|
|
||||||
constexpr auto operator""sq_m(unsigned long long l) { return quantity<square_metre, std::int64_t>(l); }
|
|
||||||
constexpr auto operator""sq_m(long double l) { return quantity<square_metre, long double>(l); }
|
|
||||||
|
|
||||||
// sq_km
|
// sq_km
|
||||||
constexpr auto operator""sq_km(unsigned long long l) { return quantity<square_kilometre, std::int64_t>(l); }
|
constexpr auto operator""sq_km(unsigned long long l) { return quantity<square_kilometre, std::int64_t>(l); }
|
||||||
constexpr auto operator""sq_km(long double l) { return quantity<square_kilometre, long double>(l); }
|
constexpr auto operator""sq_km(long double l) { return quantity<square_kilometre, long double>(l); }
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Capacitance = QuantityOf<T, capacitance>;
|
concept Capacitance = QuantityOf<T, capacitance>;
|
||||||
|
|
||||||
struct farad : derived_unit<farad, decltype("F"_fs), capacitance, kilogram, metre, second, ampere> {};
|
struct farad : coherent_derived_unit<farad, decltype("F"_fs), capacitance, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Current = QuantityOf<T, current>;
|
concept Current = QuantityOf<T, current>;
|
||||||
|
|
||||||
struct ampere : derived_unit<ampere, decltype("A"_fs), current> {};
|
struct ampere : coherent_derived_unit<ampere, decltype("A"_fs), current, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept ElectricCharge = QuantityOf<T, electric_charge>;
|
concept ElectricCharge = QuantityOf<T, electric_charge>;
|
||||||
|
|
||||||
struct coulomb : derived_unit<coulomb, decltype("C"_fs), electric_charge, second, ampere> {};
|
struct coulomb : coherent_derived_unit<coulomb, decltype("C"_fs), electric_charge, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Energy = QuantityOf<T, energy>;
|
concept Energy = QuantityOf<T, energy>;
|
||||||
|
|
||||||
struct joule : derived_unit<joule, decltype("J"_fs), energy, kilogram, metre, second> {};
|
struct joule : coherent_derived_unit<joule, decltype("J"_fs), energy, si_prefix> {};
|
||||||
struct millijoule : derived_unit<millijoule, decltype("mJ"_fs), milli<joule>> {};
|
struct millijoule : derived_unit<millijoule, decltype("mJ"_fs), milli<joule>> {};
|
||||||
struct kilojoule : derived_unit<kilojoule, decltype("kJ"_fs), kilo<joule>> {};
|
struct kilojoule : derived_unit<kilojoule, decltype("kJ"_fs), kilo<joule>> {};
|
||||||
struct megajoule : derived_unit<megajoule, decltype("MJ"_fs), mega<joule>> {};
|
struct megajoule : derived_unit<megajoule, decltype("MJ"_fs), mega<joule>> {};
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Force = QuantityOf<T, force>;
|
concept Force = QuantityOf<T, force>;
|
||||||
|
|
||||||
struct newton : derived_unit<newton, decltype("N"_fs), force, kilogram, metre, second> {};
|
struct newton : coherent_derived_unit<newton, decltype("N"_fs), force, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Frequency = QuantityOf<T, frequency>;
|
concept Frequency = QuantityOf<T, frequency>;
|
||||||
|
|
||||||
struct hertz : derived_unit<hertz, decltype("Hz"_fs), frequency, second> {};
|
struct hertz : coherent_derived_unit<hertz, decltype("Hz"_fs), frequency, si_prefix> {};
|
||||||
struct millihertz : derived_unit<millihertz, decltype("mHz"_fs), milli<hertz>> {};
|
struct millihertz : derived_unit<millihertz, decltype("mHz"_fs), milli<hertz>> {};
|
||||||
struct kilohertz : derived_unit<kilohertz, decltype("kHz"_fs), kilo<hertz>> {};
|
struct kilohertz : derived_unit<kilohertz, decltype("kHz"_fs), kilo<hertz>> {};
|
||||||
struct megahertz : derived_unit<megahertz, decltype("MHz"_fs), mega<hertz>> {};
|
struct megahertz : derived_unit<megahertz, decltype("MHz"_fs), mega<hertz>> {};
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
concept Length = QuantityOf<T, length>;
|
concept Length = QuantityOf<T, length>;
|
||||||
|
|
||||||
// SI units
|
// SI units
|
||||||
struct metre : derived_unit<metre, decltype("m"_fs), length> {};
|
struct metre : coherent_derived_unit<metre, decltype("m"_fs), length, si_prefix> {};
|
||||||
struct millimetre : derived_unit<millimetre, decltype("mm"_fs), milli<metre>> {};
|
struct millimetre : derived_unit<millimetre, decltype("mm"_fs), milli<metre>> {};
|
||||||
struct centimetre : derived_unit<centimetre, decltype("cm"_fs), centi<metre>> {};
|
struct centimetre : derived_unit<centimetre, decltype("cm"_fs), centi<metre>> {};
|
||||||
struct kilometre : derived_unit<kilometre, decltype("km"_fs), kilo<metre>> {};
|
struct kilometre : derived_unit<kilometre, decltype("km"_fs), kilo<metre>> {};
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept LuminousIntensity = QuantityOf<T, luminous_intensity>;
|
concept LuminousIntensity = QuantityOf<T, luminous_intensity>;
|
||||||
|
|
||||||
struct candela : derived_unit<candela, decltype("cd"_fs), luminous_intensity> {};
|
struct candela : coherent_derived_unit<candela, decltype("cd"_fs), luminous_intensity, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Mass = QuantityOf<T, mass>;
|
concept Mass = QuantityOf<T, mass>;
|
||||||
|
|
||||||
|
struct kilogram : coherent_derived_unit<kilogram, decltype("kg"_fs), mass> {};
|
||||||
struct gram : derived_unit<gram, decltype("g"_fs), mass, ratio<1, 1000>> {};
|
struct gram : derived_unit<gram, decltype("g"_fs), mass, ratio<1, 1000>> {};
|
||||||
struct kilogram : derived_unit<kilogram, decltype("kg"_fs), kilo<gram>> {};
|
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Power = QuantityOf<T, power>;
|
concept Power = QuantityOf<T, power>;
|
||||||
|
|
||||||
struct watt : derived_unit<watt, decltype("W"_fs), power, kilogram, metre, second> {};
|
struct watt : coherent_derived_unit<watt, decltype("W"_fs), power, si_prefix> {};
|
||||||
struct milliwatt : derived_unit<milliwatt, decltype("mW"_fs), milli<watt>> {};
|
struct milliwatt : derived_unit<milliwatt, decltype("mW"_fs), milli<watt>> {};
|
||||||
struct kilowatt : derived_unit<kilowatt, decltype("kW"_fs), kilo<watt>> {};
|
struct kilowatt : derived_unit<kilowatt, decltype("kW"_fs), kilo<watt>> {};
|
||||||
struct megawatt : derived_unit<megawatt, decltype("MW"_fs), mega<watt>> {};
|
struct megawatt : derived_unit<megawatt, decltype("MW"_fs), mega<watt>> {};
|
||||||
|
@@ -33,7 +33,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Pressure = QuantityOf<T, pressure>;
|
concept Pressure = QuantityOf<T, pressure>;
|
||||||
|
|
||||||
struct pascal : derived_unit<pascal, decltype("Pa"_fs), pressure, kilogram, metre, second> {};
|
struct pascal : coherent_derived_unit<pascal, decltype("Pa"_fs), pressure, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Substance = QuantityOf<T, substance>;
|
concept Substance = QuantityOf<T, substance>;
|
||||||
|
|
||||||
struct mole : derived_unit<mole, decltype("mol"_fs), substance> {};
|
struct mole : coherent_derived_unit<mole, decltype("mol"_fs), substance, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept ThermodynamicTemperature = QuantityOf<T, temperature>;
|
concept ThermodynamicTemperature = QuantityOf<T, temperature>;
|
||||||
|
|
||||||
struct kelvin : derived_unit<kelvin, decltype("K"_fs), temperature> {};
|
struct kelvin : coherent_derived_unit<kelvin, decltype("K"_fs), temperature> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Time = QuantityOf<T, time>;
|
concept Time = QuantityOf<T, time>;
|
||||||
|
|
||||||
struct second : derived_unit<second, decltype("s"_fs), time> {};
|
struct second : coherent_derived_unit<second, decltype("s"_fs), time, si_prefix> {};
|
||||||
struct nanosecond : derived_unit<nanosecond, decltype("ns"_fs), nano<second>> {};
|
struct nanosecond : derived_unit<nanosecond, decltype("ns"_fs), nano<second>> {};
|
||||||
struct microsecond : derived_unit<microsecond, decltype("us"_fs), micro<second>> {};
|
struct microsecond : derived_unit<microsecond, decltype("us"_fs), micro<second>> {};
|
||||||
struct millisecond : derived_unit<millisecond, decltype("ms"_fs), milli<second>> {};
|
struct millisecond : derived_unit<millisecond, decltype("ms"_fs), milli<second>> {};
|
||||||
|
@@ -32,7 +32,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Velocity = QuantityOf<T, velocity>;
|
concept Velocity = QuantityOf<T, velocity>;
|
||||||
|
|
||||||
struct metre_per_second : derived_unit<metre_per_second, decltype("m/s"_fs), velocity, metre, second> {};
|
struct metre_per_second : coherent_derived_unit<metre_per_second, decltype("m/s"_fs), velocity> {};
|
||||||
struct kilometre_per_hour : derived_unit<kilometre_per_hour, decltype("km/h"_fs), velocity, kilometre, hour> {};
|
struct kilometre_per_hour : derived_unit<kilometre_per_hour, decltype("km/h"_fs), velocity, kilometre, hour> {};
|
||||||
struct mile_per_hour : derived_unit<mile_per_hour, decltype("mi/h"_fs), velocity, mile, hour> {};
|
struct mile_per_hour : derived_unit<mile_per_hour, decltype("mi/h"_fs), velocity, mile, hour> {};
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Voltage = QuantityOf<T, voltage>;
|
concept Voltage = QuantityOf<T, voltage>;
|
||||||
|
|
||||||
struct volt : derived_unit<volt, decltype("V"_fs), voltage, kilogram, metre, second, ampere> {};
|
struct volt : coherent_derived_unit<volt, decltype("V"_fs), voltage, si_prefix> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -31,9 +31,9 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Volume = QuantityOf<T, volume>;
|
concept Volume = QuantityOf<T, volume>;
|
||||||
|
|
||||||
|
struct cubic_metre : coherent_derived_unit<cubic_metre, decltype("m^3"_fs), volume> {};
|
||||||
struct cubic_millimetre : derived_unit<cubic_millimetre, decltype("mm^3"_fs), volume, millimetre> {};
|
struct cubic_millimetre : derived_unit<cubic_millimetre, decltype("mm^3"_fs), volume, millimetre> {};
|
||||||
struct cubic_centimetre : derived_unit<cubic_centimetre, decltype("cm^3"_fs), volume, centimetre> {};
|
struct cubic_centimetre : derived_unit<cubic_centimetre, decltype("cm^3"_fs), volume, centimetre> {};
|
||||||
struct cubic_metre : derived_unit<cubic_metre, decltype("m^3"_fs), volume, metre> {};
|
|
||||||
struct cubic_kilometre : derived_unit<cubic_kilometre, decltype("km^3"_fs), volume, kilometre, metre> {};
|
struct cubic_kilometre : derived_unit<cubic_kilometre, decltype("km^3"_fs), volume, kilometre, metre> {};
|
||||||
struct cubic_foot : derived_unit<cubic_foot, decltype("ft^3"_fs), volume, foot> {};
|
struct cubic_foot : derived_unit<cubic_foot, decltype("ft^3"_fs), volume, foot> {};
|
||||||
|
|
||||||
|
@@ -26,6 +26,9 @@
|
|||||||
|
|
||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
|
template<typename Prefix, typename Ratio>
|
||||||
|
inline constexpr std::string_view prefix_symbol = "";
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename Ratio, typename CharT, typename Traits>
|
template<typename Ratio, typename CharT, typename Traits>
|
||||||
@@ -41,31 +44,11 @@ namespace units {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ratio>
|
template<typename Ratio, typename Prefix, typename CharT, typename Traits>
|
||||||
inline constexpr std::string_view ratio_txt = "";
|
|
||||||
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::atto::den>> = "a";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::femto::den>> = "f";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::pico::den>> = "p";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::nano::den>> = "n";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::micro::den>> = "\u00b5\u0073";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::milli::den>> = "m";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::centi::den>> = "c";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<1, std::deci::den>> = "d";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::deca::num>> = "da";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::hecto::num>> = "h";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::kilo::num>> = "k";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::mega::num>> = "M";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::giga::num>> = "G";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::tera::num>> = "T";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::peta::num>> = "P";
|
|
||||||
template<> inline constexpr std::string_view ratio_txt<ratio<std::exa::num>> = "E";
|
|
||||||
|
|
||||||
template<typename Ratio, typename CharT, typename Traits>
|
|
||||||
void print_prefix_or_ratio(std::basic_ostream<CharT, Traits>& os)
|
void print_prefix_or_ratio(std::basic_ostream<CharT, Traits>& os)
|
||||||
{
|
{
|
||||||
if constexpr(Ratio::num != 1 || Ratio::den != 1) {
|
if constexpr(Ratio::num != 1 || Ratio::den != 1) {
|
||||||
constexpr auto prefix = ratio_txt<Ratio>;
|
constexpr auto prefix = prefix_symbol<Prefix, Ratio>;
|
||||||
|
|
||||||
if constexpr(prefix != "") {
|
if constexpr(prefix != "") {
|
||||||
// print as a prefixed unit
|
// print as a prefixed unit
|
||||||
|
68
src/include/units/prefix.h
Normal file
68
src/include/units/prefix.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 Mateusz Pusz
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <units/unit.h>
|
||||||
|
#include <units/format.h>
|
||||||
|
|
||||||
|
namespace units {
|
||||||
|
|
||||||
|
// prefix tags
|
||||||
|
struct si_prefix;
|
||||||
|
|
||||||
|
// SI prefixes
|
||||||
|
|
||||||
|
template<Unit U> using atto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::atto::den>>>;
|
||||||
|
template<Unit U> using femto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::femto::den>>>;
|
||||||
|
template<Unit U> using pico = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::pico::den>>>;
|
||||||
|
template<Unit U> using nano = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::nano::den>>>;
|
||||||
|
template<Unit U> using micro = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::micro::den>>>;
|
||||||
|
template<Unit U> using milli = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::milli::den>>>;
|
||||||
|
template<Unit U> using centi = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::centi::den>>>;
|
||||||
|
template<Unit U> using deca = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::deca::num>>>;
|
||||||
|
template<Unit U> using hecto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::hecto::num>>>;
|
||||||
|
template<Unit U> using kilo = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::kilo::num>>>;
|
||||||
|
template<Unit U> using mega = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::mega::num>>>;
|
||||||
|
template<Unit U> using giga = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::giga::num>>>;
|
||||||
|
template<Unit U> using tera = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::tera::num>>>;
|
||||||
|
template<Unit U> using peta = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::peta::num>>>;
|
||||||
|
template<Unit U> using exa = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::exa::num>>>;
|
||||||
|
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::atto::den>> = "a";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::femto::den>> = "f";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::pico::den>> = "p";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::nano::den>> = "n";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::micro::den>> = "\u00b5\u0073"; // µ
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::milli::den>> = "m";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::centi::den>> = "c";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<1, std::deci::den>> = "d";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::deca::num>> = "da";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::hecto::num>> = "h";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::kilo::num>> = "k";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::mega::num>> = "M";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::giga::num>> = "G";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::tera::num>> = "T";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::peta::num>> = "P";
|
||||||
|
template<> inline constexpr std::string_view prefix_symbol<si_prefix, ratio<std::exa::num>> = "E";
|
||||||
|
|
||||||
|
}
|
@@ -23,8 +23,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <units/bits/concepts.h>
|
#include <units/bits/concepts.h>
|
||||||
#include <units/unit.h>
|
#include <units/prefix.h>
|
||||||
#include <units/format.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
@@ -290,13 +289,10 @@ namespace units {
|
|||||||
using ratio = quantity::unit::ratio;
|
using ratio = quantity::unit::ratio;
|
||||||
using dim = quantity::unit::dimension;
|
using dim = quantity::unit::dimension;
|
||||||
if constexpr(!detail::is_dimension<dim>) {
|
if constexpr(!detail::is_dimension<dim>) {
|
||||||
// print as a prefix or ratio of a coherent unit
|
// print as a prefix or ratio of a coherent unit symbol defined by the user
|
||||||
detail::print_prefix_or_ratio<ratio>(os);
|
using coherent_unit = downcast_target<units::unit<dim, units::ratio<1>>>;
|
||||||
|
detail::print_prefix_or_ratio<ratio, typename coherent_unit::prefix>(os);
|
||||||
if constexpr(!detail::is_dimension<dim>) {
|
os << coherent_unit::symbol::c_str();
|
||||||
// print coherent unit symbol defined by the user
|
|
||||||
os << downcast_target<units::unit<dim>>::symbol::c_str();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// print as a ratio of a coherent unit
|
// print as a ratio of a coherent unit
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
template<Dimension D, Ratio R = ratio<1>>
|
template<Dimension D, Ratio R>
|
||||||
requires (R::num * R::den > 0)
|
requires (R::num * R::den > 0)
|
||||||
struct unit : downcast_base<unit<D, R>> {
|
struct unit : downcast_base<unit<D, R>> {
|
||||||
using dimension = D;
|
using dimension = D;
|
||||||
@@ -141,14 +141,17 @@ namespace units {
|
|||||||
// static constexpr auto symbol = Symbol;
|
// static constexpr auto symbol = Symbol;
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
struct no_prefix;
|
||||||
|
|
||||||
|
template<typename Child, typename Symbol, Dimension D, typename Prefix = no_prefix>
|
||||||
|
struct coherent_derived_unit : downcast_helper<Child, unit<D, ratio<1>>> {
|
||||||
|
using symbol = Symbol;
|
||||||
|
using prefix = Prefix;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Child, typename Symbol, typename...>
|
template<typename Child, typename Symbol, typename...>
|
||||||
struct derived_unit;
|
struct derived_unit;
|
||||||
|
|
||||||
template<typename Child, typename Symbol, Dimension D>
|
|
||||||
struct derived_unit<Child, Symbol, D> : downcast_helper<Child, unit<D, ratio<1>>> {
|
|
||||||
using symbol = Symbol;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Child, typename Symbol, Dimension D, Ratio R>
|
template<typename Child, typename Symbol, Dimension D, Ratio R>
|
||||||
struct derived_unit<Child, Symbol, D, R> : downcast_helper<Child, unit<D, R>> {
|
struct derived_unit<Child, Symbol, D, R> : downcast_helper<Child, unit<D, R>> {
|
||||||
using symbol = Symbol;
|
using symbol = Symbol;
|
||||||
@@ -164,22 +167,4 @@ namespace units {
|
|||||||
using symbol = Symbol;
|
using symbol = Symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SI prefixes
|
|
||||||
|
|
||||||
template<Unit U> using atto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::atto::den>>>;
|
|
||||||
template<Unit U> using femto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::femto::den>>>;
|
|
||||||
template<Unit U> using pico = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::pico::den>>>;
|
|
||||||
template<Unit U> using nano = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::nano::den>>>;
|
|
||||||
template<Unit U> using micro = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::micro::den>>>;
|
|
||||||
template<Unit U> using milli = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::milli::den>>>;
|
|
||||||
template<Unit U> using centi = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<1, std::centi::den>>>;
|
|
||||||
template<Unit U> using deca = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::deca::num>>>;
|
|
||||||
template<Unit U> using hecto = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::hecto::num>>>;
|
|
||||||
template<Unit U> using kilo = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::kilo::num>>>;
|
|
||||||
template<Unit U> using mega = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::mega::num>>>;
|
|
||||||
template<Unit U> using giga = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::giga::num>>>;
|
|
||||||
template<Unit U> using tera = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::tera::num>>>;
|
|
||||||
template<Unit U> using peta = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::peta::num>>>;
|
|
||||||
template<Unit U> using exa = unit<typename U::dimension, ratio_multiply<typename U::ratio, ratio<std::exa::num>>>;
|
|
||||||
|
|
||||||
} // namespace units
|
} // namespace units
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
add_executable(unit_tests_runtime
|
add_executable(unit_tests_runtime
|
||||||
catch_main.cpp
|
catch_main.cpp
|
||||||
|
digital_information_test.cpp
|
||||||
math_test.cpp
|
math_test.cpp
|
||||||
text_test.cpp
|
text_test.cpp
|
||||||
)
|
)
|
||||||
|
77
test/unit_test/runtime/digital_information_test.cpp
Normal file
77
test/unit_test/runtime/digital_information_test.cpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 Mateusz Pusz
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
#include <units/quantity.h>
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
struct base_dim_digital_information : units::base_dimension<"digital information", "b"> {};
|
||||||
|
|
||||||
|
struct digital_information : units::derived_dimension<digital_information, units::exp<base_dim_digital_information, 1>> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept DigitalInformation = units::QuantityOf<T, digital_information>;
|
||||||
|
|
||||||
|
using namespace units::hacks;
|
||||||
|
|
||||||
|
struct data_prefix;
|
||||||
|
|
||||||
|
struct bit : units::coherent_derived_unit<bit, decltype("b"_fs), digital_information, data_prefix> {};
|
||||||
|
struct kilobit : units::derived_unit<bit, decltype("Kib"_fs), digital_information, units::ratio<1'024>> {};
|
||||||
|
struct byte : units::derived_unit<byte, decltype("B"_fs), digital_information, units::ratio<8>> {};
|
||||||
|
|
||||||
|
inline namespace literals {
|
||||||
|
|
||||||
|
constexpr auto operator""_b(unsigned long long l) { return units::quantity<bit, std::int64_t>(l); }
|
||||||
|
constexpr auto operator""_Kib(unsigned long long l) { return units::quantity<kilobit, std::int64_t>(l); }
|
||||||
|
constexpr auto operator""_B(unsigned long long l) { return units::quantity<byte, std::int64_t>(l); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline constexpr std::string_view units::prefix_symbol<data::data_prefix, units::ratio< 1'024>> = "Ki";
|
||||||
|
template<> inline constexpr std::string_view units::prefix_symbol<data::data_prefix, units::ratio<1'048'576>> = "Mi";
|
||||||
|
|
||||||
|
using namespace data;
|
||||||
|
|
||||||
|
TEST_CASE("operator<< on a custom quantity", "[text][ostream]")
|
||||||
|
{
|
||||||
|
std::stringstream stream;
|
||||||
|
|
||||||
|
SECTION("quantity with a predefined unit and prefix")
|
||||||
|
{
|
||||||
|
SECTION("named unit")
|
||||||
|
{
|
||||||
|
stream << 64_B;
|
||||||
|
REQUIRE(stream.str() == "64 B");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("other unit matching prefix")
|
||||||
|
{
|
||||||
|
stream << 8_Kib * 8_Kib / 2_b;
|
||||||
|
REQUIRE(stream.str() == "32 Mib");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -39,25 +39,31 @@ TEST_CASE("operator<< on a quantity", "[text][ostream]")
|
|||||||
{
|
{
|
||||||
SECTION("integral representation")
|
SECTION("integral representation")
|
||||||
{
|
{
|
||||||
stream << 16sq_m;
|
stream << 60W;
|
||||||
REQUIRE(stream.str() == "16 m^2");
|
REQUIRE(stream.str() == "60 W");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("floating-point representation")
|
SECTION("floating-point representation")
|
||||||
{
|
{
|
||||||
stream << 72.5kmph;
|
stream << 72.5kJ;
|
||||||
REQUIRE(stream.str() == "72.5 km/h");
|
REQUIRE(stream.str() == "72.5 kJ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("quantity with a predefined dimension but unknown unit")
|
SECTION("quantity with a predefined dimension but unknown unit")
|
||||||
{
|
{
|
||||||
SECTION("unit::ratio as an SI prefix")
|
SECTION("unit::ratio as an SI prefix for a dimension with a special symbol")
|
||||||
{
|
{
|
||||||
stream << 4.N * 2cm;
|
stream << 4.N * 2cm;
|
||||||
REQUIRE(stream.str() == "8 cJ");
|
REQUIRE(stream.str() == "8 cJ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("unit::ratio for a dimension without a special symbol")
|
||||||
|
{
|
||||||
|
stream << 2.cm * 2m * 2m;
|
||||||
|
REQUIRE(stream.str() == "8 [1/100]m^3");
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("unit::ratio::num != 1 && unit::ratio::den == 1")
|
SECTION("unit::ratio::num != 1 && unit::ratio::den == 1")
|
||||||
{
|
{
|
||||||
stream << 4 * 2min / (2s * 2s);
|
stream << 4 * 2min / (2s * 2s);
|
||||||
|
@@ -37,7 +37,9 @@ namespace {
|
|||||||
|
|
||||||
using namespace units::hacks;
|
using namespace units::hacks;
|
||||||
|
|
||||||
struct bit : units::derived_unit<bit, decltype("b"_fs), digital_information> {};
|
struct data_prefix {};
|
||||||
|
|
||||||
|
struct bit : units::coherent_derived_unit<bit, decltype("b"_fs), digital_information, data_prefix> {};
|
||||||
struct byte : units::derived_unit<byte, decltype("B"_fs), digital_information, units::ratio<8>> {};
|
struct byte : units::derived_unit<byte, decltype("B"_fs), digital_information, units::ratio<8>> {};
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
@@ -63,13 +65,11 @@ namespace {
|
|||||||
|
|
||||||
// power spectral density
|
// power spectral density
|
||||||
struct power_spectral_density : derived_dimension<power_spectral_density, units::exp<voltage, 2>, units::exp<frequency, -1>> {};
|
struct power_spectral_density : derived_dimension<power_spectral_density, units::exp<voltage, 2>, units::exp<frequency, -1>> {};
|
||||||
struct sq_volt_per_hertz : derived_unit<sq_volt_per_hertz, decltype("V^2/Hz"_fs), power_spectral_density> {};
|
struct sq_volt_per_hertz : coherent_derived_unit<sq_volt_per_hertz, decltype("V^2/Hz"_fs), power_spectral_density> {};
|
||||||
|
|
||||||
// amplitude spectral density
|
// amplitude spectral density
|
||||||
struct amplitude_spectral_density : derived_dimension<amplitude_spectral_density, units::exp<voltage, 1>, units::exp<frequency, -1, 2>> {};
|
struct amplitude_spectral_density : derived_dimension<amplitude_spectral_density, units::exp<voltage, 1>, units::exp<frequency, -1, 2>> {};
|
||||||
// TODO: add support for derived_unit
|
struct volt_per_sqrt_hertz : coherent_derived_unit<volt_per_sqrt_hertz, decltype("V/Hz^(1/2)"_fs), amplitude_spectral_density> {};
|
||||||
//struct volt_per_sq_hertz : derived_unit<volt_per_sq_hertz, amplitude_spectral_density, volt, hertz> {};
|
|
||||||
struct volt_per_sqrt_hertz : derived_unit<volt_per_sqrt_hertz, decltype("V/Hz^(1/2)"_fs), amplitude_spectral_density> {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
Reference in New Issue
Block a user