feat!: 💥 dimensionless quantities refactored
Dimensionless quantities are now represented by quantity types rather than by plain representation types. Only dimensionless quantities with `unitless` unit are implicitly convertible from representation types. `units::exp()` now is a function doing std::exp() on a representation type (previous `units::exp` class template was renamed to `units::exponent`). BREAKING_CHANGE: gcc-9.3 support removed BREAKING_CHANGE: `exp` and `Exp` renamed to `exponent` and `Exponent` Resolves #27 Resolves #42
This commit is contained in:
1 parent
c8b60b80c1
commit
563b358d5e
47 files changed
+599
-422
No files matched your search
@@ -15,6 +15,8 @@
|
||||
- FPS system added (thanks [@mikeford3](https://github.com/mikeford3))
|
||||
- `quantity_point` support added (thanks [@johelegp](https://github.com/johelegp))
|
||||
- `ratio` changed to the NTTP kind
|
||||
- `exp` and `Exp` renamed to `exponent` and `Exponent`
|
||||
- Added support for `exp()` mathematical support
|
||||
|
||||
- **0.5.0 May 17, 2020**
|
||||
- Major refactoring and rewrite of the library
|
||||
|
||||
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
+11
-11
@@ -14,18 +14,18 @@ The same can be observed during debugging of a source code that use template ali
|
||||
Let's assume that we want to provide a user friendly name for a derived dimension of capacitance
|
||||
quantity. Other libraries will do it in the following way::
|
||||
|
||||
using dim_capacitance = detail::derived_dimension_base<exp<si::dim_electric_current, 2>,
|
||||
exp<si::dim_length, -2>,
|
||||
exp<si::dim_mass, -1>,
|
||||
exp<si::dim_time, 4>>;
|
||||
using dim_capacitance = detail::derived_dimension_base<exponent<si::dim_electric_current, 2>,
|
||||
exponent<si::dim_length, -2>,
|
||||
exponent<si::dim_mass, -1>,
|
||||
exponent<si::dim_time, 4>>;
|
||||
|
||||
The above solution does provide a good developer's experience but a really poor one for the end
|
||||
user. If we will get a compilation error message containing `dim_capacitance` in most cases
|
||||
the compiler will print the following type instead of the alias::
|
||||
|
||||
units::detail::derived_dimension_base<units::exp<units::physical::si::dim_electric_current, 2, 1>,
|
||||
units::exp<units::physical::si::dim_length, -2, 1>, units::exp<units::physical::si::dim_mass, -1, 1>,
|
||||
units::exp<units::physical::si::dim_time, 4, 1> >
|
||||
units::detail::derived_dimension_base<units::exponent<units::physical::si::dim_electric_current, 2, 1>,
|
||||
units::exponent<units::physical::si::dim_length, -2, 1>, units::exponent<units::physical::si::dim_mass,
|
||||
-1, 1>, units::exponent<units::physical::si::dim_time, 4, 1> >
|
||||
|
||||
You can notice that in case of **mp-units** even this long syntax was carefully selected to
|
||||
provide quite good user experience (some other units libraries produce a type that cannot easily
|
||||
@@ -48,7 +48,7 @@ to use inheritance:
|
||||
..
|
||||
http://www.nomnoml.com
|
||||
|
||||
[derived_dimension_base<exp<si::dim_length, 2>>]<:-[dim_area]
|
||||
[derived_dimension_base<exponent<si::dim_length, 2>>]<:-[dim_area]
|
||||
|
||||
This gives us a nice looking strong type when directly used by the user. However, we just got
|
||||
ourselves into problems. The library's framework does not know how to switch from a long
|
||||
@@ -79,9 +79,9 @@ The downcasting facility is provided by injecting two classes into our hierarchy
|
||||
..
|
||||
http://www.nomnoml.com
|
||||
|
||||
[downcast_base<detail::derived_dimension_base<exp<si::dim_length, 2>>>]<:-[detail::derived_dimension_base<exp<si::dim_length, 2>>]
|
||||
[detail::derived_dimension_base<exp<si::dim_length, 2>>]<:-[downcast_child<dim_area, detail::derived_dimension_base<exp<si::dim_length, 2>>>]
|
||||
[downcast_child<dim_area, detail::derived_dimension_base<exp<si::dim_length, 2>>>]<:-[dim_area]
|
||||
[downcast_base<detail::derived_dimension_base<exponent<si::dim_length, 2>>>]<:-[detail::derived_dimension_base<exponent<si::dim_length, 2>>]
|
||||
[detail::derived_dimension_base<exponent<si::dim_length, 2>>]<:-[downcast_child<dim_area, detail::derived_dimension_base<exponent<si::dim_length, 2>>>]
|
||||
[downcast_child<dim_area, detail::derived_dimension_base<exponent<si::dim_length, 2>>>]<:-[dim_area]
|
||||
|
||||
In the above example:
|
||||
|
||||
|
||||
@@ -97,14 +97,6 @@ Unfortunately, if `using-directives <https://en.cppreference.com/w/cpp/language/
|
||||
collide with C `time <https://en.cppreference.com/w/c/chrono/time>`_ function. In such a case the library's
|
||||
`time` function needs to be prefixed with at least one (or all) namespace names.
|
||||
|
||||
error: template argument 1 is invalid
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Again, usage of ``using namespace units``
|
||||
`using-directive <https://en.cppreference.com/w/cpp/language/namespace#Using-directives>`_ may result in
|
||||
the collision between `units::exp` class template and C `exp <https://en.cppreference.com/w/c/numeric/math/exp>`_
|
||||
function. In such a case the library's `exp` class template needs to be prefixed with `units` namespace name.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ The most important concepts in the library are `Unit`, `Dimension`,
|
||||
http://www.nomnoml.com
|
||||
|
||||
[<abstract>Dimension|
|
||||
[base_dimension<Symbol, Unit>]<-[exp<Dimension, Num, Den>]
|
||||
[derived_dimension<Child, Unit, Exponent...>]<-[exp<Dimension, Num, Den>]
|
||||
[exp<Dimension, Num, Den>]<-[derived_dimension<Child, Unit, Exponent...>]
|
||||
[base_dimension<Symbol, Unit>]<-[exponent<Dimension, Num, Den>]
|
||||
[derived_dimension<Child, Unit, Exponent...>]<-[exponent<Dimension, Num, Den>]
|
||||
[exponent<Dimension, Num, Den>]<-[derived_dimension<Child, Unit, Exponent...>]
|
||||
]
|
||||
|
||||
[<abstract>Quantity|
|
||||
|
||||
@@ -147,9 +147,9 @@ The above dimensions can be defined in the library with the
|
||||
namespace si {
|
||||
|
||||
struct dim_area : derived_dimension<dim_area, square_metre,
|
||||
exp<dim_length, 2>> {};
|
||||
exponent<dim_length, 2>> {};
|
||||
struct dim_speed : derived_dimension<dim_speed, metre_per_second,
|
||||
exp<dim_length, 1>, exp<dim_time, -1>> {};
|
||||
exponent<dim_length, 1>, exponent<dim_time, -1>> {};
|
||||
|
||||
}
|
||||
|
||||
@@ -179,9 +179,9 @@ matter. Even if we define the above as:
|
||||
namespace si {
|
||||
|
||||
struct dim_area : derived_dimension<dim_area, square_metre,
|
||||
exp<dim_length, 1>, exp<dim_length, 1>> {};
|
||||
exponent<dim_length, 1>, exponent<dim_length, 1>> {};
|
||||
struct dim_speed : derived_dimension<dim_speed, metre_per_second,
|
||||
exp<dim_time, -1>, exp<dim_length, 1>> {};
|
||||
exponent<dim_time, -1>, exponent<dim_length, 1>> {};
|
||||
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -120,17 +120,17 @@ will result in a different unnamed unit symbol:
|
||||
:emphasize-lines: 2-4, 6-8, 10-12
|
||||
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_time, -1>> {}; // kg ⋅ m/s
|
||||
exponent<si::dim_mass, 1>,
|
||||
exponent<si::dim_length, 1>,
|
||||
exponent<si::dim_time, -1>> {}; // kg ⋅ m/s
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_time, -1>> {}; // m ⋅ kg/s
|
||||
exponent<si::dim_length, 1>,
|
||||
exponent<si::dim_mass, 1>,
|
||||
exponent<si::dim_time, -1>> {}; // m ⋅ kg/s
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_time, -1>,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_mass, 1>> {}; // 1/s ⋅ m ⋅ kg
|
||||
exponent<si::dim_time, -1>,
|
||||
exponent<si::dim_length, 1>,
|
||||
exponent<si::dim_mass, 1>> {}; // 1/s ⋅ m ⋅ kg
|
||||
|
||||
where ``kilogram_metre_per_second`` is defined as::
|
||||
|
||||
@@ -143,8 +143,8 @@ However, the easiest way to define momentum is just to use the
|
||||
:emphasize-lines: 3
|
||||
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_speed, 1>> {}; // kg ⋅ m/s
|
||||
exponent<si::dim_mass, 1>,
|
||||
exponent<si::dim_speed, 1>> {}; // kg ⋅ m/s
|
||||
|
||||
In such a case the library will do its magic and will automatically
|
||||
unpack a provided derived dimension to its base dimensions in order to
|
||||
@@ -161,8 +161,8 @@ of ``N/m``):
|
||||
:emphasize-lines: 2
|
||||
|
||||
struct dim_surface_tension : derived_dimension<dim_surface_tension, newton_per_metre,
|
||||
exp<si::dim_force, 1>,
|
||||
exp<si::dim_length, -1>> {}; // N/m
|
||||
exponent<si::dim_force, 1>,
|
||||
exponent<si::dim_length, -1>> {}; // N/m
|
||||
|
||||
If we defined the above in terms of base units we would end up with
|
||||
a ``kg/s²`` derived unit symbol.
|
||||
@@ -194,7 +194,7 @@ where `no_prefix` is a special tag type describing that the library should
|
||||
not allow to define a new prefixed unit that would use this unit as a
|
||||
reference ("kilohours" does not have much sense, right?). The `ratio` type
|
||||
used in the definition is really similar to ``std::ratio`` but it takes
|
||||
an additional ``Exp`` template parameter that defines the exponent of the ratio.
|
||||
an additional ``Exponent`` template parameter that defines the exponent of the ratio.
|
||||
Another important difference is the fact that the objects of that class are used
|
||||
as class NTTPs rather then a type template parameter kind.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ Concepts
|
||||
|
||||
.. concept:: template<typename T> Exponent
|
||||
|
||||
A concept matching dimension's exponents. Satisfied by all instantiations of :class:`exp`.
|
||||
A concept matching dimension's exponents. Satisfied by all instantiations of :class:`exponent`.
|
||||
|
||||
.. concept:: template<typename T> DerivedDimension
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Dimensions
|
||||
.. doxygenstruct:: units::base_dimension
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::exp
|
||||
.. doxygenstruct:: units::exponent
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::derived_dimension
|
||||
|
||||
@@ -115,7 +115,7 @@ coherent unit::
|
||||
|
||||
// new derived dimensions
|
||||
struct dim_desk_rate : derived_dimension<dim_desk_rate, square_metre_per_second,
|
||||
exp<si::dim_area, 1>, exp<si::dim_time, -1>> {};
|
||||
exponent<si::dim_area, 1>, exponent<si::dim_time, -1>> {};
|
||||
|
||||
// our unit of interest for a new derived dimension
|
||||
struct desk_per_hour : deduced_unit<desk_per_hour, dim_desk_rate, desk, si::hour> {};
|
||||
@@ -164,7 +164,8 @@ With the above we can now define a new derived dimension::
|
||||
|
||||
struct person_per_square_metre : unit<person_per_square_metre> {};
|
||||
struct dim_occupancy_rate : derived_dimension<dim_occupancy_rate, person_per_square_metre,
|
||||
exp<dim_people, 1>, exp<si::dim_area, -1>> {};
|
||||
exponent<dim_people, 1>,
|
||||
exponent<si::dim_area, -1>> {};
|
||||
|
||||
struct person_per_desk : deduced_unit<person_per_desk, dim_occupancy_rate, person, desk> {};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ we forget to include a header file with the resulting dimension definition:
|
||||
|
||||
constexpr auto result = 144q_km / 2q_h;
|
||||
static_assert(is_same_v<decltype(result)::dimension,
|
||||
unknown_dimension<exp<dim_length, 1>, exp<dim_time, -1>>>);
|
||||
unknown_dimension<exponent<dim_length, 1>, exponent<dim_time, -1>>>);
|
||||
static_assert(is_same_v<decltype(result)::unit,
|
||||
scaled_unit<ratio(1, 36, 1), unknown_coherent_unit>>);
|
||||
|
||||
|
||||
Reference in new issue
Block a user