style: clang-format applied to the remaining files

This commit is contained in:
Mateusz Pusz
2022-04-02 21:36:42 +02:00
parent 0dca41b5ae
commit b221dace3f
109 changed files with 4546 additions and 3140 deletions

View File

@ -25,8 +25,8 @@
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
#include <units/isq/si/length.h> // IWYU pragma: keep
#include <units/isq/si/time.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/quantity_io.h>
#include <exception>
#include <iostream>
@ -35,38 +35,31 @@ namespace {
using namespace units::isq;
constexpr si::speed<si::metre_per_second, int>
fixed_int_si_avg_speed(si::length<si::metre, int> d,
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
si::time<si::second, int> t)
{
return d / t;
}
constexpr si::speed<si::metre_per_second>
fixed_double_si_avg_speed(si::length<si::metre> d,
si::time<si::second> t)
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
{
return d / t;
}
template<typename U1, typename R1, typename U2, typename R2>
constexpr Speed auto si_avg_speed(si::length<U1, R1> d,
si::time<U2, R2> t)
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
template<Length D, Time T, Speed V>
void print_result(D distance, T duration, V speed)
{
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
std::cout << "Average speed of a car that makes " << distance << " in "
<< duration << " is " << result_in_kmph << ".\n";
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
<< ".\n";
}
void example()
@ -94,7 +87,8 @@ void example()
std::cout << "\nSI units with 'double' as representation\n";
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration,
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -130,7 +124,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// also it is not possible to make a lossless conversion of miles to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -169,7 +165,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
@ -178,7 +176,6 @@ void example()
print_result(distance, duration, avg_speed(distance, duration));
}
}
} // namespace
@ -187,11 +184,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -40,7 +40,7 @@ namespace {
using namespace units::aliases::isq::si;
inline constexpr auto g = units::isq::si::si2019::standard_gravity<>;
inline constexpr auto g = units::isq::si::si2019::standard_gravity<>; // NOLINT(readability-identifier-length)
inline constexpr auto air_density = kg_per_m3<>(1.225);
class Box {
@ -48,7 +48,10 @@ class Box {
length::m<> height_;
density::kg_per_m3<> density_ = air_density;
public:
constexpr Box(const length::m<>& length, const length::m<>& width, length::m<> height): base_(length * width), height_(std::move(height)) {}
constexpr Box(const length::m<>& length, const length::m<>& width, length::m<> height) :
base_(length * width), height_(std::move(height))
{
}
[[nodiscard]] constexpr force::N<> filled_weight() const
{

View File

@ -52,7 +52,7 @@ struct Ship {
};
// Print 'a' in its current units and print its value cast to the units in each of Args
template<class ...Args, units::Quantity Q>
template<class... Args, units::Quantity Q>
auto fmt_line(const Q a)
{
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
@ -67,12 +67,17 @@ void print_details(std::string_view description, const Ship& ship)
<< STD_FMT::format("{:20} : {}\n", "draft", fmt_line<si::fps::length::yd<>, si::length::m<>>(ship.draft))
<< STD_FMT::format("{:20} : {}\n", "beam", fmt_line<si::fps::length::yd<>, si::length::m<>>(ship.beam))
<< STD_FMT::format("{:20} : {}\n", "mass", fmt_line<si::fps::mass::lton<>, si::mass::t<>>(ship.mass))
<< STD_FMT::format("{:20} : {}\n", "speed", fmt_line<si::fps::speed::knot<>, si::speed::km_per_h<>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "speed",
fmt_line<si::fps::speed::knot<>, si::speed::km_per_h<>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "power", fmt_line<si::fps::power::hp<>, si::power::kW<>>(ship.power))
<< STD_FMT::format("{:20} : {}\n", "main guns", fmt_line<si::fps::length::in<>, si::length::mm<>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",fmt_line<si::fps::mass::lton<>, si::mass::kg<>>(ship.shellMass))
<< STD_FMT::format("{:20} : {}\n", "fire shells at",fmt_line<si::fps::speed::mph<>, si::speed::km_per_h<>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line<si::volume::m3<>, si::volume::l<>>(ship.mass / waterDensity));
<< STD_FMT::format("{:20} : {}\n", "main guns",
fmt_line<si::fps::length::in<>, si::length::mm<>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
fmt_line<si::fps::mass::lton<>, si::mass::kg<>>(ship.shellMass))
<< STD_FMT::format("{:20} : {}\n", "fire shells at",
fmt_line<si::fps::speed::mph<>, si::speed::km_per_h<>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
fmt_line<si::volume::m3<>, si::volume::l<>>(ship.mass / waterDensity));
}
int main()
@ -82,13 +87,37 @@ int main()
using units::aliases::isq::si::fps::length::ft; // to disambiguate from si::femptotonne
// KMS Bismark, using the units the Germans would use, taken from Wiki
auto bismark = Ship{.length{m<>(251.)}, .draft{m<>(9.3)}, .beam{m<>(36)}, .speed{km_per_h<>(56)}, .mass{t<>(50'300)}, .mainGuns{mm<>(380)}, .shellMass{kg<>(800)}, .shellSpeed{m_per_s<>(820.)}, .power{kW<>(110.45)}};
auto bismark = Ship{.length{m<>(251.)},
.draft{m<>(9.3)},
.beam{m<>(36)},
.speed{km_per_h<>(56)},
.mass{t<>(50'300)},
.mainGuns{mm<>(380)},
.shellMass{kg<>(800)},
.shellSpeed{m_per_s<>(820.)},
.power{kW<>(110.45)}};
// USS Iowa, using units from the foot-pound-second system
auto iowa = Ship{.length{ft<>(860.)}, .draft{ft<>(37.) + in<>(2.)}, .beam{ft<>(108.) + in<>(2.)}, .speed{knot<>(33)}, .mass{lton<>(57'540)}, .mainGuns{in<>(16)}, .shellMass{lb<>(2700)}, .shellSpeed{ft_per_s<>(2690.)}, .power{hp<>(212'000)}};
auto iowa = Ship{.length{ft<>(860.)},
.draft{ft<>(37.) + in<>(2.)},
.beam{ft<>(108.) + in<>(2.)},
.speed{knot<>(33)},
.mass{lton<>(57'540)},
.mainGuns{in<>(16)},
.shellMass{lb<>(2700)},
.shellSpeed{ft_per_s<>(2690.)},
.power{hp<>(212'000)}};
// HMS King George V, using units from the foot-pound-second system
auto kgv = Ship{.length{ft<>(745.1)}, .draft{ft<>(33.) + in<>(7.5)}, .beam{ft<>(103.2) + in<>(2.5)}, .speed{knot<>(28.3)}, .mass{lton<>(42'245)}, .mainGuns{in<>(14)}, .shellMass{lb<>(1'590)}, .shellSpeed{ft_per_s<>(2483)}, .power{hp<>(110'000)}};
auto kgv = Ship{.length{ft<>(745.1)},
.draft{ft<>(33.) + in<>(7.5)},
.beam{ft<>(103.2) + in<>(2.5)},
.speed{knot<>(28.3)},
.mass{lton<>(42'245)},
.mainGuns{in<>(14)},
.shellMass{lb<>(1'590)},
.shellSpeed{ft_per_s<>(2483)},
.power{hp<>(110'000)}};
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
std::cout << "\n\n";

View File

@ -25,7 +25,6 @@
#include <units/chrono.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/international/length.h>
#include <array>
#include <exception>
#include <iostream>
@ -43,14 +42,14 @@ using namespace units::isq;
auto get_gliders()
{
using namespace units::aliases::isq::si;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
static const std::array gliders = {
glider{"SZD-30 Pirat", {velocity(km_per_h<>(83)), rate_of_climb(m_per_s<>(-0.7389))}},
glider{"SZD-51 Junior", {velocity(km_per_h<>(80)), rate_of_climb(m_per_s<>(-0.6349))}},
glider{"SZD-48 Jantar Std 3", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.77355))}},
glider{"SZD-56 Diana", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.63657))}}};
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
return gliders;
}
@ -76,7 +75,7 @@ auto get_waypoints()
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, glider>
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
void print(const R& gliders)
{
std::cout << "Gliders:\n";
@ -85,13 +84,14 @@ void print(const R& gliders)
std::cout << "- Name: " << g.name << "\n";
std::cout << "- Polar:\n";
for (const auto& p : g.polar)
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v, units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v,
units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << "\n";
}
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
void print(const R& conditions)
{
std::cout << "Weather:\n";
@ -106,7 +106,7 @@ void print(const R& conditions)
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, waypoint>
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
void print(const R& waypoints)
{
std::cout << "Waypoints:\n";
@ -125,7 +125,8 @@ void print(const task& t)
std::cout << "- Finish: " << t.get_finish().name << "\n";
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
std::cout << "- Legs: " << "\n";
std::cout << "- Legs: "
<< "\n";
for (const auto& l : t.get_legs())
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
std::cout << "\n";

View File

@ -20,14 +20,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <units/format.h>
#include <units/isq/si/energy.h> // IWYU pragma: keep
#include <units/isq/si/force.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/format.h>
#include <units/quantity_io.h>
#include <linear_algebra.hpp>
#include <iostream>
#include <linear_algebra.hpp>
namespace STD_LA {
@ -72,9 +72,9 @@ void vector_of_quantity_add()
{
std::cout << "\nvector_of_quantity_add:\n";
vector<length::m<>> v = { m<>(1), m<>(2), m<>(3) };
vector<length::m<>> u = { m<>(3), m<>(2), m<>(1) };
vector<length::km<>> t = { km<>(3), km<>(2), km<>(1) };
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
vector<length::km<>> t = {km<>(3), km<>(2), km<>(1)};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -89,8 +89,8 @@ void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<length::m<>> v = { m<>(1), m<>(2), m<>(3) };
vector<length::m<>> u = { m<>(3), m<>(2), m<>(1) };
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -103,8 +103,8 @@ void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<force::N<>> v = { N<>(1), N<>(2), N<>(3) };
vector<length::m<>> u = { m<>(3), m<>(2), m<>(1) };
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -118,7 +118,7 @@ void vector_of_quantity_divide_by_scalar()
{
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
vector<length::m<>> v = { m<>(4), m<>(8), m<>(12) };
vector<length::m<>> v = {m<>(4), m<>(8), m<>(12)};
std::cout << "v = " << v << "\n";
@ -139,9 +139,9 @@ void matrix_of_quantity_add()
{
std::cout << "\nmatrix_of_quantity_add:\n";
matrix<length::m<>> v = {{ m<>(1), m<>(2), m<>(3) }, { m<>(4), m<>(5), m<>(6) }, { m<>(7), m<>(8), m<>(9) }};
matrix<length::m<>> u = {{ m<>(3), m<>(2), m<>(1) }, { m<>(3), m<>(2), m<>(1) }, { m<>(3), m<>(2), m<>(1) }};
matrix<length::mm<>> t = {{ mm<>(3), mm<>(2), mm<>(1) }, { mm<>(3), mm<>(2), mm<>(1) }, { mm<>(3), mm<>(2), mm<>(1) }};
matrix<length::m<>> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
matrix<length::m<>> u = {{m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}};
matrix<length::mm<>> t = {{mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -158,8 +158,8 @@ void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<length::m<>> v = {{ m<>(1), m<>(2), m<>(3) }, { m<>(4), m<>(5), m<>(6) }, { m<>(7), m<>(8), m<>(9) }};
vector<length::m<>> u = { m<>(3), m<>(2), m<>(1) };
matrix<length::m<>> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -172,8 +172,8 @@ void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<force::N<>> v = { N<>(1), N<>(2), N<>(3) };
matrix<length::m<>> u = {{ m<>(1), m<>(2), m<>(3) }, { m<>(4), m<>(5), m<>(6) }, { m<>(7), m<>(8), m<>(9) }};
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
matrix<length::m<>> u = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -187,7 +187,7 @@ void matrix_of_quantity_divide_by_scalar()
{
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
matrix<length::m<>> v = {{ m<>(2), m<>(4), m<>(6) }, { m<>(4), m<>(6), m<>(8) }, { m<>(8), m<>(4), m<>(2) }};
matrix<length::m<>> v = {{m<>(2), m<>(4), m<>(6)}, {m<>(4), m<>(6), m<>(8)}, {m<>(8), m<>(4), m<>(2)}};
std::cout << "v =\n" << v << "\n";
@ -216,9 +216,9 @@ void quantity_of_vector_add()
{
std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<si::kilometre> t(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -233,8 +233,8 @@ void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -247,8 +247,8 @@ void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -262,7 +262,7 @@ void quantity_of_vector_divide_by_scalar()
{
std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
length_v<> v(vector<>{ 4, 8, 12 });
length_v<> v(vector<>{4, 8, 12});
std::cout << "v = " << v << "\n";
@ -286,9 +286,9 @@ void quantity_of_matrix_add()
{
std::cout << "\nquantity_of_matrix_add:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_m<> u(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<si::kilometre> t(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -305,8 +305,8 @@ void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_v<> u(vector<>{ 3, 2, 1 });
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -319,8 +319,8 @@ void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_m<> u(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -334,7 +334,7 @@ void quantity_of_matrix_divide_by_scalar()
{
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
length_m<> v(matrix<>{{ 2, 4, 6 }, { 4, 6, 8 }, { 8, 4, 2 }});
length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}});
std::cout << "v =\n" << v << "\n";

View File

@ -38,8 +38,7 @@ public:
measurement() = default;
constexpr explicit measurement(const value_type& val, const value_type& err = {}) :
value_(val)
constexpr explicit measurement(const value_type& val, const value_type& err = {}) : value_(val)
{
// it sucks that using declaration cannot be provided for a constructor initializer list
using namespace std;

View File

@ -21,11 +21,11 @@
// SOFTWARE.
#include <units/isq/natural/natural.h>
#include <units/isq/si/constants.h>
#include <units/isq/si/energy.h>
#include <units/isq/si/mass.h>
#include <units/isq/si/momentum.h>
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/isq/si/constants.h>
#include <units/math.h>
#include <units/quantity_io.h>
#include <exception>
@ -92,11 +92,9 @@ int main()
try {
si_example();
natural_example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -44,7 +44,8 @@ void example()
Time auto t1 = s<>(10);
Speed auto v1 = avg_speed(d1, t1);
auto temp1 = v1 * m<>(50); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
auto temp1 =
v1 * m<>(50); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
Speed auto v2 = temp1 / m<>(100); // back to known dimensions again
Length auto d2 = v2 * s<>(60);
@ -62,11 +63,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -54,7 +54,8 @@ int main()
std::cout << STD_FMT::format("therefore ratio lengthA / lengthB == {}\n\n", lengthA / lengthB);
std::cout << STD_FMT::format("conversion factor from lengthA::unit of {:%q} to lengthB::unit of {:%q}:\n\n", lengthA, lengthB)
std::cout << STD_FMT::format("conversion factor from lengthA::unit of {:%q} to lengthB::unit of {:%q}:\n\n", lengthA,
lengthB)
<< STD_FMT::format("lengthB.number( {} ) == lengthA.number( {} ) * conversion_factor( {} )\n",
lengthB.number(), lengthA.number(), conversion_factor(lengthB, lengthA));
}

View File

@ -66,10 +66,7 @@ using length = quantity<dim_length, U, Rep>;
} // namespace si
template<typename Q, typename U>
concept castable_to = Quantity<Q> && Unit<U> &&
requires (Q q) {
quantity_cast<U>(q);
};
concept castable_to = Quantity<Q> && Unit<U> && requires(Q q) { quantity_cast<U>(q); };
void conversions()
{

View File

@ -49,7 +49,8 @@ distance spherical_distance(position from, position to)
if constexpr (sizeof(rep) >= 8) {
// spherical law of cosines
const auto central_angle = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1));
// const auto central_angle = 2 * asin(sqrt(0.5 - cos(lat2 - lat1) / 2 + cos(lat1) * cos(lat2) * (1 - cos(lon2 - lon1)) / 2));
// const auto central_angle = 2 * asin(sqrt(0.5 - cos(lat2 - lat1) / 2 + cos(lat1) * cos(lat2) * (1 - cos(lon2 -
// lon1)) / 2));
return distance(earth_radius * central_angle);
} else {
// the haversine formula

View File

@ -34,7 +34,8 @@ task::legs task::make_legs(const waypoints& wpts)
task::legs res;
res.reserve(wpts.size() - 1);
auto to_leg = [](const waypoint& w1, const waypoint& w2) { return task::leg(w1, w2); };
std::ranges::transform(wpts.cbegin(), prev(wpts.cend()), next(wpts.cbegin()), wpts.cend(), std::back_inserter(res), to_leg);
std::ranges::transform(wpts.cbegin(), prev(wpts.cend()), next(wpts.cbegin()), wpts.cend(), std::back_inserter(res),
to_leg);
return res;
}
@ -64,24 +65,23 @@ distance glide_distance(const flight_point& pos, const glider& g, const task& t,
((ground_alt - t.get_finish().alt) / dist_to_finish - 1 / glide_ratio(g.polar[0])));
}
}
} // namespace glide_computer
namespace {
using namespace glide_computer;
void print(std::string_view phase_name, timestamp start_ts, const glide_computer::flight_point& point, const glide_computer::flight_point& new_point)
void print(std::string_view phase_name, timestamp start_ts, const glide_computer::flight_point& point,
const glide_computer::flight_point& new_point)
{
std::cout << STD_FMT::format(
"| {:<12} | {:>9%.1Q %q} (Total: {:>9%.1Q %q}) | {:>8%.1Q %q} (Total: {:>8%.1Q %q}) | {:>7%.0Q %q} ({:>6%.0Q %q}) |\n",
"| {:<12} | {:>9%.1Q %q} (Total: {:>9%.1Q %q}) | {:>8%.1Q %q} (Total: {:>8%.1Q %q}) | {:>7%.0Q %q} ({:>6%.0Q %q}) "
"|\n",
phase_name, quantity_cast<si::minute>(new_point.ts - point.ts), quantity_cast<si::minute>(new_point.ts - start_ts),
new_point.dist - point.dist, new_point.dist, new_point.alt - point.alt, new_point.alt);
}
flight_point takeoff(timestamp start_ts, const task& t)
{
return {start_ts, t.get_start().alt};
}
flight_point takeoff(timestamp start_ts, const task& t) { return {start_ts, t.get_start().alt}; }
flight_point tow(timestamp start_ts, const flight_point& pos, const aircraft_tow& at)
{
@ -92,7 +92,8 @@ flight_point tow(timestamp start_ts, const flight_point& pos, const aircraft_tow
return new_pos;
}
flight_point circle(timestamp start_ts, const flight_point& pos, const glider& g, const weather& w, const task& t, height& height_to_gain)
flight_point circle(timestamp start_ts, const flight_point& pos, const glider& g, const weather& w, const task& t,
height& height_to_gain)
{
const height h_agl = agl(pos.alt, terrain_level_alt(t, pos));
const height circling_height = std::min(w.cloud_base - h_agl, height_to_gain);
@ -114,7 +115,8 @@ flight_point glide(timestamp start_ts, const flight_point& pos, const glider& g,
const auto alt = ground_alt + s.min_agl_height;
const auto l3d = length_3d(dist, pos.alt - alt);
const duration d = l3d / g.polar[0].v.common();
const flight_point new_pos{pos.ts + d, terrain_level_alt(t, pos) + s.min_agl_height, t.get_leg_index(new_distance), new_distance};
const flight_point new_pos{pos.ts + d, terrain_level_alt(t, pos) + s.min_agl_height, t.get_leg_index(new_distance),
new_distance};
print("Glide", start_ts, pos, new_pos);
return new_pos;
@ -135,9 +137,11 @@ flight_point final_glide(timestamp start_ts, const flight_point& pos, const glid
namespace glide_computer {
void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s, const aircraft_tow& at)
void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s,
const aircraft_tow& at)
{
std::cout << STD_FMT::format("| {:<12} | {:^28} | {:^26} | {:^21} |\n", "Flight phase", "Duration", "Distance", "Height");
std::cout << STD_FMT::format("| {:<12} | {:^28} | {:^26} | {:^21} |\n", "Flight phase", "Duration", "Distance",
"Height");
std::cout << STD_FMT::format("|{0:-^14}|{0:-^30}|{0:-^28}|{0:-^23}|\n", "");
// ready to takeoff

View File

@ -25,7 +25,6 @@
#include <units/bits/fmt_hacks.h>
#include <units/isq/si/length.h>
#include <units/quantity_kind.h>
#include <limits>
#include <ostream>

View File

@ -69,7 +69,7 @@ namespace glide_computer {
template<units::QuantityKind QK1, units::QuantityKind QK2>
constexpr units::Dimensionless auto operator/(const QK1& lhs, const QK2& rhs)
requires(!units::QuantityKindRelatedTo<QK1, QK2>) && requires { lhs.common() / rhs.common();}
requires(!units::QuantityKindRelatedTo<QK1, QK2>) && requires { lhs.common() / rhs.common(); }
{
return lhs.common() / rhs.common();
}
@ -149,7 +149,7 @@ public:
const waypoint* end_;
distance length_ = geographic::spherical_distance(begin().pos, end().pos);
public:
leg(const waypoint& b, const waypoint& e) noexcept: begin_(&b), end_(&e) {}
leg(const waypoint& b, const waypoint& e) noexcept : begin_(&b), end_(&e) {}
constexpr const waypoint& begin() const { return *begin_; };
constexpr const waypoint& end() const { return *end_; }
constexpr const distance get_length() const { return length_; }
@ -157,8 +157,11 @@ public:
using legs = std::vector<leg>;
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, waypoint>
explicit task(const R& r) : waypoints_(std::ranges::begin(r), std::ranges::end(r)) {}
requires std::same_as<std::ranges::range_value_t<R>,
waypoint> explicit task(const R& r) :
waypoints_(std::ranges::begin(r), std::ranges::end(r))
{
}
task(std::initializer_list<waypoint> wpts) : waypoints_(wpts) {}
@ -170,10 +173,14 @@ public:
distance get_length() const { return length_; }
distance get_leg_dist_offset(std::size_t leg_index) const { return leg_index == 0 ? distance{} : leg_total_distances_[leg_index - 1]; }
distance get_leg_dist_offset(std::size_t leg_index) const
{
return leg_index == 0 ? distance{} : leg_total_distances_[leg_index - 1];
}
std::size_t get_leg_index(distance dist) const
{
return static_cast<std::size_t>(std::ranges::distance(leg_total_distances_.cbegin(), std::ranges::lower_bound(leg_total_distances_, dist)));
return static_cast<std::size_t>(
std::ranges::distance(leg_total_distances_.cbegin(), std::ranges::lower_bound(leg_total_distances_, dist)));
}
private:
@ -214,6 +221,7 @@ inline units::isq::si::length<units::isq::si::kilometre> length_3d(distance dist
distance glide_distance(const flight_point& pos, const glider& g, const task& t, const safety& s, altitude ground_alt);
void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s, const aircraft_tow& at);
void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s,
const aircraft_tow& at);
} // namespace glide_computer

View File

@ -31,10 +31,7 @@
using namespace units::isq;
constexpr Speed auto avg_speed(Length auto d, Time auto t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
int main()
{

View File

@ -34,7 +34,8 @@
namespace kalman {
template<typename T>
concept QuantityOrQuantityPoint = units::Quantity<T> || units::QuantityPoint<T>; // TODO Should it also account for `kinds`?
concept QuantityOrQuantityPoint =
units::Quantity<T> || units::QuantityPoint<T>; // TODO Should it also account for `kinds`?
template<typename... Qs>
inline constexpr bool are_derivatives = false;
@ -44,32 +45,40 @@ inline constexpr bool are_derivatives<Q> = true;
template<typename Q1, typename Q2, typename... Qs>
inline constexpr bool are_derivatives<Q1, Q2, Qs...> =
units::DimensionOfT<typename decltype(Q1::reference / Q2::reference)::dimension, units::isq::dim_time> && // TODO Think on how to simplify this
units::DimensionOfT<typename decltype(Q1::reference / Q2::reference)::dimension,
units::isq::dim_time> && // TODO Think on how to simplify this
are_derivatives<Q2, Qs...>;
// state
template<QuantityOrQuantityPoint... QQPs>
requires (sizeof...(QQPs) > 0) && (sizeof...(QQPs) <= 3) && are_derivatives<QQPs...>
requires(sizeof...(QQPs) > 0) && (sizeof...(QQPs) <= 3) && are_derivatives<QQPs...>
struct state {
std::tuple<QQPs...> variables_;
constexpr state(QQPs... qqps): variables_(std::move(qqps)...) {}
constexpr state(QQPs... qqps) : variables_(std::move(qqps)...) {}
};
template<typename T>
concept State = units::is_specialization_of<T, state>;
template<std::size_t Idx, typename... Qs>
constexpr auto& get(state<Qs...>& s) { return get<Idx>(s.variables_); }
constexpr auto& get(state<Qs...>& s)
{
return get<Idx>(s.variables_);
}
template<std::size_t Idx, typename... Qs>
constexpr const auto& get(const state<Qs...>& s) { return get<Idx>(s.variables_); }
constexpr const auto& get(const state<Qs...>& s)
{
return get<Idx>(s.variables_);
}
// estimation
template<QuantityOrQuantityPoint QQP, QuantityOrQuantityPoint... QQPs>
struct estimation {
private:
using uncertainty_ref = decltype(QQP::reference * QQP::reference);
using uncertainty_type = units::quantity<typename uncertainty_ref::dimension, typename uncertainty_ref::unit, typename QQP::rep>;
using uncertainty_type =
units::quantity<typename uncertainty_ref::dimension, typename uncertainty_ref::unit, typename QQP::rep>;
public:
kalman::state<QQP, QQPs...> state; // TODO extend kalman functions to work with this variadic patermater list
uncertainty_type uncertainty;
@ -94,7 +103,7 @@ template<typename Q, QuantityOrQuantityPoint QM, units::Dimensionless K>
requires units::equivalent<typename Q::dimension, typename QM::dimension>
constexpr state<Q> state_update(const state<Q>& predicted, QM measured, K gain)
{
return { get<0>(predicted) + gain * (measured - get<0>(predicted)) };
return {get<0>(predicted) + gain * (measured - get<0>(predicted))};
}
template<typename Q1, typename Q2, QuantityOrQuantityPoint QM, units::Dimensionless K, units::isq::Time T>
@ -103,17 +112,18 @@ constexpr state<Q1, Q2> state_update(const state<Q1, Q2>& predicted, QM measured
{
const auto q1 = get<0>(predicted) + get<0>(gain) * (measured - get<0>(predicted));
const auto q2 = get<1>(predicted) + get<1>(gain) * (measured - get<0>(predicted)) / interval;
return { q1, q2 };
return {q1, q2};
}
template<typename Q1, typename Q2, typename Q3, QuantityOrQuantityPoint QM, units::Dimensionless K, units::isq::Time T>
requires units::equivalent<typename Q1::dimension, typename QM::dimension>
constexpr state<Q1, Q2, Q3> state_update(const state<Q1, Q2, Q3>& predicted, QM measured, std::array<K, 3> gain, T interval)
constexpr state<Q1, Q2, Q3> state_update(const state<Q1, Q2, Q3>& predicted, QM measured, std::array<K, 3> gain,
T interval)
{
const auto q1 = get<0>(predicted) + get<0>(gain) * (measured - get<0>(predicted));
const auto q2 = get<1>(predicted) + get<1>(gain) * (measured - get<0>(predicted)) / interval;
const auto q3 = get<2>(predicted) + get<2>(gain) * (measured - get<0>(predicted)) / (interval * interval / 2);
return { q1, q2, q3 };
return {q1, q2, q3};
}
// covariance update
@ -129,7 +139,7 @@ constexpr state<Q1, Q2> state_extrapolation(const state<Q1, Q2>& estimated, T in
{
const auto q1 = get<0>(estimated) + get<1>(estimated) * interval;
const auto q2 = get<1>(estimated);
return { q1, q2 };
return {q1, q2};
}
template<typename Q1, typename Q2, typename Q3, units::isq::Time T>
@ -138,7 +148,7 @@ constexpr state<Q1, Q2, Q3> state_extrapolation(const state<Q1, Q2, Q3>& estimat
const auto q1 = get<0>(estimated) + get<1>(estimated) * interval + get<2>(estimated) * pow<2>(interval) / 2;
const auto q2 = get<1>(estimated) + get<2>(estimated) * interval;
const auto q3 = get<2>(estimated);
return { q1, q2, q3 };
return {q1, q2, q3};
}
// covariance extrapolation
@ -164,24 +174,26 @@ struct STD_FMT::formatter<kalman::state<Qs...>> {
std::string value_buffer;
auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) {
if constexpr(sizeof...(Qs) == 1)
if constexpr (sizeof...(Qs) == 1)
STD_FMT::format_to(to_value_buffer, "{1:%.{0}Q %q}", specs.precision, kalman::get<0>(s));
else if constexpr(sizeof...(Qs) == 2)
STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", specs.precision, kalman::get<0>(s), kalman::get<1>(s));
else if constexpr (sizeof...(Qs) == 2)
STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", specs.precision, kalman::get<0>(s),
kalman::get<1>(s));
else
STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}", specs.precision, kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
}
else {
if constexpr(sizeof...(Qs) == 1)
STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}", specs.precision,
kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
} else {
if constexpr (sizeof...(Qs) == 1)
STD_FMT::format_to(to_value_buffer, "{}", kalman::get<0>(s));
else if constexpr(sizeof...(Qs) == 2)
else if constexpr (sizeof...(Qs) == 2)
STD_FMT::format_to(to_value_buffer, "{{ {}, {} }}", kalman::get<0>(s), kalman::get<1>(s));
else
STD_FMT::format_to(to_value_buffer, "{{ {}, {}, {} }}", kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
STD_FMT::format_to(to_value_buffer, "{{ {}, {}, {} }}", kalman::get<0>(s), kalman::get<1>(s),
kalman::get<2>(s));
}
std::string global_format_buffer;
units::detail::quantity_global_format_specs<char> global_specs = { specs.fill, specs.align, specs.width };
units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width};
units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return STD_FMT::vformat_to(ctx.out(), global_format_buffer, STD_FMT::make_format_args(value_buffer));
@ -202,7 +214,7 @@ struct STD_FMT::formatter<kalman::estimation<Q>> {
auto format(kalman::estimation<Q> e, FormatContext& ctx)
{
units::Quantity auto q = [](const Q& t) {
if constexpr(units::Quantity<Q>)
if constexpr (units::Quantity<Q>)
return t;
else
return t.relative();
@ -212,13 +224,12 @@ struct STD_FMT::formatter<kalman::estimation<Q>> {
auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) {
STD_FMT::format_to(to_value_buffer, "{0:%.{2}Q} ± {1:%.{2}Q} {0:%q}", q, sqrt(e.uncertainty), specs.precision);
}
else {
} else {
STD_FMT::format_to(to_value_buffer, "{0:%Q} ± {1:%Q} {0:%q}", q, sqrt(e.uncertainty));
}
std::string global_format_buffer;
units::detail::quantity_global_format_specs<char> global_specs = { specs.fill, specs.align, specs.width };
units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width};
units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return STD_FMT::vformat_to(ctx.out(), global_format_buffer, STD_FMT::make_format_args(value_buffer));

View File

@ -21,9 +21,9 @@
// SOFTWARE.
#include "kalman.h"
#include <units/isq/si/mass.h>
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/mass.h>
#include <array>
#include <iostream>
@ -34,10 +34,12 @@ using namespace units;
void print_header(const kalman::State auto& initial)
{
std::cout << STD_FMT::format("Initial: {}\n", initial);
std::cout << STD_FMT::format("{:>2} | {:>9} | {:>8} | {:>14} | {:>14}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
std::cout << STD_FMT::format("{:>2} | {:>9} | {:>8} | {:>14} | {:>14}\n", "N", "Gain", "Measured", "Curr. Estimate",
"Next Estimate");
}
void print(auto iteration, Dimensionless auto gain, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
void print(auto iteration, Dimensionless auto gain, Quantity auto measured, const kalman::State auto& current,
const kalman::State auto& next)
{
std::cout << STD_FMT::format("{:2} | {:9} | {:8} | {:14} | {:14}\n", iteration, gain, measured, current, next);
}
@ -48,13 +50,13 @@ int main()
using namespace units::isq::si::references;
using state = kalman::state<si::mass<si::gram>>;
const state initial = { 1 * kg };
const std::array measurements = { 1030 * g, 989 * g, 1017 * g, 1009 * g, 1013 * g,
979 * g, 1008 * g, 1042 * g, 1012 * g, 1011 * g };
const state initial = {1 * kg};
const std::array measurements = {1030 * g, 989 * g, 1017 * g, 1009 * g, 1013 * g,
979 * g, 1008 * g, 1042 * g, 1012 * g, 1011 * g};
print_header(initial);
state next = initial;
for(int index = 1; const auto& m : measurements) {
for (int index = 1; const auto& m : measurements) {
const auto& previous = next;
const dimensionless<one> gain = 1. / index;
const auto current = state_update(previous, m, gain);

View File

@ -21,11 +21,11 @@
// SOFTWARE.
#include "kalman.h"
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <array>
#include <iostream>
@ -51,14 +51,14 @@ int main()
using state = kalman::state<si::length<si::metre>, si::speed<si::metre_per_second>>;
const auto interval = 5 * s;
const state initial = { 30 * km, 40 * (m / s) };
const std::array measurements = { 30110 * m, 30265 * m, 30740 * m, 30750 * m, 31135 * m,
31015 * m, 31180 * m, 31610 * m, 31960 * m, 31865 * m };
const state initial = {30 * km, 40 * (m / s)};
const std::array measurements = {30110 * m, 30265 * m, 30740 * m, 30750 * m, 31135 * m,
31015 * m, 31180 * m, 31610 * m, 31960 * m, 31865 * m};
std::array gain = {dimensionless<one>(0.2), dimensionless<one>(0.1)};
print_header(initial);
state next = state_extrapolation(initial, interval);
for(int index = 1; const auto& measured : measurements) {
for (int index = 1; const auto& measured : measurements) {
const auto& previous = next;
const auto current = state_update(previous, measured, gain, interval);
next = state_extrapolation(current, interval);

View File

@ -21,11 +21,11 @@
// SOFTWARE.
#include "kalman.h"
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <array>
#include <iostream>
@ -51,14 +51,14 @@ int main()
using state = kalman::state<si::length<si::metre>, si::speed<si::metre_per_second>>;
const auto interval = 5 * s;
const state initial = { 30 * km, 50 * (m / s) };
const std::array measurements = { 30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m,
32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m };
const state initial = {30 * km, 50 * (m / s)};
const std::array measurements = {30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m,
32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m};
std::array gain = {dimensionless<one>(0.2), dimensionless<one>(0.1)};
print_header(initial);
state next = state_extrapolation(initial, interval);
for(int index = 1; const auto& measured : measurements) {
for (int index = 1; const auto& measured : measurements) {
const auto& previous = next;
const auto current = state_update(previous, measured, gain, interval);
next = state_extrapolation(current, interval);

View File

@ -21,12 +21,12 @@
// SOFTWARE.
#include "kalman.h"
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/acceleration.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/format.h>
#include <units/generic/dimensionless.h>
#include <array>
#include <iostream>
@ -49,19 +49,20 @@ int main()
{
using namespace units::isq;
using namespace units::isq::si::references;
using state = kalman::state<si::length<si::metre>, si::speed<si::metre_per_second>, si::acceleration<si::metre_per_second_sq>>;
using state =
kalman::state<si::length<si::metre>, si::speed<si::metre_per_second>, si::acceleration<si::metre_per_second_sq>>;
constexpr auto mps = m / s;
constexpr auto mps2 = mps / s;
const auto interval = 5. * s;
const state initial = { 30 * km, 50 * mps, 0 * mps2 };
const std::array measurements = { 30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m,
32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m };
const state initial = {30 * km, 50 * mps, 0 * mps2};
const std::array measurements = {30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m,
32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m};
std::array gain = {dimensionless<one>(0.5), dimensionless<one>(0.4), dimensionless<one>(0.1)};
print_header(initial);
state next = state_extrapolation(initial, interval);
for(int index = 1; const auto& measured : measurements) {
for (int index = 1; const auto& measured : measurements) {
const auto& previous = next;
const auto current = state_update(previous, measured, gain, interval);
next = state_extrapolation(current, interval);

View File

@ -21,8 +21,8 @@
// SOFTWARE.
#include "kalman.h"
#include <units/isq/si/length.h>
#include <units/format.h>
#include <units/isq/si/length.h>
#include <units/math.h>
#include <array>
#include <iostream>
@ -35,13 +35,15 @@ template<Quantity Q>
void print_header(kalman::estimation<Q> initial)
{
std::cout << STD_FMT::format("Initial: {}\n", initial);
std::cout << STD_FMT::format("{:>2} | {:>5} | {:>8} | {:>16} | {:>16}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
std::cout << STD_FMT::format("{:>2} | {:>5} | {:>8} | {:>16} | {:>16}\n", "N", "Gain", "Measured", "Curr. Estimate",
"Next Estimate");
}
template<Quantity Q, Dimensionless K>
void print(auto iteration, K gain, Q measured, kalman::estimation<Q> current, kalman::estimation<Q> next)
{
std::cout << STD_FMT::format("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured, current, next);
std::cout << STD_FMT::format("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured, current,
next);
}
int main()
@ -50,20 +52,20 @@ int main()
using namespace units::isq;
using namespace units::isq::si::references;
const estimation initial = { state{ 60. * m }, pow<2>(15. * m) };
const std::array measurements = { 48.54 * m, 47.11 * m, 55.01 * m, 55.15 * m, 49.89 * m,
40.85 * m, 46.72 * m, 50.05 * m, 51.27 * m, 49.95 * m };
const estimation initial = {state{60. * m}, pow<2>(15. * m)};
const std::array measurements = {48.54 * m, 47.11 * m, 55.01 * m, 55.15 * m, 49.89 * m,
40.85 * m, 46.72 * m, 50.05 * m, 51.27 * m, 49.95 * m};
const auto measurement_uncertainty = pow<2>(5. * m);
auto update = [=]<Quantity Q>(const estimation<Q>& previous, const Q& meassurement, Dimensionless auto gain) {
return estimation{ state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain) };
return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)};
};
auto predict = []<Quantity Q>(const estimation<Q>& current) { return current; };
print_header(initial);
estimation next = predict(initial);
for(int index = 1; const auto& measured : measurements) {
for (int index = 1; const auto& measured : measurements) {
const auto& previous = next;
const auto gain = kalman_gain(previous.uncertainty, measurement_uncertainty);
const estimation current = update(previous, measured, gain);

View File

@ -21,8 +21,8 @@
// SOFTWARE.
#include "kalman.h"
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/format.h>
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/math.h>
#include <units/quantity_point.h>
#include <units/unit.h>
@ -56,13 +56,15 @@ template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial)
{
std::cout << STD_FMT::format("Initial: {}\n", initial);
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", "Curr. Estimate",
"Next Estimate");
}
template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{
std::cout << STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, measured.relative(), current, next);
std::cout << STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain,
measured.relative(), current, next);
}
int main()
@ -72,32 +74,25 @@ int main()
using namespace units::isq::si::references;
const auto process_noise_variance = 0.0001 * (deg_C * deg_C);
const estimation initial = { state{ quantity_point(10. * deg_C) }, pow<2>(100. * deg_C) };
const std::array measurements = {
quantity_point(49.95 * deg_C),
quantity_point(49.967 * deg_C),
quantity_point(50.1 * deg_C),
quantity_point(50.106 * deg_C),
quantity_point(49.992 * deg_C),
quantity_point(49.819 * deg_C),
quantity_point(49.933 * deg_C),
quantity_point(50.007 * deg_C),
quantity_point(50.023 * deg_C),
quantity_point(49.99 * deg_C)
};
const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)};
const std::array measurements = {quantity_point(49.95 * deg_C), quantity_point(49.967 * deg_C),
quantity_point(50.1 * deg_C), quantity_point(50.106 * deg_C),
quantity_point(49.992 * deg_C), quantity_point(49.819 * deg_C),
quantity_point(49.933 * deg_C), quantity_point(50.007 * deg_C),
quantity_point(50.023 * deg_C), quantity_point(49.99 * deg_C)};
const auto measurement_uncertainty = pow<2>(0.1 * deg_C);
auto update = [=]<QuantityPoint QP>(const estimation<QP>& previous, const QP& meassurement, Dimensionless auto gain) {
return estimation{ state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain) };
return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)};
};
auto predict = [=]<QuantityPoint QP>(const estimation<QP>& current) {
return estimation{ current.state, covariance_extrapolation(current.uncertainty, process_noise_variance) };
return estimation{current.state, covariance_extrapolation(current.uncertainty, process_noise_variance)};
};
print_header(initial);
estimation next = predict(initial);
for(int index = 1; const auto& m : measurements) {
for (int index = 1; const auto& m : measurements) {
const auto& previous = next;
const auto gain = kalman_gain(previous.uncertainty, measurement_uncertainty);
const estimation current = update(previous, m, gain);

View File

@ -21,8 +21,8 @@
// SOFTWARE.
#include "kalman.h"
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/format.h>
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/math.h>
#include <units/quantity_point.h>
#include <units/unit.h>
@ -56,13 +56,15 @@ template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial)
{
std::cout << STD_FMT::format("Initial: {}\n", initial);
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", "Curr. Estimate",
"Next Estimate");
}
template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{
std::cout << STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, measured.relative(), current, next);
std::cout << STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain,
measured.relative(), current, next);
}
int main()
@ -72,32 +74,25 @@ int main()
using namespace units::isq::si::references;
const auto process_noise_variance = 0.0001 * (deg_C * deg_C);
const estimation initial = { state{ quantity_point(10. * deg_C) }, pow<2>(100. * deg_C) };
const std::array measurements = {
quantity_point(50.45 * deg_C),
quantity_point(50.967 * deg_C),
quantity_point(51.6 * deg_C),
quantity_point(52.106 * deg_C),
quantity_point(52.492 * deg_C),
quantity_point(52.819 * deg_C),
quantity_point(53.433 * deg_C),
quantity_point(54.007 * deg_C),
quantity_point(54.523 * deg_C),
quantity_point(54.99 * deg_C)
};
const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)};
const std::array measurements = {quantity_point(50.45 * deg_C), quantity_point(50.967 * deg_C),
quantity_point(51.6 * deg_C), quantity_point(52.106 * deg_C),
quantity_point(52.492 * deg_C), quantity_point(52.819 * deg_C),
quantity_point(53.433 * deg_C), quantity_point(54.007 * deg_C),
quantity_point(54.523 * deg_C), quantity_point(54.99 * deg_C)};
const auto measurement_uncertainty = pow<2>(0.1 * deg_C);
auto update = [=]<QuantityPoint QP>(const estimation<QP>& previous, const QP& meassurement, Dimensionless auto gain) {
return estimation{ state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain) };
return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)};
};
auto predict = [=]<QuantityPoint QP>(const estimation<QP>& current) {
return estimation{ current.state, covariance_extrapolation(current.uncertainty, process_noise_variance) };
return estimation{current.state, covariance_extrapolation(current.uncertainty, process_noise_variance)};
};
print_header(initial);
estimation next = predict(initial);
for(int index = 1; const auto& m : measurements) {
for (int index = 1; const auto& m : measurements) {
const auto& previous = next;
const auto gain = kalman_gain(previous.uncertainty, measurement_uncertainty);
const estimation current = update(previous, m, gain);

View File

@ -21,8 +21,8 @@
// SOFTWARE.
#include "kalman.h"
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/format.h>
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/math.h>
#include <units/quantity_point.h>
#include <units/unit.h>
@ -56,13 +56,15 @@ template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial)
{
std::cout << STD_FMT::format("Initial: {}\n", initial);
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>16} | {:>16}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
std::cout << STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>16} | {:>16}\n", "N", "Gain", "Measured", "Curr. Estimate",
"Next Estimate");
}
template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{
std::cout << STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain, measured.relative(), current, next);
std::cout << STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain,
measured.relative(), current, next);
}
int main()
@ -72,32 +74,25 @@ int main()
using namespace units::isq::si::references;
const auto process_noise_variance = 0.15 * (deg_C * deg_C);
const estimation initial = { state{ quantity_point(10. * deg_C) }, pow<2>(100. * deg_C) };
const std::array measurements = {
quantity_point(50.45 * deg_C),
quantity_point(50.967 * deg_C),
quantity_point(51.6 * deg_C),
quantity_point(52.106 * deg_C),
quantity_point(52.492 * deg_C),
quantity_point(52.819 * deg_C),
quantity_point(53.433 * deg_C),
quantity_point(54.007 * deg_C),
quantity_point(54.523 * deg_C),
quantity_point(54.99 * deg_C)
};
const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)};
const std::array measurements = {quantity_point(50.45 * deg_C), quantity_point(50.967 * deg_C),
quantity_point(51.6 * deg_C), quantity_point(52.106 * deg_C),
quantity_point(52.492 * deg_C), quantity_point(52.819 * deg_C),
quantity_point(53.433 * deg_C), quantity_point(54.007 * deg_C),
quantity_point(54.523 * deg_C), quantity_point(54.99 * deg_C)};
const auto measurement_uncertainty = pow<2>(0.1 * deg_C);
auto update = [=]<QuantityPoint QP>(const estimation<QP>& previous, const QP& meassurement, Dimensionless auto gain) {
return estimation{ state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain) };
return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)};
};
auto predict = [=]<QuantityPoint QP>(const estimation<QP>& current) {
return estimation{ current.state, covariance_extrapolation(current.uncertainty, process_noise_variance) };
return estimation{current.state, covariance_extrapolation(current.uncertainty, process_noise_variance)};
};
print_header(initial);
estimation next = predict(initial);
for(int index = 1; const auto& m : measurements) {
for (int index = 1; const auto& m : measurements) {
const auto& previous = next;
const auto gain = kalman_gain(previous.uncertainty, measurement_uncertainty);
const estimation current = update(previous, m, gain);

View File

@ -25,8 +25,8 @@
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
#include <units/isq/si/length.h> // IWYU pragma: keep
#include <units/isq/si/time.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/quantity_io.h>
#include <exception>
#include <iostream>
@ -35,38 +35,31 @@ namespace {
using namespace units::isq;
constexpr si::speed<si::metre_per_second, int>
fixed_int_si_avg_speed(si::length<si::metre, int> d,
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
si::time<si::second, int> t)
{
return d / t;
}
constexpr si::speed<si::metre_per_second>
fixed_double_si_avg_speed(si::length<si::metre> d,
si::time<si::second> t)
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
{
return d / t;
}
template<typename U1, typename R1, typename U2, typename R2>
constexpr Speed auto si_avg_speed(si::length<U1, R1> d,
si::time<U2, R2> t)
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
template<Length D, Time T, Speed V>
void print_result(D distance, T duration, V speed)
{
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
std::cout << "Average speed of a car that makes " << distance << " in "
<< duration << " is " << result_in_kmph << ".\n";
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
<< ".\n";
}
void example()
@ -94,7 +87,8 @@ void example()
std::cout << "\nSI units with 'double' as representation\n";
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration,
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -130,7 +124,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// also it is not possible to make a lossless conversion of miles to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -167,7 +163,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
@ -176,7 +174,6 @@ void example()
print_result(distance, duration, avg_speed(distance, duration));
}
}
} // namespace
@ -185,11 +182,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -56,7 +56,10 @@ class Box {
si::length<m> height_;
si::density<kgpm3> density_ = air_density;
public:
constexpr Box(const si::length<m>& length, const si::length<m>& width, si::length<m> height) : base_(length * width), height_(std::move(height)) {}
constexpr Box(const si::length<m>& length, const si::length<m>& width, si::length<m> height) :
base_(length * width), height_(std::move(height))
{
}
[[nodiscard]] constexpr si::force<N> filled_weight() const
{

View File

@ -53,7 +53,7 @@ struct Ship {
};
// Print 'a' in its current units and print its value cast to the units in each of Args
template<class ...Args, units::Quantity Q>
template<class... Args, units::Quantity Q>
auto fmt_line(const Q a)
{
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
@ -65,16 +65,27 @@ void print_details(std::string_view description, const Ship& ship)
using namespace units::isq::si::fps::literals;
const auto waterDensity = 62.4_q_lb_per_ft3;
std::cout << STD_FMT::format("{}\n", description);
std::cout << STD_FMT::format("{:20} : {}\n", "length", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
<< STD_FMT::format("{:20} : {}\n", "draft", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
<< STD_FMT::format("{:20} : {}\n", "beam", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
<< STD_FMT::format("{:20} : {}\n", "mass", fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
<< STD_FMT::format("{:20} : {}\n", "speed", fmt_line<si::fps::speed<si::fps::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "power", fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
<< STD_FMT::format("{:20} : {}\n", "main guns", fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
<< STD_FMT::format("{:20} : {}\n", "fire shells at",fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
std::cout << STD_FMT::format("{:20} : {}\n", "length",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
<< STD_FMT::format("{:20} : {}\n", "draft",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
<< STD_FMT::format("{:20} : {}\n", "beam",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
<< STD_FMT::format("{:20} : {}\n", "mass",
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
<< STD_FMT::format("{:20} : {}\n", "speed",
fmt_line<si::fps::speed<si::fps::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "power",
fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
<< STD_FMT::format("{:20} : {}\n", "main guns",
fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
<< STD_FMT::format(
"{:20} : {}\n", "fire shells at",
fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
}
int main()
@ -83,13 +94,37 @@ int main()
using namespace units::isq::si::fps::literals;
// KMS Bismark, using the units the Germans would use, taken from Wiki
auto bismark = Ship{.length{251._q_m}, .draft{9.3_q_m}, .beam{36_q_m}, .speed{56_q_km_per_h}, .mass{50'300_q_t}, .mainGuns{380_q_mm}, .shellMass{800_q_kg}, .shellSpeed{820._q_m_per_s}, .power{110.45_q_kW}};
auto bismark = Ship{.length{251._q_m},
.draft{9.3_q_m},
.beam{36_q_m},
.speed{56_q_km_per_h},
.mass{50'300_q_t},
.mainGuns{380_q_mm},
.shellMass{800_q_kg},
.shellSpeed{820._q_m_per_s},
.power{110.45_q_kW}};
// USS Iowa, using units from the foot-pound-second system
auto iowa = Ship{.length{860._q_ft}, .draft{37._q_ft + 2._q_in}, .beam{108._q_ft + 2._q_in}, .speed{33_q_knot}, .mass{57'540_q_lton}, .mainGuns{16_q_in}, .shellMass{2700_q_lb}, .shellSpeed{2690._q_ft_per_s}, .power{212'000_q_hp}};
auto iowa = Ship{.length{860._q_ft},
.draft{37._q_ft + 2._q_in},
.beam{108._q_ft + 2._q_in},
.speed{33_q_knot},
.mass{57'540_q_lton},
.mainGuns{16_q_in},
.shellMass{2700_q_lb},
.shellSpeed{2690._q_ft_per_s},
.power{212'000_q_hp}};
// HMS King George V, using units from the foot-pound-second system
auto kgv = Ship{.length{745.1_q_ft}, .draft{33._q_ft + 7.5_q_in}, .beam{103.2_q_ft + 2.5_q_in}, .speed{28.3_q_knot}, .mass{42'245_q_lton}, .mainGuns{14_q_in}, .shellMass{1'590_q_lb}, .shellSpeed{2483._q_ft_per_s}, .power{110'000_q_hp}};
auto kgv = Ship{.length{745.1_q_ft},
.draft{33._q_ft + 7.5_q_in},
.beam{103.2_q_ft + 2.5_q_in},
.speed{28.3_q_knot},
.mass{42'245_q_lton},
.mainGuns{14_q_in},
.shellMass{1'590_q_lb},
.shellSpeed{2483._q_ft_per_s},
.power{110'000_q_hp}};
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
std::cout << "\n\n";

View File

@ -25,7 +25,6 @@
#include <units/chrono.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/international/length.h>
#include <array>
#include <exception>
#include <iostream>
@ -43,14 +42,14 @@ using namespace units::isq;
auto get_gliders()
{
using namespace si::literals;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
static const std::array gliders = {
glider{"SZD-30 Pirat", {velocity(83_q_km_per_h), rate_of_climb(-0.7389_q_m_per_s)}},
glider{"SZD-51 Junior", {velocity(80_q_km_per_h), rate_of_climb(-0.6349_q_m_per_s)}},
glider{"SZD-48 Jantar Std 3", {velocity(110_q_km_per_h), rate_of_climb(-0.77355_q_m_per_s)}},
glider{"SZD-56 Diana", {velocity(110_q_km_per_h), rate_of_climb(-0.63657_q_m_per_s)}}};
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
return gliders;
}
@ -76,7 +75,7 @@ auto get_waypoints()
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, glider>
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
void print(const R& gliders)
{
std::cout << "Gliders:\n";
@ -85,13 +84,14 @@ void print(const R& gliders)
std::cout << "- Name: " << g.name << "\n";
std::cout << "- Polar:\n";
for (const auto& p : g.polar)
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v, units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v,
units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << "\n";
}
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
void print(const R& conditions)
{
std::cout << "Weather:\n";
@ -106,7 +106,7 @@ void print(const R& conditions)
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, waypoint>
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
void print(const R& waypoints)
{
std::cout << "Waypoints:\n";
@ -125,7 +125,8 @@ void print(const task& t)
std::cout << "- Finish: " << t.get_finish().name << "\n";
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
std::cout << "- Legs: " << "\n";
std::cout << "- Legs: "
<< "\n";
for (const auto& l : t.get_legs())
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
std::cout << "\n";

View File

@ -20,14 +20,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <units/format.h>
#include <units/isq/si/energy.h> // IWYU pragma: keep
#include <units/isq/si/force.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/format.h>
#include <units/quantity_io.h>
#include <linear_algebra.hpp>
#include <iostream>
#include <linear_algebra.hpp>
namespace STD_LA {
@ -73,9 +73,9 @@ void vector_of_quantity_add()
{
std::cout << "\nvector_of_quantity_add:\n";
vector<si::length<si::metre>> v = { 1_q_m, 2_q_m, 3_q_m };
vector<si::length<si::metre>> u = { 3_q_m, 2_q_m, 1_q_m };
vector<si::length<si::kilometre>> t = { 3_q_km, 2_q_km, 1_q_km };
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
vector<si::length<si::kilometre>> t = {3_q_km, 2_q_km, 1_q_km};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -90,8 +90,8 @@ void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<si::length<si::metre>> v = { 1_q_m, 2_q_m, 3_q_m };
vector<si::length<si::metre>> u = { 3_q_m, 2_q_m, 1_q_m };
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -104,8 +104,8 @@ void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = { 1_q_N, 2_q_N, 3_q_N };
vector<si::length<si::metre>> u = { 3_q_m, 2_q_m, 1_q_m };
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -119,7 +119,7 @@ void vector_of_quantity_divide_by_scalar()
{
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
vector<si::length<si::metre>> v = { 4_q_m, 8_q_m, 12_q_m };
vector<si::length<si::metre>> v = {4_q_m, 8_q_m, 12_q_m};
std::cout << "v = " << v << "\n";
@ -140,9 +140,9 @@ void matrix_of_quantity_add()
{
std::cout << "\nmatrix_of_quantity_add:\n";
matrix<si::length<si::metre>> v = {{ 1_q_m, 2_q_m, 3_q_m }, { 4_q_m, 5_q_m, 6_q_m }, { 7_q_m, 8_q_m, 9_q_m }};
matrix<si::length<si::metre>> u = {{ 3_q_m, 2_q_m, 1_q_m }, { 3_q_m, 2_q_m, 1_q_m }, { 3_q_m, 2_q_m, 1_q_m }};
matrix<si::length<si::millimetre>> t = {{ 3_q_mm, 2_q_mm, 1_q_mm }, { 3_q_mm, 2_q_mm, 1_q_mm }, { 3_q_mm, 2_q_mm, 1_q_mm }};
matrix<si::length<si::metre>> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
matrix<si::length<si::metre>> u = {{3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}};
matrix<si::length<si::millimetre>> t = {{3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -159,8 +159,8 @@ void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<si::length<si::metre>> v = {{ 1_q_m, 2_q_m, 3_q_m }, { 4_q_m, 5_q_m, 6_q_m }, { 7_q_m, 8_q_m, 9_q_m }};
vector<si::length<si::metre>> u = { 3_q_m, 2_q_m, 1_q_m };
matrix<si::length<si::metre>> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -173,8 +173,8 @@ void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = { 1_q_N, 2_q_N, 3_q_N };
matrix<si::length<si::metre>> u = {{ 1_q_m, 2_q_m, 3_q_m }, { 4_q_m, 5_q_m, 6_q_m }, { 7_q_m, 8_q_m, 9_q_m }};
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
matrix<si::length<si::metre>> u = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -188,7 +188,7 @@ void matrix_of_quantity_divide_by_scalar()
{
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
matrix<si::length<si::metre>> v = {{ 2_q_m, 4_q_m, 6_q_m }, { 4_q_m, 6_q_m, 8_q_m }, { 8_q_m, 4_q_m, 2_q_m }};
matrix<si::length<si::metre>> v = {{2_q_m, 4_q_m, 6_q_m}, {4_q_m, 6_q_m, 8_q_m}, {8_q_m, 4_q_m, 2_q_m}};
std::cout << "v =\n" << v << "\n";
@ -215,9 +215,9 @@ void quantity_of_vector_add()
{
std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<si::kilometre> t(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -232,8 +232,8 @@ void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -246,8 +246,8 @@ void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -261,7 +261,7 @@ void quantity_of_vector_divide_by_scalar()
{
std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
length_v<> v(vector<>{ 4, 8, 12 });
length_v<> v(vector<>{4, 8, 12});
std::cout << "v = " << v << "\n";
@ -285,9 +285,9 @@ void quantity_of_matrix_add()
{
std::cout << "\nquantity_of_matrix_add:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_m<> u(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<si::kilometre> t(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -304,8 +304,8 @@ void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_v<> u(vector<>{ 3, 2, 1 });
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -318,8 +318,8 @@ void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_m<> u(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -333,7 +333,7 @@ void quantity_of_matrix_divide_by_scalar()
{
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
length_m<> v(matrix<>{{ 2, 4, 6 }, { 4, 6, 8 }, { 8, 4, 2 }});
length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}});
std::cout << "v =\n" << v << "\n";

View File

@ -21,11 +21,11 @@
// SOFTWARE.
#include <units/isq/natural/natural.h>
#include <units/isq/si/constants.h>
#include <units/isq/si/energy.h>
#include <units/isq/si/mass.h>
#include <units/isq/si/momentum.h>
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/isq/si/constants.h>
#include <units/math.h>
#include <units/quantity_io.h>
#include <exception>
@ -95,11 +95,9 @@ int main()
try {
si_example();
natural_example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -44,7 +44,8 @@ void example()
Time auto t1 = 10_q_s;
Speed auto v1 = avg_speed(d1, t1);
auto temp1 = v1 * 50_q_m; // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
auto temp1 =
v1 * 50_q_m; // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
Speed auto v2 = temp1 / 100_q_m; // back to known dimensions again
Length auto d2 = v2 * 60_q_s;
@ -62,11 +63,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -38,8 +38,7 @@ public:
measurement() = default;
constexpr explicit measurement(const value_type& val, const value_type& err = {}) :
value_(val)
constexpr explicit measurement(const value_type& val, const value_type& err = {}) : value_(val)
{
// it sucks that using declaration cannot be provided for a constructor initializer list
using namespace std;
@ -133,7 +132,8 @@ void example()
const Speed auto v1 = a * t;
#if UNITS_DOWNCAST_MODE == 0
std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast<si::dim_speed, si::kilometre_per_hour>(v1) << '\n';
std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast<si::dim_speed, si::kilometre_per_hour>(v1)
<< '\n';
#else
std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast<si::kilometre_per_hour>(v1) << '\n';
#endif

View File

@ -25,8 +25,8 @@
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
#include <units/isq/si/length.h> // IWYU pragma: keep
#include <units/isq/si/time.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/quantity_io.h>
#include <exception>
#include <iostream>
@ -35,38 +35,31 @@ namespace {
using namespace units::isq;
constexpr si::speed<si::metre_per_second, int>
fixed_int_si_avg_speed(si::length<si::metre, int> d,
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
si::time<si::second, int> t)
{
return d / t;
}
constexpr si::speed<si::metre_per_second>
fixed_double_si_avg_speed(si::length<si::metre> d,
si::time<si::second> t)
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
{
return d / t;
}
template<typename U1, typename R1, typename U2, typename R2>
constexpr Speed auto si_avg_speed(si::length<U1, R1> d,
si::time<U2, R2> t)
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t)
{
return d / t;
}
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
template<Length D, Time T, Speed V>
void print_result(D distance, T duration, V speed)
{
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
std::cout << "Average speed of a car that makes " << distance << " in "
<< duration << " is " << result_in_kmph << ".\n";
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
<< ".\n";
}
void example()
@ -94,7 +87,8 @@ void example()
std::cout << "\nSI units with 'double' as representation\n";
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration,
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -130,7 +124,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// also it is not possible to make a lossless conversion of miles to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
print_result(distance, duration, si_avg_speed(distance, duration));
@ -169,7 +165,9 @@ void example()
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
// (explicit cast needed)
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(
distance, duration,
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
@ -178,7 +176,6 @@ void example()
print_result(distance, duration, avg_speed(distance, duration));
}
}
} // namespace
@ -187,11 +184,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -50,7 +50,10 @@ class Box {
si::length<si::metre> height_;
si::density<si::kilogram_per_metre_cub> density_ = air_density;
public:
constexpr Box(const si::length<si::metre>& length, const si::length<si::metre>& width, si::length<si::metre> height) : base_(length * width), height_(std::move(height)) {}
constexpr Box(const si::length<si::metre>& length, const si::length<si::metre>& width, si::length<si::metre> height) :
base_(length * width), height_(std::move(height))
{
}
[[nodiscard]] constexpr si::force<si::newton> filled_weight() const
{

View File

@ -39,15 +39,15 @@ void simple_quantities()
using distance = si::length<si::metre>;
using duration = si::time<si::second>;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW
constexpr distance km = 1.0 * references::km;
constexpr distance miles = 1.0 * mi;
constexpr duration sec = 1 * s;
constexpr duration min = 1 * references::min;
constexpr duration hr = 1 * h;
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
std::cout << "A physical quantities library can choose the simple\n";
std::cout << "option to provide output using a single type for each base unit:\n\n";
@ -66,8 +66,8 @@ void quantities_with_typed_units()
using namespace units::isq::si::international;
using namespace units::isq::si::international::references;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW
constexpr length<kilometre> km = 1.0 * si::references::km;
constexpr length<mile> miles = 1.0 * mi;
@ -76,7 +76,7 @@ UNITS_DIAGNOSTIC_IGNORE_SHADOW
constexpr si::time<second> sec = 1 * s;
constexpr si::time<minute> min = 1 * si::references::min;
constexpr si::time<hour> hr = 1 * h;
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
std::cout << "A more flexible option is to provide separate types for each unit,\n\n";
std::cout << km << '\n';

View File

@ -56,7 +56,7 @@ struct Ship {
};
// Print 'a' in its current units and print its value cast to the units in each of Args
template<class ...Args, units::Quantity Q>
template<class... Args, units::Quantity Q>
auto fmt_line(const Q a)
{
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
@ -68,16 +68,27 @@ void print_details(std::string_view description, const Ship& ship)
using namespace units::isq::si::fps::references;
const auto waterDensity = 62.4 * (lb / ft3);
std::cout << STD_FMT::format("{}\n", description);
std::cout << STD_FMT::format("{:20} : {}\n", "length", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
<< STD_FMT::format("{:20} : {}\n", "draft", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
<< STD_FMT::format("{:20} : {}\n", "beam", fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
<< STD_FMT::format("{:20} : {}\n", "mass", fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
<< STD_FMT::format("{:20} : {}\n", "speed", fmt_line<si::fps::speed<si::fps::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "power", fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
<< STD_FMT::format("{:20} : {}\n", "main guns", fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing", fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
<< STD_FMT::format("{:20} : {}\n", "fire shells at", fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
std::cout << STD_FMT::format("{:20} : {}\n", "length",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
<< STD_FMT::format("{:20} : {}\n", "draft",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
<< STD_FMT::format("{:20} : {}\n", "beam",
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
<< STD_FMT::format("{:20} : {}\n", "mass",
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
<< STD_FMT::format("{:20} : {}\n", "speed",
fmt_line<si::fps::speed<si::fps::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
<< STD_FMT::format("{:20} : {}\n", "power",
fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
<< STD_FMT::format("{:20} : {}\n", "main guns",
fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
<< STD_FMT::format(
"{:20} : {}\n", "fire shells at",
fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
}
int main()
@ -87,13 +98,37 @@ int main()
using units::isq::si::fps::references::ft; // collides with si::femtotonne (alias unit of mass)
// KMS Bismark, using the units the Germans would use, taken from Wiki
auto bismark = Ship{.length{251. * m}, .draft{9.3 * m}, .beam{36 * m}, .speed{56 * (km / h)}, .mass{50'300 * t}, .mainGuns{380 * mm}, .shellMass{800 * kg}, .shellSpeed{820. * (m / s)}, .power{110.45 * kW}};
auto bismark = Ship{.length{251. * m},
.draft{9.3 * m},
.beam{36 * m},
.speed{56 * (km / h)},
.mass{50'300 * t},
.mainGuns{380 * mm},
.shellMass{800 * kg},
.shellSpeed{820. * (m / s)},
.power{110.45 * kW}};
// USS Iowa, using units from the foot-pound-second system
auto iowa = Ship{.length{860. * ft}, .draft{37. * ft + 2. * in}, .beam{108. * ft + 2. * in}, .speed{33 * knot}, .mass{57'540 * lton}, .mainGuns{16 * in}, .shellMass{2700 * lb}, .shellSpeed{2690. * (ft / s)}, .power{212'000 * hp}};
auto iowa = Ship{.length{860. * ft},
.draft{37. * ft + 2. * in},
.beam{108. * ft + 2. * in},
.speed{33 * knot},
.mass{57'540 * lton},
.mainGuns{16 * in},
.shellMass{2700 * lb},
.shellSpeed{2690. * (ft / s)},
.power{212'000 * hp}};
// HMS King George V, using units from the foot-pound-second system
auto kgv = Ship{.length{745.1 * ft}, .draft{33. * ft + 7.5 * in}, .beam{103.2 * ft + 2.5 * in}, .speed{28.3 * knot}, .mass{42'245 * lton}, .mainGuns{14 * in}, .shellMass{1'590 * lb}, .shellSpeed{2483. * (ft / s)}, .power{110'000 * hp}};
auto kgv = Ship{.length{745.1 * ft},
.draft{33. * ft + 7.5 * in},
.beam{103.2 * ft + 2.5 * in},
.speed{28.3 * knot},
.mass{42'245 * lton},
.mainGuns{14 * in},
.shellMass{1'590 * lb},
.shellSpeed{2483. * (ft / s)},
.power{110'000 * hp}};
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
std::cout << "\n\n";

View File

@ -25,7 +25,6 @@
#include <units/chrono.h>
#include <units/generic/dimensionless.h>
#include <units/isq/si/international/length.h>
#include <array>
#include <exception>
#include <iostream>
@ -43,14 +42,14 @@ using namespace units::isq;
auto get_gliders()
{
using namespace si::references;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
static const std::array gliders = {
glider{"SZD-30 Pirat", {velocity(83 * (km / h)), rate_of_climb(-0.7389 * (m / s))}},
glider{"SZD-51 Junior", {velocity(80 * (km / h)), rate_of_climb(-0.6349 * (m / s))}},
glider{"SZD-48 Jantar Std 3", {velocity(110 * (km / h)), rate_of_climb(-0.77355 * (m / s))}},
glider{"SZD-56 Diana", {velocity(110 * (km / h)), rate_of_climb(-0.63657 * (m / s))}}};
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
return gliders;
}
@ -76,7 +75,7 @@ auto get_waypoints()
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, glider>
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
void print(const R& gliders)
{
std::cout << "Gliders:\n";
@ -85,13 +84,14 @@ void print(const R& gliders)
std::cout << "- Name: " << g.name << "\n";
std::cout << "- Polar:\n";
for (const auto& p : g.polar)
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v, units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q}\n", p.climb, p.v,
units::quantity_cast<units::one>(glide_ratio(g.polar[0])));
std::cout << "\n";
}
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
void print(const R& conditions)
{
std::cout << "Weather:\n";
@ -106,7 +106,7 @@ void print(const R& conditions)
}
template<std::ranges::input_range R>
requires std::same_as<std::ranges::range_value_t<R>, waypoint>
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
void print(const R& waypoints)
{
std::cout << "Waypoints:\n";
@ -125,7 +125,8 @@ void print(const task& t)
std::cout << "- Finish: " << t.get_finish().name << "\n";
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
std::cout << "- Legs: " << "\n";
std::cout << "- Legs: "
<< "\n";
for (const auto& l : t.get_legs())
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
std::cout << "\n";

View File

@ -20,14 +20,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <units/format.h>
#include <units/isq/si/energy.h> // IWYU pragma: keep
#include <units/isq/si/force.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h> // IWYU pragma: keep
#include <units/format.h>
#include <units/quantity_io.h>
#include <linear_algebra.hpp>
#include <iostream>
#include <linear_algebra.hpp>
namespace STD_LA {
@ -73,9 +73,9 @@ void vector_of_quantity_add()
{
std::cout << "\nvector_of_quantity_add:\n";
vector<si::length<si::metre>> v = { 1 * m, 2 * m, 3 * m };
vector<si::length<si::metre>> u = { 3 * m, 2 * m, 1 * m };
vector<si::length<si::kilometre>> t = { 3 * km, 2 * km, 1 * km };
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
vector<si::length<si::kilometre>> t = {3 * km, 2 * km, 1 * km};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -90,8 +90,8 @@ void vector_of_quantity_multiply_same()
{
std::cout << "\nvector_of_quantity_multiply_same:\n";
vector<si::length<si::metre>> v = { 1 * m, 2 * m, 3 * m };
vector<si::length<si::metre>> u = { 3 * m, 2 * m, 1 * m };
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -104,8 +104,8 @@ void vector_of_quantity_multiply_different()
{
std::cout << "\nvector_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = { 1 * N, 2 * N, 3 * N };
vector<si::length<si::metre>> u = { 3 * m, 2 * m, 1 * m };
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -119,7 +119,7 @@ void vector_of_quantity_divide_by_scalar()
{
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
vector<si::length<si::metre>> v = { 4 * m, 8 * m, 12 * m };
vector<si::length<si::metre>> v = {4 * m, 8 * m, 12 * m};
std::cout << "v = " << v << "\n";
@ -140,9 +140,9 @@ void matrix_of_quantity_add()
{
std::cout << "\nmatrix_of_quantity_add:\n";
matrix<si::length<si::metre>> v = {{ 1 * m, 2 * m, 3 * m }, { 4 * m, 5 * m, 6 * m }, { 7 * m, 8 * m, 9 * m }};
matrix<si::length<si::metre>> u = {{ 3 * m, 2 * m, 1 * m }, { 3 * m, 2 * m, 1 * m }, { 3 * m, 2 * m, 1 * m }};
matrix<si::length<si::millimetre>> t = {{ 3 * mm, 2 * mm, 1 * mm }, { 3 * mm, 2 * mm, 1 * mm }, { 3 * mm, 2 * mm, 1 * mm }};
matrix<si::length<si::metre>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
matrix<si::length<si::metre>> u = {{3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}};
matrix<si::length<si::millimetre>> t = {{3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -159,8 +159,8 @@ void matrix_of_quantity_multiply_same()
{
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
matrix<si::length<si::metre>> v = {{ 1 * m, 2 * m, 3 * m }, { 4 * m, 5 * m, 6 * m }, { 7 * m, 8 * m, 9 * m }};
vector<si::length<si::metre>> u = { 3 * m, 2 * m, 1 * m };
matrix<si::length<si::metre>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -173,8 +173,8 @@ void matrix_of_quantity_multiply_different()
{
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
vector<si::force<si::newton>> v = { 1 * N, 2 * N, 3 * N };
matrix<si::length<si::metre>> u = {{ 1 * m, 2 * m, 3 * m }, { 4 * m, 5 * m, 6 * m }, { 7 * m, 8 * m, 9 * m }};
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
matrix<si::length<si::metre>> u = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -188,7 +188,7 @@ void matrix_of_quantity_divide_by_scalar()
{
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
matrix<si::length<si::metre>> v = {{ 2 * m, 4 * m, 6 * m }, { 4 * m, 6 * m, 8 * m }, { 8 * m, 4 * m, 2 * m }};
matrix<si::length<si::metre>> v = {{2 * m, 4 * m, 6 * m}, {4 * m, 6 * m, 8 * m}, {8 * m, 4 * m, 2 * m}};
std::cout << "v =\n" << v << "\n";
@ -215,9 +215,9 @@ void quantity_of_vector_add()
{
std::cout << "\nquantity_of_vector_add:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<si::kilometre> t(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
length_v<si::kilometre> t(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -232,8 +232,8 @@ void quantity_of_vector_multiply_same()
{
std::cout << "\nquantity_of_vector_multiply_same:\n";
length_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
length_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -246,8 +246,8 @@ void quantity_of_vector_multiply_different()
{
std::cout << "\nquantity_of_vector_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_v<> u(vector<>{ 3, 2, 1 });
force_v<> v(vector<>{1, 2, 3});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v = " << v << "\n";
std::cout << "u = " << u << "\n";
@ -261,7 +261,7 @@ void quantity_of_vector_divide_by_scalar()
{
std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
length_v<> v(vector<>{ 4, 8, 12 });
length_v<> v(vector<>{4, 8, 12});
std::cout << "v = " << v << "\n";
@ -285,9 +285,9 @@ void quantity_of_matrix_add()
{
std::cout << "\nquantity_of_matrix_add:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_m<> u(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<si::kilometre> t(matrix<>{{ 3, 2, 1 }, { 3, 2, 1 }, { 3, 2, 1 }});
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -304,8 +304,8 @@ void quantity_of_matrix_multiply_same()
{
std::cout << "\nquantity_of_matrix_multiply_same:\n";
length_m<> v(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
length_v<> u(vector<>{ 3, 2, 1 });
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
length_v<> u(vector<>{3, 2, 1});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -318,8 +318,8 @@ void quantity_of_matrix_multiply_different()
{
std::cout << "\nquantity_of_matrix_multiply_different:\n";
force_v<> v(vector<>{ 1, 2, 3 });
length_m<> u(matrix<>{{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }});
force_v<> v(vector<>{1, 2, 3});
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
std::cout << "v =\n" << v << "\n";
std::cout << "u =\n" << u << "\n";
@ -333,7 +333,7 @@ void quantity_of_matrix_divide_by_scalar()
{
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
length_m<> v(matrix<>{{ 2, 4, 6 }, { 4, 6, 8 }, { 8, 4, 2 }});
length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}});
std::cout << "v =\n" << v << "\n";

View File

@ -94,11 +94,9 @@ int main()
try {
si_example();
natural_example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -44,7 +44,8 @@ void example()
Time auto t1 = 10 * s;
Speed auto v1 = avg_speed(d1, t1);
auto temp1 = v1 * (50 * m); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
auto temp1 =
v1 * (50 * m); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
Speed auto v2 = temp1 / (100 * m); // back to known dimensions again
Length auto d2 = v2 * (60 * s);
@ -62,11 +63,9 @@ int main()
{
try {
example();
}
catch (const std::exception& ex) {
} catch (const std::exception& ex) {
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
}
catch (...) {
} catch (...) {
std::cerr << "Unhandled unknown exception caught\n";
}
}

View File

@ -48,7 +48,11 @@ using angle = quantity<dim_angle<>, U, Rep>;
inline namespace literals {
// rad
constexpr auto operator"" _q_rad(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return angle<radian, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_rad(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return angle<radian, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_rad(long double l) { return angle<radian, long double>(l); }
} // namespace literals

View File

@ -44,7 +44,11 @@ using acceleration = quantity<dim_acceleration, U, Rep>;
inline namespace literals {
// ft/s2
constexpr auto operator"" _q_ft_per_s2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return acceleration<foot_per_second_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_per_s2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return acceleration<foot_per_second_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_per_s2(long double l) { return acceleration<foot_per_second_sq, long double>(l); }
} // namespace literals
@ -57,7 +61,8 @@ constexpr auto operator"" _q_ft_per_s2(long double l) { return acceleration<foot
namespace units::aliases::isq::si::fps::inline acceleration {
template<Representation Rep = double> using ft_per_s2 = units::isq::si::fps::acceleration<units::isq::si::fps::foot_per_second_sq, Rep>;
template<Representation Rep = double>
using ft_per_s2 = units::isq::si::fps::acceleration<units::isq::si::fps::foot_per_second_sq, Rep>;
} // namespace units::aliases::isq::si::fps::inline acceleration

View File

@ -46,7 +46,11 @@ using area = quantity<dim_area, U, Rep>;
inline namespace literals {
// ft2
constexpr auto operator"" _q_ft2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft2(long double l) { return area<square_foot, long double>(l); }
} // namespace literals
@ -75,8 +79,9 @@ using namespace area_references;
namespace units::aliases::isq::si::fps::inline area {
template<Representation Rep = double> using ft2 = units::isq::si::fps::area<units::isq::si::fps::square_foot, Rep>;
template<Representation Rep = double>
using ft2 = units::isq::si::fps::area<units::isq::si::fps::square_foot, Rep>;
} // namespace units::aliases::isq::si::fps::inlipne area
} // namespace units::aliases::isq::si::fps::inline area
#endif // UNITS_NO_ALIASES

View File

@ -28,8 +28,8 @@
#include <units/symbol_text.h>
// IWYU pragma: end_exports
#include <units/isq/si/fps/mass.h>
#include <units/isq/si/fps/length.h>
#include <units/isq/si/fps/mass.h>
#include <units/unit.h>
namespace units::isq::si::fps {
@ -46,7 +46,11 @@ using density = quantity<dim_density, U, Rep>;
inline namespace literals {
// lb/ft³
constexpr auto operator"" _q_lb_per_ft3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return density<pound_per_foot_cub, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_lb_per_ft3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return density<pound_per_foot_cub, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_lb_per_ft3(long double l) { return density<pound_per_foot_cub, long double>(l); }
} // namespace literals
@ -59,7 +63,8 @@ constexpr auto operator"" _q_lb_per_ft3(long double l) { return density<pound_pe
namespace units::aliases::isq::si::fps::inline density {
template<Representation Rep = double> using lb_per_ft3 = units::isq::si::fps::density<units::isq::si::fps::pound_per_foot_cub, Rep>;
template<Representation Rep = double>
using lb_per_ft3 = units::isq::si::fps::density<units::isq::si::fps::pound_per_foot_cub, Rep>;
} // namespace units::aliases::isq::si::fps::inline density

View File

@ -40,7 +40,7 @@ struct foot_poundal : unit<foot_poundal> {};
struct dim_energy : isq::dim_energy<dim_energy, foot_poundal, dim_length, dim_force> {};
// https://en.wikipedia.org/wiki/Foot-pound_(energy)
struct foot_pound_force : derived_unit<foot_pound_force, dim_energy, foot, pound_force> {};
struct foot_pound_force : derived_unit<foot_pound_force, dim_energy, foot, pound_force> {};
template<UnitOf<dim_energy> U, Representation Rep = double>
using energy = quantity<dim_energy, U, Rep>;
@ -50,11 +50,19 @@ using energy = quantity<dim_energy, U, Rep>;
inline namespace literals {
// foot poundal
constexpr auto operator"" _q_ft_pdl(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<foot_poundal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_pdl(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<foot_poundal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_pdl(long double l) { return energy<foot_poundal, long double>(l); }
// foot_pound force
constexpr auto operator"" _q_ft_lbf(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<foot_pound_force, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_lbf(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<foot_pound_force, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_lbf(long double l) { return energy<foot_pound_force, long double>(l); }
} // namespace literals
@ -67,8 +75,10 @@ constexpr auto operator"" _q_ft_lbf(long double l) { return energy<foot_pound_fo
namespace units::aliases::isq::si::fps::inline energy {
template<Representation Rep = double> using ft_pdl = units::isq::si::fps::energy<units::isq::si::fps::foot_poundal, Rep>;
template<Representation Rep = double> using ft_lbf = units::isq::si::fps::energy<units::isq::si::fps::foot_pound_force, Rep>;
template<Representation Rep = double>
using ft_pdl = units::isq::si::fps::energy<units::isq::si::fps::foot_poundal, Rep>;
template<Representation Rep = double>
using ft_lbf = units::isq::si::fps::energy<units::isq::si::fps::foot_pound_force, Rep>;
} // namespace units::aliases::isq::si::fps::inline energy

View File

@ -57,15 +57,27 @@ using force = quantity<dim_force, U, Rep>;
inline namespace literals {
// poundal
constexpr auto operator"" _q_pdl(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<poundal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pdl(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<poundal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pdl(long double l) { return force<poundal, long double>(l); }
// pound force
constexpr auto operator"" _q_lbf(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<pound_force, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_lbf(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<pound_force, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_lbf(long double l) { return force<pound_force, long double>(l); }
// kilopound force
constexpr auto operator"" _q_klbf(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<kilopound_force, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_klbf(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<kilopound_force, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_klbf(long double l) { return force<kilopound_force, long double>(l); }
} // namespace literals
@ -96,9 +108,12 @@ using namespace force_references;
namespace units::aliases::isq::si::fps::inline force {
template<Representation Rep = double> using pdl = units::isq::si::fps::force<units::isq::si::fps::poundal, Rep>;
template<Representation Rep = double> using lbf = units::isq::si::fps::force<units::isq::si::fps::pound_force, Rep>;
template<Representation Rep = double> using klbf = units::isq::si::fps::force<units::isq::si::fps::kilopound_force, Rep>;
template<Representation Rep = double>
using pdl = units::isq::si::fps::force<units::isq::si::fps::poundal, Rep>;
template<Representation Rep = double>
using lbf = units::isq::si::fps::force<units::isq::si::fps::pound_force, Rep>;
template<Representation Rep = double>
using klbf = units::isq::si::fps::force<units::isq::si::fps::kilopound_force, Rep>;
} // namespace units::aliases::isq::si::fps::inline force

View File

@ -23,17 +23,16 @@
#pragma once
// IWYU pragma: begin_exports
#include <units/isq/si/fps/length.h>
#include <units/isq/si/fps/mass.h>
#include <units/isq/si/fps/time.h>
#include <units/isq/si/fps/acceleration.h>
#include <units/isq/si/fps/area.h>
#include <units/isq/si/fps/density.h>
#include <units/isq/si/fps/energy.h>
#include <units/isq/si/fps/force.h>
#include <units/isq/si/fps/length.h>
#include <units/isq/si/fps/mass.h>
#include <units/isq/si/fps/power.h>
#include <units/isq/si/fps/pressure.h>
#include <units/isq/si/fps/speed.h>
#include <units/isq/si/fps/time.h>
#include <units/isq/si/fps/volume.h>
// IWYU pragma: end_exports

View File

@ -43,9 +43,12 @@ struct dim_pressure : isq::dim_pressure<dim_pressure, poundal_per_foot_sq, dim_f
template<UnitOf<dim_pressure> U, Representation Rep = double>
using pressure = quantity<dim_pressure, U, Rep>;
struct pound_force_per_foot_sq : named_scaled_unit<pound_force_per_foot_sq, "lbf ft2", si::prefix, ratio(32'174'049, 1'000'000), poundal_per_foot_sq> {};
struct pound_force_per_foot_sq :
named_scaled_unit<pound_force_per_foot_sq, "lbf ft2", si::prefix, ratio(32'174'049, 1'000'000),
poundal_per_foot_sq> {};
struct pound_force_per_inch_sq : named_scaled_unit<pound_force_per_inch_sq, "psi", si::prefix, ratio(1, 144), pound_force_per_foot_sq> {};
struct pound_force_per_inch_sq :
named_scaled_unit<pound_force_per_inch_sq, "psi", si::prefix, ratio(1, 144), pound_force_per_foot_sq> {};
struct kilopound_force_per_inch_sq : prefixed_unit<kilopound_force_per_inch_sq, si::kilo, pound_force_per_inch_sq> {};
@ -54,15 +57,27 @@ struct kilopound_force_per_inch_sq : prefixed_unit<kilopound_force_per_inch_sq,
inline namespace literals {
// Poundal per square foot
constexpr auto operator"" _q_pdl_per_ft2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<poundal_per_foot_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pdl_per_ft2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<poundal_per_foot_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pdl_per_ft2(long double l) { return pressure<poundal_per_foot_sq, long double>(l); }
// Pounds per square inch
constexpr auto operator"" _q_psi(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<pound_force_per_inch_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_psi(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<pound_force_per_inch_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_psi(long double l) { return pressure<pound_force_per_inch_sq, long double>(l); }
// kilopounds per square inch
constexpr auto operator"" _q_kpsi(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<kilopound_force_per_inch_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kpsi(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<kilopound_force_per_inch_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kpsi(long double l) { return pressure<kilopound_force_per_inch_sq, long double>(l); }
} // namespace literals
@ -92,9 +107,12 @@ using namespace pressure_references;
namespace units::aliases::isq::si::fps::inline pressure {
template<Representation Rep = double> using pdl_per_ft2 = units::isq::si::fps::pressure<units::isq::si::fps::poundal_per_foot_sq, Rep>;
template<Representation Rep = double> using psi = units::isq::si::fps::pressure<units::isq::si::fps::pound_force_per_inch_sq, Rep>;
template<Representation Rep = double> using kpsi = units::isq::si::fps::pressure<units::isq::si::fps::kilopound_force_per_inch_sq, Rep>;
template<Representation Rep = double>
using pdl_per_ft2 = units::isq::si::fps::pressure<units::isq::si::fps::poundal_per_foot_sq, Rep>;
template<Representation Rep = double>
using psi = units::isq::si::fps::pressure<units::isq::si::fps::pound_force_per_inch_sq, Rep>;
template<Representation Rep = double>
using kpsi = units::isq::si::fps::pressure<units::isq::si::fps::kilopound_force_per_inch_sq, Rep>;
} // namespace units::aliases::isq::si::fps::inline pressure

View File

@ -41,8 +41,8 @@ struct dim_speed : isq::dim_speed<dim_speed, foot_per_second, dim_length, dim_ti
template<UnitOf<dim_speed> U, Representation Rep = double>
using speed = quantity<dim_speed, U, Rep>;
struct mile_per_hour : derived_unit<mile_per_hour, dim_speed, mile, hour>{};
struct nautical_mile_per_hour : derived_unit<nautical_mile_per_hour, dim_speed, nautical_mile, hour>{};
struct mile_per_hour : derived_unit<mile_per_hour, dim_speed, mile, hour> {};
struct nautical_mile_per_hour : derived_unit<nautical_mile_per_hour, dim_speed, nautical_mile, hour> {};
struct knot : alias_unit<nautical_mile_per_hour, "knot", no_prefix> {};
#ifndef UNITS_NO_LITERALS
@ -50,15 +50,27 @@ struct knot : alias_unit<nautical_mile_per_hour, "knot", no_prefix> {};
inline namespace literals {
// ft/s
constexpr auto operator"" _q_ft_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return speed<foot_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return speed<foot_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_per_s(long double l) { return speed<foot_per_second, long double>(l); }
// mph
constexpr auto operator"" _q_mph(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return speed<mile_per_hour, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mph(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return speed<mile_per_hour, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mph(long double l) { return speed<mile_per_hour, long double>(l); }
// kn
constexpr auto operator"" _q_knot(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return speed<knot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_knot(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return speed<knot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_knot(long double l) { return speed<knot, long double>(l); }
} // namespace literals
@ -88,9 +100,12 @@ using namespace speed_references;
namespace units::aliases::isq::si::fps::inline speed {
template<Representation Rep = double> using ft_per_s = units::isq::si::fps::speed<units::isq::si::fps::foot_per_second, Rep>;
template<Representation Rep = double> using mph = units::isq::si::fps::speed<units::isq::si::fps::mile_per_hour, Rep>;
template<Representation Rep = double> using knot = units::isq::si::fps::speed<units::isq::si::fps::knot, Rep>;
template<Representation Rep = double>
using ft_per_s = units::isq::si::fps::speed<units::isq::si::fps::foot_per_second, Rep>;
template<Representation Rep = double>
using mph = units::isq::si::fps::speed<units::isq::si::fps::mile_per_hour, Rep>;
template<Representation Rep = double>
using knot = units::isq::si::fps::speed<units::isq::si::fps::knot, Rep>;
} // namespace units::aliases::isq::si::fps::inline speed

View File

@ -50,23 +50,59 @@ struct milli_barn : prefixed_unit<milli_barn, milli, barn> {};
#ifndef UNITS_NO_LITERALS
inline namespace literals {
constexpr auto operator"" _q_yb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<yocto_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<yocto_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yb(long double l) { return area<yocto_barn, long double>(l); }
constexpr auto operator"" _q_zb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<zepto_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<zepto_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zb(long double l) { return area<zepto_barn, long double>(l); }
constexpr auto operator"" _q_ab(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<atto_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ab(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<atto_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ab(long double l) { return area<atto_barn, long double>(l); }
constexpr auto operator"" _q_fb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<femto_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<femto_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fb(long double l) { return area<femto_barn, long double>(l); }
constexpr auto operator"" _q_pb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<pico_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<pico_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pb(long double l) { return area<pico_barn, long double>(l); }
constexpr auto operator"" _q_nb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<nano_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<nano_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nb(long double l) { return area<nano_barn, long double>(l); }
constexpr auto operator"" _q_ub(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<micro_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ub(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<micro_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ub(long double l) { return area<micro_barn, long double>(l); }
constexpr auto operator"" _q_mb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<milli_barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<milli_barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mb(long double l) { return area<milli_barn, long double>(l); }
constexpr auto operator"" _q_b(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<barn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_b(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<barn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_b(long double l) { return area<barn, long double>(l); }
} // namespace literals
@ -94,7 +130,8 @@ using namespace area_references;
namespace units::aliases::isq::si::hep::inline area {
template<Representation Rep = double> using barn = units::isq::si::area<units::isq::si::hep::barn, Rep>;
template<Representation Rep = double>
using barn = units::isq::si::area<units::isq::si::hep::barn, Rep>;
} // namespace units::aliases::isq::si::hep::inline area

View File

@ -42,7 +42,11 @@ struct square_foot : derived_unit<square_foot, si::dim_area, si::international::
inline namespace literals {
// ft2
constexpr auto operator"" _q_ft2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::area<square_foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::area<square_foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft2(long double l) { return si::area<square_foot, long double>(l); }
} // namespace literals
@ -71,7 +75,8 @@ using namespace area_references;
namespace units::aliases::isq::si::international::inline area {
template<Representation Rep = double> using ft2 = units::isq::si::area<units::isq::si::international::square_foot, Rep>;
template<Representation Rep = double>
using ft2 = units::isq::si::area<units::isq::si::international::square_foot, Rep>;
} // namespace units::aliases::isq::si::international::inline area

View File

@ -23,9 +23,8 @@
#pragma once
// IWYU pragma: begin_exports
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/area.h>
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/speed.h>
#include <units/isq/si/international/volume.h>
// IWYU pragma: end_exports

View File

@ -67,87 +67,171 @@ using absorbed_dose = quantity<dim_absorbed_dose, U, Rep>;
inline namespace literals {
// Gy
constexpr auto operator"" _q_Gy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<gray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<gray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gy(long double l) { return absorbed_dose<gray, long double>(l); }
// yGy
constexpr auto operator"" _q_yGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<yoctogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<yoctogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yGy(long double l) { return absorbed_dose<yoctogray, long double>(l); }
// zGy
constexpr auto operator"" _q_zGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<zeptogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<zeptogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zGy(long double l) { return absorbed_dose<zeptogray, long double>(l); }
// aGy
constexpr auto operator"" _q_aGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<attogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<attogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aGy(long double l) { return absorbed_dose<attogray, long double>(l); }
// fGy
constexpr auto operator"" _q_fGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<femtogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<femtogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fGy(long double l) { return absorbed_dose<femtogray, long double>(l); }
// pGy
constexpr auto operator"" _q_pGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<picogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<picogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pGy(long double l) { return absorbed_dose<picogray, long double>(l); }
// nGy
constexpr auto operator"" _q_nGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<nanogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<nanogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nGy(long double l) { return absorbed_dose<nanogray, long double>(l); }
// uGy
constexpr auto operator"" _q_uGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<microgray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<microgray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uGy(long double l) { return absorbed_dose<microgray, long double>(l); }
// mGy
constexpr auto operator"" _q_mGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<milligray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<milligray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mGy(long double l) { return absorbed_dose<milligray, long double>(l); }
// cGy
constexpr auto operator"" _q_cGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<centigray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<centigray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cGy(long double l) { return absorbed_dose<centigray, long double>(l); }
// dGy
constexpr auto operator"" _q_dGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<decigray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<decigray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dGy(long double l) { return absorbed_dose<decigray, long double>(l); }
// daGy
constexpr auto operator"" _q_daGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<decagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<decagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daGy(long double l) { return absorbed_dose<decagray, long double>(l); }
// hGy
constexpr auto operator"" _q_hGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<hectogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<hectogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hGy(long double l) { return absorbed_dose<hectogray, long double>(l); }
// kGy
constexpr auto operator"" _q_kGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<kilogray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<kilogray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kGy(long double l) { return absorbed_dose<kilogray, long double>(l); }
// MGy
constexpr auto operator"" _q_MGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<megagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<megagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MGy(long double l) { return absorbed_dose<megagray, long double>(l); }
// GGy
constexpr auto operator"" _q_GGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<gigagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<gigagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GGy(long double l) { return absorbed_dose<gigagray, long double>(l); }
// TGy
constexpr auto operator"" _q_TGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<teragray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<teragray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TGy(long double l) { return absorbed_dose<teragray, long double>(l); }
// PGy
constexpr auto operator"" _q_PGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<petagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<petagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PGy(long double l) { return absorbed_dose<petagray, long double>(l); }
// EGy
constexpr auto operator"" _q_EGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<exagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<exagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EGy(long double l) { return absorbed_dose<exagray, long double>(l); }
// ZGy
constexpr auto operator"" _q_ZGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<zettagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<zettagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZGy(long double l) { return absorbed_dose<zettagray, long double>(l); }
// YGy
constexpr auto operator"" _q_YGy(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return absorbed_dose<yottagray, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YGy(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return absorbed_dose<yottagray, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YGy(long double l) { return absorbed_dose<yottagray, long double>(l); }
} // namespace literals
@ -196,27 +280,48 @@ using namespace absorbed_dose_references;
namespace units::aliases::isq::si::inline absorbed_dose {
template<Representation Rep = double> using Gy = units::isq::si::absorbed_dose<units::isq::si::gray, Rep>;
template<Representation Rep = double> using yGy = units::isq::si::absorbed_dose<units::isq::si::yoctogray, Rep>;
template<Representation Rep = double> using zGy = units::isq::si::absorbed_dose<units::isq::si::zeptogray, Rep>;
template<Representation Rep = double> using aGy = units::isq::si::absorbed_dose<units::isq::si::attogray, Rep>;
template<Representation Rep = double> using fGy = units::isq::si::absorbed_dose<units::isq::si::femtogray, Rep>;
template<Representation Rep = double> using pGy = units::isq::si::absorbed_dose<units::isq::si::picogray, Rep>;
template<Representation Rep = double> using nGy = units::isq::si::absorbed_dose<units::isq::si::nanogray, Rep>;
template<Representation Rep = double> using uGy = units::isq::si::absorbed_dose<units::isq::si::microgray, Rep>;
template<Representation Rep = double> using mGy = units::isq::si::absorbed_dose<units::isq::si::milligray, Rep>;
template<Representation Rep = double> using cGy = units::isq::si::absorbed_dose<units::isq::si::centigray, Rep>;
template<Representation Rep = double> using dGy = units::isq::si::absorbed_dose<units::isq::si::decigray, Rep>;
template<Representation Rep = double> using daGy = units::isq::si::absorbed_dose<units::isq::si::decagray, Rep>;
template<Representation Rep = double> using hGy = units::isq::si::absorbed_dose<units::isq::si::hectogray, Rep>;
template<Representation Rep = double> using kGy = units::isq::si::absorbed_dose<units::isq::si::kilogray, Rep>;
template<Representation Rep = double> using MGy = units::isq::si::absorbed_dose<units::isq::si::megagray, Rep>;
template<Representation Rep = double> using GGy = units::isq::si::absorbed_dose<units::isq::si::gigagray, Rep>;
template<Representation Rep = double> using TGy = units::isq::si::absorbed_dose<units::isq::si::teragray, Rep>;
template<Representation Rep = double> using PGy = units::isq::si::absorbed_dose<units::isq::si::petagray, Rep>;
template<Representation Rep = double> using EGy = units::isq::si::absorbed_dose<units::isq::si::exagray, Rep>;
template<Representation Rep = double> using ZGy = units::isq::si::absorbed_dose<units::isq::si::zettagray, Rep>;
template<Representation Rep = double> using YGy = units::isq::si::absorbed_dose<units::isq::si::yottagray, Rep>;
template<Representation Rep = double>
using Gy = units::isq::si::absorbed_dose<units::isq::si::gray, Rep>;
template<Representation Rep = double>
using yGy = units::isq::si::absorbed_dose<units::isq::si::yoctogray, Rep>;
template<Representation Rep = double>
using zGy = units::isq::si::absorbed_dose<units::isq::si::zeptogray, Rep>;
template<Representation Rep = double>
using aGy = units::isq::si::absorbed_dose<units::isq::si::attogray, Rep>;
template<Representation Rep = double>
using fGy = units::isq::si::absorbed_dose<units::isq::si::femtogray, Rep>;
template<Representation Rep = double>
using pGy = units::isq::si::absorbed_dose<units::isq::si::picogray, Rep>;
template<Representation Rep = double>
using nGy = units::isq::si::absorbed_dose<units::isq::si::nanogray, Rep>;
template<Representation Rep = double>
using uGy = units::isq::si::absorbed_dose<units::isq::si::microgray, Rep>;
template<Representation Rep = double>
using mGy = units::isq::si::absorbed_dose<units::isq::si::milligray, Rep>;
template<Representation Rep = double>
using cGy = units::isq::si::absorbed_dose<units::isq::si::centigray, Rep>;
template<Representation Rep = double>
using dGy = units::isq::si::absorbed_dose<units::isq::si::decigray, Rep>;
template<Representation Rep = double>
using daGy = units::isq::si::absorbed_dose<units::isq::si::decagray, Rep>;
template<Representation Rep = double>
using hGy = units::isq::si::absorbed_dose<units::isq::si::hectogray, Rep>;
template<Representation Rep = double>
using kGy = units::isq::si::absorbed_dose<units::isq::si::kilogray, Rep>;
template<Representation Rep = double>
using MGy = units::isq::si::absorbed_dose<units::isq::si::megagray, Rep>;
template<Representation Rep = double>
using GGy = units::isq::si::absorbed_dose<units::isq::si::gigagray, Rep>;
template<Representation Rep = double>
using TGy = units::isq::si::absorbed_dose<units::isq::si::teragray, Rep>;
template<Representation Rep = double>
using PGy = units::isq::si::absorbed_dose<units::isq::si::petagray, Rep>;
template<Representation Rep = double>
using EGy = units::isq::si::absorbed_dose<units::isq::si::exagray, Rep>;
template<Representation Rep = double>
using ZGy = units::isq::si::absorbed_dose<units::isq::si::zettagray, Rep>;
template<Representation Rep = double>
using YGy = units::isq::si::absorbed_dose<units::isq::si::yottagray, Rep>;
} // namespace units::aliases::isq::si::inline absorbed_dose

View File

@ -44,7 +44,11 @@ using acceleration = quantity<dim_acceleration, U, Rep>;
inline namespace literals {
// m/s2
constexpr auto operator"" _q_m_per_s2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return acceleration<metre_per_second_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_m_per_s2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return acceleration<metre_per_second_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_m_per_s2(long double l) { return acceleration<metre_per_second_sq, long double>(l); }
} // namespace literals
@ -57,7 +61,8 @@ constexpr auto operator"" _q_m_per_s2(long double l) { return acceleration<metre
namespace units::aliases::isq::si::inline acceleration {
template<Representation Rep = double> using m_per_s2 = units::isq::si::acceleration<units::isq::si::metre_per_second_sq, Rep>;
template<Representation Rep = double>
using m_per_s2 = units::isq::si::acceleration<units::isq::si::metre_per_second_sq, Rep>;
} // namespace units::aliases::isq::si::inline acceleration

View File

@ -46,7 +46,11 @@ using amount_of_substance = quantity<dim_amount_of_substance, U, Rep>;
inline namespace literals {
// mol
constexpr auto operator"" _q_mol(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return amount_of_substance<mole, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mol(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return amount_of_substance<mole, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mol(long double l) { return amount_of_substance<mole, long double>(l); }
} // namespace literals
@ -75,7 +79,8 @@ using namespace amount_of_substance_references;
namespace units::aliases::isq::si::inline amount_of_substance {
template<Representation Rep = double> using mol = units::isq::si::amount_of_substance<units::isq::si::mole, Rep>;
template<Representation Rep = double>
using mol = units::isq::si::amount_of_substance<units::isq::si::mole, Rep>;
} // namespace units::aliases::isq::si::inline amount_of_substance

View File

@ -36,7 +36,8 @@ namespace units::isq::si {
struct radian_per_second : named_unit<radian_per_second, basic_symbol_text{"ω", "w"}, no_prefix> {};
struct dim_angular_velocity : isq::dim_angular_velocity<dim_angular_velocity, radian_per_second, dim_angle<>, dim_time> {};
struct dim_angular_velocity :
isq::dim_angular_velocity<dim_angular_velocity, radian_per_second, dim_angle<>, dim_time> {};
template<UnitOf<dim_angular_velocity> U, Representation Rep = double>
using angular_velocity = quantity<dim_angular_velocity, U, Rep>;
@ -46,7 +47,11 @@ using angular_velocity = quantity<dim_angular_velocity, U, Rep>;
inline namespace literals {
// rad / s
constexpr auto operator"" _q_rad_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return angular_velocity<radian_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_rad_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return angular_velocity<radian_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_rad_per_s(long double l) { return angular_velocity<radian_per_second, long double>(l); }
} // namespace literals
@ -59,7 +64,8 @@ constexpr auto operator"" _q_rad_per_s(long double l) { return angular_velocity<
namespace units::aliases::isq::si::inline angular_velocity {
template<Representation Rep = double> using rad_per_s = units::isq::si::angular_velocity<units::isq::si::radian_per_second, Rep>;
template<Representation Rep = double>
using rad_per_s = units::isq::si::angular_velocity<units::isq::si::radian_per_second, Rep>;
} // namespace units::aliases::isq::si::inline angular_velocity

View File

@ -68,91 +68,179 @@ using area = quantity<dim_area, U, Rep>;
inline namespace literals {
// m2
constexpr auto operator"" _q_m2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_metre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_m2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_metre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_m2(long double l) { return area<square_metre, long double>(l); }
// ym2
constexpr auto operator"" _q_ym2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_yoctometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ym2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_yoctometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ym2(long double l) { return area<square_yoctometre, long double>(l); }
// zm2
constexpr auto operator"" _q_zm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_zeptometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_zeptometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zm2(long double l) { return area<square_zeptometre, long double>(l); }
// am2
constexpr auto operator"" _q_am2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_attometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_am2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_attometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_am2(long double l) { return area<square_attometre, long double>(l); }
// fm2
constexpr auto operator"" _q_fm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_femtometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_femtometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fm2(long double l) { return area<square_femtometre, long double>(l); }
// pm2
constexpr auto operator"" _q_pm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_picometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_picometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pm2(long double l) { return area<square_picometre, long double>(l); }
// nm2
constexpr auto operator"" _q_nm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_nanometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_nanometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nm2(long double l) { return area<square_nanometre, long double>(l); }
// um2
constexpr auto operator"" _q_um2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_micrometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_um2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_micrometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_um2(long double l) { return area<square_micrometre, long double>(l); }
// mm2
constexpr auto operator"" _q_mm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_millimetre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_millimetre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mm2(long double l) { return area<square_millimetre, long double>(l); }
// cm2
constexpr auto operator"" _q_cm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_centimetre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_centimetre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cm2(long double l) { return area<square_centimetre, long double>(l); }
// dm2
constexpr auto operator"" _q_dm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_decimetre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_decimetre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dm2(long double l) { return area<square_decimetre, long double>(l); }
// dam2
constexpr auto operator"" _q_dam2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_decametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dam2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_decametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dam2(long double l) { return area<square_decametre, long double>(l); }
// hm2
constexpr auto operator"" _q_hm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_hectometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_hectometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hm2(long double l) { return area<square_hectometre, long double>(l); }
// km2
constexpr auto operator"" _q_km2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_kilometre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_km2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_kilometre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_km2(long double l) { return area<square_kilometre, long double>(l); }
// Mm2
constexpr auto operator"" _q_Mm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_megametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Mm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_megametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Mm2(long double l) { return area<square_megametre, long double>(l); }
// Gm2
constexpr auto operator"" _q_Gm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_gigametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_gigametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gm2(long double l) { return area<square_gigametre, long double>(l); }
// Tm2
constexpr auto operator"" _q_Tm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_terametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Tm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_terametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Tm2(long double l) { return area<square_terametre, long double>(l); }
// Pm2
constexpr auto operator"" _q_Pm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_petametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_petametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pm2(long double l) { return area<square_petametre, long double>(l); }
// Em2
constexpr auto operator"" _q_Em2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_exametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Em2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_exametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Em2(long double l) { return area<square_exametre, long double>(l); }
// Zm2
constexpr auto operator"" _q_Zm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_zettametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Zm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_zettametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Zm2(long double l) { return area<square_zettametre, long double>(l); }
// Ym2
constexpr auto operator"" _q_Ym2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_yottametre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ym2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_yottametre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ym2(long double l) { return area<square_yottametre, long double>(l); }
// ha
constexpr auto operator"" _q_ha(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<hectare, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ha(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<hectare, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ha(long double l) { return area<hectare, long double>(l); }
} // namespace literals
@ -203,29 +291,51 @@ using namespace area_references;
namespace units::aliases::isq::si::inline area {
template<Representation Rep = double> using m2 = units::isq::si::area<units::isq::si::square_metre, Rep>;
template<Representation Rep = double> using ym2 = units::isq::si::area<units::isq::si::square_yoctometre, Rep>;
template<Representation Rep = double> using zm2 = units::isq::si::area<units::isq::si::square_zeptometre, Rep>;
template<Representation Rep = double> using am2 = units::isq::si::area<units::isq::si::square_attometre, Rep>;
template<Representation Rep = double> using fm2 = units::isq::si::area<units::isq::si::square_femtometre, Rep>;
template<Representation Rep = double> using pm2 = units::isq::si::area<units::isq::si::square_picometre, Rep>;
template<Representation Rep = double> using nm2 = units::isq::si::area<units::isq::si::square_nanometre, Rep>;
template<Representation Rep = double> using um2 = units::isq::si::area<units::isq::si::square_micrometre, Rep>;
template<Representation Rep = double> using mm2 = units::isq::si::area<units::isq::si::square_millimetre, Rep>;
template<Representation Rep = double> using cm2 = units::isq::si::area<units::isq::si::square_centimetre, Rep>;
template<Representation Rep = double> using dm2 = units::isq::si::area<units::isq::si::square_decimetre, Rep>;
template<Representation Rep = double> using dam2 = units::isq::si::area<units::isq::si::square_decametre, Rep>;
template<Representation Rep = double> using hm2 = units::isq::si::area<units::isq::si::square_hectometre, Rep>;
template<Representation Rep = double> using km2 = units::isq::si::area<units::isq::si::square_kilometre, Rep>;
template<Representation Rep = double> using Mm2 = units::isq::si::area<units::isq::si::square_megametre, Rep>;
template<Representation Rep = double> using Gm2 = units::isq::si::area<units::isq::si::square_gigametre, Rep>;
template<Representation Rep = double> using Tm2 = units::isq::si::area<units::isq::si::square_terametre, Rep>;
template<Representation Rep = double> using Pm2 = units::isq::si::area<units::isq::si::square_petametre, Rep>;
template<Representation Rep = double> using Em2 = units::isq::si::area<units::isq::si::square_exametre, Rep>;
template<Representation Rep = double> using Zm2 = units::isq::si::area<units::isq::si::square_zettametre, Rep>;
template<Representation Rep = double> using Ym2 = units::isq::si::area<units::isq::si::square_yottametre, Rep>;
template<Representation Rep = double>
using m2 = units::isq::si::area<units::isq::si::square_metre, Rep>;
template<Representation Rep = double>
using ym2 = units::isq::si::area<units::isq::si::square_yoctometre, Rep>;
template<Representation Rep = double>
using zm2 = units::isq::si::area<units::isq::si::square_zeptometre, Rep>;
template<Representation Rep = double>
using am2 = units::isq::si::area<units::isq::si::square_attometre, Rep>;
template<Representation Rep = double>
using fm2 = units::isq::si::area<units::isq::si::square_femtometre, Rep>;
template<Representation Rep = double>
using pm2 = units::isq::si::area<units::isq::si::square_picometre, Rep>;
template<Representation Rep = double>
using nm2 = units::isq::si::area<units::isq::si::square_nanometre, Rep>;
template<Representation Rep = double>
using um2 = units::isq::si::area<units::isq::si::square_micrometre, Rep>;
template<Representation Rep = double>
using mm2 = units::isq::si::area<units::isq::si::square_millimetre, Rep>;
template<Representation Rep = double>
using cm2 = units::isq::si::area<units::isq::si::square_centimetre, Rep>;
template<Representation Rep = double>
using dm2 = units::isq::si::area<units::isq::si::square_decimetre, Rep>;
template<Representation Rep = double>
using dam2 = units::isq::si::area<units::isq::si::square_decametre, Rep>;
template<Representation Rep = double>
using hm2 = units::isq::si::area<units::isq::si::square_hectometre, Rep>;
template<Representation Rep = double>
using km2 = units::isq::si::area<units::isq::si::square_kilometre, Rep>;
template<Representation Rep = double>
using Mm2 = units::isq::si::area<units::isq::si::square_megametre, Rep>;
template<Representation Rep = double>
using Gm2 = units::isq::si::area<units::isq::si::square_gigametre, Rep>;
template<Representation Rep = double>
using Tm2 = units::isq::si::area<units::isq::si::square_terametre, Rep>;
template<Representation Rep = double>
using Pm2 = units::isq::si::area<units::isq::si::square_petametre, Rep>;
template<Representation Rep = double>
using Em2 = units::isq::si::area<units::isq::si::square_exametre, Rep>;
template<Representation Rep = double>
using Zm2 = units::isq::si::area<units::isq::si::square_zettametre, Rep>;
template<Representation Rep = double>
using Ym2 = units::isq::si::area<units::isq::si::square_yottametre, Rep>;
template<Representation Rep = double> using ha = units::isq::si::area<units::isq::si::hectare, Rep>;
template<Representation Rep = double>
using ha = units::isq::si::area<units::isq::si::hectare, Rep>;
} // namespace units::aliases::isq::si::inline area

View File

@ -30,8 +30,8 @@
// IWYU pragma: end_exports
#include <units/isq/si/electric_charge.h>
#include <units/isq/si/voltage.h>
#include <units/isq/si/prefixes.h>
#include <units/isq/si/voltage.h>
#include <units/unit.h>
namespace units::isq::si {
@ -68,87 +68,171 @@ using capacitance = quantity<dim_capacitance, U, Rep>;
inline namespace literals {
// F
constexpr auto operator"" _q_F(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<farad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_F(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<farad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_F(long double l) { return capacitance<farad, long double>(l); }
// yF
constexpr auto operator"" _q_yF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<yoctofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<yoctofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yF(long double l) { return capacitance<yoctofarad, long double>(l); }
// zF
constexpr auto operator"" _q_zF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<zeptofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<zeptofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zF(long double l) { return capacitance<zeptofarad, long double>(l); }
// aF
constexpr auto operator"" _q_aF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<attofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<attofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aF(long double l) { return capacitance<attofarad, long double>(l); }
// fF
constexpr auto operator"" _q_fF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<femtofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<femtofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fF(long double l) { return capacitance<femtofarad, long double>(l); }
// pF
constexpr auto operator"" _q_pF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<picofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<picofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pF(long double l) { return capacitance<picofarad, long double>(l); }
// nF
constexpr auto operator"" _q_nF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<nanofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<nanofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nF(long double l) { return capacitance<nanofarad, long double>(l); }
// uF
constexpr auto operator"" _q_uF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<microfarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<microfarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uF(long double l) { return capacitance<microfarad, long double>(l); }
// mF
constexpr auto operator"" _q_mF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<millifarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<millifarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mF(long double l) { return capacitance<millifarad, long double>(l); }
// cF
constexpr auto operator"" _q_cF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<centifarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<centifarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cF(long double l) { return capacitance<centifarad, long double>(l); }
// dF
constexpr auto operator"" _q_dF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<decifarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<decifarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dF(long double l) { return capacitance<decifarad, long double>(l); }
// daF
constexpr auto operator"" _q_daF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<decafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<decafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daF(long double l) { return capacitance<decafarad, long double>(l); }
// hF
constexpr auto operator"" _q_hF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<hectofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<hectofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hF(long double l) { return capacitance<hectofarad, long double>(l); }
// kF
constexpr auto operator"" _q_kF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<kilofarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<kilofarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kF(long double l) { return capacitance<kilofarad, long double>(l); }
// MF
constexpr auto operator"" _q_MF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<megafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<megafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MF(long double l) { return capacitance<megafarad, long double>(l); }
// GF
constexpr auto operator"" _q_GF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<gigafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<gigafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GF(long double l) { return capacitance<gigafarad, long double>(l); }
// TF
constexpr auto operator"" _q_TF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<terafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<terafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TF(long double l) { return capacitance<terafarad, long double>(l); }
// PF
constexpr auto operator"" _q_PF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<petafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<petafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PF(long double l) { return capacitance<petafarad, long double>(l); }
// EF
constexpr auto operator"" _q_EF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<exafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<exafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EF(long double l) { return capacitance<exafarad, long double>(l); }
// ZF
constexpr auto operator"" _q_ZF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<zettafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<zettafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZF(long double l) { return capacitance<zettafarad, long double>(l); }
// YF
constexpr auto operator"" _q_YF(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return capacitance<yottafarad, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YF(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return capacitance<yottafarad, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YF(long double l) { return capacitance<yottafarad, long double>(l); }
} // namespace literals
@ -197,27 +281,48 @@ using namespace capacitance_references;
namespace units::aliases::isq::si::inline capacitance {
template<Representation Rep = double> using F = units::isq::si::capacitance<units::isq::si::farad, Rep>;
template<Representation Rep = double> using yF = units::isq::si::capacitance<units::isq::si::yoctofarad, Rep>;
template<Representation Rep = double> using zF = units::isq::si::capacitance<units::isq::si::zeptofarad, Rep>;
template<Representation Rep = double> using aF = units::isq::si::capacitance<units::isq::si::attofarad, Rep>;
template<Representation Rep = double> using fF = units::isq::si::capacitance<units::isq::si::femtofarad, Rep>;
template<Representation Rep = double> using pF = units::isq::si::capacitance<units::isq::si::picofarad, Rep>;
template<Representation Rep = double> using nF = units::isq::si::capacitance<units::isq::si::nanofarad, Rep>;
template<Representation Rep = double> using uF = units::isq::si::capacitance<units::isq::si::microfarad, Rep>;
template<Representation Rep = double> using mF = units::isq::si::capacitance<units::isq::si::millifarad, Rep>;
template<Representation Rep = double> using cF = units::isq::si::capacitance<units::isq::si::centifarad, Rep>;
template<Representation Rep = double> using dF = units::isq::si::capacitance<units::isq::si::decifarad, Rep>;
template<Representation Rep = double> using daF = units::isq::si::capacitance<units::isq::si::decafarad, Rep>;
template<Representation Rep = double> using hF = units::isq::si::capacitance<units::isq::si::hectofarad, Rep>;
template<Representation Rep = double> using kF = units::isq::si::capacitance<units::isq::si::kilofarad, Rep>;
template<Representation Rep = double> using MF = units::isq::si::capacitance<units::isq::si::megafarad, Rep>;
template<Representation Rep = double> using GF = units::isq::si::capacitance<units::isq::si::gigafarad, Rep>;
template<Representation Rep = double> using TF = units::isq::si::capacitance<units::isq::si::terafarad, Rep>;
template<Representation Rep = double> using PF = units::isq::si::capacitance<units::isq::si::petafarad, Rep>;
template<Representation Rep = double> using EF = units::isq::si::capacitance<units::isq::si::exafarad, Rep>;
template<Representation Rep = double> using ZF = units::isq::si::capacitance<units::isq::si::zettafarad, Rep>;
template<Representation Rep = double> using YF = units::isq::si::capacitance<units::isq::si::yottafarad, Rep>;
template<Representation Rep = double>
using F = units::isq::si::capacitance<units::isq::si::farad, Rep>;
template<Representation Rep = double>
using yF = units::isq::si::capacitance<units::isq::si::yoctofarad, Rep>;
template<Representation Rep = double>
using zF = units::isq::si::capacitance<units::isq::si::zeptofarad, Rep>;
template<Representation Rep = double>
using aF = units::isq::si::capacitance<units::isq::si::attofarad, Rep>;
template<Representation Rep = double>
using fF = units::isq::si::capacitance<units::isq::si::femtofarad, Rep>;
template<Representation Rep = double>
using pF = units::isq::si::capacitance<units::isq::si::picofarad, Rep>;
template<Representation Rep = double>
using nF = units::isq::si::capacitance<units::isq::si::nanofarad, Rep>;
template<Representation Rep = double>
using uF = units::isq::si::capacitance<units::isq::si::microfarad, Rep>;
template<Representation Rep = double>
using mF = units::isq::si::capacitance<units::isq::si::millifarad, Rep>;
template<Representation Rep = double>
using cF = units::isq::si::capacitance<units::isq::si::centifarad, Rep>;
template<Representation Rep = double>
using dF = units::isq::si::capacitance<units::isq::si::decifarad, Rep>;
template<Representation Rep = double>
using daF = units::isq::si::capacitance<units::isq::si::decafarad, Rep>;
template<Representation Rep = double>
using hF = units::isq::si::capacitance<units::isq::si::hectofarad, Rep>;
template<Representation Rep = double>
using kF = units::isq::si::capacitance<units::isq::si::kilofarad, Rep>;
template<Representation Rep = double>
using MF = units::isq::si::capacitance<units::isq::si::megafarad, Rep>;
template<Representation Rep = double>
using GF = units::isq::si::capacitance<units::isq::si::gigafarad, Rep>;
template<Representation Rep = double>
using TF = units::isq::si::capacitance<units::isq::si::terafarad, Rep>;
template<Representation Rep = double>
using PF = units::isq::si::capacitance<units::isq::si::petafarad, Rep>;
template<Representation Rep = double>
using EF = units::isq::si::capacitance<units::isq::si::exafarad, Rep>;
template<Representation Rep = double>
using ZF = units::isq::si::capacitance<units::isq::si::zettafarad, Rep>;
template<Representation Rep = double>
using YF = units::isq::si::capacitance<units::isq::si::yottafarad, Rep>;
} // namespace units::aliases::isq::si::inline capacitance

View File

@ -28,14 +28,15 @@
#include <units/symbol_text.h>
// IWYU pragma: end_exports
#include <units/isq/si/length.h>
#include <units/isq/si/amount_of_substance.h>
#include <units/isq/si/length.h>
#include <units/unit.h>
namespace units::isq::si {
struct mol_per_metre_cub : unit<mol_per_metre_cub> {};
struct dim_concentration : isq::dim_concentration<dim_concentration, mol_per_metre_cub, dim_amount_of_substance, dim_length> {};
struct dim_concentration :
isq::dim_concentration<dim_concentration, mol_per_metre_cub, dim_amount_of_substance, dim_length> {};
template<UnitOf<dim_concentration> U, Representation Rep = double>
using concentration = quantity<dim_concentration, U, Rep>;
@ -45,7 +46,11 @@ using concentration = quantity<dim_concentration, U, Rep>;
inline namespace literals {
// mol/m³
constexpr auto operator"" _q_mol_per_m3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return concentration<mol_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mol_per_m3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return concentration<mol_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mol_per_m3(long double l) { return concentration<mol_per_metre_cub, long double>(l); }
} // namespace literals
@ -58,7 +63,8 @@ constexpr auto operator"" _q_mol_per_m3(long double l) { return concentration<mo
namespace units::aliases::isq::si::inline concentration {
template<Representation Rep = double> using mol_per_m3 = units::isq::si::concentration<units::isq::si::mol_per_metre_cub, Rep>;
template<Representation Rep = double>
using mol_per_m3 = units::isq::si::concentration<units::isq::si::mol_per_metre_cub, Rep>;
} // namespace units::aliases::isq::si::inline concentration

View File

@ -29,8 +29,8 @@
#include <units/symbol_text.h>
// IWYU pragma: end_exports
#include <units/isq/si/resistance.h>
#include <units/isq/si/prefixes.h>
#include <units/isq/si/resistance.h>
#include <units/unit.h>
namespace units::isq::si {
@ -63,71 +63,139 @@ using conductance = quantity<dim_conductance, U, Rep>;
inline namespace literals {
// R
constexpr auto operator"" _q_S(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<siemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_S(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<siemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_S(long double l) { return conductance<siemens, long double>(l); }
// yS
constexpr auto operator"" _q_yS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<yoctosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<yoctosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yS(long double l) { return conductance<yoctosiemens, long double>(l); }
// zS
constexpr auto operator"" _q_zS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<zeptosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<zeptosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zS(long double l) { return conductance<zeptosiemens, long double>(l); }
// aS
constexpr auto operator"" _q_aS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<attosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<attosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aS(long double l) { return conductance<attosiemens, long double>(l); }
// fS
constexpr auto operator"" _q_fS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<femtosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<femtosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fS(long double l) { return conductance<femtosiemens, long double>(l); }
// pS
constexpr auto operator"" _q_pS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<picosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<picosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pS(long double l) { return conductance<picosiemens, long double>(l); }
// nS
constexpr auto operator"" _q_nS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<nanosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<nanosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nS(long double l) { return conductance<nanosiemens, long double>(l); }
// µS
constexpr auto operator"" _q_uS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<microsiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<microsiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uS(long double l) { return conductance<microsiemens, long double>(l); }
// mS
constexpr auto operator"" _q_mS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<millisiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<millisiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mS(long double l) { return conductance<millisiemens, long double>(l); }
// kS
constexpr auto operator"" _q_kS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<kilosiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<kilosiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kS(long double l) { return conductance<kilosiemens, long double>(l); }
// MS
constexpr auto operator"" _q_MS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<megasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<megasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MS(long double l) { return conductance<megasiemens, long double>(l); }
// GS
constexpr auto operator"" _q_GS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<gigasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<gigasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GS(long double l) { return conductance<gigasiemens, long double>(l); }
// TS
constexpr auto operator"" _q_TS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<terasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<terasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TS(long double l) { return conductance<terasiemens, long double>(l); }
// PS
constexpr auto operator"" _q_PS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<petasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<petasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PS(long double l) { return conductance<petasiemens, long double>(l); }
// ES
constexpr auto operator"" _q_ES(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<exasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ES(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<exasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ES(long double l) { return conductance<exasiemens, long double>(l); }
// ZS
constexpr auto operator"" _q_ZS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<zettasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<zettasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZS(long double l) { return conductance<zettasiemens, long double>(l); }
// YS
constexpr auto operator"" _q_YS(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return conductance<yottasiemens, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YS(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return conductance<yottasiemens, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YS(long double l) { return conductance<yottasiemens, long double>(l); }
} // namespace literals
@ -172,23 +240,40 @@ using namespace conductance_references;
namespace units::aliases::isq::si::inline conductance {
template<Representation Rep = double> using S = units::isq::si::conductance<units::isq::si::siemens, Rep>;
template<Representation Rep = double> using yS = units::isq::si::conductance<units::isq::si::yoctosiemens, Rep>;
template<Representation Rep = double> using zS = units::isq::si::conductance<units::isq::si::zeptosiemens, Rep>;
template<Representation Rep = double> using aS = units::isq::si::conductance<units::isq::si::attosiemens, Rep>;
template<Representation Rep = double> using fS = units::isq::si::conductance<units::isq::si::femtosiemens, Rep>;
template<Representation Rep = double> using pS = units::isq::si::conductance<units::isq::si::picosiemens, Rep>;
template<Representation Rep = double> using nS = units::isq::si::conductance<units::isq::si::nanosiemens, Rep>;
template<Representation Rep = double> using uS = units::isq::si::conductance<units::isq::si::microsiemens, Rep>;
template<Representation Rep = double> using mS = units::isq::si::conductance<units::isq::si::millisiemens, Rep>;
template<Representation Rep = double> using kS = units::isq::si::conductance<units::isq::si::kilosiemens, Rep>;
template<Representation Rep = double> using MS = units::isq::si::conductance<units::isq::si::megasiemens, Rep>;
template<Representation Rep = double> using GS = units::isq::si::conductance<units::isq::si::gigasiemens, Rep>;
template<Representation Rep = double> using TS = units::isq::si::conductance<units::isq::si::terasiemens, Rep>;
template<Representation Rep = double> using PS = units::isq::si::conductance<units::isq::si::petasiemens, Rep>;
template<Representation Rep = double> using ES = units::isq::si::conductance<units::isq::si::exasiemens, Rep>;
template<Representation Rep = double> using ZS = units::isq::si::conductance<units::isq::si::zettasiemens, Rep>;
template<Representation Rep = double> using YS = units::isq::si::conductance<units::isq::si::yottasiemens, Rep>;
template<Representation Rep = double>
using S = units::isq::si::conductance<units::isq::si::siemens, Rep>;
template<Representation Rep = double>
using yS = units::isq::si::conductance<units::isq::si::yoctosiemens, Rep>;
template<Representation Rep = double>
using zS = units::isq::si::conductance<units::isq::si::zeptosiemens, Rep>;
template<Representation Rep = double>
using aS = units::isq::si::conductance<units::isq::si::attosiemens, Rep>;
template<Representation Rep = double>
using fS = units::isq::si::conductance<units::isq::si::femtosiemens, Rep>;
template<Representation Rep = double>
using pS = units::isq::si::conductance<units::isq::si::picosiemens, Rep>;
template<Representation Rep = double>
using nS = units::isq::si::conductance<units::isq::si::nanosiemens, Rep>;
template<Representation Rep = double>
using uS = units::isq::si::conductance<units::isq::si::microsiemens, Rep>;
template<Representation Rep = double>
using mS = units::isq::si::conductance<units::isq::si::millisiemens, Rep>;
template<Representation Rep = double>
using kS = units::isq::si::conductance<units::isq::si::kilosiemens, Rep>;
template<Representation Rep = double>
using MS = units::isq::si::conductance<units::isq::si::megasiemens, Rep>;
template<Representation Rep = double>
using GS = units::isq::si::conductance<units::isq::si::gigasiemens, Rep>;
template<Representation Rep = double>
using TS = units::isq::si::conductance<units::isq::si::terasiemens, Rep>;
template<Representation Rep = double>
using PS = units::isq::si::conductance<units::isq::si::petasiemens, Rep>;
template<Representation Rep = double>
using ES = units::isq::si::conductance<units::isq::si::exasiemens, Rep>;
template<Representation Rep = double>
using ZS = units::isq::si::conductance<units::isq::si::zettasiemens, Rep>;
template<Representation Rep = double>
using YS = units::isq::si::conductance<units::isq::si::yottasiemens, Rep>;
} // namespace units::aliases::isq::si::inline conductance

View File

@ -28,8 +28,8 @@
#include <units/symbol_text.h>
// IWYU pragma: end_exports
#include <units/isq/si/mass.h>
#include <units/isq/si/length.h>
#include <units/isq/si/mass.h>
#include <units/isq/si/prefixes.h>
#include <units/unit.h>
@ -47,7 +47,11 @@ using density = quantity<dim_density, U, Rep>;
inline namespace literals {
// kg / m³
constexpr auto operator"" _q_kg_per_m3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return density<kilogram_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kg_per_m3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return density<kilogram_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kg_per_m3(long double l) { return density<kilogram_per_metre_cub, long double>(l); }
} // namespace literals
@ -60,7 +64,8 @@ constexpr auto operator"" _q_kg_per_m3(long double l) { return density<kilogram_
namespace units::aliases::isq::si::inline density {
template<Representation Rep = double> using kg_per_m3 = units::isq::si::density<units::isq::si::kilogram_per_metre_cub, Rep>;
template<Representation Rep = double>
using kg_per_m3 = units::isq::si::density<units::isq::si::kilogram_per_metre_cub, Rep>;
} // namespace units::aliases::isq::si::inline density

View File

@ -53,7 +53,8 @@ struct exajoule : prefixed_unit<exajoule, exa, joule> {};
struct zettajoule : prefixed_unit<zettajoule, zetta, joule> {};
struct yottajoule : prefixed_unit<yottajoule, yotta, joule> {};
// N.B. electron charge (and eV) is an exact constant: https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147
// N.B. electron charge (and eV) is an exact constant:
// https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147
struct electronvolt : named_scaled_unit<electronvolt, "eV", prefix, ratio(1'602'176'634, 1'000'000'000, -19), joule> {};
struct gigaelectronvolt : prefixed_unit<gigaelectronvolt, giga, electronvolt> {};
@ -67,79 +68,155 @@ using energy = quantity<dim_energy, U, Rep>;
inline namespace literals {
// J
constexpr auto operator"" _q_J(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<joule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_J(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<joule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_J(long double l) { return energy<joule, long double>(l); }
// yJ
constexpr auto operator"" _q_yJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<yoctojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<yoctojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yJ(long double l) { return energy<yoctojoule, long double>(l); }
// zJ
constexpr auto operator"" _q_zJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<zeptojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<zeptojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zJ(long double l) { return energy<zeptojoule, long double>(l); }
// aJ
constexpr auto operator"" _q_aJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<attojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<attojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aJ(long double l) { return energy<attojoule, long double>(l); }
// fJ
constexpr auto operator"" _q_fJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<femtojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<femtojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fJ(long double l) { return energy<femtojoule, long double>(l); }
// pJ
constexpr auto operator"" _q_pJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<picojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<picojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pJ(long double l) { return energy<picojoule, long double>(l); }
// nJ
constexpr auto operator"" _q_nJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<nanojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<nanojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nJ(long double l) { return energy<nanojoule, long double>(l); }
// uJ
constexpr auto operator"" _q_uJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<microjoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<microjoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uJ(long double l) { return energy<microjoule, long double>(l); }
// mJ
constexpr auto operator"" _q_mJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<millijoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<millijoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mJ(long double l) { return energy<millijoule, long double>(l); }
// kJ
constexpr auto operator"" _q_kJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<kilojoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<kilojoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kJ(long double l) { return energy<kilojoule, long double>(l); }
// MJ
constexpr auto operator"" _q_MJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<megajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<megajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MJ(long double l) { return energy<megajoule, long double>(l); }
// GJ
constexpr auto operator"" _q_GJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<gigajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<gigajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GJ(long double l) { return energy<gigajoule, long double>(l); }
// TJ
constexpr auto operator"" _q_TJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<terajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<terajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TJ(long double l) { return energy<terajoule, long double>(l); }
// PJ
constexpr auto operator"" _q_PJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<petajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<petajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PJ(long double l) { return energy<petajoule, long double>(l); }
// EJ
constexpr auto operator"" _q_EJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<exajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<exajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EJ(long double l) { return energy<exajoule, long double>(l); }
// ZJ
constexpr auto operator"" _q_ZJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<zettajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<zettajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZJ(long double l) { return energy<zettajoule, long double>(l); }
// YJ
constexpr auto operator"" _q_YJ(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<yottajoule, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YJ(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<yottajoule, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YJ(long double l) { return energy<yottajoule, long double>(l); }
// eV
constexpr auto operator"" _q_eV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<electronvolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_eV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<electronvolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_eV(long double l) { return energy<electronvolt, long double>(l); }
// GeV
constexpr auto operator"" _q_GeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<gigaelectronvolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<gigaelectronvolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GeV(long double l) { return energy<gigaelectronvolt, long double>(l); }
} // namespace literals
@ -187,26 +264,45 @@ using namespace energy_references;
namespace units::aliases::isq::si::inline energy {
template<Representation Rep = double> using J = units::isq::si::energy<units::isq::si::joule, Rep>;
template<Representation Rep = double> using yJ = units::isq::si::energy<units::isq::si::yoctojoule, Rep>;
template<Representation Rep = double> using zJ = units::isq::si::energy<units::isq::si::zeptojoule, Rep>;
template<Representation Rep = double> using aJ = units::isq::si::energy<units::isq::si::attojoule, Rep>;
template<Representation Rep = double> using fJ = units::isq::si::energy<units::isq::si::femtojoule, Rep>;
template<Representation Rep = double> using pJ = units::isq::si::energy<units::isq::si::picojoule, Rep>;
template<Representation Rep = double> using nJ = units::isq::si::energy<units::isq::si::nanojoule, Rep>;
template<Representation Rep = double> using uJ = units::isq::si::energy<units::isq::si::microjoule, Rep>;
template<Representation Rep = double> using mJ = units::isq::si::energy<units::isq::si::millijoule, Rep>;
template<Representation Rep = double> using kJ = units::isq::si::energy<units::isq::si::kilojoule, Rep>;
template<Representation Rep = double> using MJ = units::isq::si::energy<units::isq::si::megajoule, Rep>;
template<Representation Rep = double> using GJ = units::isq::si::energy<units::isq::si::gigajoule, Rep>;
template<Representation Rep = double> using TJ = units::isq::si::energy<units::isq::si::terajoule, Rep>;
template<Representation Rep = double> using PJ = units::isq::si::energy<units::isq::si::petajoule, Rep>;
template<Representation Rep = double> using EJ = units::isq::si::energy<units::isq::si::exajoule, Rep>;
template<Representation Rep = double> using ZJ = units::isq::si::energy<units::isq::si::zettajoule, Rep>;
template<Representation Rep = double> using YJ = units::isq::si::energy<units::isq::si::yottajoule, Rep>;
template<Representation Rep = double>
using J = units::isq::si::energy<units::isq::si::joule, Rep>;
template<Representation Rep = double>
using yJ = units::isq::si::energy<units::isq::si::yoctojoule, Rep>;
template<Representation Rep = double>
using zJ = units::isq::si::energy<units::isq::si::zeptojoule, Rep>;
template<Representation Rep = double>
using aJ = units::isq::si::energy<units::isq::si::attojoule, Rep>;
template<Representation Rep = double>
using fJ = units::isq::si::energy<units::isq::si::femtojoule, Rep>;
template<Representation Rep = double>
using pJ = units::isq::si::energy<units::isq::si::picojoule, Rep>;
template<Representation Rep = double>
using nJ = units::isq::si::energy<units::isq::si::nanojoule, Rep>;
template<Representation Rep = double>
using uJ = units::isq::si::energy<units::isq::si::microjoule, Rep>;
template<Representation Rep = double>
using mJ = units::isq::si::energy<units::isq::si::millijoule, Rep>;
template<Representation Rep = double>
using kJ = units::isq::si::energy<units::isq::si::kilojoule, Rep>;
template<Representation Rep = double>
using MJ = units::isq::si::energy<units::isq::si::megajoule, Rep>;
template<Representation Rep = double>
using GJ = units::isq::si::energy<units::isq::si::gigajoule, Rep>;
template<Representation Rep = double>
using TJ = units::isq::si::energy<units::isq::si::terajoule, Rep>;
template<Representation Rep = double>
using PJ = units::isq::si::energy<units::isq::si::petajoule, Rep>;
template<Representation Rep = double>
using EJ = units::isq::si::energy<units::isq::si::exajoule, Rep>;
template<Representation Rep = double>
using ZJ = units::isq::si::energy<units::isq::si::zettajoule, Rep>;
template<Representation Rep = double>
using YJ = units::isq::si::energy<units::isq::si::yottajoule, Rep>;
template<Representation Rep = double> using eV = units::isq::si::energy<units::isq::si::electronvolt, Rep>;
template<Representation Rep = double> using GeV = units::isq::si::energy<units::isq::si::gigaelectronvolt, Rep>;
template<Representation Rep = double>
using eV = units::isq::si::energy<units::isq::si::electronvolt, Rep>;
template<Representation Rep = double>
using GeV = units::isq::si::energy<units::isq::si::gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::si::inline energy

View File

@ -68,87 +68,171 @@ using force = quantity<dim_force, U, Rep>;
inline namespace literals {
// N
constexpr auto operator"" _q_N(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<newton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_N(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<newton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_N(long double l) { return force<newton, long double>(l); }
// yN
constexpr auto operator"" _q_yN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<yoctonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<yoctonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yN(long double l) { return force<yoctonewton, long double>(l); }
// zN
constexpr auto operator"" _q_zN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<zeptonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<zeptonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zN(long double l) { return force<zeptonewton, long double>(l); }
// aN
constexpr auto operator"" _q_aN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<attonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<attonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aN(long double l) { return force<attonewton, long double>(l); }
// fN
constexpr auto operator"" _q_fN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<femtonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<femtonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fN(long double l) { return force<femtonewton, long double>(l); }
// pN
constexpr auto operator"" _q_pN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<piconewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<piconewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pN(long double l) { return force<piconewton, long double>(l); }
// nN
constexpr auto operator"" _q_nN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<nanonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<nanonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nN(long double l) { return force<nanonewton, long double>(l); }
// uN
constexpr auto operator"" _q_uN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<micronewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<micronewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uN(long double l) { return force<micronewton, long double>(l); }
// mN
constexpr auto operator"" _q_mN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<millinewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<millinewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mN(long double l) { return force<millinewton, long double>(l); }
// cN
constexpr auto operator"" _q_cN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<centinewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<centinewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cN(long double l) { return force<centinewton, long double>(l); }
// dN
constexpr auto operator"" _q_dN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<decinewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<decinewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dN(long double l) { return force<decinewton, long double>(l); }
// daN
constexpr auto operator"" _q_daN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<decanewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<decanewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daN(long double l) { return force<decanewton, long double>(l); }
// hN
constexpr auto operator"" _q_hN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<hectonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<hectonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hN(long double l) { return force<hectonewton, long double>(l); }
// kN
constexpr auto operator"" _q_kN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<kilonewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<kilonewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kN(long double l) { return force<kilonewton, long double>(l); }
// MN
constexpr auto operator"" _q_MN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<meganewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<meganewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MN(long double l) { return force<meganewton, long double>(l); }
// GN
constexpr auto operator"" _q_GN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<giganewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<giganewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GN(long double l) { return force<giganewton, long double>(l); }
// TN
constexpr auto operator"" _q_TN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<teranewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<teranewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TN(long double l) { return force<teranewton, long double>(l); }
// PN
constexpr auto operator"" _q_PN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<petanewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<petanewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PN(long double l) { return force<petanewton, long double>(l); }
// EN
constexpr auto operator"" _q_EN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<exanewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<exanewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EN(long double l) { return force<exanewton, long double>(l); }
// ZN
constexpr auto operator"" _q_ZN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<zettanewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<zettanewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZN(long double l) { return force<zettanewton, long double>(l); }
// YN
constexpr auto operator"" _q_YN(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<yottanewton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YN(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<yottanewton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YN(long double l) { return force<yottanewton, long double>(l); }
} // namespace literals
@ -197,27 +281,48 @@ using namespace force_references;
namespace units::aliases::isq::si::inline force {
template<Representation Rep = double> using N = units::isq::si::force<units::isq::si::newton, Rep>;
template<Representation Rep = double> using yN = units::isq::si::force<units::isq::si::yoctonewton, Rep>;
template<Representation Rep = double> using zN = units::isq::si::force<units::isq::si::zeptonewton, Rep>;
template<Representation Rep = double> using aN = units::isq::si::force<units::isq::si::attonewton, Rep>;
template<Representation Rep = double> using fN = units::isq::si::force<units::isq::si::femtonewton, Rep>;
template<Representation Rep = double> using pN = units::isq::si::force<units::isq::si::piconewton, Rep>;
template<Representation Rep = double> using nN = units::isq::si::force<units::isq::si::nanonewton, Rep>;
template<Representation Rep = double> using uN = units::isq::si::force<units::isq::si::micronewton, Rep>;
template<Representation Rep = double> using mN = units::isq::si::force<units::isq::si::millinewton, Rep>;
template<Representation Rep = double> using cN = units::isq::si::force<units::isq::si::centinewton, Rep>;
template<Representation Rep = double> using dN = units::isq::si::force<units::isq::si::decinewton, Rep>;
template<Representation Rep = double> using daN = units::isq::si::force<units::isq::si::decanewton, Rep>;
template<Representation Rep = double> using hN = units::isq::si::force<units::isq::si::hectonewton, Rep>;
template<Representation Rep = double> using kN = units::isq::si::force<units::isq::si::kilonewton, Rep>;
template<Representation Rep = double> using MN = units::isq::si::force<units::isq::si::meganewton, Rep>;
template<Representation Rep = double> using GN = units::isq::si::force<units::isq::si::giganewton, Rep>;
template<Representation Rep = double> using TN = units::isq::si::force<units::isq::si::teranewton, Rep>;
template<Representation Rep = double> using PN = units::isq::si::force<units::isq::si::petanewton, Rep>;
template<Representation Rep = double> using EN = units::isq::si::force<units::isq::si::exanewton, Rep>;
template<Representation Rep = double> using ZN = units::isq::si::force<units::isq::si::zettanewton, Rep>;
template<Representation Rep = double> using YN = units::isq::si::force<units::isq::si::yottanewton, Rep>;
template<Representation Rep = double>
using N = units::isq::si::force<units::isq::si::newton, Rep>;
template<Representation Rep = double>
using yN = units::isq::si::force<units::isq::si::yoctonewton, Rep>;
template<Representation Rep = double>
using zN = units::isq::si::force<units::isq::si::zeptonewton, Rep>;
template<Representation Rep = double>
using aN = units::isq::si::force<units::isq::si::attonewton, Rep>;
template<Representation Rep = double>
using fN = units::isq::si::force<units::isq::si::femtonewton, Rep>;
template<Representation Rep = double>
using pN = units::isq::si::force<units::isq::si::piconewton, Rep>;
template<Representation Rep = double>
using nN = units::isq::si::force<units::isq::si::nanonewton, Rep>;
template<Representation Rep = double>
using uN = units::isq::si::force<units::isq::si::micronewton, Rep>;
template<Representation Rep = double>
using mN = units::isq::si::force<units::isq::si::millinewton, Rep>;
template<Representation Rep = double>
using cN = units::isq::si::force<units::isq::si::centinewton, Rep>;
template<Representation Rep = double>
using dN = units::isq::si::force<units::isq::si::decinewton, Rep>;
template<Representation Rep = double>
using daN = units::isq::si::force<units::isq::si::decanewton, Rep>;
template<Representation Rep = double>
using hN = units::isq::si::force<units::isq::si::hectonewton, Rep>;
template<Representation Rep = double>
using kN = units::isq::si::force<units::isq::si::kilonewton, Rep>;
template<Representation Rep = double>
using MN = units::isq::si::force<units::isq::si::meganewton, Rep>;
template<Representation Rep = double>
using GN = units::isq::si::force<units::isq::si::giganewton, Rep>;
template<Representation Rep = double>
using TN = units::isq::si::force<units::isq::si::teranewton, Rep>;
template<Representation Rep = double>
using PN = units::isq::si::force<units::isq::si::petanewton, Rep>;
template<Representation Rep = double>
using EN = units::isq::si::force<units::isq::si::exanewton, Rep>;
template<Representation Rep = double>
using ZN = units::isq::si::force<units::isq::si::zettanewton, Rep>;
template<Representation Rep = double>
using YN = units::isq::si::force<units::isq::si::yottanewton, Rep>;
} // namespace units::aliases::isq::si::inline force

View File

@ -45,7 +45,11 @@ using luminance = quantity<dim_luminance, U, Rep>;
inline namespace literals {
// cd/m²
constexpr auto operator"" _q_cd_per_m2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminance<candela_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cd_per_m2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminance<candela_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cd_per_m2(long double l) { return luminance<candela_per_metre_sq, long double>(l); }
} // namespace literals
@ -58,7 +62,8 @@ constexpr auto operator"" _q_cd_per_m2(long double l) { return luminance<candela
namespace units::aliases::isq::si::inline luminance {
template<Representation Rep = double> using cd_per_m2 = units::isq::si::luminance<units::isq::si::candela_per_metre_sq, Rep>;
template<Representation Rep = double>
using cd_per_m2 = units::isq::si::luminance<units::isq::si::candela_per_metre_sq, Rep>;
} // namespace units::aliases::isq::si::inline luminance

View File

@ -66,87 +66,171 @@ using luminous_intensity = quantity<dim_luminous_intensity, U, Rep>;
inline namespace literals {
// cd
constexpr auto operator"" _q_cd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<candela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<candela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cd(long double l) { return luminous_intensity<candela, long double>(l); }
// ycd
constexpr auto operator"" _q_ycd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<yoctocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ycd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<yoctocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ycd(long double l) { return luminous_intensity<yoctocandela, long double>(l); }
// zcd
constexpr auto operator"" _q_zcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<zeptocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<zeptocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zcd(long double l) { return luminous_intensity<zeptocandela, long double>(l); }
// acd
constexpr auto operator"" _q_acd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<attocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_acd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<attocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_acd(long double l) { return luminous_intensity<attocandela, long double>(l); }
// fcd
constexpr auto operator"" _q_fcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<femtocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<femtocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fcd(long double l) { return luminous_intensity<femtocandela, long double>(l); }
// pcd
constexpr auto operator"" _q_pcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<picocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<picocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pcd(long double l) { return luminous_intensity<picocandela, long double>(l); }
// ncd
constexpr auto operator"" _q_ncd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<nanocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ncd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<nanocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ncd(long double l) { return luminous_intensity<nanocandela, long double>(l); }
// ucd
constexpr auto operator"" _q_ucd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<microcandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ucd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<microcandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ucd(long double l) { return luminous_intensity<microcandela, long double>(l); }
// mcd
constexpr auto operator"" _q_mcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<millicandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<millicandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mcd(long double l) { return luminous_intensity<millicandela, long double>(l); }
// ccd
constexpr auto operator"" _q_ccd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<centicandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ccd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<centicandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ccd(long double l) { return luminous_intensity<centicandela, long double>(l); }
// dcd
constexpr auto operator"" _q_dcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<decicandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<decicandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dcd(long double l) { return luminous_intensity<decicandela, long double>(l); }
// dacd
constexpr auto operator"" _q_dacd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<decacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dacd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<decacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dacd(long double l) { return luminous_intensity<decacandela, long double>(l); }
// hcd
constexpr auto operator"" _q_hcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<hectocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<hectocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hcd(long double l) { return luminous_intensity<hectocandela, long double>(l); }
// kcd
constexpr auto operator"" _q_kcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<kilocandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<kilocandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kcd(long double l) { return luminous_intensity<kilocandela, long double>(l); }
// Mcd
constexpr auto operator"" _q_Mcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<megacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Mcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<megacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Mcd(long double l) { return luminous_intensity<megacandela, long double>(l); }
// Gcd
constexpr auto operator"" _q_Gcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<gigacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<gigacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gcd(long double l) { return luminous_intensity<gigacandela, long double>(l); }
// Tcd
constexpr auto operator"" _q_Tcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<teracandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Tcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<teracandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Tcd(long double l) { return luminous_intensity<teracandela, long double>(l); }
// Pcd
constexpr auto operator"" _q_Pcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<petacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<petacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pcd(long double l) { return luminous_intensity<petacandela, long double>(l); }
// Ecd
constexpr auto operator"" _q_Ecd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<exacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ecd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<exacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ecd(long double l) { return luminous_intensity<exacandela, long double>(l); }
// Zcd
constexpr auto operator"" _q_Zcd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<zettacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Zcd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<zettacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Zcd(long double l) { return luminous_intensity<zettacandela, long double>(l); }
// Ycd
constexpr auto operator"" _q_Ycd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return luminous_intensity<yottacandela, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ycd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return luminous_intensity<yottacandela, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ycd(long double l) { return luminous_intensity<yottacandela, long double>(l); }
} // namespace literals
@ -195,27 +279,48 @@ using namespace luminous_intensity_references;
namespace units::aliases::isq::si::luminous_intensity {
template<Representation Rep = double> using cd = units::isq::si::luminous_intensity<units::isq::si::candela, Rep>;
template<Representation Rep = double> using ycd = units::isq::si::luminous_intensity<units::isq::si::yoctocandela, Rep>;
template<Representation Rep = double> using zcd = units::isq::si::luminous_intensity<units::isq::si::zeptocandela, Rep>;
template<Representation Rep = double> using acd = units::isq::si::luminous_intensity<units::isq::si::attocandela, Rep>;
template<Representation Rep = double> using fcd = units::isq::si::luminous_intensity<units::isq::si::femtocandela, Rep>;
template<Representation Rep = double> using pcd = units::isq::si::luminous_intensity<units::isq::si::picocandela, Rep>;
template<Representation Rep = double> using ncd = units::isq::si::luminous_intensity<units::isq::si::nanocandela, Rep>;
template<Representation Rep = double> using ucd = units::isq::si::luminous_intensity<units::isq::si::microcandela, Rep>;
template<Representation Rep = double> using mcd = units::isq::si::luminous_intensity<units::isq::si::millicandela, Rep>;
template<Representation Rep = double> using ccd = units::isq::si::luminous_intensity<units::isq::si::centicandela, Rep>;
template<Representation Rep = double> using dcd = units::isq::si::luminous_intensity<units::isq::si::decicandela, Rep>;
template<Representation Rep = double> using dacd = units::isq::si::luminous_intensity<units::isq::si::decacandela, Rep>;
template<Representation Rep = double> using hcd = units::isq::si::luminous_intensity<units::isq::si::hectocandela, Rep>;
template<Representation Rep = double> using kcd = units::isq::si::luminous_intensity<units::isq::si::kilocandela, Rep>;
template<Representation Rep = double> using Mcd = units::isq::si::luminous_intensity<units::isq::si::megacandela, Rep>;
template<Representation Rep = double> using Gcd = units::isq::si::luminous_intensity<units::isq::si::gigacandela, Rep>;
template<Representation Rep = double> using Tcd = units::isq::si::luminous_intensity<units::isq::si::teracandela, Rep>;
template<Representation Rep = double> using Pcd = units::isq::si::luminous_intensity<units::isq::si::petacandela, Rep>;
template<Representation Rep = double> using Ecd = units::isq::si::luminous_intensity<units::isq::si::exacandela, Rep>;
template<Representation Rep = double> using Zcd = units::isq::si::luminous_intensity<units::isq::si::zettacandela, Rep>;
template<Representation Rep = double> using Ycd = units::isq::si::luminous_intensity<units::isq::si::yottacandela, Rep>;
template<Representation Rep = double>
using cd = units::isq::si::luminous_intensity<units::isq::si::candela, Rep>;
template<Representation Rep = double>
using ycd = units::isq::si::luminous_intensity<units::isq::si::yoctocandela, Rep>;
template<Representation Rep = double>
using zcd = units::isq::si::luminous_intensity<units::isq::si::zeptocandela, Rep>;
template<Representation Rep = double>
using acd = units::isq::si::luminous_intensity<units::isq::si::attocandela, Rep>;
template<Representation Rep = double>
using fcd = units::isq::si::luminous_intensity<units::isq::si::femtocandela, Rep>;
template<Representation Rep = double>
using pcd = units::isq::si::luminous_intensity<units::isq::si::picocandela, Rep>;
template<Representation Rep = double>
using ncd = units::isq::si::luminous_intensity<units::isq::si::nanocandela, Rep>;
template<Representation Rep = double>
using ucd = units::isq::si::luminous_intensity<units::isq::si::microcandela, Rep>;
template<Representation Rep = double>
using mcd = units::isq::si::luminous_intensity<units::isq::si::millicandela, Rep>;
template<Representation Rep = double>
using ccd = units::isq::si::luminous_intensity<units::isq::si::centicandela, Rep>;
template<Representation Rep = double>
using dcd = units::isq::si::luminous_intensity<units::isq::si::decicandela, Rep>;
template<Representation Rep = double>
using dacd = units::isq::si::luminous_intensity<units::isq::si::decacandela, Rep>;
template<Representation Rep = double>
using hcd = units::isq::si::luminous_intensity<units::isq::si::hectocandela, Rep>;
template<Representation Rep = double>
using kcd = units::isq::si::luminous_intensity<units::isq::si::kilocandela, Rep>;
template<Representation Rep = double>
using Mcd = units::isq::si::luminous_intensity<units::isq::si::megacandela, Rep>;
template<Representation Rep = double>
using Gcd = units::isq::si::luminous_intensity<units::isq::si::gigacandela, Rep>;
template<Representation Rep = double>
using Tcd = units::isq::si::luminous_intensity<units::isq::si::teracandela, Rep>;
template<Representation Rep = double>
using Pcd = units::isq::si::luminous_intensity<units::isq::si::petacandela, Rep>;
template<Representation Rep = double>
using Ecd = units::isq::si::luminous_intensity<units::isq::si::exacandela, Rep>;
template<Representation Rep = double>
using Zcd = units::isq::si::luminous_intensity<units::isq::si::zettacandela, Rep>;
template<Representation Rep = double>
using Ycd = units::isq::si::luminous_intensity<units::isq::si::yottacandela, Rep>;
} // namespace units::aliases::isq::si::luminous_intensity

View File

@ -28,8 +28,8 @@
#include <units/symbol_text.h>
// IWYU pragma: end_exports
#include <units/isq/si/energy.h>
#include <units/isq/si/amount_of_substance.h>
#include <units/isq/si/energy.h>
#include <units/isq/si/prefixes.h>
#include <units/unit.h>
@ -37,7 +37,8 @@ namespace units::isq::si {
struct joule_per_mole : unit<joule_per_mole> {};
struct dim_molar_energy : isq::dim_molar_energy<dim_molar_energy, joule_per_mole, dim_energy, dim_amount_of_substance> {};
struct dim_molar_energy :
isq::dim_molar_energy<dim_molar_energy, joule_per_mole, dim_energy, dim_amount_of_substance> {};
template<UnitOf<dim_molar_energy> U, Representation Rep = double>
using molar_energy = quantity<dim_molar_energy, U, Rep>;
@ -47,7 +48,11 @@ using molar_energy = quantity<dim_molar_energy, U, Rep>;
inline namespace literals {
// J/mol
constexpr auto operator"" _q_J_per_mol(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return molar_energy<joule_per_mole, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_J_per_mol(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return molar_energy<joule_per_mole, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_J_per_mol(long double l) { return molar_energy<joule_per_mole, long double>(l); }
} // namespace literals
@ -60,7 +65,8 @@ constexpr auto operator"" _q_J_per_mol(long double l) { return molar_energy<joul
namespace units::aliases::isq::si::inline molar_energy {
template<Representation Rep = double> using J_per_mol = units::isq::si::molar_energy<units::isq::si::joule_per_mole, Rep>;
template<Representation Rep = double>
using J_per_mol = units::isq::si::molar_energy<units::isq::si::joule_per_mole, Rep>;
} // namespace units::aliases::isq::si::inline molar_energy

View File

@ -68,87 +68,171 @@ using pressure = quantity<dim_pressure, U, Rep>;
inline namespace literals {
// Pa
constexpr auto operator"" _q_Pa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<pascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<pascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pa(long double l) { return pressure<pascal, long double>(l); }
// yPa
constexpr auto operator"" _q_yPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<yoctopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<yoctopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yPa(long double l) { return pressure<yoctopascal, long double>(l); }
// zPa
constexpr auto operator"" _q_zPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<zeptopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<zeptopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zPa(long double l) { return pressure<zeptopascal, long double>(l); }
// aPa
constexpr auto operator"" _q_aPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<attopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<attopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aPa(long double l) { return pressure<attopascal, long double>(l); }
// fPa
constexpr auto operator"" _q_fPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<femtopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<femtopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fPa(long double l) { return pressure<femtopascal, long double>(l); }
// pPa
constexpr auto operator"" _q_pPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<picopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<picopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pPa(long double l) { return pressure<picopascal, long double>(l); }
// nPa
constexpr auto operator"" _q_nPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<nanopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<nanopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nPa(long double l) { return pressure<nanopascal, long double>(l); }
// uPa
constexpr auto operator"" _q_uPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<micropascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<micropascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uPa(long double l) { return pressure<micropascal, long double>(l); }
// mPa
constexpr auto operator"" _q_mPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<millipascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<millipascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mPa(long double l) { return pressure<millipascal, long double>(l); }
// cPa
constexpr auto operator"" _q_cPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<centipascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<centipascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cPa(long double l) { return pressure<centipascal, long double>(l); }
// dPa
constexpr auto operator"" _q_dPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<decipascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<decipascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dPa(long double l) { return pressure<decipascal, long double>(l); }
// daPa
constexpr auto operator"" _q_daPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<decapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<decapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daPa(long double l) { return pressure<decapascal, long double>(l); }
// hPa
constexpr auto operator"" _q_hPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<hectopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<hectopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hPa(long double l) { return pressure<hectopascal, long double>(l); }
// kPa
constexpr auto operator"" _q_kPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<kilopascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<kilopascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kPa(long double l) { return pressure<kilopascal, long double>(l); }
// MPa
constexpr auto operator"" _q_MPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<megapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<megapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MPa(long double l) { return pressure<megapascal, long double>(l); }
// GPa
constexpr auto operator"" _q_GPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<gigapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<gigapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GPa(long double l) { return pressure<gigapascal, long double>(l); }
// TPa
constexpr auto operator"" _q_TPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<terapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<terapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TPa(long double l) { return pressure<terapascal, long double>(l); }
// PPa
constexpr auto operator"" _q_PPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<petapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<petapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PPa(long double l) { return pressure<petapascal, long double>(l); }
// EPa
constexpr auto operator"" _q_EPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<exapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<exapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EPa(long double l) { return pressure<exapascal, long double>(l); }
// ZPa
constexpr auto operator"" _q_ZPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<zettapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<zettapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZPa(long double l) { return pressure<zettapascal, long double>(l); }
// YPa
constexpr auto operator"" _q_YPa(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<yottapascal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YPa(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<yottapascal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YPa(long double l) { return pressure<yottapascal, long double>(l); }
} // namespace literals
@ -197,27 +281,48 @@ using namespace pressure_references;
namespace units::aliases::isq::si::inline pressure {
template<Representation Rep = double> using Pa = units::isq::si::pressure<units::isq::si::pascal, Rep>;
template<Representation Rep = double> using yPa = units::isq::si::pressure<units::isq::si::yoctopascal, Rep>;
template<Representation Rep = double> using zPa = units::isq::si::pressure<units::isq::si::zeptopascal, Rep>;
template<Representation Rep = double> using aPa = units::isq::si::pressure<units::isq::si::attopascal, Rep>;
template<Representation Rep = double> using fPa = units::isq::si::pressure<units::isq::si::femtopascal, Rep>;
template<Representation Rep = double> using pPa = units::isq::si::pressure<units::isq::si::picopascal, Rep>;
template<Representation Rep = double> using nPa = units::isq::si::pressure<units::isq::si::nanopascal, Rep>;
template<Representation Rep = double> using uPa = units::isq::si::pressure<units::isq::si::micropascal, Rep>;
template<Representation Rep = double> using mPa = units::isq::si::pressure<units::isq::si::millipascal, Rep>;
template<Representation Rep = double> using cPa = units::isq::si::pressure<units::isq::si::centipascal, Rep>;
template<Representation Rep = double> using dPa = units::isq::si::pressure<units::isq::si::decipascal, Rep>;
template<Representation Rep = double> using daPa = units::isq::si::pressure<units::isq::si::decapascal, Rep>;
template<Representation Rep = double> using hPa = units::isq::si::pressure<units::isq::si::hectopascal, Rep>;
template<Representation Rep = double> using kPa = units::isq::si::pressure<units::isq::si::kilopascal, Rep>;
template<Representation Rep = double> using MPa = units::isq::si::pressure<units::isq::si::megapascal, Rep>;
template<Representation Rep = double> using GPa = units::isq::si::pressure<units::isq::si::gigapascal, Rep>;
template<Representation Rep = double> using TPa = units::isq::si::pressure<units::isq::si::terapascal, Rep>;
template<Representation Rep = double> using PPa = units::isq::si::pressure<units::isq::si::petapascal, Rep>;
template<Representation Rep = double> using EPa = units::isq::si::pressure<units::isq::si::exapascal, Rep>;
template<Representation Rep = double> using ZPa = units::isq::si::pressure<units::isq::si::zettapascal, Rep>;
template<Representation Rep = double> using YPa = units::isq::si::pressure<units::isq::si::yottapascal, Rep>;
template<Representation Rep = double>
using Pa = units::isq::si::pressure<units::isq::si::pascal, Rep>;
template<Representation Rep = double>
using yPa = units::isq::si::pressure<units::isq::si::yoctopascal, Rep>;
template<Representation Rep = double>
using zPa = units::isq::si::pressure<units::isq::si::zeptopascal, Rep>;
template<Representation Rep = double>
using aPa = units::isq::si::pressure<units::isq::si::attopascal, Rep>;
template<Representation Rep = double>
using fPa = units::isq::si::pressure<units::isq::si::femtopascal, Rep>;
template<Representation Rep = double>
using pPa = units::isq::si::pressure<units::isq::si::picopascal, Rep>;
template<Representation Rep = double>
using nPa = units::isq::si::pressure<units::isq::si::nanopascal, Rep>;
template<Representation Rep = double>
using uPa = units::isq::si::pressure<units::isq::si::micropascal, Rep>;
template<Representation Rep = double>
using mPa = units::isq::si::pressure<units::isq::si::millipascal, Rep>;
template<Representation Rep = double>
using cPa = units::isq::si::pressure<units::isq::si::centipascal, Rep>;
template<Representation Rep = double>
using dPa = units::isq::si::pressure<units::isq::si::decipascal, Rep>;
template<Representation Rep = double>
using daPa = units::isq::si::pressure<units::isq::si::decapascal, Rep>;
template<Representation Rep = double>
using hPa = units::isq::si::pressure<units::isq::si::hectopascal, Rep>;
template<Representation Rep = double>
using kPa = units::isq::si::pressure<units::isq::si::kilopascal, Rep>;
template<Representation Rep = double>
using MPa = units::isq::si::pressure<units::isq::si::megapascal, Rep>;
template<Representation Rep = double>
using GPa = units::isq::si::pressure<units::isq::si::gigapascal, Rep>;
template<Representation Rep = double>
using TPa = units::isq::si::pressure<units::isq::si::terapascal, Rep>;
template<Representation Rep = double>
using PPa = units::isq::si::pressure<units::isq::si::petapascal, Rep>;
template<Representation Rep = double>
using EPa = units::isq::si::pressure<units::isq::si::exapascal, Rep>;
template<Representation Rep = double>
using ZPa = units::isq::si::pressure<units::isq::si::zettapascal, Rep>;
template<Representation Rep = double>
using YPa = units::isq::si::pressure<units::isq::si::yottapascal, Rep>;
} // namespace units::aliases::isq::si::inline pressure

View File

@ -66,87 +66,171 @@ using radioactivity = quantity<dim_radioactivity, U, Rep>;
inline namespace literals {
// Bq
constexpr auto operator"" _q_Bq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<becquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Bq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<becquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Bq(long double l) { return radioactivity<becquerel, long double>(l); }
// yBq
constexpr auto operator"" _q_yBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<yoctobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<yoctobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yBq(long double l) { return radioactivity<yoctobecquerel, long double>(l); }
// zBq
constexpr auto operator"" _q_zBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<zeptobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<zeptobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zBq(long double l) { return radioactivity<zeptobecquerel, long double>(l); }
// aBq
constexpr auto operator"" _q_aBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<attobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<attobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aBq(long double l) { return radioactivity<attobecquerel, long double>(l); }
// fBq
constexpr auto operator"" _q_fBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<femtobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<femtobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fBq(long double l) { return radioactivity<femtobecquerel, long double>(l); }
// pBq
constexpr auto operator"" _q_pBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<picobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<picobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pBq(long double l) { return radioactivity<picobecquerel, long double>(l); }
// nBq
constexpr auto operator"" _q_nBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<nanobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<nanobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nBq(long double l) { return radioactivity<nanobecquerel, long double>(l); }
// uBq
constexpr auto operator"" _q_uBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<microbecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<microbecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uBq(long double l) { return radioactivity<microbecquerel, long double>(l); }
// mBq
constexpr auto operator"" _q_mBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<millibecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<millibecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mBq(long double l) { return radioactivity<millibecquerel, long double>(l); }
// cBq
constexpr auto operator"" _q_cBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<centibecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<centibecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cBq(long double l) { return radioactivity<centibecquerel, long double>(l); }
// dBq
constexpr auto operator"" _q_dBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<decibecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<decibecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dBq(long double l) { return radioactivity<decibecquerel, long double>(l); }
// daBq
constexpr auto operator"" _q_daBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<decabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<decabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daBq(long double l) { return radioactivity<decabecquerel, long double>(l); }
// hBq
constexpr auto operator"" _q_hBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<hectobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<hectobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hBq(long double l) { return radioactivity<hectobecquerel, long double>(l); }
// kBq
constexpr auto operator"" _q_kBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<kilobecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<kilobecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kBq(long double l) { return radioactivity<kilobecquerel, long double>(l); }
// MBq
constexpr auto operator"" _q_MBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<megabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<megabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MBq(long double l) { return radioactivity<megabecquerel, long double>(l); }
// GBq
constexpr auto operator"" _q_GBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<gigabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<gigabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GBq(long double l) { return radioactivity<gigabecquerel, long double>(l); }
// TBq
constexpr auto operator"" _q_TBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<terabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<terabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TBq(long double l) { return radioactivity<terabecquerel, long double>(l); }
// PBq
constexpr auto operator"" _q_PBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<petabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<petabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PBq(long double l) { return radioactivity<petabecquerel, long double>(l); }
// EBq
constexpr auto operator"" _q_EBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<exabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<exabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EBq(long double l) { return radioactivity<exabecquerel, long double>(l); }
// ZBq
constexpr auto operator"" _q_ZBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<zettabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<zettabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZBq(long double l) { return radioactivity<zettabecquerel, long double>(l); }
// YBq
constexpr auto operator"" _q_YBq(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return radioactivity<yottabecquerel, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YBq(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return radioactivity<yottabecquerel, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YBq(long double l) { return radioactivity<yottabecquerel, long double>(l); }
} // namespace literals
@ -195,27 +279,48 @@ using namespace radioactivity_references;
namespace units::aliases::isq::si::inline radioactivity {
template<Representation Rep = double> using Bq = units::isq::radioactivity<units::isq::becquerel, Rep>;
template<Representation Rep = double> using yBq = units::isq::radioactivity<units::isq::yoctobecquerel, Rep>;
template<Representation Rep = double> using zBq = units::isq::radioactivity<units::isq::zeptobecquerel, Rep>;
template<Representation Rep = double> using aBq = units::isq::radioactivity<units::isq::attobecquerel, Rep>;
template<Representation Rep = double> using fBq = units::isq::radioactivity<units::isq::femtobecquerel, Rep>;
template<Representation Rep = double> using pBq = units::isq::radioactivity<units::isq::picobecquerel, Rep>;
template<Representation Rep = double> using nBq = units::isq::radioactivity<units::isq::nanobecquerel, Rep>;
template<Representation Rep = double> using uBq = units::isq::radioactivity<units::isq::microbecquerel, Rep>;
template<Representation Rep = double> using mBq = units::isq::radioactivity<units::isq::millibecquerel, Rep>;
template<Representation Rep = double> using cBq = units::isq::radioactivity<units::isq::centibecquerel, Rep>;
template<Representation Rep = double> using dBq = units::isq::radioactivity<units::isq::decibecquerel, Rep>;
template<Representation Rep = double> using daBq = units::isq::radioactivity<units::isq::decabecquerel, Rep>;
template<Representation Rep = double> using hBq = units::isq::radioactivity<units::isq::hectobecquerel, Rep>;
template<Representation Rep = double> using kBq = units::isq::radioactivity<units::isq::kilobecquerel, Rep>;
template<Representation Rep = double> using MBq = units::isq::radioactivity<units::isq::megabecquerel, Rep>;
template<Representation Rep = double> using GBq = units::isq::radioactivity<units::isq::gigabecquerel, Rep>;
template<Representation Rep = double> using TBq = units::isq::radioactivity<units::isq::terabecquerel, Rep>;
template<Representation Rep = double> using PBq = units::isq::radioactivity<units::isq::petabecquerel, Rep>;
template<Representation Rep = double> using EBq = units::isq::radioactivity<units::isq::exabecquerel, Rep>;
template<Representation Rep = double> using ZBq = units::isq::radioactivity<units::isq::zettabecquerel, Rep>;
template<Representation Rep = double> using YBq = units::isq::radioactivity<units::isq::yottabecquerel, Rep>;
template<Representation Rep = double>
using Bq = units::isq::radioactivity<units::isq::becquerel, Rep>;
template<Representation Rep = double>
using yBq = units::isq::radioactivity<units::isq::yoctobecquerel, Rep>;
template<Representation Rep = double>
using zBq = units::isq::radioactivity<units::isq::zeptobecquerel, Rep>;
template<Representation Rep = double>
using aBq = units::isq::radioactivity<units::isq::attobecquerel, Rep>;
template<Representation Rep = double>
using fBq = units::isq::radioactivity<units::isq::femtobecquerel, Rep>;
template<Representation Rep = double>
using pBq = units::isq::radioactivity<units::isq::picobecquerel, Rep>;
template<Representation Rep = double>
using nBq = units::isq::radioactivity<units::isq::nanobecquerel, Rep>;
template<Representation Rep = double>
using uBq = units::isq::radioactivity<units::isq::microbecquerel, Rep>;
template<Representation Rep = double>
using mBq = units::isq::radioactivity<units::isq::millibecquerel, Rep>;
template<Representation Rep = double>
using cBq = units::isq::radioactivity<units::isq::centibecquerel, Rep>;
template<Representation Rep = double>
using dBq = units::isq::radioactivity<units::isq::decibecquerel, Rep>;
template<Representation Rep = double>
using daBq = units::isq::radioactivity<units::isq::decabecquerel, Rep>;
template<Representation Rep = double>
using hBq = units::isq::radioactivity<units::isq::hectobecquerel, Rep>;
template<Representation Rep = double>
using kBq = units::isq::radioactivity<units::isq::kilobecquerel, Rep>;
template<Representation Rep = double>
using MBq = units::isq::radioactivity<units::isq::megabecquerel, Rep>;
template<Representation Rep = double>
using GBq = units::isq::radioactivity<units::isq::gigabecquerel, Rep>;
template<Representation Rep = double>
using TBq = units::isq::radioactivity<units::isq::terabecquerel, Rep>;
template<Representation Rep = double>
using PBq = units::isq::radioactivity<units::isq::petabecquerel, Rep>;
template<Representation Rep = double>
using EBq = units::isq::radioactivity<units::isq::exabecquerel, Rep>;
template<Representation Rep = double>
using ZBq = units::isq::radioactivity<units::isq::zettabecquerel, Rep>;
template<Representation Rep = double>
using YBq = units::isq::radioactivity<units::isq::yottabecquerel, Rep>;
} // namespace units::aliases::isq::si::inline radioactivity

View File

@ -68,87 +68,171 @@ using voltage = quantity<dim_voltage, U, Rep>;
inline namespace literals {
// V
constexpr auto operator"" _q_V(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<volt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_V(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<volt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_V(long double l) { return voltage<volt, long double>(l); }
// yV
constexpr auto operator"" _q_yV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<yoctovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<yoctovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yV(long double l) { return voltage<yoctovolt, long double>(l); }
// zV
constexpr auto operator"" _q_zV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<zeptovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<zeptovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zV(long double l) { return voltage<zeptovolt, long double>(l); }
// aV
constexpr auto operator"" _q_aV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<attovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_aV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<attovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_aV(long double l) { return voltage<attovolt, long double>(l); }
// fV
constexpr auto operator"" _q_fV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<femtovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<femtovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fV(long double l) { return voltage<femtovolt, long double>(l); }
// pV
constexpr auto operator"" _q_pV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<picovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<picovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pV(long double l) { return voltage<picovolt, long double>(l); }
// nV
constexpr auto operator"" _q_nV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<nanovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<nanovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nV(long double l) { return voltage<nanovolt, long double>(l); }
// uV
constexpr auto operator"" _q_uV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<microvolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_uV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<microvolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_uV(long double l) { return voltage<microvolt, long double>(l); }
// mV
constexpr auto operator"" _q_mV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<millivolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<millivolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mV(long double l) { return voltage<millivolt, long double>(l); }
// cV
constexpr auto operator"" _q_cV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<centivolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<centivolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cV(long double l) { return voltage<centivolt, long double>(l); }
// dV
constexpr auto operator"" _q_dV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<decivolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<decivolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dV(long double l) { return voltage<decivolt, long double>(l); }
// daV
constexpr auto operator"" _q_daV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<decavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_daV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<decavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_daV(long double l) { return voltage<decavolt, long double>(l); }
// hV
constexpr auto operator"" _q_hV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<hectovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<hectovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hV(long double l) { return voltage<hectovolt, long double>(l); }
// kV
constexpr auto operator"" _q_kV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<kilovolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<kilovolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kV(long double l) { return voltage<kilovolt, long double>(l); }
// MV
constexpr auto operator"" _q_MV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<megavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<megavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MV(long double l) { return voltage<megavolt, long double>(l); }
// GV
constexpr auto operator"" _q_GV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<gigavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<gigavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GV(long double l) { return voltage<gigavolt, long double>(l); }
// TV
constexpr auto operator"" _q_TV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<teravolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<teravolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TV(long double l) { return voltage<teravolt, long double>(l); }
// PV
constexpr auto operator"" _q_PV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<petavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<petavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PV(long double l) { return voltage<petavolt, long double>(l); }
// EV
constexpr auto operator"" _q_EV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<exavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<exavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EV(long double l) { return voltage<exavolt, long double>(l); }
// ZV
constexpr auto operator"" _q_ZV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<zettavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<zettavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZV(long double l) { return voltage<zettavolt, long double>(l); }
// YV
constexpr auto operator"" _q_YV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return voltage<yottavolt, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return voltage<yottavolt, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YV(long double l) { return voltage<yottavolt, long double>(l); }
} // namespace literals
@ -197,27 +281,48 @@ using namespace voltage_references;
namespace units::aliases::isq::si::inline voltage {
template<Representation Rep = double> using V = units::isq::si::voltage<units::isq::si::volt, Rep>;
template<Representation Rep = double> using yV = units::isq::si::voltage<units::isq::si::yoctovolt, Rep>;
template<Representation Rep = double> using zV = units::isq::si::voltage<units::isq::si::zeptovolt, Rep>;
template<Representation Rep = double> using aV = units::isq::si::voltage<units::isq::si::attovolt, Rep>;
template<Representation Rep = double> using fV = units::isq::si::voltage<units::isq::si::femtovolt, Rep>;
template<Representation Rep = double> using pV = units::isq::si::voltage<units::isq::si::picovolt, Rep>;
template<Representation Rep = double> using nV = units::isq::si::voltage<units::isq::si::nanovolt, Rep>;
template<Representation Rep = double> using uV = units::isq::si::voltage<units::isq::si::microvolt, Rep>;
template<Representation Rep = double> using mV = units::isq::si::voltage<units::isq::si::millivolt, Rep>;
template<Representation Rep = double> using cV = units::isq::si::voltage<units::isq::si::centivolt, Rep>;
template<Representation Rep = double> using dV = units::isq::si::voltage<units::isq::si::decivolt, Rep>;
template<Representation Rep = double> using daV = units::isq::si::voltage<units::isq::si::decavolt, Rep>;
template<Representation Rep = double> using hV = units::isq::si::voltage<units::isq::si::hectovolt, Rep>;
template<Representation Rep = double> using kV = units::isq::si::voltage<units::isq::si::kilovolt, Rep>;
template<Representation Rep = double> using MV = units::isq::si::voltage<units::isq::si::megavolt, Rep>;
template<Representation Rep = double> using GV = units::isq::si::voltage<units::isq::si::gigavolt, Rep>;
template<Representation Rep = double> using TV = units::isq::si::voltage<units::isq::si::teravolt, Rep>;
template<Representation Rep = double> using PV = units::isq::si::voltage<units::isq::si::petavolt, Rep>;
template<Representation Rep = double> using EV = units::isq::si::voltage<units::isq::si::exavolt, Rep>;
template<Representation Rep = double> using ZV = units::isq::si::voltage<units::isq::si::zettavolt, Rep>;
template<Representation Rep = double> using YV = units::isq::si::voltage<units::isq::si::yottavolt, Rep>;
template<Representation Rep = double>
using V = units::isq::si::voltage<units::isq::si::volt, Rep>;
template<Representation Rep = double>
using yV = units::isq::si::voltage<units::isq::si::yoctovolt, Rep>;
template<Representation Rep = double>
using zV = units::isq::si::voltage<units::isq::si::zeptovolt, Rep>;
template<Representation Rep = double>
using aV = units::isq::si::voltage<units::isq::si::attovolt, Rep>;
template<Representation Rep = double>
using fV = units::isq::si::voltage<units::isq::si::femtovolt, Rep>;
template<Representation Rep = double>
using pV = units::isq::si::voltage<units::isq::si::picovolt, Rep>;
template<Representation Rep = double>
using nV = units::isq::si::voltage<units::isq::si::nanovolt, Rep>;
template<Representation Rep = double>
using uV = units::isq::si::voltage<units::isq::si::microvolt, Rep>;
template<Representation Rep = double>
using mV = units::isq::si::voltage<units::isq::si::millivolt, Rep>;
template<Representation Rep = double>
using cV = units::isq::si::voltage<units::isq::si::centivolt, Rep>;
template<Representation Rep = double>
using dV = units::isq::si::voltage<units::isq::si::decivolt, Rep>;
template<Representation Rep = double>
using daV = units::isq::si::voltage<units::isq::si::decavolt, Rep>;
template<Representation Rep = double>
using hV = units::isq::si::voltage<units::isq::si::hectovolt, Rep>;
template<Representation Rep = double>
using kV = units::isq::si::voltage<units::isq::si::kilovolt, Rep>;
template<Representation Rep = double>
using MV = units::isq::si::voltage<units::isq::si::megavolt, Rep>;
template<Representation Rep = double>
using GV = units::isq::si::voltage<units::isq::si::gigavolt, Rep>;
template<Representation Rep = double>
using TV = units::isq::si::voltage<units::isq::si::teravolt, Rep>;
template<Representation Rep = double>
using PV = units::isq::si::voltage<units::isq::si::petavolt, Rep>;
template<Representation Rep = double>
using EV = units::isq::si::voltage<units::isq::si::exavolt, Rep>;
template<Representation Rep = double>
using ZV = units::isq::si::voltage<units::isq::si::zettavolt, Rep>;
template<Representation Rep = double>
using YV = units::isq::si::voltage<units::isq::si::yottavolt, Rep>;
} // namespace units::aliases::isq::si::inline voltage

View File

@ -26,160 +26,159 @@
namespace units {
namespace detail {
namespace detail {
template<bool>
struct conditional {
template<bool>
struct conditional {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional<true> {
template<>
struct conditional<true> {
template<typename T, typename F>
using type = T;
};
};
template<bool B, typename T, typename F>
using conditional_t = conditional<B>::template type<T, F>;
template<bool B, typename T, typename F>
using conditional_t = conditional<B>::template type<T, F>;
}
} // namespace detail
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
template<TypeList List, typename... Types>
struct type_list_push_front;
template<TypeList List, typename... Types>
struct type_list_push_front;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
template<TypeList List, typename... Types>
using type_list_push_front_t = type_list_push_front<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front_t = type_list_push_front<List, Types...>::type;
// push_back
// push_back
template<TypeList List, typename... Types>
struct type_list_push_back;
template<TypeList List, typename... Types>
struct type_list_push_back;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
template<TypeList List, typename... Types>
using type_list_push_back_t = type_list_push_back<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back_t = type_list_push_back<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using base_first = base::first_list;
using base_second = base::second_list;
using first_list = detail::conditional_t<Idx < N, type_list_push_front_t<base_first, T>, base_first>;
using second_list = detail::conditional_t<Idx < N, base_second, type_list_push_front_t<base_second, T>>;
};
using first_list = detail::conditional_t < Idx<N, type_list_push_front_t<base_first, T>, base_first>;
using second_list = detail::conditional_t < Idx<N, base_second, type_list_push_front_t<base_second, T>>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted;
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted;
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted_t = type_list_merge_sorted<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted_t = type_list_merge_sorted<SortedList1, SortedList2, Pred>::type;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = detail::conditional_t<
Pred<Lhs1, Rhs1>::value,
type_list_push_front_t<type_list_merge_sorted_t<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>, Lhs1>,
type_list_push_front_t<type_list_merge_sorted_t<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>, Rhs1>>;
};
};
// sort
// sort
template<TypeList List, template<typename, typename> typename Pred>
struct type_list_sort;
template<TypeList List, template<typename, typename> typename Pred>
struct type_list_sort;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort<typename split::first_list, Pred>::type;
using right = type_list_sort<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_t<left, right, Pred>;
};
};
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort_t = type_list_sort<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort_t = type_list_sort<List, Pred>::type;
} // namespace units

View File

@ -26,179 +26,180 @@
namespace units {
namespace detail {
namespace detail {
template<bool>
struct conditional {
template<bool>
struct conditional {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional<true> {
template<>
struct conditional<true> {
template<typename T, typename F>
using type = T;
};
};
}
} // namespace detail
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = units::conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = units::conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
units::conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
units::conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = units::conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,166 +26,167 @@
namespace units {
namespace detail {
namespace detail {
template<bool>
struct conditional {
template<bool>
struct conditional {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional<true> {
template<>
struct conditional<true> {
template<typename T, typename F>
using type = T;
};
};
}
} // namespace detail
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<typename List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<typename List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<typename List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<typename List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = units::conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = units::conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
units::conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
units::conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<typename List, std::size_t N>
struct type_list_split;
template<typename List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<typename List>
struct type_list_split_half;
template<typename List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = units::conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<typename List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<typename List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,179 +26,180 @@
namespace units {
namespace detail {
namespace detail {
template<bool>
struct conditional {
template<bool>
struct conditional {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional<true> {
template<>
struct conditional<true> {
template<typename T, typename F>
using type = T;
};
};
}
} // namespace detail
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
template<bool B, typename T, typename F>
using conditional = detail::conditional<B>::template type<T, F>;
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = units::conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = units::conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
units::conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
units::conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = units::conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,172 +26,172 @@
namespace units {
template<bool>
struct conditional {
template<bool>
struct conditional {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional<true> {
template<>
struct conditional<true> {
template<typename T, typename F>
using type = T;
};
};
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = conditional<Idx < N>::template type<
typename type_list_push_front_impl<typename base::first_list, T>::type,
using first_list =
conditional < Idx<N>::template type<typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = conditional<Idx < N>::template type<
typename base::second_list,
using second_list =
conditional < Idx<N>::template type<typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = units::conditional<
Pred<Lhs1, Rhs1>::value>::template type<
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = units::conditional<Pred<Lhs1, Rhs1>::value>::template type<
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,160 +26,161 @@
namespace units {
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = std::conditional_t<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = std::conditional_t<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
std::conditional_t <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
std::conditional_t <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = std::conditional_t<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -22,193 +22,190 @@
#pragma once
#include "type_list_concepts_all.h"
#include "downcasting_concepts_all.h"
#include "ratio_concepts_all.h"
#include "type_list_concepts_all.h"
#include <ratio>
namespace units {
struct base_dimension {
struct base_dimension {
const char* name;
};
};
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 != *p2) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 != *p2) return false;
}
return *p1 == *p2;
}
}
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 < *p2) return true;
if(*p2 < *p1) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 < *p2) return true;
if (*p2 < *p1) return false;
}
return (*p1 == '\0') && (*p2 != '\0');
}
}
// base_dimension_less
// base_dimension_less
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant<D1 < D2> {
};
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant < D1<D2> {};
// exponent
// exponent
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr std::intmax_t num = Num;
static constexpr std::intmax_t den = Den;
};
};
// is_exponent
namespace detail {
template<typename T>
inline constexpr bool is_exponent = false;
// is_exponent
namespace detail {
template<typename T>
inline constexpr bool is_exponent = false;
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exponent<exponent<BaseDimension, Num, Den>> = true;
} // namespace detail
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exponent<exponent<BaseDimension, Num, Den>> = true;
} // namespace detail
template<typename T>
concept Exponent = detail::is_exponent<T>;
template<typename T>
concept Exponent = detail::is_exponent<T>;
// exp_dim_id_less
// exp_dim_id_less
template<Exponent E1, Exponent E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {
};
template<Exponent E1, Exponent E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {};
// exponent_invert
// exponent_invert
template<Exponent E>
struct exponent_invert;
template<Exponent E>
struct exponent_invert;
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
using type = exponent<BaseDimension, -Num, Den>;
};
};
template<Exponent E>
using exponent_invert_t = exponent_invert<E>::type;
template<Exponent E>
using exponent_invert_t = exponent_invert<E>::type;
// dimension
// dimension
template<Exponent... Es>
struct dimension : downcast_base<dimension<Es...>> {};
template<Exponent... Es>
struct dimension : downcast_base<dimension<Es...>> {};
// is_dimension
namespace detail {
// is_dimension
namespace detail {
template<typename T>
inline constexpr bool is_dimension = false;
template<typename T>
inline constexpr bool is_dimension = false;
template<typename... Es>
inline constexpr bool is_dimension<dimension<Es...>> = true;
template<typename... Es>
inline constexpr bool is_dimension<dimension<Es...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept Dimension =
std::is_empty_v<T> &&
detail::is_dimension<downcast_base_t<T>>;
template<typename T>
concept Dimension = std::is_empty_v<T> && detail::is_dimension<downcast_base_t<T>>;
// dim_invert
// dim_invert
template<Dimension E>
struct dim_invert;
template<Dimension E>
struct dim_invert;
template<Exponent... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<Exponent... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<Dimension D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
template<Dimension D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
// make_dimension
// make_dimension
namespace detail {
namespace detail {
template<Dimension D>
struct dim_consolidate;
template<Dimension D>
struct dim_consolidate;
template<Dimension D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<Dimension D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<>
struct dim_consolidate<dimension<>> {
template<>
struct dim_consolidate<dimension<>> {
using type = dimension<>;
};
};
template<Exponent E>
struct dim_consolidate<dimension<E>> {
template<Exponent E>
struct dim_consolidate<dimension<E>> {
using type = dimension<E>;
};
};
template<Exponent E1, Exponent... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
template<Exponent E1, Exponent... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
using rest = dim_consolidate_t<dimension<ERest...>>;
using type = conditional<is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
};
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, Exponent... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2,
Exponent... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;
using r = std::ratio_add<r1, r2>;
using type = conditional<r::num == 0, dim_consolidate_t<dimension<ERest...>>,
dim_consolidate_t<dimension<exponent<D, r::num, r::den>, ERest...>>>;
};
};
} // namespace detail
} // namespace detail
template<Exponent... Es>
struct make_dimension {
template<Exponent... Es>
struct make_dimension {
using type = detail::dim_consolidate_t<type_list_sort<dimension<Es...>, exponent_less>>;
};
};
template<Exponent... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<Exponent... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<Dimension D1, Dimension D2>
struct merge_dimension {
template<Dimension D1, Dimension D2>
struct merge_dimension {
using type = detail::dim_consolidate_t<type_list_merge_sorted<D1, D2, exponent_less>>;
};
};
template<Dimension D1, Dimension D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
template<Dimension D1, Dimension D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
// dimension_multiply
// dimension_multiply
template<Dimension D1, Dimension D2>
struct dimension_multiply;
template<Dimension D1, Dimension D2>
struct dimension_multiply;
template<Exponent... E1, Exponent... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<Exponent... E1, Exponent... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> :
std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<Dimension D1, Dimension D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<Dimension D1, Dimension D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
// dimension_divide
// dimension_divide
template<Dimension D1, Dimension D2>
struct dimension_divide;
template<Dimension D1, Dimension D2>
struct dimension_divide;
template<Exponent... E1, Exponent... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>>
: dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {
};
template<Exponent... E1, Exponent... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>> :
dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {};
template<Dimension D1, Dimension D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<Dimension D1, Dimension D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
} // namespace units

View File

@ -22,193 +22,190 @@
#pragma once
#include "type_list_concepts_iface.h"
#include "downcasting_concepts_all.h"
#include "ratio_concepts_iface.h"
#include "type_list_concepts_iface.h"
#include <ratio>
namespace units {
struct base_dimension {
struct base_dimension {
const char* name;
};
};
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 != *p2) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 != *p2) return false;
}
return *p1 == *p2;
}
}
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 < *p2) return true;
if(*p2 < *p1) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 < *p2) return true;
if (*p2 < *p1) return false;
}
return (*p1 == '\0') && (*p2 != '\0');
}
}
// base_dimension_less
// base_dimension_less
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant<D1 < D2> {
};
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant < D1<D2> {};
// exponent
// exponent
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr int num = Num;
static constexpr int den = Den;
};
};
// is_exponent
namespace detail {
template<typename T>
inline constexpr bool is_exponent = false;
// is_exponent
namespace detail {
template<typename T>
inline constexpr bool is_exponent = false;
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exponent<exponent<BaseDimension, Num, Den>> = true;
} // namespace detail
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exponent<exponent<BaseDimension, Num, Den>> = true;
} // namespace detail
template<typename T>
concept Exponent = detail::is_exponent<T>;
template<typename T>
concept Exponent = detail::is_exponent<T>;
// exp_dim_id_less
// exp_dim_id_less
template<Exponent E1, Exponent E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {
};
template<Exponent E1, Exponent E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {};
// exponent_invert
// exponent_invert
template<Exponent E>
struct exponent_invert;
template<Exponent E>
struct exponent_invert;
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
using type = exponent<BaseDimension, -Num, Den>;
};
};
template<Exponent E>
using exponent_invert_t = exponent_invert<E>::type;
template<Exponent E>
using exponent_invert_t = exponent_invert<E>::type;
// dimension
// dimension
template<Exponent... Es>
struct dimension : downcast_base<dimension<Es...>> {};
template<Exponent... Es>
struct dimension : downcast_base<dimension<Es...>> {};
// is_dimension
namespace detail {
// is_dimension
namespace detail {
template<typename T>
inline constexpr bool is_dimension = false;
template<typename T>
inline constexpr bool is_dimension = false;
template<typename... Es>
inline constexpr bool is_dimension<dimension<Es...>> = true;
template<typename... Es>
inline constexpr bool is_dimension<dimension<Es...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept Dimension =
std::is_empty_v<T> &&
detail::is_dimension<downcast_base_t<T>>;
template<typename T>
concept Dimension = std::is_empty_v<T> && detail::is_dimension<downcast_base_t<T>>;
// dim_invert
// dim_invert
template<Dimension E>
struct dim_invert;
template<Dimension E>
struct dim_invert;
template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<Dimension D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
template<Dimension D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
// make_dimension
// make_dimension
namespace detail {
namespace detail {
template<Dimension D>
struct dim_consolidate;
template<Dimension D>
struct dim_consolidate;
template<Dimension D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<Dimension D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<>
struct dim_consolidate<dimension<>> {
template<>
struct dim_consolidate<dimension<>> {
using type = dimension<>;
};
};
template<typename E>
struct dim_consolidate<dimension<E>> {
template<typename E>
struct dim_consolidate<dimension<E>> {
using type = dimension<E>;
};
};
template<typename E1, typename... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
template<typename E1, typename... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
using rest = dim_consolidate_t<dimension<ERest...>>;
using type = conditional<is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
};
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2,
typename... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;
using r = std::ratio_add<r1, r2>;
using type = conditional<r::num == 0, dim_consolidate_t<dimension<ERest...>>,
dim_consolidate_t<dimension<exponent<D, r::num, r::den>, ERest...>>>;
};
};
} // namespace detail
} // namespace detail
template<Exponent... Es>
struct make_dimension {
template<Exponent... Es>
struct make_dimension {
using type = detail::dim_consolidate_t<type_list_sort<dimension<Es...>, exponent_less>>;
};
};
template<Exponent... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<Exponent... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<Dimension D1, Dimension D2>
struct merge_dimension {
template<Dimension D1, Dimension D2>
struct merge_dimension {
using type = detail::dim_consolidate_t<type_list_merge_sorted<D1, D2, exponent_less>>;
};
};
template<Dimension D1, Dimension D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
template<Dimension D1, Dimension D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
// dimension_multiply
// dimension_multiply
template<Dimension D1, Dimension D2>
struct dimension_multiply;
template<Dimension D1, Dimension D2>
struct dimension_multiply;
template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> :
std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<Dimension D1, Dimension D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<Dimension D1, Dimension D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
// dimension_divide
// dimension_divide
template<Dimension D1, Dimension D2>
struct dimension_divide;
template<Dimension D1, Dimension D2>
struct dimension_divide;
template<typename... E1, typename... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>>
: dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {
};
template<typename... E1, typename... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>> :
dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {};
template<Dimension D1, Dimension D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<Dimension D1, Dimension D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
} // namespace units

View File

@ -22,164 +22,163 @@
#pragma once
#include "type_list_no_concepts.h"
#include "downcasting_no_concepts.h"
#include "ratio_no_concepts.h"
#include "type_list_no_concepts.h"
#include <ratio>
namespace units {
struct base_dimension {
struct base_dimension {
const char* name;
};
};
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 != *p2) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 != *p2) return false;
}
return *p1 == *p2;
}
}
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs)
{
const char* p1 = lhs.name;
const char* p2 = rhs.name;
for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if(*p1 < *p2) return true;
if(*p2 < *p1) return false;
for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) {
if (*p1 < *p2) return true;
if (*p2 < *p1) return false;
}
return (*p1 == '\0') && (*p2 != '\0');
}
}
// base_dimension_less
// base_dimension_less
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant<D1 < D2> {
};
template<const base_dimension& D1, const base_dimension& D2>
struct base_dimension_less : std::bool_constant < D1<D2> {};
// exponent
// exponent
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exponent {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr std::intmax_t num = Num;
static constexpr std::intmax_t den = Den;
};
};
// exp_dim_id_less
// exp_dim_id_less
template<typename E1, typename E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {
};
template<typename E1, typename E2>
struct exponent_less : base_dimension_less<E1::dimension, E2::dimension> {};
// exponent_invert
// exponent_invert
template<typename E>
struct exponent_invert;
template<typename E>
struct exponent_invert;
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exponent_invert<exponent<BaseDimension, Num, Den>> {
using type = exponent<BaseDimension, -Num, Den>;
};
};
template<typename E>
using exponent_invert_t = exponent_invert<E>::type;
template<typename E>
using exponent_invert_t = exponent_invert<E>::type;
// dimension
// dimension
template<typename... Es>
struct dimension : downcast_base<dimension<Es...>> {};
template<typename... Es>
struct dimension : downcast_base<dimension<Es...>> {};
// dim_invert
// dim_invert
template<typename E>
struct dim_invert;
template<typename E>
struct dim_invert;
template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exponent_invert_t<Es>...>>> {};
template<typename D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
template<typename D>
using dim_invert_t = dim_invert<typename D::downcast_base_type>::type;
// make_dimension
// make_dimension
namespace detail {
namespace detail {
template<typename D>
struct dim_consolidate;
template<typename D>
struct dim_consolidate;
template<typename D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<typename D>
using dim_consolidate_t = dim_consolidate<D>::type;
template<>
struct dim_consolidate<dimension<>> {
template<>
struct dim_consolidate<dimension<>> {
using type = dimension<>;
};
};
template<typename E>
struct dim_consolidate<dimension<E>> {
template<typename E>
struct dim_consolidate<dimension<E>> {
using type = dimension<E>;
};
};
template<typename E1, typename... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
template<typename E1, typename... ERest>
struct dim_consolidate<dimension<E1, ERest...>> {
using rest = dim_consolidate_t<dimension<ERest...>>;
using type = conditional<is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
};
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2,
typename... ERest>
struct dim_consolidate<dimension<exponent<D, Num1, Den1>, exponent<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;
using r = std::ratio_add<r1, r2>;
using type = conditional<r::num == 0, dim_consolidate_t<dimension<ERest...>>,
dim_consolidate_t<dimension<exponent<D, r::num, r::den>, ERest...>>>;
};
};
} // namespace detail
} // namespace detail
template<typename... Es>
struct make_dimension {
template<typename... Es>
struct make_dimension {
using type = detail::dim_consolidate_t<type_list_sort<dimension<Es...>, exponent_less>>;
};
};
template<typename... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<typename... Es>
using make_dimension_t = make_dimension<Es...>::type;
template<typename D1, typename D2>
struct merge_dimension {
template<typename D1, typename D2>
struct merge_dimension {
using type = detail::dim_consolidate_t<type_list_merge_sorted<D1, D2, exponent_less>>;
};
};
template<typename D1, typename D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
template<typename D1, typename D2>
using merge_dimension_t = merge_dimension<D1, D2>::type;
// dimension_multiply
// dimension_multiply
template<typename D1, typename D2>
struct dimension_multiply;
template<typename D1, typename D2>
struct dimension_multiply;
template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> :
std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<typename D1, typename D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<typename D1, typename D2>
using dimension_multiply_t = dimension_multiply<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
// dimension_divide
// dimension_divide
template<typename D1, typename D2>
struct dimension_divide;
template<typename D1, typename D2>
struct dimension_divide;
template<typename... E1, typename... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>>
: dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {
};
template<typename... E1, typename... E2>
struct dimension_divide<dimension<E1...>, dimension<E2...>> :
dimension_multiply<dimension<E1...>, dimension<exponent_invert_t<E2>...>> {};
template<typename D1, typename D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
template<typename D1, typename D2>
using dimension_divide_t = dimension_divide<typename D1::downcast_base_type, typename D2::downcast_base_type>::type;
} // namespace units

View File

@ -27,25 +27,22 @@
namespace units {
template<typename BaseType>
struct downcast_base {
template<typename BaseType>
struct downcast_base {
using downcast_base_type = BaseType;
};
};
template<typename T>
concept Downcastable =
requires {
typename T::downcast_base_type;
} &&
std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
template<typename T>
concept Downcastable =
requires { typename T::downcast_base_type; } && std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
template<Downcastable T>
using downcast_base_t = T::downcast_base_type;
template<Downcastable T>
using downcast_base_t = T::downcast_base_type;
template<Downcastable T>
struct downcast_traits : std::type_identity<T> {};
template<Downcastable T>
struct downcast_traits : std::type_identity<T> {};
template<Downcastable T>
using downcast_traits_t = downcast_traits<T>::type;
template<Downcastable T>
using downcast_traits_t = downcast_traits<T>::type;
} // namespace units

View File

@ -27,18 +27,18 @@
namespace units {
template<typename BaseType>
struct downcast_base {
template<typename BaseType>
struct downcast_base {
using downcast_base_type = BaseType;
};
};
template<typename T>
using downcast_base_t = T::downcast_base_type;
template<typename T>
using downcast_base_t = T::downcast_base_type;
template<typename T>
struct downcast_traits : std::type_identity<T> {};
template<typename T>
struct downcast_traits : std::type_identity<T> {};
template<typename T>
using downcast_traits_t = downcast_traits<T>::type;
template<typename T>
using downcast_traits_t = downcast_traits<T>::type;
} // namespace units

View File

@ -26,11 +26,11 @@
namespace std {
// concepts
using concepts::same_as;
using concepts::derived_from;
using concepts::regular;
using concepts::totally_ordered;
using concepts::convertible_to;
// concepts
using concepts::convertible_to;
using concepts::derived_from;
using concepts::regular;
using concepts::same_as;
using concepts::totally_ordered;
}
} // namespace std

View File

@ -23,21 +23,24 @@
#pragma once
#include "hacks.h"
#include <type_traits>
#include <numeric>
#include <cstdint>
#include <numeric>
#include <type_traits>
namespace units {
namespace detail {
namespace detail {
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept { return v < 0 ? -v : v; }
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept
{
return v < 0 ? -v : v;
}
}
} // namespace detail
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
static_assert(Den != 0, "zero denominator");
static_assert(-INTMAX_MAX <= Num, "numerator too negative");
static_assert(-INTMAX_MAX <= Den, "denominator too negative");
@ -46,29 +49,29 @@ namespace units {
static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den);
using type = ratio<num, den>;
};
};
// is_ratio
// is_ratio
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_ratio = false;
template<typename T>
inline constexpr bool is_ratio = false;
template<intmax_t Num, intmax_t Den>
inline constexpr bool is_ratio<ratio<Num, Den>> = true;
template<intmax_t Num, intmax_t Den>
inline constexpr bool is_ratio<ratio<Num, Den>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept Ratio = detail::is_ratio<T>;
template<typename T>
concept Ratio = detail::is_ratio<T>;
// ratio_multiply
// ratio_multiply
namespace detail {
namespace detail {
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
const std::uintmax_t a0 = detail::abs(lhs) % c;
@ -82,56 +85,56 @@ namespace units {
Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication
return lhs * rhs;
}
}
template<Ratio R1, Ratio R2>
struct ratio_multiply_impl {
private:
template<Ratio R1, Ratio R2>
struct ratio_multiply_impl {
private:
static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den);
static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den);
public:
public:
using type = ratio<safe_multiply(R1::num / gcd1, R2::num / gcd2), safe_multiply(R1::den / gcd2, R2::den / gcd1)>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
// ratio_divide
// ratio_divide
namespace detail {
namespace detail {
template<Ratio R1, Ratio R2>
struct ratio_divide_impl {
template<Ratio R1, Ratio R2>
struct ratio_divide_impl {
static_assert(R2::num != 0, "division by 0");
using type = ratio_multiply<R1, ratio<R2::den, R2::num>>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
// common_ratio
// common_ratio
namespace detail {
namespace detail {
template<Ratio R1, Ratio R2>
struct common_ratio_impl {
template<Ratio R1, Ratio R2>
struct common_ratio_impl {
static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num);
static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den);
using type = ratio<gcd_num, (R1::den / gcd_den) * R2::den>;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
} // namespace units

View File

@ -23,21 +23,24 @@
#pragma once
#include "hacks.h"
#include <type_traits>
#include <numeric>
#include <cstdint>
#include <numeric>
#include <type_traits>
namespace units {
namespace detail {
namespace detail {
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept { return v < 0 ? -v : v; }
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept
{
return v < 0 ? -v : v;
}
}
} // namespace detail
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
static_assert(Den != 0, "zero denominator");
static_assert(-INTMAX_MAX <= Num, "numerator too negative");
static_assert(-INTMAX_MAX <= Den, "denominator too negative");
@ -46,29 +49,29 @@ namespace units {
static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den);
using type = ratio<num, den>;
};
};
// is_ratio
// is_ratio
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_ratio = false;
template<typename T>
inline constexpr bool is_ratio = false;
template<intmax_t Num, intmax_t Den>
inline constexpr bool is_ratio<ratio<Num, Den>> = true;
template<intmax_t Num, intmax_t Den>
inline constexpr bool is_ratio<ratio<Num, Den>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept Ratio = detail::is_ratio<T>;
template<typename T>
concept Ratio = detail::is_ratio<T>;
// ratio_multiply
// ratio_multiply
namespace detail {
namespace detail {
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
const std::uintmax_t a0 = detail::abs(lhs) % c;
@ -82,56 +85,56 @@ namespace units {
Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication
return lhs * rhs;
}
}
template<typename R1, typename R2>
struct ratio_multiply_impl {
private:
template<typename R1, typename R2>
struct ratio_multiply_impl {
private:
static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den);
static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den);
public:
public:
using type = ratio<safe_multiply(R1::num / gcd1, R2::num / gcd2), safe_multiply(R1::den / gcd2, R2::den / gcd1)>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
// ratio_divide
// ratio_divide
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct ratio_divide_impl {
template<typename R1, typename R2>
struct ratio_divide_impl {
static_assert(R2::num != 0, "division by 0");
using type = ratio_multiply<R1, ratio<R2::den, R2::num>>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
// common_ratio
// common_ratio
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct common_ratio_impl {
template<typename R1, typename R2>
struct common_ratio_impl {
static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num);
static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den);
using type = ratio<gcd_num, (R1::den / gcd_den) * R2::den>;
};
};
}
} // namespace detail
template<Ratio R1, Ratio R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
template<Ratio R1, Ratio R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
} // namespace units

View File

@ -23,21 +23,24 @@
#pragma once
#include "hacks.h"
#include <type_traits>
#include <numeric>
#include <cstdint>
#include <numeric>
#include <type_traits>
namespace units {
namespace detail {
namespace detail {
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept { return v < 0 ? -v : v; }
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept
{
return v < 0 ? -v : v;
}
}
} // namespace detail
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
static_assert(Den != 0, "zero denominator");
static_assert(-INTMAX_MAX <= Num, "numerator too negative");
static_assert(-INTMAX_MAX <= Den, "denominator too negative");
@ -46,14 +49,14 @@ namespace units {
static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den);
using type = ratio<num, den>;
};
};
// ratio_multiply
// ratio_multiply
namespace detail {
namespace detail {
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
const std::uintmax_t a0 = detail::abs(lhs) % c;
@ -67,56 +70,56 @@ namespace units {
Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication
return lhs * rhs;
}
}
template<typename R1, typename R2>
struct ratio_multiply_impl {
private:
template<typename R1, typename R2>
struct ratio_multiply_impl {
private:
static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den);
static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den);
public:
public:
using type = ratio<safe_multiply(R1::num / gcd1, R2::num / gcd2), safe_multiply(R1::den / gcd2, R2::den / gcd1)>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
template<typename R1, typename R2>
using ratio_multiply = detail::ratio_multiply_impl<R1, R2>::type;
// ratio_divide
// ratio_divide
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct ratio_divide_impl {
template<typename R1, typename R2>
struct ratio_divide_impl {
static_assert(R2::num != 0, "division by 0");
using type = ratio_multiply<R1, ratio<R2::den, R2::num>>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
template<typename R1, typename R2>
using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
// common_ratio
// common_ratio
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct common_ratio_impl {
template<typename R1, typename R2>
struct common_ratio_impl {
static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num);
static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den);
using type = ratio<gcd_num, (R1::den / gcd_den) * R2::den>;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
template<typename R1, typename R2>
using common_ratio = detail::common_ratio_impl<R1, R2>::type;
} // namespace units

View File

@ -26,160 +26,161 @@
namespace units {
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<TypeList List, typename... Types>
struct type_list_push_front_impl;
template<TypeList List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<TypeList List, typename... Types>
struct type_list_push_back_impl;
template<TypeList List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<TypeList List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<TypeList List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,160 +26,161 @@
namespace units {
namespace detail {
namespace detail {
template<typename T>
inline constexpr bool is_type_list = false;
template<typename T>
inline constexpr bool is_type_list = false;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
template<template<typename...> typename T, typename... Types>
inline constexpr bool is_type_list<T<Types...>> = true;
} // namespace detail
} // namespace detail
template<typename T>
concept TypeList = detail::is_type_list<T>;
template<typename T>
concept TypeList = detail::is_type_list<T>;
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<TypeList List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<TypeList List, std::size_t N>
struct type_list_split;
template<TypeList List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<TypeList List>
struct type_list_split_half;
template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<TypeList SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,147 +26,148 @@
namespace units {
// push_front
// push_front
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<typename List, typename... Types>
struct type_list_push_front_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
using type = List<NewTypes..., OldTypes...>;
};
};
}
} // namespace detail
template<typename List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
template<typename List, typename... Types>
using type_list_push_front = detail::type_list_push_front_impl<List, Types...>::type;
// push_back
// push_back
namespace detail {
namespace detail {
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<typename List, typename... Types>
struct type_list_push_back_impl;
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
template<template<typename...> typename List, typename... OldTypes, typename... NewTypes>
struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
using type = List<OldTypes..., NewTypes...>;
};
};
}
} // namespace detail
template<typename List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
template<typename List, typename... Types>
using type_list_push_back = detail::type_list_push_back_impl<List, Types...>::type;
// split
// split
namespace detail {
namespace detail {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename... Types>
struct split_impl;
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N>
struct split_impl<List, Idx, N> {
using first_list = List<>;
using second_list = List<>;
};
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = conditional<Idx < N,
typename type_list_push_front_impl<typename base::first_list, T>::type,
typename base::first_list>;
using second_list = conditional<Idx < N,
typename base::second_list,
typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
using first_list =
conditional <
Idx<N, typename type_list_push_front_impl<typename base::first_list, T>::type, typename base::first_list>;
using second_list =
conditional <
Idx<N, typename base::second_list, typename type_list_push_front_impl<typename base::second_list, T>::type>;
};
} // namespace detail
} // namespace detail
template<typename List, std::size_t N>
struct type_list_split;
template<typename List, std::size_t N>
struct type_list_split;
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
template<template<typename...> typename List, std::size_t N, typename... Types>
struct type_list_split<List<Types...>, N> {
static_assert(N <= sizeof...(Types), "Invalid index provided");
using split = detail::split_impl<List, 0, N, Types...>;
using first_list = split::first_list;
using second_list = split::second_list;
};
};
// split_half
// split_half
template<typename List>
struct type_list_split_half;
template<typename List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
// merge_sorted
namespace detail {
namespace detail {
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl;
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
template<template<typename...> typename List, typename... Lhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs...>, List<>, Pred> {
using type = List<Lhs...>;
};
};
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
template<template<typename...> typename List, typename... Rhs, template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<>, List<Rhs...>, Pred> {
using type = List<Rhs...>;
};
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = conditional<
Pred<Lhs1, Rhs1>::value,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type,
typename type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type>;
};
}
} // namespace detail
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
template<typename SortedList1, typename SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = detail::type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort
// sort
namespace detail {
namespace detail {
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl;
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
template<template<typename...> typename List, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<>, Pred> {
using type = List<>;
};
};
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
template<template<typename...> typename List, typename T, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<T>, Pred> {
using type = List<T>;
};
};
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
template<template<typename...> typename List, typename... Types, template<typename, typename> typename Pred>
struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>;
using split = type_list_split_half<List<Types...>>;
using left = type_list_sort_impl<typename split::first_list, Pred>::type;
using right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<left, right, Pred>::type;
};
};
}
} // namespace detail
template<typename List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
template<typename List, template<typename, typename> typename Pred>
using type_list_sort = detail::type_list_sort_impl<List, Pred>::type;
} // namespace units

View File

@ -26,23 +26,23 @@
namespace units {
namespace detail {
namespace detail {
template<bool>
struct conditional_impl {
template<bool>
struct conditional_impl {
template<typename T, typename F>
using type = F;
};
};
template<>
struct conditional_impl<true> {
template<>
struct conditional_impl<true> {
template<typename T, typename F>
using type = T;
};
};
}
} // namespace detail
template<bool B, typename T, typename F>
using conditional = TYPENAME detail::conditional_impl<B>::template type<T, F>;
template<bool B, typename T, typename F>
using conditional = TYPENAME detail::conditional_impl<B>::template type<T, F>;
}
} // namespace units

View File

@ -22,24 +22,28 @@
#pragma once
#include <exception>
#include <type_traits>
#include <numeric>
#include <cstdint>
#include <exception>
#include <numeric>
#include <type_traits>
#define Expects(cond) if(!(cond)) ::std::terminate();
#define Expects(cond) \
if (!(cond)) ::std::terminate();
namespace units {
namespace detail {
namespace detail {
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept { return v < 0 ? -v : v; }
template<typename T>
[[nodiscard]] constexpr T abs(T v) noexcept
{
return v < 0 ? -v : v;
}
}
} // namespace detail
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
template<std::intmax_t Num, std::intmax_t Den = 1>
struct ratio {
static_assert(Den != 0, "zero denominator");
static_assert(-INTMAX_MAX <= Num, "numerator too negative");
static_assert(-INTMAX_MAX <= Den, "denominator too negative");
@ -48,14 +52,14 @@ namespace units {
static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den);
using type = ratio<num, den>;
};
};
// ratio_multiply
// ratio_multiply
namespace detail {
namespace detail {
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
const std::uintmax_t a0 = detail::abs(lhs) % c;
@ -69,56 +73,56 @@ namespace units {
Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication
return lhs * rhs;
}
}
template<typename R1, typename R2>
struct ratio_multiply {
private:
template<typename R1, typename R2>
struct ratio_multiply {
private:
static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den);
static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den);
public:
public:
using type = ratio<safe_multiply(R1::num / gcd1, R2::num / gcd2), safe_multiply(R1::den / gcd2, R2::den / gcd1)>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using ratio_multiply = typename detail::ratio_multiply<R1, R2>::type;
template<typename R1, typename R2>
using ratio_multiply = typename detail::ratio_multiply<R1, R2>::type;
// ratio_divide
// ratio_divide
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct ratio_divide {
template<typename R1, typename R2>
struct ratio_divide {
static_assert(R2::num != 0, "division by 0");
using type = ratio_multiply<R1, ratio<R2::den, R2::num>>;
static constexpr std::intmax_t num = type::num;
static constexpr std::intmax_t den = type::den;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using ratio_divide = typename detail::ratio_divide<R1, R2>::type;
template<typename R1, typename R2>
using ratio_divide = typename detail::ratio_divide<R1, R2>::type;
// common_ratio
// common_ratio
namespace detail {
namespace detail {
template<typename R1, typename R2>
struct common_ratio_impl {
template<typename R1, typename R2>
struct common_ratio_impl {
static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num);
static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den);
using type = ratio<gcd_num, (R1::den / gcd_den) * R2::den>;
};
};
}
} // namespace detail
template<typename R1, typename R2>
using common_ratio_t = typename detail::common_ratio_impl<R1, R2>::type;
template<typename R1, typename R2>
using common_ratio_t = typename detail::common_ratio_impl<R1, R2>::type;
} // namespace units

View File

@ -27,42 +27,37 @@
namespace units {
// static_sign
// static_sign
template<std::intmax_t Pn>
struct static_sign : std::integral_constant<std::intmax_t, (Pn < 0) ? -1 : 1> {
};
template<std::intmax_t Pn>
struct static_sign : std::integral_constant<std::intmax_t, (Pn < 0) ? -1 : 1> {};
// static_abs
// static_abs
template<std::intmax_t Pn>
struct static_abs : std::integral_constant<std::intmax_t, Pn * static_sign<Pn>::value> {
};
template<std::intmax_t Pn>
struct static_abs : std::integral_constant<std::intmax_t, Pn * static_sign<Pn>::value> {};
// static_gcd
// static_gcd
template<std::intmax_t Pn, std::intmax_t Qn>
struct static_gcd : static_gcd<Qn, (Pn % Qn)> {
};
template<std::intmax_t Pn, std::intmax_t Qn>
struct static_gcd : static_gcd<Qn, (Pn % Qn)> {};
template<std::intmax_t Pn>
struct static_gcd<Pn, 0> : std::integral_constant<std::intmax_t, static_abs<Pn>::value> {
};
template<std::intmax_t Pn>
struct static_gcd<Pn, 0> : std::integral_constant<std::intmax_t, static_abs<Pn>::value> {};
template<std::intmax_t Qn>
struct static_gcd<0, Qn> : std::integral_constant<std::intmax_t, static_abs<Qn>::value> {
};
template<std::intmax_t Qn>
struct static_gcd<0, Qn> : std::integral_constant<std::intmax_t, static_abs<Qn>::value> {};
// common_ratio
// common_ratio
template<typename R1, typename R2>
struct common_ratio {
template<typename R1, typename R2>
struct common_ratio {
using gcd_num = static_gcd<R1::num, R2::num>;
using gcd_den = static_gcd<R1::den, R2::den>;
using type = std::ratio<gcd_num::value, (R1::den / gcd_den::value) * R2::den>;
};
};
template<typename R1, typename R2>
using common_ratio_t = typename common_ratio<R1, R2>::type;
template<typename R1, typename R2>
using common_ratio_t = typename common_ratio<R1, R2>::type;
} // namespace units

View File

@ -67,19 +67,22 @@ static_assert(!Speed<si::time<si::second>>);
static_assert(Acceleration<si::acceleration<si::metre_per_second_sq>>);
static_assert(!Acceleration<si::time<si::second>>);
#if UNITS_DOWNCAST_MODE == 0
static_assert(Acceleration<quantity<unknown_dimension<exponent<si::dim_length, 1>, exponent<si::dim_time, -2>>, unknown_coherent_unit>>);
static_assert(Acceleration<quantity<unknown_dimension<exponent<si::dim_length, 1>, exponent<si::dim_time, -2>>,
unknown_coherent_unit>>);
#endif
static_assert(Force<si::force<si::newton>>);
static_assert(!Force<si::time<si::second>>);
#if UNITS_DOWNCAST_MODE == 0
// static_assert(Force<quantity<unknown_dimension<exponent<si::dim_length, 1>, exponent<si::dim_time, -2>, exponent<si::dim_mass, 1>>, unknown_coherent_unit>>);
// static_assert(Force<quantity<unknown_dimension<exponent<si::dim_length, 1>, exponent<si::dim_time, -2>,
// exponent<si::dim_mass, 1>>, unknown_coherent_unit>>);
#endif
static_assert(Energy<si::energy<si::joule>>);
static_assert(!Energy<si::time<si::second>>);
#if UNITS_DOWNCAST_MODE == 0
// static_assert(Energy<quantity<unknown_dimension<exponent<si::dim_mass, 1>, exponent<si::dim_length, 2>, exponent<si::dim_time, -3>>, unknown_coherent_unit>>);
// static_assert(Energy<quantity<unknown_dimension<exponent<si::dim_mass, 1>, exponent<si::dim_length, 2>,
// exponent<si::dim_time, -3>>, unknown_coherent_unit>>);
#endif
static_assert(Power<si::power<si::watt>>);
@ -168,4 +171,4 @@ static_assert(!Permeability<si::time<si::second>>);
static_assert(MolarEnergy<si::molar_energy<si::joule_per_mole>>);
static_assert(!MolarEnergy<si::time<si::second>>);
}
} // namespace

View File

@ -50,4 +50,4 @@ static_assert(basic_fixed_string('d') + txt2 == basic_fixed_string("dabc"));
static_assert(txt2 + basic_fixed_string("def") == basic_fixed_string("abcdef"));
static_assert(basic_fixed_string("def") + txt2 == basic_fixed_string("defabc"));
}
} // namespace

View File

@ -100,6 +100,7 @@ static_assert(1_q_ft_pdl_per_s * 10_q_s == 10_q_ft_pdl);
static_assert(10_q_ft_pdl / 1_q_ft_pdl_per_s == 10_q_s);
static_assert(detail::unit_text<dim_power, foot_poundal_per_second>() == basic_symbol_text("ft ⋅ pdl/s", "ft pdl/s"));
static_assert(detail::unit_text<dim_power, foot_pound_force_per_second>() == basic_symbol_text("ft ⋅ lbf/s", "ft lbf/s"));
static_assert(detail::unit_text<dim_power, foot_pound_force_per_second>() ==
basic_symbol_text("ft ⋅ lbf/s", "ft lbf/s"));
}
} // namespace

View File

@ -20,7 +20,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <units/quantity_point.h>
#include "test_tools.h"
#include <units/bits/common_type.h>
#include <units/bits/external/type_traits.h>
@ -29,6 +28,7 @@
#include <units/isq/si/speed.h>
#include <units/isq/si/uscs/length.h>
#include <units/isq/si/volume.h>
#include <units/quantity_point.h>
#include <limits>
#include <type_traits>
#include <utility>
@ -46,20 +46,22 @@ struct sea_level_origin : point_origin<dim_length> {};
// class invariants
template<typename DimLength>
concept invalid_types = requires
{
concept invalid_types =
requires {
// unit of a different dimension:
requires !requires { typename quantity_point<dynamic_origin<DimLength>, second, int>; };
// quantity used as Rep:
requires !requires { typename quantity_point<dynamic_origin<DimLength>, metre, quantity<DimLength, metre, int>>; };
// quantity point used as Rep:
requires !requires { typename quantity_point<dynamic_origin<DimLength>, metre,
quantity_point<dynamic_origin<DimLength>, metre, int>>; };
requires !requires {
typename quantity_point<dynamic_origin<DimLength>, metre,
quantity_point<dynamic_origin<DimLength>, metre, int>>;
};
// reordered arguments:
requires !requires { typename quantity_point<metre, dynamic_origin<DimLength>, double>; };
// dimension used as origin:
requires !requires { typename quantity_point<DimLength, second, int>; };
};
};
static_assert(invalid_types<dim_length>);
@ -71,7 +73,8 @@ static_assert(is_same_v<quantity_point<dynamic_origin<dim_length>, metre, int>::
static_assert(is_same_v<quantity_point<dynamic_origin<dim_length>, kilometre, int>::unit, kilometre>);
static_assert(is_same_v<quantity_point<dynamic_origin<dim_length>, metre, int>::dimension, dim_length>);
static_assert(is_same_v<quantity_point<dynamic_origin<dim_length>, metre, int>::origin, dynamic_origin<dim_length>>);
static_assert(is_same_v<quantity_point<dynamic_origin<dim_length>, metre, int>::quantity_type, quantity<dim_length, metre, int>>);
static_assert(
is_same_v<quantity_point<dynamic_origin<dim_length>, metre, int>::quantity_type, quantity<dim_length, metre, int>>);
// constructors
@ -80,10 +83,14 @@ static_assert(!std::is_convertible_v<int, quantity_point<dynamic_origin<dim_one>
static_assert(quantity_point(42s).relative() == 42 * s);
static_assert(quantity_point(sys_seconds{42s}).relative() == 42 * s);
static_assert(!std::is_convertible_v<std::chrono::seconds, quantity_point<dynamic_origin<dim_time>, second, std::chrono::seconds::rep>>);
static_assert(!std::is_convertible_v<std::chrono::seconds, quantity_point<clock_origin<std::chrono::system_clock>, second, std::chrono::seconds::rep>>);
static_assert(!std::is_convertible_v<std::chrono::seconds,
quantity_point<dynamic_origin<dim_time>, second, std::chrono::seconds::rep>>);
static_assert(
!std::is_convertible_v<std::chrono::seconds,
quantity_point<clock_origin<std::chrono::system_clock>, second, std::chrono::seconds::rep>>);
static_assert(!std::is_convertible_v<sys_seconds, quantity_point<dynamic_origin<dim_time>, second, sys_seconds::rep>>);
static_assert(!std::is_convertible_v<sys_seconds, quantity_point<clock_origin<std::chrono::system_clock>, second, sys_seconds::rep>>);
static_assert(!std::is_convertible_v<
sys_seconds, quantity_point<clock_origin<std::chrono::system_clock>, second, sys_seconds::rep>>);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>().relative() == 0_q_m);
constexpr quantity_point<dynamic_origin<dim_length>, metre, int> km{1000_q_m};
@ -91,20 +98,24 @@ static_assert(km.relative() == 1000_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>(km).relative() == km.relative());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>(1_q_m).relative() == 1_q_m);
static_assert(!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, metre, int>, double>); // truncating conversion
static_assert(
!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, metre, int>, double>); // truncating conversion
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>(1.0_q_m).relative() == 1.0_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>(1_q_m).relative() == 1_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, long double>(3.14_q_m).relative() == 3.14_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>(km).relative() == 1000_q_m);
static_assert(!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, metre, int>,
static_assert(
!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, metre, int>,
quantity_point<dynamic_origin<dim_length>, metre, double>>); // truncating conversion
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>(quantity_point(1000.0_q_m)).relative() == 1000.0_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>(quantity_point(1000.0_q_m)).relative() ==
1000.0_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>(km).relative() == 1000.0_q_m);
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>(quantity_point(1_q_km)).relative() == 1000_q_m);
static_assert(!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, metre, int>,
quantity_point<dynamic_origin<dim_time>, second, int>>); // different dimensions
static_assert(!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, kilometre, int>,
static_assert(
!std::is_constructible_v<quantity_point<dynamic_origin<dim_length>, kilometre, int>,
quantity_point<dynamic_origin<dim_length>, metre, int>>); // truncating conversion
static_assert(!std::is_constructible_v<quantity_point<sea_level_origin, kilometre, int>,
@ -115,12 +126,18 @@ static_assert(!std::is_constructible_v<quantity_point<dynamic_origin<dim_time>,
// assignment operator
static_assert([]() { quantity_point<dynamic_origin<dim_length>, metre, int> l1(1_q_m), l2{}; return l2 = l1; }().relative() == 1_q_m);
static_assert(([]() {
quantity_point<dynamic_origin<dim_length>, metre, int> l1(1_q_m), l2{};
return l2 = l1;
}())
.relative() == 1_q_m);
// static member functions
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>::min().relative().number() == std::numeric_limits<int>::lowest());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>::max().relative().number() == std::numeric_limits<int>::max());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>::min().relative().number() ==
std::numeric_limits<int>::lowest());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, int>::max().relative().number() ==
std::numeric_limits<int>::max());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>::min().relative().number() ==
std::numeric_limits<double>::lowest());
static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>::max().relative().number() ==
@ -131,19 +148,23 @@ static_assert(quantity_point<dynamic_origin<dim_length>, metre, double>::max().r
static_assert([](auto v) {
auto vv = v++;
return std::pair(v, vv);
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m), quantity_point<dynamic_origin<dim_length>, metre, int>(1000_q_m)));
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m),
quantity_point<dynamic_origin<dim_length>, metre, int>(1000_q_m)));
static_assert([](auto v) {
auto vv = ++v;
return std::pair(v, vv);
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m), quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m)));
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m),
quantity_point<dynamic_origin<dim_length>, metre, int>(1001_q_m)));
static_assert([](auto v) {
auto vv = v--;
return std::pair(v, vv);
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m), quantity_point<dynamic_origin<dim_length>, metre, int>(1000_q_m)));
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m),
quantity_point<dynamic_origin<dim_length>, metre, int>(1000_q_m)));
static_assert([](auto v) {
auto vv = --v;
return std::pair(v, vv);
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m), quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m)));
}(km) == std::pair(quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m),
quantity_point<dynamic_origin<dim_length>, metre, int>(999_q_m)));
// compound assignment
@ -164,11 +185,11 @@ static_assert(compare<decltype(quantity_point<dynamic_origin<dim_length>, metre,
quantity_point<dynamic_origin<dim_length>, metre, double>>);
static_assert(compare<decltype(quantity_point<dynamic_origin<dim_length>, kilometre, double>() - length<metre, int>()),
quantity_point<dynamic_origin<dim_length>, metre, double>>);
static_assert(
compare<decltype(quantity_point<dynamic_origin<dim_length>, metre, double>() - quantity_point<dynamic_origin<dim_length>, metre, int>()),
static_assert(compare<decltype(quantity_point<dynamic_origin<dim_length>, metre, double>() -
quantity_point<dynamic_origin<dim_length>, metre, int>()),
length<metre, double>>);
static_assert(
compare<decltype(quantity_point<dynamic_origin<dim_length>, kilometre, double>() - quantity_point<dynamic_origin<dim_length>, metre, int>()),
static_assert(compare<decltype(quantity_point<dynamic_origin<dim_length>, kilometre, double>() -
quantity_point<dynamic_origin<dim_length>, metre, int>()),
length<metre, double>>);
static_assert((1_q_m + km).relative().number() == 1001);
@ -177,10 +198,9 @@ static_assert((km - 1_q_m).relative().number() == 999);
static_assert((quantity_point(1_q_km) - quantity_point(1_q_m)).number() == 999);
template<typename Int>
concept invalid_subtraction = requires(quantity_point<dynamic_origin<dim_length>, metre, Int> lhs,
quantity_point<sea_level_origin, metre, Int> rhs) {
requires !requires { rhs - lhs; };
};
concept invalid_subtraction =
requires(quantity_point<dynamic_origin<dim_length>, metre, Int> lhs,
quantity_point<sea_level_origin, metre, Int> rhs) { requires !requires { rhs - lhs; }; };
static_assert(invalid_subtraction<int>);
// comparators
@ -219,7 +239,7 @@ concept invalid_comparisons = requires(quantity_point<dynamic_origin<dim_length>
quantity_point<sea_level_origin, metre, Int> rhs) {
requires !requires { lhs == rhs; };
requires !requires { lhs < rhs; };
};
};
static_assert(invalid_comparisons<int>);
// alias units
@ -256,25 +276,35 @@ static_assert(std::equality_comparable_with<decltype(quantity_point(1_q_m)), dec
// quantity_cast
static_assert(quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, int>>(quantity_point(2_q_km)).relative().number() ==
2000);
static_assert(
quantity_point_cast<quantity_point<dynamic_origin<dim_length>, kilometre, int>>(quantity_point(2000_q_m)).relative().number() == 2);
static_assert(quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, int>>(quantity_point(1.23_q_m)).relative().number() ==
1);
static_assert(quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, int>>(quantity_point(2_q_km))
.relative()
.number() == 2000);
static_assert(quantity_point_cast<quantity_point<dynamic_origin<dim_length>, kilometre, int>>(quantity_point(2000_q_m))
.relative()
.number() == 2);
static_assert(quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, int>>(quantity_point(1.23_q_m))
.relative()
.number() == 1);
static_assert(quantity_point_cast<length<metre, int>>(quantity_point(2_q_km)).relative().number() == 2000);
static_assert(quantity_point_cast<length<kilometre, int>>(quantity_point(2000_q_m)).relative().number() == 2);
static_assert(quantity_point_cast<length<metre, int>>(quantity_point(1.23_q_m)).relative().number() == 1);
static_assert(quantity_point_cast<metre>(quantity_point(2_q_km)).relative().number() == 2000);
static_assert(quantity_point_cast<kilometre>(quantity_point(2000_q_m)).relative().number() == 2);
static_assert(quantity_point_cast<int>(quantity_point(1.23_q_m)).relative().number() == 1);
static_assert(quantity_point_cast<dim_speed, kilometre_per_hour>(quantity_point(2000.0_q_m / 3600.0_q_s)).relative().number() == 2);
static_assert(
quantity_point_cast<dim_speed, kilometre_per_hour>(quantity_point(2000.0_q_m / 3600.0_q_s)).relative().number() == 2);
template<typename Int>
concept invalid_cast = requires(Int i) {
requires !requires { quantity_point_cast<quantity_point<dynamic_origin<dim_time>, second, Int>>(quantity_point(i * m)); };
requires !requires { quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, Int>>(quantity_point<sea_level_origin, metre, Int>(i * m)); };
};
concept invalid_cast =
requires(Int i) {
requires !requires {
quantity_point_cast<quantity_point<dynamic_origin<dim_time>, second, Int>>(quantity_point(i * m));
};
requires !requires {
quantity_point_cast<quantity_point<dynamic_origin<dim_length>, metre, Int>>(
quantity_point<sea_level_origin, metre, Int>(i * m));
};
};
static_assert(invalid_cast<int>);
// time
@ -282,10 +312,7 @@ static_assert(invalid_cast<int>);
static_assert(quantity_point{1_q_h} == quantity_point{3600_q_s});
template<typename Metre>
concept no_crossdimensional_equality = !requires
{
quantity_point(1_q_s) == quantity_point(length<Metre, int>(1));
};
concept no_crossdimensional_equality = !requires { quantity_point(1_q_s) == quantity_point(length<Metre, int>(1)); };
static_assert(no_crossdimensional_equality<metre>);
@ -297,10 +324,7 @@ static_assert(quantity_point(1_q_km) + 1_q_m == quantity_point(1001_q_m));
static_assert(1_q_km + quantity_point(1_q_m) == quantity_point(1001_q_m));
template<class T>
concept dimensional_analysis = requires(T t)
{
pow<2>(t);
};
concept dimensional_analysis = requires(T t) { pow<2>(t); };
static_assert(!dimensional_analysis<quantity_point<dynamic_origin<dim_length>, metre, int>>);

View File

@ -62,7 +62,7 @@ concept invalid_types = requires {
requires !requires { typename Q<dim_length, metre, length<metre>>; }; // quantity used as Rep
requires !requires { typename Q<metre, dim_length, double>; }; // reordered arguments
requires !requires { typename Q<metre, double, dim_length>; }; // reordered arguments
};
};
static_assert(invalid_types<quantity>);
#endif
@ -128,7 +128,8 @@ static_assert(!std::convertible_to<double, length<metre>>);
static_assert(std::constructible_from<length<metre>, float>);
static_assert(!std::convertible_to<float, length<metre>>);
static_assert(std::constructible_from<length<metre, float>, double>); // truncating implicit conversions double -> float allowed
static_assert(
std::constructible_from<length<metre, float>, double>); // truncating implicit conversions double -> float allowed
static_assert(!std::convertible_to<double, length<metre, float>>);
static_assert(std::constructible_from<length<metre>, int>);
@ -137,7 +138,8 @@ static_assert(!std::convertible_to<int, length<metre>>);
static_assert(std::constructible_from<length<metre>, short>);
static_assert(!std::convertible_to<short, length<metre>>);
static_assert(std::constructible_from<length<metre, short>, int>); // truncating implicit conversions int -> short allowed
static_assert(
std::constructible_from<length<metre, short>, int>); // truncating implicit conversions int -> short allowed
static_assert(!std::convertible_to<int, length<metre, short>>);
// exception, implicit construction from a value allowed for a dimensionless quantity
@ -166,7 +168,8 @@ static_assert(!std::convertible_to<double, dimensionless<percent>>);
static_assert(std::constructible_from<dimensionless<percent>, float>);
static_assert(!std::convertible_to<float, dimensionless<percent>>);
static_assert(std::constructible_from<dimensionless<percent, float>, double>); // truncating implicit conversions double -> float allowed
static_assert(std::constructible_from<dimensionless<percent, float>,
double>); // truncating implicit conversions double -> float allowed
static_assert(!std::convertible_to<double, dimensionless<percent, float>>);
static_assert(std::constructible_from<dimensionless<percent>, int>);
@ -175,7 +178,8 @@ static_assert(!std::convertible_to<int, dimensionless<percent>>);
static_assert(std::constructible_from<dimensionless<percent>, short>);
static_assert(!std::convertible_to<short, dimensionless<percent>>);
static_assert(std::constructible_from<dimensionless<percent, short>, int>); // truncating implicit conversions int -> short allowed
static_assert(
std::constructible_from<dimensionless<percent, short>, int>); // truncating implicit conversions int -> short allowed
static_assert(!std::convertible_to<int, dimensionless<percent, short>>);
// floating-point to integral truncating conversion not allowed
@ -220,8 +224,10 @@ static_assert(!std::convertible_to<length<metre>, length<metre, int>>); // trun
static_assert(std::constructible_from<length<metre, int>, length<kilometre, int>>); // kilometre<int> -> metre<int> OK
static_assert(std::convertible_to<length<kilometre, int>, length<metre, int>>); // kilometre<int> -> metre<int> OK
static_assert(!std::constructible_from<length<kilometre, int>, length<metre, int>>); // truncating metre<int> -> kilometre<int> not allowed
static_assert(!std::convertible_to<length<metre, int>, length<kilometre, int>>); // truncating metre<int> -> kilometre<int> not allowed
static_assert(!std::constructible_from<length<kilometre, int>,
length<metre, int>>); // truncating metre<int> -> kilometre<int> not allowed
static_assert(!std::convertible_to<length<metre, int>,
length<kilometre, int>>); // truncating metre<int> -> kilometre<int> not allowed
// converting to double always OK
static_assert(std::constructible_from<length<metre>, length<kilometre, int>>);
@ -249,13 +255,21 @@ struct derived_quantity : quantity<typename Q::dimension, typename Q::unit, Rep>
constexpr explicit(!std::is_trivial_v<Rep>) derived_quantity(const R& t) : R(t) {}
constexpr explicit(!std::is_trivial_v<Rep>) derived_quantity(R&& t) : R(std::move(t)) {}
constexpr derived_quantity& operator=(const R& t) { R::operator=(t); return *this; }
constexpr derived_quantity& operator=(R&& t) { R::operator=(std::move(t)); return *this; }
constexpr derived_quantity& operator=(const R& t)
{
R::operator=(t);
return *this;
}
constexpr derived_quantity& operator=(R&& t)
{
R::operator=(std::move(t));
return *this;
}
constexpr operator R&() & noexcept { return *this; }
constexpr operator const R&() const & noexcept { return *this; }
constexpr operator const R&() const& noexcept { return *this; }
constexpr operator R&&() && noexcept { return *this; }
constexpr operator const R&&() const && noexcept { return *this; }
constexpr operator const R&&() const&& noexcept { return *this; }
};
static_assert(detail::is_quantity<derived_quantity<double, si::length<metre>, "NTTP type description">>);
@ -290,8 +304,16 @@ static_assert(is_same_v<decltype(quantity{1.23}), dimensionless<one, double>>);
// assignment operator
////////////////////////
static_assert([]() { length<metre, int> l1(1), l2(2); return l2 = l1; }().number() == 1);
static_assert([]() { length<metre, int> l1(1), l2(2); return l2 = std::move(l1); }().number() == 1);
static_assert([]() {
length<metre, int> l1(1), l2(2);
return l2 = l1;
}()
.number() == 1);
static_assert([]() {
length<metre, int> l1(1), l2(2);
return l2 = std::move(l1);
}()
.number() == 1);
////////////////////
@ -303,10 +325,22 @@ static_assert((-123_q_m).number() == -123);
static_assert((+(-123_q_m)).number() == -123);
static_assert((-(-123_q_m)).number() == 123);
static_assert([](auto v) { auto vv = v++; return std::pair(v, vv); }(123_q_m) == std::pair(124_q_m, 123_q_m));
static_assert([](auto v) { auto vv = ++v; return std::pair(v, vv); }(123_q_m) == std::pair(124_q_m, 124_q_m));
static_assert([](auto v) { auto vv = v--; return std::pair(v, vv); }(123_q_m) == std::pair(122_q_m, 123_q_m));
static_assert([](auto v) { auto vv = --v; return std::pair(v, vv); }(123_q_m) == std::pair(122_q_m, 122_q_m));
static_assert([](auto v) {
auto vv = v++;
return std::pair(v, vv);
}(123_q_m) == std::pair(124_q_m, 123_q_m));
static_assert([](auto v) {
auto vv = ++v;
return std::pair(v, vv);
}(123_q_m) == std::pair(124_q_m, 124_q_m));
static_assert([](auto v) {
auto vv = v--;
return std::pair(v, vv);
}(123_q_m) == std::pair(122_q_m, 123_q_m));
static_assert([](auto v) {
auto vv = --v;
return std::pair(v, vv);
}(123_q_m) == std::pair(122_q_m, 122_q_m));
static_assert(is_same_v<decltype((+(short{0} * m)).number()), int&&>);
@ -337,15 +371,32 @@ static_assert((2.5_q_m *= quantity(3)).number() == 7.5);
static_assert((7.5_q_m /= quantity(3)).number() == 2.5);
static_assert((3500_q_m %= 1_q_km).number() == 500);
static_assert((std::uint8_t(255) * m %= 256).number() == [] { std::uint8_t ui(255); return ui %= 256; }());
static_assert((std::uint8_t(255) * m %= quantity(256)).number() == [] { std::uint8_t ui(255); return ui %= 256; }());
// static_assert((std::uint8_t(255) * m %= 256 * m).number() != [] { std::uint8_t ui(255); return ui %= 256; }()); // UB
static_assert((std::uint8_t(255) * m %= 257).number() == [] { std::uint8_t ui(255); return ui %= 257; }());
static_assert((std::uint8_t(255) * m %= quantity(257)).number() == [] { std::uint8_t ui(255); return ui %= 257; }());
static_assert((std::uint8_t(255) * m %= 256).number() == [] {
std::uint8_t ui(255);
return ui %= 256;
}());
static_assert((std::uint8_t(255) * m %= quantity(256)).number() == [] {
std::uint8_t ui(255);
return ui %= 256;
}());
// static_assert((std::uint8_t(255) * m %= 256 * m).number() != [] { std::uint8_t ui(255); return ui %= 256; }()); //
// UB
static_assert((std::uint8_t(255) * m %= 257).number() == [] {
std::uint8_t ui(255);
return ui %= 257;
}());
static_assert((std::uint8_t(255) * m %= quantity(257)).number() == [] {
std::uint8_t ui(255);
return ui %= 257;
}());
// TODO: Fix
static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] { std::uint8_t ui(255); return ui %= 257; }());
static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] {
std::uint8_t ui(255);
return ui %= 257;
}());
#ifndef UNITS_COMP_MSVC // TODO ICE (https://developercommunity2.visualstudio.com/t/ICE-on-a-constexpr-operator-in-mp-unit/1302907)
#ifndef UNITS_COMP_MSVC // TODO ICE
// (https://developercommunity2.visualstudio.com/t/ICE-on-a-constexpr-operator-in-mp-unit/1302907)
// next two lines trigger conversions warnings
// (warning disabled in CMake for this file)
static_assert((22_q_m *= 33.33).number() == 733);
@ -355,7 +406,8 @@ static_assert((22_q_m /= quantity(3.33)).number() == 6);
#endif
template<typename Metre, typename Kilometre>
concept invalid_compound_assignments = requires() {
concept invalid_compound_assignments =
requires() {
// truncating not allowed
requires !requires(length<Metre, int> l) { l += 2.5_q_m; };
requires !requires(length<Metre, int> l) { l -= 2.5_q_m; };
@ -391,7 +443,7 @@ concept invalid_compound_assignments = requires() {
requires !requires(length<Metre, int> l) { l *= m; };
requires !requires(length<Metre, int> l) { l /= m; };
requires !requires(length<Metre, int> l) { l %= m; };
};
};
static_assert(invalid_compound_assignments<metre, kilometre>);
@ -420,7 +472,7 @@ concept invalid_binary_operations = requires {
requires !requires { m + length<Metre, int>(1); };
requires !requires { m - length<Metre, int>(1); };
requires !requires { m % length<Metre, int>(1); };
};
};
static_assert(invalid_binary_operations<metre>);
// same representation type
@ -443,7 +495,8 @@ static_assert(compare<decltype(1_q_m * 1_q_m), area<square_metre, std::int64_t>>
static_assert(compare<decltype(1_q_m / 1_q_m), dimensionless<one, std::int64_t>>);
static_assert(compare<decltype(1 / 1_q_s), frequency<hertz, std::int64_t>>);
static_assert(compare<decltype(quantity{1} / 1_q_s), frequency<hertz, std::int64_t>>);
static_assert(compare<decltype(dimensionless<percent, std::int64_t>(1) / 1_q_s), frequency<scaled_unit<ratio(1, 100), hertz>, std::int64_t>>);
static_assert(compare<decltype(dimensionless<percent, std::int64_t>(1) / 1_q_s),
frequency<scaled_unit<ratio(1, 100), hertz>, std::int64_t>>);
static_assert(is_same_v<decltype((std::uint8_t(0) * m + std::uint8_t(0) * m).number()), int&&>);
static_assert(is_same_v<decltype((std::uint8_t(0) * m - std::uint8_t(0) * m).number()), int&&>);
@ -456,9 +509,13 @@ static_assert(is_same_v<decltype(((std::uint8_t(0) * m) % (std::uint8_t(0) * m))
// different representation types
static_assert(is_same_v<decltype(1_q_m + 1._q_m), length<metre, long double>>);
static_assert(is_same_v<decltype(1_q_m - 1._q_m), length<metre, long double>>);
static_assert(is_same_v<decltype(1_q_m * 1.L), length<metre, long double>>); // TODO should we address fundamental types implicit truncating conversions with concepts?
static_assert(
is_same_v<decltype(1_q_m * 1.L), length<metre, long double>>); // TODO should we address fundamental types implicit
// truncating conversions with concepts?
static_assert(is_same_v<decltype(1 * 1._q_m), length<metre, long double>>);
static_assert(is_same_v<decltype(1_q_m * quantity{1.L}), length<metre, long double>>); // TODO should we address fundamental types implicit truncating conversions with concepts?
static_assert(is_same_v<decltype(1_q_m * quantity{1.L}),
length<metre, long double>>); // TODO should we address fundamental types implicit truncating
// conversions with concepts?
static_assert(is_same_v<decltype(quantity{1} * 1._q_m), length<metre, long double>>);
static_assert(is_same_v<decltype(1_q_m / 1.L), length<metre, long double>>);
static_assert(is_same_v<decltype(1_q_m / quantity{1.L}), length<metre, long double>>);
@ -469,7 +526,8 @@ static_assert(compare<decltype(1_q_m / dimensionless<percent, long double>(1)),
static_assert(compare<decltype(1_q_m / 1._q_m), dimensionless<one, long double>>);
static_assert(compare<decltype(1 / 1._q_s), frequency<hertz, long double>>);
static_assert(compare<decltype(quantity{1} / 1._q_s), frequency<hertz, long double>>);
static_assert(compare<decltype(dimensionless<percent, std::int64_t>(1) / 1._q_s), frequency<scaled_unit<ratio(1, 100), hertz>, long double>>);
static_assert(compare<decltype(dimensionless<percent, std::int64_t>(1) / 1._q_s),
frequency<scaled_unit<ratio(1, 100), hertz>, long double>>);
static_assert(compare<decltype(1_q_m % short(1)), length<metre, std::int64_t>>);
static_assert(compare<decltype(1_q_m % quantity{short(1)}), length<metre, std::int64_t>>);
static_assert(compare<decltype(1_q_m % dimensionless<percent, short>(1)), length<metre, std::int64_t>>);
@ -490,7 +548,8 @@ static_assert(compare<decltype(1._q_m * 1_q_m), area<square_metre, long double>>
static_assert(compare<decltype(1._q_m / 1_q_m), dimensionless<one, long double>>);
static_assert(compare<decltype(1.L / 1_q_s), frequency<hertz, long double>>);
static_assert(compare<decltype(quantity{1.L} / 1_q_s), frequency<hertz, long double>>);
static_assert(compare<decltype(dimensionless<percent, long double>(1) / 1_q_s), frequency<scaled_unit<ratio(1, 100), hertz>, long double>>);
static_assert(compare<decltype(dimensionless<percent, long double>(1) / 1_q_s),
frequency<scaled_unit<ratio(1, 100), hertz>, long double>>);
// different units
static_assert(is_same_v<decltype(1_q_m + 1_q_km), length<metre, std::int64_t>>);
@ -519,15 +578,21 @@ static_assert(is_same_v<decltype(1_q_km % 1_q_m), length<kilometre, std::int64_t
// different dimensions
static_assert(compare<decltype(1_q_m_per_s * 1_q_s), length<metre, std::int64_t>>);
static_assert(compare<decltype(1_q_m_per_s * 1_q_h), length<scaled_unit<ratio(36, 1, 2), metre>, std::int64_t>>);
static_assert(compare<decltype(1_q_m * 1_q_min), quantity<unknown_dimension<exponent<dim_length, 1>, exponent<dim_time, 1>>, scaled_unit<ratio(60), unknown_coherent_unit>, std::int64_t>>);
static_assert(
compare<decltype(1_q_m * 1_q_min), quantity<unknown_dimension<exponent<dim_length, 1>, exponent<dim_time, 1>>,
scaled_unit<ratio(60), unknown_coherent_unit>, std::int64_t>>);
static_assert(compare<decltype(1_q_s * 1_q_Hz), dimensionless<one, std::int64_t>>);
static_assert(compare<decltype(1 / 1_q_min), frequency<scaled_unit<ratio(1, 60), hertz>, std::int64_t>>);
static_assert(compare<decltype(1 / 1_q_Hz), isq::si::time<second, std::int64_t>>);
static_assert(compare<decltype(1 / 1_q_km), quantity<unknown_dimension<exponent<dim_length, -1>>, scaled_unit<ratio(1, 1, -3), unknown_coherent_unit>, std::int64_t>>);
static_assert(
compare<decltype(1 / 1_q_km), quantity<unknown_dimension<exponent<dim_length, -1>>,
scaled_unit<ratio(1, 1, -3), unknown_coherent_unit>, std::int64_t>>);
static_assert(compare<decltype(1_q_km / 1_q_m), dimensionless<scaled_unit<ratio(1000), one>, std::int64_t>>);
static_assert(compare<decltype(1_q_m / 1_q_s), speed<metre_per_second, std::int64_t>>);
static_assert(compare<decltype(1_q_m / 1_q_min), speed<scaled_unit<ratio(1, 60), metre_per_second>, std::int64_t>>);
static_assert(compare<decltype(1_q_min / 1_q_m), quantity<unknown_dimension<exponent<dim_length, -1>, exponent<dim_time, 1>>, scaled_unit<ratio(60), unknown_coherent_unit>, std::int64_t>>);
static_assert(
compare<decltype(1_q_min / 1_q_m), quantity<unknown_dimension<exponent<dim_length, -1>, exponent<dim_time, 1>>,
scaled_unit<ratio(60), unknown_coherent_unit>, std::int64_t>>);
static_assert((1_q_m + 1_q_m).number() == 2);
static_assert((1_q_m + 1_q_km).number() == 1001);
@ -654,7 +719,7 @@ template<typename Metre>
concept no_crossdimensional_equality = requires {
requires !requires { 1_q_s == length<Metre, int>(1); };
requires !requires { 1_q_s != length<Metre, int>(1); };
};
};
static_assert(no_crossdimensional_equality<metre>);
// same type
@ -692,7 +757,7 @@ concept no_crossdimensional_ordering = requires {
requires !requires { 1_q_s > length<Metre, int>(1); };
requires !requires { 1_q_s <= length<Metre, int>(1); };
requires !requires { 1_q_s >= length<Metre, int>(1); };
};
};
static_assert(no_crossdimensional_ordering<metre>);
// same type
@ -766,7 +831,7 @@ template<typename Int>
concept invalid_dimensionless_operations = requires {
requires !requires(dimensionless<percent, Int> d) { 1 + d; };
requires !requires(dimensionless<percent, Int> d) { d + 1; };
};
};
static_assert(invalid_dimensionless_operations<int>);
static_assert(compare<decltype(10_q_km / 5_q_km), quantity<dim_one, one, std::int64_t>>);
@ -815,7 +880,9 @@ static_assert(!is_same_v<decltype(quantity_cast<litre>(2_q_dm3)), volume<cubic_d
#if UNITS_DOWNCAST_MODE == 0
static_assert(is_same_v<decltype(10_q_m / 5_q_s), quantity<unknown_dimension<units::exponent<dim_length, 1>, units::exponent<dim_time, -1>>, scaled_unit<ratio(1), unknown_coherent_unit>, std::int64_t>>);
static_assert(is_same_v<decltype(10_q_m / 5_q_s),
quantity<unknown_dimension<units::exponent<dim_length, 1>, units::exponent<dim_time, -1>>,
scaled_unit<ratio(1), unknown_coherent_unit>, std::int64_t>>);
static_assert(is_same_v<decltype(1_q_mm + 1_q_km), length<scaled_unit<ratio(1, 1, -3), metre>, std::int64_t>>);
#else
@ -846,6 +913,7 @@ static_assert(same(quotient_remainder_theorem(3'000 * m, 400), 3'000 * m));
static_assert(same(quotient_remainder_theorem(3'000 * m, quantity(400)), 3'000 * m));
static_assert(same(quotient_remainder_theorem(3 * km, quantity(400)), 3 * km));
static_assert(same(quotient_remainder_theorem(3 * km, quantity(2)), 3 * km));
static_assert(same(quotient_remainder_theorem(3 * km, dimensionless<scaled_unit<ratio(1, 1000), one>, int>(400)), 3 * km));
static_assert(same(quotient_remainder_theorem(3 * km, dimensionless<scaled_unit<ratio(1, 1000), one>, int>(400)),
3 * km));
} // namespace

View File

@ -53,7 +53,7 @@ concept invalid_operations = requires {
requires !requires { 1_q_s - s; };
requires !requires { 1_q_s * s; };
requires !requires { 1_q_s / s; };
};
};
static_assert(invalid_operations<s>);
static_assert(2_q_m / (1 * s) == 2_q_m_per_s);
@ -77,7 +77,8 @@ static_assert(1. / 4 * m2 == 1._q_m2 / 4);
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW
constexpr bool test_hiding() {
constexpr bool test_hiding()
{
Speed auto v0 = 10 * (m / s);
signed s = 2; // hides ^
Length auto v = 20 * m / s;

View File

@ -40,8 +40,10 @@ static_assert(units::detail::quantity_ratio<si::length<si::metre>> == units::rat
static_assert(units::detail::quantity_ratio<si::cgs::length<si::cgs::centimetre>> == units::ratio(1, 100));
static_assert(units::detail::quantity_ratio<si::speed<si::metre_per_second>> == units::ratio(1));
static_assert(units::detail::quantity_ratio<si::cgs::speed<si::cgs::centimetre_per_second>> == units::ratio(1, 100));
static_assert(units::detail::quantity_ratio<si::force<si::newton>> == units::ratio(1000)); // defined in terms of kilogram that are 1000 * gram
static_assert(units::detail::quantity_ratio<si::cgs::force<si::cgs::dyne>> == units::ratio(1, 100)); // defined in terms of gram so only centimetre ratio counts here
static_assert(units::detail::quantity_ratio<si::force<si::newton>> ==
units::ratio(1000)); // defined in terms of kilogram that are 1000 * gram
static_assert(units::detail::quantity_ratio<si::cgs::force<si::cgs::dyne>> ==
units::ratio(1, 100)); // defined in terms of gram so only centimetre ratio counts here
static_assert(si::cgs::length<si::cgs::centimetre>(100) == si::length<si::metre>(1));
static_assert(si::cgs::mass<si::cgs::gram>(1'000) == si::mass<si::kilogram>(1));
@ -68,7 +70,7 @@ static_assert(si::cgs::energy<si::cgs::erg>(10'000'000) == 1_q_J);
static_assert(si::cgs::power<si::cgs::erg_per_second>(10'000'000) == 1_q_W);
static_assert(si::cgs::pressure<si::cgs::barye>(10) == 1_q_Pa);
}
} // namespace si_test
namespace cgs_test {
@ -84,7 +86,7 @@ static_assert(10'000'000_q_erg == si::energy<si::joule>(1));
static_assert(10'000'000_q_erg_per_s == si::power<si::watt>(1));
static_assert(10_q_Ba == si::pressure<si::pascal>(1));
}
} // namespace cgs_test
namespace both_test {
@ -101,7 +103,7 @@ static_assert(10'000'000_q_erg == 1_q_J);
static_assert(10'000'000_q_erg_per_s == 1_q_W);
static_assert(10_q_Ba == quantity_cast<double>(1_q_Pa));
}
} // namespace both_test
namespace cgs_test {
@ -125,24 +127,29 @@ static_assert(quantity_cast<si::cgs::length<si::cgs::centimetre>>(si::length<si:
// multiplication
// static_assert(200_q_cm * si::length<si::metre>(2) == si::area<si::square_metre>(4)); // TODO Add support for comparing of an unknown_dimension
// static_assert(200_q_cm * si::length<si::metre>(2) == si::area<si::square_metre>(4)); // TODO Add support for
// comparing of an unknown_dimension
static_assert(quantity_cast<si::dim_length>(200._q_cm) * si::length<si::metre>(2) == si::area<si::square_metre>(4));
static_assert(200._q_cm * quantity_cast<si::cgs::dim_length>(si::length<si::metre>(2)) == 40'000_q_cm2);
// TODO Add support for quantity_cast on an unknown_dimension?
// static_assert(quantity_cast<si::area<si::square_metre>>(200_q_cm * si::length<si::metre>(2)) == si::area<si::square_metre>(4));
// static_assert(quantity_cast<si::dim_area>(200_q_cm * si::length<si::metre>(2)) == si::area<si::square_metre>(4));
// static_assert(quantity_cast<si::cgs::area<si::cgs::square_centimeters>>(200_q_cm * si::length<si::metre>(2)) == 40'000_q_cm2);
// static_assert(quantity_cast<si::cgs::dim_area>(200_q_cm * si::length<si::metre>(2)) == 40'000_q_cm2);
// static_assert(quantity_cast<si::area<si::square_metre>>(200_q_cm * si::length<si::metre>(2)) ==
// si::area<si::square_metre>(4)); static_assert(quantity_cast<si::dim_area>(200_q_cm * si::length<si::metre>(2)) ==
// si::area<si::square_metre>(4)); static_assert(quantity_cast<si::cgs::area<si::cgs::square_centimeters>>(200_q_cm *
// si::length<si::metre>(2)) == 40'000_q_cm2); static_assert(quantity_cast<si::cgs::dim_area>(200_q_cm *
// si::length<si::metre>(2)) == 40'000_q_cm2);
// division
// static_assert(si::area<si::square_metre>(4) / 200_q_cm == si::length<si::metre>(2)); // TODO Add support for comparing of an unknown_dimension
// static_assert(si::area<si::square_metre>(4) / 200_q_cm == si::length<si::metre>(2)); // TODO Add support for
// comparing of an unknown_dimension
static_assert(si::area<si::square_metre>(4) / quantity_cast<si::length<si::metre>>(200_q_cm) == si::length<si::metre>(2));
static_assert(quantity_cast<si::cgs::area<si::cgs::square_centimetre>>(si::area<si::square_metre>(4)) / 200._q_cm == 200_q_cm);
static_assert(si::area<si::square_metre>(4) / quantity_cast<si::length<si::metre>>(200_q_cm) ==
si::length<si::metre>(2));
static_assert(quantity_cast<si::cgs::area<si::cgs::square_centimetre>>(si::area<si::square_metre>(4)) / 200._q_cm ==
200_q_cm);
}
} // namespace cgs_test
}
} // namespace

View File

@ -41,7 +41,8 @@ static_assert(si::fps::mass<si::fps::pound>(1) == si::mass<si::kilogram>(0.45359
static_assert(si::fps::time<si::fps::second>(1) == si::time<si::second>(1));
static_assert(si::fps::speed<si::fps::foot_per_second>(1) == si::speed<si::metre_per_second>(0.3048));
static_assert(si::fps::area<si::fps::square_foot>(1) == si::area<si::square_metre>(0.09290304));
static_assert(si::fps::acceleration<si::fps::foot_per_second_sq>(1) == si::acceleration<si::metre_per_second_sq>(0.3048));
static_assert(si::fps::acceleration<si::fps::foot_per_second_sq>(1) ==
si::acceleration<si::metre_per_second_sq>(0.3048));
static_assert(si::fps::force<si::fps::poundal>(1) > si::force<si::newton>(0.138254) &&
si::fps::force<si::fps::poundal>(1) < si::force<si::newton>(0.138256));
static_assert(si::fps::energy<si::fps::foot_poundal>(1) > si::energy<si::joule>(0.042140110093804) &&
@ -61,15 +62,14 @@ static_assert(si::fps::time<si::fps::second>(1) == 1_q_s);
static_assert(si::fps::speed<si::fps::foot_per_second>(1) == 0.3048_q_m_per_s);
static_assert(si::fps::area<si::fps::square_foot>(1) == 0.09290304_q_m2);
static_assert(si::fps::acceleration<si::fps::foot_per_second_sq>(1) == 0.3048_q_m_per_s2);
static_assert(si::fps::force<si::fps::poundal>(1) > 0.138254_q_N &&
si::fps::force<si::fps::poundal>(1) < 0.138256_q_N);
static_assert(si::fps::force<si::fps::poundal>(1) > 0.138254_q_N && si::fps::force<si::fps::poundal>(1) < 0.138256_q_N);
static_assert(si::fps::energy<si::fps::foot_poundal>(1) > 0.042140110093804_q_J &&
si::fps::energy<si::fps::foot_poundal>(1) < 0.042140110093806_q_J);
static_assert(si::fps::power<si::fps::foot_poundal_per_second>(1) > 0.042140110093804_q_W &&
si::fps::power<si::fps::foot_poundal_per_second>(1) < 0.042140110093806_q_W);
static_assert(si::fps::pressure<si::fps::poundal_per_foot_sq>(1) > 1.4881639435_q_Pa &&
si::fps::pressure<si::fps::poundal_per_foot_sq>(1) < 1.4881639437_q_Pa);
}
} // namespace si_literals
namespace fps_literals {
@ -82,15 +82,14 @@ static_assert(1_q_s == si::time<si::second>(1));
static_assert(1_q_ft_per_s == si::speed<si::metre_per_second>(0.3048));
static_assert(1_q_ft2 == si::area<si::square_metre>(0.09290304));
static_assert(1_q_ft_per_s2 == si::acceleration<si::metre_per_second_sq>(0.3048));
static_assert(1_q_pdl > si::force<si::newton>(0.138254) &&
1_q_pdl < si::force<si::newton>(0.138256));
static_assert(1_q_pdl > si::force<si::newton>(0.138254) && 1_q_pdl < si::force<si::newton>(0.138256));
static_assert(1_q_ft_pdl > si::energy<si::joule>(0.042140110093804) &&
1_q_ft_pdl < si::energy<si::joule>(0.042140110093806));
static_assert(1_q_ft_pdl_per_s > si::power<si::watt>(0.042140110093804) &&
1_q_ft_pdl_per_s < si::power<si::watt>(0.042140110093806));
static_assert(1_q_pdl_per_ft2> si::pressure<si::pascal>(1.4881639435) &&
static_assert(1_q_pdl_per_ft2 > si::pressure<si::pascal>(1.4881639435) &&
1_q_pdl_per_ft2 < si::pressure<si::pascal>(1.4881639437));
}
} // namespace fps_literals
namespace fps_plus_si_literals {
@ -106,16 +105,12 @@ static_assert(1_q_s == 1_q_s);
static_assert(1_q_ft_per_s == 0.3048_q_m_per_s);
static_assert(1_q_ft2 == 0.09290304_q_m2);
static_assert(1_q_ft_per_s2 == 0.3048_q_m_per_s2);
static_assert(1_q_pdl > 0.138254_q_N &&
1_q_pdl < 0.138256_q_N);
static_assert(1_q_ft_pdl > 0.042140110093804_q_J &&
1_q_ft_pdl < 0.042140110093806_q_J);
static_assert(1_q_ft_pdl_per_s > 0.042140110093804_q_W &&
1_q_ft_pdl_per_s < 0.042140110093806_q_W);
static_assert(1_q_pdl_per_ft2> 1.4881639435_q_Pa &&
1_q_pdl_per_ft2 <1.4881639437_q_Pa);
static_assert(1_q_pdl > 0.138254_q_N && 1_q_pdl < 0.138256_q_N);
static_assert(1_q_ft_pdl > 0.042140110093804_q_J && 1_q_ft_pdl < 0.042140110093806_q_J);
static_assert(1_q_ft_pdl_per_s > 0.042140110093804_q_W && 1_q_ft_pdl_per_s < 0.042140110093806_q_W);
static_assert(1_q_pdl_per_ft2 > 1.4881639435_q_Pa && 1_q_pdl_per_ft2 < 1.4881639437_q_Pa);
}
} // namespace fps_plus_si_literals
namespace fps_test {
@ -126,34 +121,49 @@ using namespace units::isq::si::fps::references;
static_assert(si::length<si::metre>(1) + 1 * ft == si::length<si::metre>(1.3048));
static_assert(1 * ft + si::length<si::metre>(1) == si::length<si::metre>(1.3048));
static_assert(quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) + si::length<si::metre>(1) == si::length<si::metre>(2)); // 1 m in ft + 1 m
static_assert(si::length<si::metre>(1) + quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) == si::length<si::metre>(2)); // 1 m + 1 m in ft
static_assert(1 * ft + quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) == 2 * ft); // 1 ft + 1 ft in m
static_assert(quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) + 1 * ft == 2 * ft); // 1 ft in m + 1 ft
static_assert(quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) + si::length<si::metre>(1) ==
si::length<si::metre>(2)); // 1 m in ft + 1 m
static_assert(si::length<si::metre>(1) + quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) ==
si::length<si::metre>(2)); // 1 m + 1 m in ft
static_assert(1 * ft + quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) ==
2 * ft); // 1 ft + 1 ft in m
static_assert(quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) + 1 * ft ==
2 * ft); // 1 ft in m + 1 ft
// substraction
static_assert(1 * ft - si::length<si::metre>(1) == -si::length<si::metre>(0.6952));
static_assert(si::length<si::metre>(1) - 1 * ft == si::length<si::metre>(0.6952));
static_assert(quantity_cast<si::length<si::metre>>(6. * ft) - si::length<si::metre>(1) > si::length<si::metre>(0.8287) &&
quantity_cast<si::length<si::metre>>(6. * ft) - si::length<si::metre>(1) < si::length<si::metre>(0.8289)); // 6 ft in m - 1 m = ... m
static_assert(si::length<si::metre>(5) - quantity_cast<si::length<si::metre>>(6 * ft) == si::length<si::metre>(3.1712)); // 5 m - 6 ft in m = ...
static_assert(6. * ft - quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) == 5. * ft); // 6 ft - 1 ft in m = 5 ft
static_assert(quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(1.8288)) - 1. * ft == 5. * ft); // 6 ft in m - 1 ft = 5 ft
static_assert(quantity_cast<si::length<si::metre>>(6. * ft) - si::length<si::metre>(1) >
si::length<si::metre>(0.8287) &&
quantity_cast<si::length<si::metre>>(6. * ft) - si::length<si::metre>(1) <
si::length<si::metre>(0.8289)); // 6 ft in m - 1 m = ... m
static_assert(si::length<si::metre>(5) - quantity_cast<si::length<si::metre>>(6 * ft) ==
si::length<si::metre>(3.1712)); // 5 m - 6 ft in m = ...
static_assert(6. * ft - quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) ==
5. * ft); // 6 ft - 1 ft in m = 5 ft
static_assert(quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(1.8288)) - 1. * ft ==
5. * ft); // 6 ft in m - 1 ft = 5 ft
// multiplication
// static_assert(2 * ft * si::length<si::metre>(2) == si::area<si::square_metre>(1.2192)); // TODO Add support for comparing of an unknown_dimension
static_assert(quantity_cast<si::length<si::metre>>(2. * ft) * si::length<si::metre>(2) == si::area<si::square_metre>(1.2192));
static_assert(quantity_cast<si::length<si::metre>>(2. * ft) * si::length<si::metre>(0.6096) == si::area<si::square_metre>(0.371612160)); // 2 ft * 2 ft == 4 sq ft
// static_assert(2 * ft * si::length<si::metre>(2) == si::area<si::square_metre>(1.2192)); // TODO Add support for
// comparing of an unknown_dimension
static_assert(quantity_cast<si::length<si::metre>>(2. * ft) * si::length<si::metre>(2) ==
si::area<si::square_metre>(1.2192));
static_assert(quantity_cast<si::length<si::metre>>(2. * ft) * si::length<si::metre>(0.6096) ==
si::area<si::square_metre>(0.371612160)); // 2 ft * 2 ft == 4 sq ft
static_assert(2. * ft * quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.6096)) == 4._q_ft2);
// division
// static_assert(si::area<si::square_metre>(4) / 200_q_cm == si::length<si::metre>(2)); // TODO Add support for comparing of an unknown_dimension
static_assert(si::area<si::square_metre>(1.48644864) / quantity_cast<si::length<si::metre>>(4 * ft) == si::length<si::metre>(1.2192)); // 16 ft2 / 4 ft = 4 ft
static_assert(quantity_cast<si::fps::area<si::fps::square_foot>>(si::area<si::square_metre>(1.48644864)) / (4. * ft) == 4. * ft); // 16 ft2 / 4 ft = 4 ft
// static_assert(si::area<si::square_metre>(4) / 200_q_cm == si::length<si::metre>(2)); // TODO Add support for
// comparing of an unknown_dimension
static_assert(si::area<si::square_metre>(1.48644864) / quantity_cast<si::length<si::metre>>(4 * ft) ==
si::length<si::metre>(1.2192)); // 16 ft2 / 4 ft = 4 ft
static_assert(quantity_cast<si::fps::area<si::fps::square_foot>>(si::area<si::square_metre>(1.48644864)) / (4. * ft) ==
4. * ft); // 16 ft2 / 4 ft = 4 ft
}
} // namespace fps_test
}
} // namespace

View File

@ -23,9 +23,9 @@
#include <units/isq/si/area.h>
#include <units/isq/si/hep/area.h>
#include <units/isq/si/hep/energy.h>
#include <units/isq/si/length.h>
#include <units/isq/si/hep/mass.h>
#include <units/isq/si/hep/momentum.h>
#include <units/isq/si/length.h>
namespace {
@ -45,7 +45,8 @@ static_assert(si::momentum<si::hep::eV_per_c>(1'000'000) == si::hep::momentum<si
// area
static_assert(si::area<si::hep::barn>(1e28) == si::area<si::square_metre>(1));
//static_assert(si::area<si::hep::barn>(1) == si::area<si::square_metre>(1e-28)); // numeric rounding issues on some platforms
// static_assert(si::area<si::hep::barn>(1) == si::area<si::square_metre>(1e-28)); // numeric rounding issues on some
// platforms
namespace hep_literal_test {
@ -62,9 +63,10 @@ static_assert(si::hep::momentum<si::hep::eV_per_c>(1'000) == 1_q_keV_per_c);
static_assert(si::hep::momentum<si::hep::eV_per_c>(1'000'000) == 1_q_MeV_per_c);
// static_assert(si::area<si::square_metre, long double>(1e-28L) == 1_q_b); // numeric rounding issues on some platforms
//static_assert(si::hep::area<si::square_yoctometre, long double>(1e-4L) == 1_q_b); // numeric rounding issues on some platforms
// static_assert(si::hep::area<si::square_yoctometre, long double>(1e-4L) == 1_q_b); // numeric rounding issues on some
// platforms
static_assert(si::area<si::square_metre>(1e-43) == 1_q_fb);
}
} // namespace hep_literal_test
}
} // namespace

View File

@ -334,16 +334,18 @@ static_assert(1_q_J_per_K * 1_q_K == 1_q_s * 1_q_N * 1_q_m_per_s);
static_assert(1_q_J_per_mol_K == 1_q_J_per_K / 1_q_mol);
static_assert(detail::unit_text<dim_heat_capacity, joule_per_kelvin>() == "J/K");
static_assert(detail::unit_text<dim_specific_heat_capacity, joule_per_kilogram_kelvin>() == basic_symbol_text("J ⋅ K⁻¹ ⋅ kg⁻¹", "J K^-1 kg^-1"));
static_assert(detail::unit_text<dim_specific_heat_capacity, joule_per_kilogram_kelvin>() ==
basic_symbol_text("J ⋅ K⁻¹ ⋅ kg⁻¹", "J K^-1 kg^-1"));
// thermal conductivity
static_assert(20_q_W_per_m_K * 10_q_m * 300_q_K == 60'000_q_W);
static_assert(detail::unit_text<dim_thermal_conductivity, watt_per_metre_kelvin>() == basic_symbol_text("W ⋅ m⁻¹ ⋅ K⁻¹", "W m^-1 K^-1"));
static_assert(detail::unit_text<dim_thermal_conductivity, watt_per_metre_kelvin>() ==
basic_symbol_text("W ⋅ m⁻¹ ⋅ K⁻¹", "W m^-1 K^-1"));
// electric field strength
static_assert(100_q_N/20_q_C == 5_q_V_per_m);
static_assert(100_q_N / 20_q_C == 5_q_V_per_m);
static_assert(1_q_C * 10_q_V_per_m * 3_q_m == 30_q_J);
static_assert(detail::unit_text<dim_electric_field_strength, volt_per_metre>() == "V/m");
@ -358,12 +360,13 @@ static_assert(1_q_C_per_m2 == 1_q_C_per_m3 * 1_q_m);
static_assert(1_q_V_per_m * 10_q_C_per_m3 * 1_q_m3 == 10_q_N);
static_assert(detail::unit_text<dim_charge_density, coulomb_per_metre_cub>() == basic_symbol_text("C/m³", "C/m^3"));
static_assert(detail::unit_text<dim_surface_charge_density, coulomb_per_metre_sq>() == basic_symbol_text("C/m²", "C/m^2"));
static_assert(detail::unit_text<dim_surface_charge_density, coulomb_per_metre_sq>() ==
basic_symbol_text("C/m²", "C/m^2"));
// permittivity
static_assert(1_q_F_per_m == 1_q_F / 1_q_m);
static_assert(1/(1_q_F_per_m) * 1_q_C * 1_q_C / 1_q_m2 == 1_q_N);
static_assert(1 / (1_q_F_per_m) * 1_q_C * 1_q_C / 1_q_m2 == 1_q_N);
static_assert(1_q_C_per_m3 / 1_q_F_per_m * 1_q_m == 1_q_V_per_m);
static_assert(detail::unit_text<dim_permittivity, farad_per_metre>() == "F/m");

Some files were not shown because too many files have changed in this diff Show More