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 {
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 d2 = 3q_km;
if(d1 / d2 > dimensionless<unitless, 2>) {
if(d1 / d2 > dimensionless<one, 2>) {
// ...
}
or::
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.
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;
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
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)
{
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)
{
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
@@ -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::
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::

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`::
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
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:
- `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
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::

View File

@@ -26,8 +26,8 @@
namespace units {
struct unitless : named_unit<unitless, "", no_prefix> {};
struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), unitless> {};
struct one : named_unit<one, "", no_prefix> {};
struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), 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
* 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>
concept Dimensionless = QuantityOf<T, dim_one>;

View File

@@ -27,6 +27,6 @@
namespace units::physical::natural {
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

View File

@@ -40,7 +40,7 @@ struct dim_mass : physical::dim_mass<gigaelectronvolt> {};
template<Unit U, ScalableNumber Rep = double>
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>
using speed = quantity<dim_speed, U, Rep>;

View File

@@ -27,7 +27,6 @@
namespace units::physical::natural {
struct unitless : named_unit<unitless, "", no_prefix> {};
struct electronvolt : named_unit<electronvolt, "eV", si::prefix> {};
struct gigaelectronvolt : prefixed_unit<gigaelectronvolt, si::giga, electronvolt> {};
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>
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>
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("unitless with ratio == 1")
SECTION("one with ratio == 1")
{
const auto q = 4q_m / 2q_m;
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;
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>()),
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>() / length<metre, double>()), dimensionless<unitless, 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<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), one>, double>>);
static_assert(
is_same_v<decltype(length<metre, int>() / physical::si::time<second, int>()), speed<metre_per_second, int>>);
static_assert(
@@ -195,16 +195,16 @@ static_assert((7q_km % 2000q_m).count() == 1000);
static_assert((10q_km2 * 10q_km2) / 50q_km2 == 2q_km2);
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);
constexpr dimensionless<unitless> q2 = q1;
constexpr dimensionless<one> q2 = q1;
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;
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);
// comparators
@@ -279,32 +279,32 @@ static_assert(quantity_cast<int>(1.23q_m).count() == 1);
// dimensionless
static_assert(std::is_convertible_v<double, dimensionless<unitless>>);
static_assert(std::is_convertible_v<float, dimensionless<unitless>>);
static_assert(!std::is_convertible_v<double, dimensionless<unitless, int>>);
static_assert(std::is_convertible_v<int, dimensionless<unitless>>);
static_assert(std::is_convertible_v<double, dimensionless<one>>);
static_assert(std::is_convertible_v<float, dimensionless<one>>);
static_assert(!std::is_convertible_v<double, dimensionless<one, int>>);
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_constructible_v<dimensionless<scaled_unit<ratio(1, 1, 1), unitless>>, double>);
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), one>>, double>);
static_assert(dimensionless<unitless>(1.23) + dimensionless<unitless>(1.23) == dimensionless<unitless>(2.46));
static_assert(dimensionless<unitless>(1.23) + dimensionless<unitless>(1.23) == 2.46);
static_assert(dimensionless<unitless>(1.23) + 1.23 == 2.46);
static_assert(1.23 + dimensionless<unitless>(1.23) == 2.46);
static_assert(dimensionless<unitless>(1) + 1 == 2);
static_assert(dimensionless<unitless, int>(1) + 1 == 2);
static_assert(dimensionless<one>(1.23) + dimensionless<one>(1.23) == dimensionless<one>(2.46));
static_assert(dimensionless<one>(1.23) + dimensionless<one>(1.23) == 2.46);
static_assert(dimensionless<one>(1.23) + 1.23 == 2.46);
static_assert(1.23 + dimensionless<one>(1.23) == 2.46);
static_assert(dimensionless<one>(1) + 1 == 2);
static_assert(dimensionless<one, int>(1) + 1 == 2);
template<typename Rep>
concept invalid_dimensionless_operation = requires()
{
!requires(dimensionless<unitless, Rep> d) { d + 1.23; };
!requires(dimensionless<unitless, 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), unitless>, Rep> d) { d + 1; };
!requires(dimensionless<one, Rep> d) { d + 1.23; };
!requires(dimensionless<one, Rep> d) { 1.23 + d; };
!requires(dimensionless<scaled_unit<ratio(1, 1, 1), one>, Rep> d) { 1 + d; };
!requires(dimensionless<scaled_unit<ratio(1, 1, 1), one>, Rep> d) { d + 1; };
};
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(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(10q_km / 5q_km == 2);
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<unitless>(2));
static_assert(100q_mm / 5q_cm == dimensionless<scaled_unit<ratio(1, 1, -1), one>>(20));
static_assert(100q_mm / 5q_cm == dimensionless<one>(2));
static_assert(10q_km / 2 == 5q_km);
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(3.2q_GHz == 3'200'000'000q_Hz);
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<unitless>(600));
static_assert(10q_Hz * 1q_min == dimensionless<scaled_unit<ratio(60), one>>(10));
static_assert(10q_Hz * 1q_min == dimensionless<one>(600));
static_assert(2 / 1q_Hz == 2q_s);
// force