Skip to content

Commit

Permalink
feat: unit_constants
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP authored and mpusz committed Dec 28, 2020
1 parent 0fb821a commit 8dede0d
Show file tree
Hide file tree
Showing 70 changed files with 1,000 additions and 28 deletions.
69 changes: 69 additions & 0 deletions src/include/units/bits/one_rep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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/bits/basic_concepts.h>
#include <units/customization_points.h>
#include <type_traits>

namespace units::detail {

struct one_rep {

This comment has been minimized.

Copy link
@mpusz

mpusz Jan 4, 2021

Owner

This does not provide an implementation for quantity::zero() which results in a compilation error when asserts in a quantity class template definition are uncommented (I am working on re-enabling them for a Debug build). Do you have an idea on how to address it?

This comment has been minimized.

Copy link
@JohelEGP

JohelEGP Jan 4, 2021

Author Collaborator

You could have a zero_rep analogous to one_rep and specialize quantity_values. It'd break again if users attempted to construct one_rep from quantity_values<one_rep>::zero(), so it's not a general solution.

This comment has been minimized.

Copy link
@JohelEGP

JohelEGP Jan 4, 2021

Author Collaborator

You'd also need to define operator==(one_rep, zero_rep) to return false. I suppose being unable to construct one_rep from quantity_values<one_rep>::zero() is fine since it's not required by QuantityValue.

This comment has been minimized.

Copy link
@mpusz

mpusz Jan 4, 2021

Owner

I suppose being unable to construct one_rep from quantity_values<one_rep>::zero() is fine since it's not required by QuantityValue.

So does it mean that there should be no contracts for a division operator? Right now I can do something like:

  if constexpr(requires { quantity<D2, U2, Rep2>::zero(); })
    gsl_ExpectsAudit(rhs != (quantity<D2, U2, Rep2>::zero()));

but I am not sure if that is a correct solution and if it will work with C++23/26 contracts.

This comment has been minimized.

Copy link
@JohelEGP

JohelEGP Jan 4, 2021

Author Collaborator

I mean after adding zero_rep. You can't construct a one_rep from a zero_rep with T{quantity_values<T>::zero()} where T is one_rep. That would work for most Ts, but none of the concepts checked by the time quantity::operator/ is instantiated actually requires that.

This comment has been minimized.

Copy link
@mpusz

mpusz Jan 4, 2021

Owner

I do not think we need a zero_rep. Also, I do not understand what you mean by:

You can't construct a one_rep from a zero_rep with T{quantity_values::zero()} where T is one_rep.

This comment has been minimized.

Copy link
@JohelEGP

JohelEGP Jan 4, 2021

Author Collaborator

You want to uncomment // Expects(v != zero().count());, but that does not work for one_rep because the default one_rep{0} is an error. My suggested solution was to add a zero_rep to make that work.

Looking at the primary quantity_values template, where all zero/one/min/max return Rep, you'd expect Rep{zero()} to work, but that always breaks for one_rep.

Now I'm leaning towards replacing one_rep with a boolean_rep that can be zero or one to avoid these kind of problems from deviating from the primary quantity_values template. I had initially considered this.

The unit constants would have to be initialized to 1. Again, I had initially considered adding a unit_constant alias, but didn't do it. As a result, earlier you had to change all of them with 671f891. And now once again when replacing one_rep with boolean_rep.

This comment has been minimized.

Copy link
@mpusz

mpusz Jan 4, 2021

Owner

It starts to be really messy. I do not like a boolean_rep for this type. Maybe it would be better to name it explicitly as unit_constant_rep?

This comment has been minimized.

Copy link
@JohelEGP

JohelEGP Jan 4, 2021

Author Collaborator

Sounds good.

template<QuantityValue Rep>
[[nodiscard]] friend constexpr Rep operator*(const Rep& lhs, one_rep)
{
return lhs;
}
template<QuantityValue Rep>
[[nodiscard]] friend constexpr Rep operator/(const Rep& lhs, one_rep)
{
return lhs;
}

template<QuantityValue Rep>
[[nodiscard]] constexpr operator Rep() const noexcept
{
return quantity_values<Rep>::one();
}

[[nodiscard]] bool operator==(const one_rep&) const = default;
[[nodiscard]] auto operator<=>(const one_rep&) const = default;
};

} // namespace units::detail

namespace std {
template<>
struct common_type<units::detail::one_rep, units::detail::one_rep> {
using type = units::detail::one_rep;
};
template<units::QuantityValue Rep>
struct common_type<units::detail::one_rep, Rep> {
using type = Rep;
};
template<units::QuantityValue Rep>
struct common_type<Rep, units::detail::one_rep> {
using type = Rep;
};

} // namespace std
19 changes: 19 additions & 0 deletions src/include/units/data/base/information.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/base_dimension.h>
#include <units/data/prefixes.h>
#include <units/unit.h>
Expand Down Expand Up @@ -71,4 +72,22 @@ constexpr auto operator"" _q_PiB(unsigned long long l) { return information<pebi

} // namespace literals

namespace unit_constants {

inline constexpr auto b = information<bit, detail::one_rep>{};
inline constexpr auto Kib = information<kibibit, detail::one_rep>{};
inline constexpr auto Mib = information<mebibit, detail::one_rep>{};
inline constexpr auto Gib = information<gibibit, detail::one_rep>{};
inline constexpr auto Tib = information<tebibit, detail::one_rep>{};
inline constexpr auto Pib = information<pebibit, detail::one_rep>{};

inline constexpr auto B = information<byte, detail::one_rep>{};
inline constexpr auto KiB = information<kibibyte, detail::one_rep>{};
inline constexpr auto MiB = information<mebibyte, detail::one_rep>{};
inline constexpr auto GiB = information<gibibyte, detail::one_rep>{};
inline constexpr auto TiB = information<tebibyte, detail::one_rep>{};
inline constexpr auto PiB = information<pebibyte, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::data
11 changes: 11 additions & 0 deletions src/include/units/data/derived/bitrate.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,15 @@ constexpr auto operator"" _q_Pib_per_s(unsigned long long l) { return bitrate<pe

} // namespace literals

namespace unit_constants {

inline constexpr auto b_per_s = bitrate<bit_per_second, detail::one_rep>{};
inline constexpr auto Kib_per_s = bitrate<kibibit_per_second, detail::one_rep>{};
inline constexpr auto Mib_per_s = bitrate<mebibit_per_second, detail::one_rep>{};
inline constexpr auto Gib_per_s = bitrate<gibibit_per_second, detail::one_rep>{};
inline constexpr auto Tib_per_s = bitrate<tebibit_per_second, detail::one_rep>{};
inline constexpr auto Pib_per_s = bitrate<pebibit_per_second, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::data
7 changes: 7 additions & 0 deletions src/include/units/physical/si/base/amount_of_substance.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/amount_of_substance.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand All @@ -43,4 +44,10 @@ constexpr auto operator"" _q_mol(long double l) { return amount_of_substance<mol

} // namespace literals

namespace unit_constants {

inline constexpr auto mol = amount_of_substance<mole, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
27 changes: 27 additions & 0 deletions src/include/units/physical/si/base/electric_current.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/electric_current.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand Down Expand Up @@ -143,4 +144,30 @@ constexpr auto operator"" _q_YA(long double l) { return electric_current<yottaam

} // namespace literals

namespace unit_constants {

inline constexpr auto A = electric_current<ampere, detail::one_rep>{};
inline constexpr auto yA = electric_current<yoctoampere, detail::one_rep>{};
inline constexpr auto zA = electric_current<zeptoampere, detail::one_rep>{};
inline constexpr auto aA = electric_current<attoampere, detail::one_rep>{};
inline constexpr auto fA = electric_current<femtoampere, detail::one_rep>{};
inline constexpr auto pA = electric_current<picoampere, detail::one_rep>{};
inline constexpr auto nA = electric_current<nanoampere, detail::one_rep>{};
inline constexpr auto uA = electric_current<microampere, detail::one_rep>{};
inline constexpr auto mA = electric_current<milliampere, detail::one_rep>{};
inline constexpr auto cA = electric_current<centiampere, detail::one_rep>{};
inline constexpr auto dA = electric_current<deciampere, detail::one_rep>{};
inline constexpr auto daA = electric_current<decaampere, detail::one_rep>{};
inline constexpr auto hA = electric_current<hectoampere, detail::one_rep>{};
inline constexpr auto kA = electric_current<kiloampere, detail::one_rep>{};
inline constexpr auto MA = electric_current<megaampere, detail::one_rep>{};
inline constexpr auto GA = electric_current<gigaampere, detail::one_rep>{};
inline constexpr auto TA = electric_current<teraampere, detail::one_rep>{};
inline constexpr auto PA = electric_current<petaampere, detail::one_rep>{};
inline constexpr auto EA = electric_current<exaampere, detail::one_rep>{};
inline constexpr auto ZA = electric_current<zettaampere, detail::one_rep>{};
inline constexpr auto YA = electric_current<yottaampere, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
28 changes: 28 additions & 0 deletions src/include/units/physical/si/base/length.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/length.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand Down Expand Up @@ -149,4 +150,31 @@ constexpr auto operator"" _q_au(long double l) { return length<astronomical_unit

} // namespace literals

namespace unit_constants {

inline constexpr auto m = length<metre, detail::one_rep>{};
inline constexpr auto ym = length<yoctometre, detail::one_rep>{};
inline constexpr auto zm = length<zeptometre, detail::one_rep>{};
inline constexpr auto am = length<attometre, detail::one_rep>{};
inline constexpr auto fm = length<femtometre, detail::one_rep>{};
inline constexpr auto pm = length<picometre, detail::one_rep>{};
inline constexpr auto nm = length<nanometre, detail::one_rep>{};
inline constexpr auto um = length<micrometre, detail::one_rep>{};
inline constexpr auto mm = length<millimetre, detail::one_rep>{};
inline constexpr auto cm = length<centimetre, detail::one_rep>{};
inline constexpr auto dm = length<decimetre, detail::one_rep>{};
inline constexpr auto dam = length<decametre, detail::one_rep>{};
inline constexpr auto hm = length<hectometre, detail::one_rep>{};
inline constexpr auto km = length<kilometre, detail::one_rep>{};
inline constexpr auto Mm = length<megametre, detail::one_rep>{};
inline constexpr auto Gm = length<gigametre, detail::one_rep>{};
inline constexpr auto Tm = length<terametre, detail::one_rep>{};
inline constexpr auto Pm = length<petametre, detail::one_rep>{};
inline constexpr auto Em = length<exametre, detail::one_rep>{};
inline constexpr auto Zm = length<zettametre, detail::one_rep>{};
inline constexpr auto Ym = length<yottametre, detail::one_rep>{};
inline constexpr auto au = length<astronomical_unit, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
27 changes: 27 additions & 0 deletions src/include/units/physical/si/base/luminous_intensity.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/luminous_intensity.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand Down Expand Up @@ -143,4 +144,30 @@ constexpr auto operator"" _q_Ycd(long double l) { return luminous_intensity<yott

} // namespace literals

namespace unit_constants {

inline constexpr auto cd = luminous_intensity<candela, detail::one_rep>{};
inline constexpr auto ycd = luminous_intensity<yoctocandela, detail::one_rep>{};
inline constexpr auto zcd = luminous_intensity<zeptocandela, detail::one_rep>{};
inline constexpr auto acd = luminous_intensity<attocandela, detail::one_rep>{};
inline constexpr auto fcd = luminous_intensity<femtocandela, detail::one_rep>{};
inline constexpr auto pcd = luminous_intensity<picocandela, detail::one_rep>{};
inline constexpr auto ncd = luminous_intensity<nanocandela, detail::one_rep>{};
inline constexpr auto ucd = luminous_intensity<microcandela, detail::one_rep>{};
inline constexpr auto mcd = luminous_intensity<millicandela, detail::one_rep>{};
inline constexpr auto ccd = luminous_intensity<centicandela, detail::one_rep>{};
inline constexpr auto dcd = luminous_intensity<decicandela, detail::one_rep>{};
inline constexpr auto dacd = luminous_intensity<decacandela, detail::one_rep>{};
inline constexpr auto hcd = luminous_intensity<hectocandela, detail::one_rep>{};
inline constexpr auto kcd = luminous_intensity<kilocandela, detail::one_rep>{};
inline constexpr auto Mcd = luminous_intensity<megacandela, detail::one_rep>{};
inline constexpr auto Gcd = luminous_intensity<gigacandela, detail::one_rep>{};
inline constexpr auto Tcd = luminous_intensity<teracandela, detail::one_rep>{};
inline constexpr auto Pcd = luminous_intensity<petacandela, detail::one_rep>{};
inline constexpr auto Ecd = luminous_intensity<exacandela, detail::one_rep>{};
inline constexpr auto Zcd = luminous_intensity<zettacandela, detail::one_rep>{};
inline constexpr auto Ycd = luminous_intensity<yottacandela, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
49 changes: 49 additions & 0 deletions src/include/units/physical/si/base/mass.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/mass.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand Down Expand Up @@ -255,4 +256,52 @@ constexpr auto operator"" _q_Da(long double l) { return mass<dalton, long double

} // namespace literals

namespace unit_constants {

inline constexpr auto g = mass<gram, detail::one_rep>{};
inline constexpr auto yg = mass<yoctogram, detail::one_rep>{};
inline constexpr auto zg = mass<zeptogram, detail::one_rep>{};
inline constexpr auto ag = mass<attogram, detail::one_rep>{};
inline constexpr auto fg = mass<femtogram, detail::one_rep>{};
inline constexpr auto pg = mass<picogram, detail::one_rep>{};
inline constexpr auto ng = mass<nanogram, detail::one_rep>{};
inline constexpr auto ug = mass<microgram, detail::one_rep>{};
inline constexpr auto mg = mass<milligram, detail::one_rep>{};
inline constexpr auto cg = mass<centigram, detail::one_rep>{};
inline constexpr auto dg = mass<decigram, detail::one_rep>{};
inline constexpr auto dag = mass<decagram, detail::one_rep>{};
inline constexpr auto hg = mass<hectogram, detail::one_rep>{};
inline constexpr auto kg = mass<kilogram, detail::one_rep>{};
inline constexpr auto Mg = mass<megagram, detail::one_rep>{};
inline constexpr auto Gg = mass<gigagram, detail::one_rep>{};
inline constexpr auto Tg = mass<teragram, detail::one_rep>{};
inline constexpr auto Pg = mass<petagram, detail::one_rep>{};
inline constexpr auto Eg = mass<exagram, detail::one_rep>{};
inline constexpr auto Zg = mass<zettagram, detail::one_rep>{};
inline constexpr auto Yg = mass<yottagram, detail::one_rep>{};
inline constexpr auto t = mass<tonne, detail::one_rep>{};
inline constexpr auto yt = mass<yoctotonne, detail::one_rep>{};
inline constexpr auto zt = mass<zeptotonne, detail::one_rep>{};
inline constexpr auto at = mass<attotonne, detail::one_rep>{};
inline constexpr auto ft = mass<femtotonne, detail::one_rep>{};
inline constexpr auto pt = mass<picotonne, detail::one_rep>{};
inline constexpr auto nt = mass<nanotonne, detail::one_rep>{};
inline constexpr auto ut = mass<microtonne, detail::one_rep>{};
inline constexpr auto mt = mass<millitonne, detail::one_rep>{};
inline constexpr auto ct = mass<centitonne, detail::one_rep>{};
inline constexpr auto dt = mass<decitonne, detail::one_rep>{};
inline constexpr auto dat = mass<decatonne, detail::one_rep>{};
inline constexpr auto ht = mass<hectotonne, detail::one_rep>{};
inline constexpr auto kt = mass<kilotonne, detail::one_rep>{};
inline constexpr auto Mt = mass<megatonne, detail::one_rep>{};
inline constexpr auto Gt = mass<gigatonne, detail::one_rep>{};
inline constexpr auto Tt = mass<teratonne, detail::one_rep>{};
inline constexpr auto Pt = mass<petatonne, detail::one_rep>{};
inline constexpr auto Et = mass<exatonne, detail::one_rep>{};
inline constexpr auto Zt = mass<zettatonne, detail::one_rep>{};
inline constexpr auto Yt = mass<yottatonne, detail::one_rep>{};
inline constexpr auto Da = mass<dalton, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/thermodynamic_temperature.h>
#include <units/quantity.h>

Expand All @@ -42,4 +43,10 @@ constexpr auto operator"" _q_K(long double l) { return thermodynamic_temperature

} // namespace literals

namespace unit_constants {

inline constexpr auto K = thermodynamic_temperature<kelvin, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
18 changes: 18 additions & 0 deletions src/include/units/physical/si/base/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#pragma once

#include <units/bits/one_rep.h>
#include <units/physical/dimensions/time.h>
#include <units/physical/si/prefixes.h>
#include <units/quantity.h>
Expand Down Expand Up @@ -98,4 +99,21 @@ constexpr auto operator"" _q_d(long double l) { return time<day, long double>(l)

} // namespace literals

namespace unit_constants {

inline constexpr auto ys = time<yoctosecond, detail::one_rep>{};
inline constexpr auto zs = time<zeptosecond, detail::one_rep>{};
inline constexpr auto as = time<attosecond, detail::one_rep>{};
inline constexpr auto fs = time<femtosecond, detail::one_rep>{};
inline constexpr auto ps = time<picosecond, detail::one_rep>{};
inline constexpr auto ns = time<nanosecond, detail::one_rep>{};
inline constexpr auto us = time<microsecond, detail::one_rep>{};
inline constexpr auto ms = time<millisecond, detail::one_rep>{};
inline constexpr auto s = time<second, detail::one_rep>{};
inline constexpr auto min = time<minute, detail::one_rep>{};
inline constexpr auto h = time<hour, detail::one_rep>{};
inline constexpr auto d = time<day, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si
8 changes: 7 additions & 1 deletion src/include/units/physical/si/cgs/base/length.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ inline namespace literals {
constexpr auto operator"" _q_cm(unsigned long long l) { return length<centimetre, std::int64_t>(l); }
constexpr auto operator"" _q_cm(long double l) { return length<centimetre, long double>(l); }

}
} // namespace literals

namespace unit_constants {

inline constexpr auto cm = length<centimetre, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si::cgs
8 changes: 7 additions & 1 deletion src/include/units/physical/si/cgs/base/mass.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ inline namespace literals {
constexpr auto operator"" _q_g(unsigned long long l) { return mass<gram, std::int64_t>(l); }
constexpr auto operator"" _q_g(long double l) { return mass<gram, long double>(l); }

}
} // namespace literals

namespace unit_constants {

inline constexpr auto g = mass<gram, detail::one_rep>{};

} // namespace unit_constants

} // namespace units::physical::si::cgs
Loading

0 comments on commit 8dede0d

Please sign in to comment.