refactor: ♻️ unitless renamed to one

Resolves #27
This commit is contained in:
Mateusz Pusz
2020-09-09 11:20:55 +02:00
parent dba2b7f44f
commit 3e9d5ca189
11 changed files with 47 additions and 48 deletions

View File

@@ -28,6 +28,6 @@ The same constant defined for natural units may be provided as::
namespace natural { namespace natural {
template<ScalableNumber Rep = double> template<ScalableNumber Rep = double>
inline constexpr auto speed_of_light = speed<unitless, Rep>(1); inline constexpr auto speed_of_light = speed<one, Rep>(1);
} }

View File

@@ -110,16 +110,16 @@ represent numbers it would be highly uncomfortable to every time type::
const auto d1 = 10q_km; const auto d1 = 10q_km;
const auto d2 = 3q_km; const auto d2 = 3q_km;
if(d1 / d2 > dimensionless<unitless, 2>) { if(d1 / d2 > dimensionless<one, 2>) {
// ... // ...
} }
or:: or::
const auto fill_time_left = (box.height / box.fill_level(measured_mass) - const auto fill_time_left = (box.height / box.fill_level(measured_mass) -
dimensionless<unitless, 1>) * fill_time; dimensionless<one, 1>) * fill_time;
This is why it was decided to allow the ``dimensionless<unitless>`` quantity of any This is why it was decided to allow the ``dimensionless<one>`` quantity of any
representation type to be implicitly constructible from this representation type. representation type to be implicitly constructible from this representation type.
With that the above examples can be rewritten as follows:: With that the above examples can be rewritten as follows::
@@ -133,7 +133,7 @@ and::
const auto fill_time_left = (box.height / box.fill_level(measured_mass) - 1) * fill_time; const auto fill_time_left = (box.height / box.fill_level(measured_mass) - 1) * fill_time;
The above is true only for dimensionless quantities of `unitless` unit. If our quantity have a unit with The above is true only for dimensionless quantities of `one` unit. If our quantity have a unit with
ratio different than ``1`` the implicit conversion will not happen. This is to prevent cases were the code ratio different than ``1`` the implicit conversion will not happen. This is to prevent cases were the code
could be ambiguous. For example:: could be ambiguous. For example::
@@ -148,14 +148,14 @@ either change the type of the resulting unit to the one having ``ratio(1)`` (:te
Dimensionless auto foo(Length auto d1, Length auto d2) Dimensionless auto foo(Length auto d1, Length auto d2)
{ {
return quantity_cast<unitless>(d1 / d2) + 1; return quantity_cast<one>(d1 / d2) + 1;
} }
or to explicitly state what is the unit of our dimensionless value, e.g. `unitless`, `percent`, etc:: or to explicitly state what is the unit of our dimensionless value, e.g. `one`, `percent`, etc::
Dimensionless auto foo(Length auto d1, Length auto d2) Dimensionless auto foo(Length auto d1, Length auto d2)
{ {
return d1 / d2 + dimensionless<unitless>(1); return d1 / d2 + dimensionless<one>(1);
} }
There is one more important point to note here. As the the dimensionless quantity is more than just There is one more important point to note here. As the the dimensionless quantity is more than just
@@ -166,7 +166,7 @@ code will not compile::
To make it compile fine we have to either explicitly get the value stored in the quantity:: To make it compile fine we have to either explicitly get the value stored in the quantity::
auto v = std::exp(quantity_cast<unitless>(10q_m / 5q_m).count()); auto v = std::exp(quantity_cast<one>(10q_m / 5q_m).count());
or use a mathematical wrapper function from `units` namespace:: or use a mathematical wrapper function from `units` namespace::

View File

@@ -167,7 +167,7 @@ Whenever we divide two quantities of the same dimension we end up with a
:term:`dimensionless quantity` otherwise known as :term:`quantity of dimension one`:: :term:`dimensionless quantity` otherwise known as :term:`quantity of dimension one`::
static_assert(10q_km / 5q_km == 2); static_assert(10q_km / 5q_km == 2);
static_assert(std::is_same_v<decltype(10q_km / 5q_km), quantity<dim_one, unitless, std::int64_t>>); static_assert(std::is_same_v<decltype(10q_km / 5q_km), quantity<dim_one, one, std::int64_t>>);
According to the official ISO definition `dim_one` is a dimension "for which all the According to the official ISO definition `dim_one` is a dimension "for which all the
exponents of the factors corresponding to the base quantities in its quantity dimension exponents of the factors corresponding to the base quantities in its quantity dimension
@@ -189,10 +189,10 @@ are provided::
There are two special units provided for usage with such a quantity: There are two special units provided for usage with such a quantity:
- `unitless` which is the :ref:`coherent unit` of dimensionless quantity and does not - `one` which is the :ref:`coherent unit` of dimensionless quantity and does not
provide any textual symbol (according to the ISO definition "the measurement units and provide any textual symbol (according to the ISO definition "the measurement units and
values of quantities of dimension one are numbers"), values of quantities of dimension one are numbers"),
- `percent` which has the symbol ``%`` and ``ratio(1, 100)`` of the `unitless` unit. - `percent` which has the symbol ``%`` and ``ratio(1, 100)`` of the `one` unit.
For example the following code:: For example the following code::

View File

@@ -26,8 +26,8 @@
namespace units { namespace units {
struct unitless : named_unit<unitless, "", no_prefix> {}; struct one : named_unit<one, "", no_prefix> {};
struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), unitless> {}; struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), one> {};
/** /**
* @brief Dimension one * @brief Dimension one
@@ -35,7 +35,7 @@ struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), unitl
* Dimension for which all the exponents of the factors corresponding to the base * Dimension for which all the exponents of the factors corresponding to the base
* dimensions are zero. Also commonly named as "dimensionless". * dimensions are zero. Also commonly named as "dimensionless".
*/ */
struct dim_one : derived_dimension<dim_one, unitless> {}; struct dim_one : derived_dimension<dim_one, one> {};
template<typename T> template<typename T>
concept Dimensionless = QuantityOf<T, dim_one>; concept Dimensionless = QuantityOf<T, dim_one>;

View File

@@ -27,6 +27,6 @@
namespace units::physical::natural { namespace units::physical::natural {
template<ScalableNumber Rep = double> template<ScalableNumber Rep = double>
inline constexpr auto speed_of_light = speed<unitless, Rep>(1); inline constexpr auto speed_of_light = speed<one, Rep>(1);
} // namespace units::physical::natural } // namespace units::physical::natural

View File

@@ -40,7 +40,7 @@ struct dim_mass : physical::dim_mass<gigaelectronvolt> {};
template<Unit U, ScalableNumber Rep = double> template<Unit U, ScalableNumber Rep = double>
using mass = quantity<dim_mass, U, Rep>; using mass = quantity<dim_mass, U, Rep>;
struct dim_speed : physical::dim_speed<dim_speed, unitless, dim_length, dim_time> {}; struct dim_speed : physical::dim_speed<dim_speed, one, dim_length, dim_time> {};
template<Unit U, ScalableNumber Rep = double> template<Unit U, ScalableNumber Rep = double>
using speed = quantity<dim_speed, U, Rep>; using speed = quantity<dim_speed, U, Rep>;

View File

@@ -27,7 +27,6 @@
namespace units::physical::natural { namespace units::physical::natural {
struct unitless : named_unit<unitless, "", no_prefix> {};
struct electronvolt : named_unit<electronvolt, "eV", si::prefix> {}; struct electronvolt : named_unit<electronvolt, "eV", si::prefix> {};
struct gigaelectronvolt : prefixed_unit<gigaelectronvolt, si::giga, electronvolt> {}; struct gigaelectronvolt : prefixed_unit<gigaelectronvolt, si::giga, electronvolt> {};
struct inverted_gigaelectronvolt : named_unit<inverted_gigaelectronvolt, basic_symbol_text{"GeV⁻¹", "GeV^-1"}, no_prefix> {}; struct inverted_gigaelectronvolt : named_unit<inverted_gigaelectronvolt, basic_symbol_text{"GeV⁻¹", "GeV^-1"}, no_prefix> {};

View File

@@ -73,7 +73,7 @@ public:
template<ScalableNumber Value> template<ScalableNumber Value>
requires detail::safe_convertible<Value, rep> requires detail::safe_convertible<Value, rep>
constexpr explicit(!(std::is_same_v<dimension, dim_one> && std::is_same_v<unit, unitless>)) quantity(const Value& v) : value_{static_cast<rep>(v)} {} constexpr explicit(!(std::is_same_v<dimension, dim_one> && std::is_same_v<unit, one>)) quantity(const Value& v) : value_{static_cast<rep>(v)} {}
template<Quantity Q2> template<Quantity Q2>
requires equivalent_dim<D, typename Q2::dimension> && requires equivalent_dim<D, typename Q2::dimension> &&

View File

@@ -423,7 +423,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("dimensionless quantity") SECTION("dimensionless quantity")
{ {
SECTION("unitless with ratio == 1") SECTION("one with ratio == 1")
{ {
const auto q = 4q_m / 2q_m; const auto q = 4q_m / 2q_m;
os << q; os << q;
@@ -444,7 +444,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
} }
} }
SECTION("unitless with ratio.exp != 0") SECTION("one with ratio.exp != 0")
{ {
const auto q = 4q_km / 2q_m; const auto q = 4q_km / 2q_m;
os << q; os << q;

View File

@@ -168,8 +168,8 @@ static_assert(is_same_v<decltype(1 / frequency<hertz, int>()), physical::si::tim
static_assert(is_same_v<decltype(1 / length<kilometre>()), static_assert(is_same_v<decltype(1 / length<kilometre>()),
quantity<unknown_dimension<units::exponent<dim_length, -1>>, scaled_unit<ratio(1, 1, -3), unknown_coherent_unit>>>); quantity<unknown_dimension<units::exponent<dim_length, -1>>, scaled_unit<ratio(1, 1, -3), unknown_coherent_unit>>>);
static_assert(is_same_v<decltype(length<metre, int>() / 1.0), length<metre, double>>); static_assert(is_same_v<decltype(length<metre, int>() / 1.0), length<metre, double>>);
static_assert(is_same_v<decltype(length<metre, int>() / length<metre, double>()), dimensionless<unitless, double>>); static_assert(is_same_v<decltype(length<metre, int>() / length<metre, double>()), dimensionless<one, double>>);
static_assert(is_same_v<decltype(length<kilometre, int>() / length<metre, double>()), dimensionless<scaled_unit<ratio(1, 1, 3), unitless>, double>>); static_assert(is_same_v<decltype(length<kilometre, int>() / length<metre, double>()), dimensionless<scaled_unit<ratio(1, 1, 3), one>, double>>);
static_assert( static_assert(
is_same_v<decltype(length<metre, int>() / physical::si::time<second, int>()), speed<metre_per_second, int>>); is_same_v<decltype(length<metre, int>() / physical::si::time<second, int>()), speed<metre_per_second, int>>);
static_assert( static_assert(
@@ -195,16 +195,16 @@ static_assert((7q_km % 2000q_m).count() == 1000);
static_assert((10q_km2 * 10q_km2) / 50q_km2 == 2q_km2); static_assert((10q_km2 * 10q_km2) / 50q_km2 == 2q_km2);
constexpr auto q1 = 10q_km / 5q_m; constexpr auto q1 = 10q_km / 5q_m;
static_assert(std::is_same_v<decltype(q1), const dimensionless<scaled_unit<ratio(1, 1, 3), unitless>, std::int64_t>>); static_assert(std::is_same_v<decltype(q1), const dimensionless<scaled_unit<ratio(1, 1, 3), one>, std::int64_t>>);
static_assert(q1.count() == 2); static_assert(q1.count() == 2);
constexpr dimensionless<unitless> q2 = q1; constexpr dimensionless<one> q2 = q1;
static_assert(q2.count() == 2000); static_assert(q2.count() == 2000);
static_assert(quantity_cast<unitless>(q1).count() == 2000); static_assert(quantity_cast<one>(q1).count() == 2000);
constexpr auto q3 = 10q_s * 2q_kHz; constexpr auto q3 = 10q_s * 2q_kHz;
static_assert(std::is_same_v<decltype(q3), const dimensionless<scaled_unit<ratio(1, 1, 3), unitless>, std::int64_t>>); static_assert(std::is_same_v<decltype(q3), const dimensionless<scaled_unit<ratio(1, 1, 3), one>, std::int64_t>>);
static_assert(q3.count() == 20); static_assert(q3.count() == 20);
// comparators // comparators
@@ -279,32 +279,32 @@ static_assert(quantity_cast<int>(1.23q_m).count() == 1);
// dimensionless // dimensionless
static_assert(std::is_convertible_v<double, dimensionless<unitless>>); static_assert(std::is_convertible_v<double, dimensionless<one>>);
static_assert(std::is_convertible_v<float, dimensionless<unitless>>); static_assert(std::is_convertible_v<float, dimensionless<one>>);
static_assert(!std::is_convertible_v<double, dimensionless<unitless, int>>); static_assert(!std::is_convertible_v<double, dimensionless<one, int>>);
static_assert(std::is_convertible_v<int, dimensionless<unitless>>); static_assert(std::is_convertible_v<int, dimensionless<one>>);
static_assert(!std::is_convertible_v<double, dimensionless<scaled_unit<ratio(1, 1, 1), unitless>>>); static_assert(!std::is_convertible_v<double, dimensionless<scaled_unit<ratio(1, 1, 1), one>>>);
static_assert(std::is_constructible_v<dimensionless<scaled_unit<ratio(1, 1, 1), unitless>>, double>); static_assert(std::is_constructible_v<dimensionless<scaled_unit<ratio(1, 1, 1), one>>, double>);
static_assert(dimensionless<unitless>(1.23) + dimensionless<unitless>(1.23) == dimensionless<unitless>(2.46)); static_assert(dimensionless<one>(1.23) + dimensionless<one>(1.23) == dimensionless<one>(2.46));
static_assert(dimensionless<unitless>(1.23) + dimensionless<unitless>(1.23) == 2.46); static_assert(dimensionless<one>(1.23) + dimensionless<one>(1.23) == 2.46);
static_assert(dimensionless<unitless>(1.23) + 1.23 == 2.46); static_assert(dimensionless<one>(1.23) + 1.23 == 2.46);
static_assert(1.23 + dimensionless<unitless>(1.23) == 2.46); static_assert(1.23 + dimensionless<one>(1.23) == 2.46);
static_assert(dimensionless<unitless>(1) + 1 == 2); static_assert(dimensionless<one>(1) + 1 == 2);
static_assert(dimensionless<unitless, int>(1) + 1 == 2); static_assert(dimensionless<one, int>(1) + 1 == 2);
template<typename Rep> template<typename Rep>
concept invalid_dimensionless_operation = requires() concept invalid_dimensionless_operation = requires()
{ {
!requires(dimensionless<unitless, Rep> d) { d + 1.23; }; !requires(dimensionless<one, Rep> d) { d + 1.23; };
!requires(dimensionless<unitless, Rep> d) { 1.23 + d; }; !requires(dimensionless<one, Rep> d) { 1.23 + d; };
!requires(dimensionless<scaled_unit<ratio(1, 1, 1), unitless>, Rep> d) { 1 + d; }; !requires(dimensionless<scaled_unit<ratio(1, 1, 1), one>, Rep> d) { 1 + d; };
!requires(dimensionless<scaled_unit<ratio(1, 1, 1), unitless>, Rep> d) { d + 1; }; !requires(dimensionless<scaled_unit<ratio(1, 1, 1), one>, Rep> d) { d + 1; };
}; };
static_assert(invalid_dimensionless_operation<int>); static_assert(invalid_dimensionless_operation<int>);
static_assert(std::is_same_v<decltype(10q_km / 5q_km), quantity<dim_one, unitless, std::int64_t>>); static_assert(std::is_same_v<decltype(10q_km / 5q_km), quantity<dim_one, one, std::int64_t>>);
static_assert(quantity_cast<percent>(50.q_m / 100.q_m).count() == 50); static_assert(quantity_cast<percent>(50.q_m / 100.q_m).count() == 50);
static_assert(50.q_m / 100.q_m == dimensionless<percent>(50)); static_assert(50.q_m / 100.q_m == dimensionless<percent>(50));

View File

@@ -41,8 +41,8 @@ static_assert(1q_au == 149'597'870'700q_m);
static_assert(1q_km + 1q_m == 1001q_m); static_assert(1q_km + 1q_m == 1001q_m);
static_assert(10q_km / 5q_km == 2); static_assert(10q_km / 5q_km == 2);
static_assert(10q_km / 5q_km < 3); static_assert(10q_km / 5q_km < 3);
static_assert(100q_mm / 5q_cm == dimensionless<scaled_unit<ratio(1, 1, -1), unitless>>(20)); static_assert(100q_mm / 5q_cm == dimensionless<scaled_unit<ratio(1, 1, -1), one>>(20));
static_assert(100q_mm / 5q_cm == dimensionless<unitless>(2)); static_assert(100q_mm / 5q_cm == dimensionless<one>(2));
static_assert(10q_km / 2 == 5q_km); static_assert(10q_km / 2 == 5q_km);
static_assert(millimetre::symbol == "mm"); static_assert(millimetre::symbol == "mm");
@@ -105,8 +105,8 @@ static_assert(1000 / 1q_s == 1q_kHz);
static_assert(1 / 1q_ms == 1q_kHz); static_assert(1 / 1q_ms == 1q_kHz);
static_assert(3.2q_GHz == 3'200'000'000q_Hz); static_assert(3.2q_GHz == 3'200'000'000q_Hz);
static_assert((10q_Hz * 1q_min).count() == 10); static_assert((10q_Hz * 1q_min).count() == 10);
static_assert(10q_Hz * 1q_min == dimensionless<scaled_unit<ratio(60), unitless>>(10)); static_assert(10q_Hz * 1q_min == dimensionless<scaled_unit<ratio(60), one>>(10));
static_assert(10q_Hz * 1q_min == dimensionless<unitless>(600)); static_assert(10q_Hz * 1q_min == dimensionless<one>(600));
static_assert(2 / 1q_Hz == 2q_s); static_assert(2 / 1q_Hz == 2q_s);
// force // force