From b889c81cb929ee3bfbbe10c7d9c613ce3420ae89 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 15 Oct 2019 11:32:59 +0200 Subject: [PATCH] Short name added to derived unit definition --- src/CMakeLists.txt | 2 + src/include/units/bits/fixed_string.h | 67 +++++++++++++++++++ src/include/units/dimensions/acceleration.h | 2 +- src/include/units/dimensions/area.h | 14 ++-- src/include/units/dimensions/capacitance.h | 2 +- src/include/units/dimensions/current.h | 2 +- .../units/dimensions/electric_charge.h | 2 +- src/include/units/dimensions/energy.h | 2 +- src/include/units/dimensions/force.h | 2 +- src/include/units/dimensions/frequency.h | 20 +++--- src/include/units/dimensions/length.h | 24 +++---- .../units/dimensions/luminous_intensity.h | 2 +- src/include/units/dimensions/mass.h | 4 +- src/include/units/dimensions/power.h | 2 +- src/include/units/dimensions/pressure.h | 2 +- src/include/units/dimensions/substance.h | 2 +- src/include/units/dimensions/temperature.h | 2 +- src/include/units/dimensions/time.h | 12 ++-- src/include/units/dimensions/velocity.h | 6 +- src/include/units/dimensions/voltage.h | 2 +- src/include/units/dimensions/volume.h | 14 ++-- src/include/units/unit.h | 55 ++++++++++++--- test/unit_test/runtime/print_helpers.h | 13 ++-- test/unit_test/static/custom_unit_test.cpp | 9 +-- 24 files changed, 186 insertions(+), 78 deletions(-) create mode 100644 src/include/units/bits/fixed_string.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52f68e6c..4c04161c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,8 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) -fconcepts -Wno-literal-suffix -Wno-non-template-friend +# TODO gcc:92101 + -Wno-pedantic ) endif() add_library(mp::units ALIAS units) diff --git a/src/include/units/bits/fixed_string.h b/src/include/units/bits/fixed_string.h new file mode 100644 index 00000000..47df025d --- /dev/null +++ b/src/include/units/bits/fixed_string.h @@ -0,0 +1,67 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +namespace units { + +// TODO gcc:92101 +// Gated by the following gcc bug +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92101 +// +// template +// struct basic_fixed_string { +// CharT data_[N+1] = {}; + +// constexpr basic_fixed_string(const CharT (&txt)[N+1]) noexcept +// { +// for(std::size_t i = 0; i <= N; ++i) +// data_[i] = txt[i]; +// } +// // auto operator==(const basic_fixed_string &) = default; +// [[nodiscard]] constexpr const CharT* c_str() const noexcept { return data_; } +// }; + +// template +// basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string; + +// template +// using fixed_string = basic_fixed_string; + + template + struct basic_fixed_string { + static constexpr CharT txt[] = { Chars..., '\0' }; + + static constexpr const CharT* c_str() noexcept + { + return txt; + } + }; + + inline namespace hacks { + + template + constexpr basic_fixed_string operator""_fs() { return {}; } + + } + +} diff --git a/src/include/units/dimensions/acceleration.h b/src/include/units/dimensions/acceleration.h index 00285a8a..de3c4a79 100644 --- a/src/include/units/dimensions/acceleration.h +++ b/src/include/units/dimensions/acceleration.h @@ -31,7 +31,7 @@ namespace units { template concept Acceleration = QuantityOf; - struct metre_per_second_sq : derived_unit {}; + struct metre_per_second_sq : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/area.h b/src/include/units/dimensions/area.h index 0c1dbe63..976073f8 100644 --- a/src/include/units/dimensions/area.h +++ b/src/include/units/dimensions/area.h @@ -31,11 +31,11 @@ namespace units { template concept Area = QuantityOf; - struct square_millimetre : derived_unit {}; - struct square_centimetre : derived_unit {}; - struct square_metre : derived_unit {}; - struct square_kilometre : derived_unit {}; - struct square_foot : derived_unit {}; + struct square_millimetre : derived_unit {}; + struct square_centimetre : derived_unit {}; + struct square_metre : derived_unit {}; + struct square_kilometre : derived_unit {}; + struct square_foot : derived_unit {}; inline namespace literals { @@ -55,6 +55,10 @@ namespace units { constexpr auto operator""sq_km(unsigned long long l) { return quantity(l); } constexpr auto operator""sq_km(long double l) { return quantity(l); } + // sq_ft + constexpr auto operator""sq_ft(unsigned long long l) { return quantity(l); } + constexpr auto operator""sq_ft(long double l) { return quantity(l); } + } // namespace literals } // namespace units diff --git a/src/include/units/dimensions/capacitance.h b/src/include/units/dimensions/capacitance.h index b17f3e05..b5b8705e 100644 --- a/src/include/units/dimensions/capacitance.h +++ b/src/include/units/dimensions/capacitance.h @@ -33,7 +33,7 @@ namespace units { template concept Capacitance = QuantityOf; - struct farad : derived_unit {}; + struct farad : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/current.h b/src/include/units/dimensions/current.h index 4c3f41c7..cb8c6c82 100644 --- a/src/include/units/dimensions/current.h +++ b/src/include/units/dimensions/current.h @@ -32,7 +32,7 @@ namespace units { template concept Current = QuantityOf; - struct ampere : derived_unit {}; + struct ampere : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/electric_charge.h b/src/include/units/dimensions/electric_charge.h index 1044bb31..173871c8 100644 --- a/src/include/units/dimensions/electric_charge.h +++ b/src/include/units/dimensions/electric_charge.h @@ -33,7 +33,7 @@ namespace units { template concept ElectricCharge = QuantityOf; - struct coulomb : derived_unit {}; + struct coulomb : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/energy.h b/src/include/units/dimensions/energy.h index 67e4e198..912a5d0d 100644 --- a/src/include/units/dimensions/energy.h +++ b/src/include/units/dimensions/energy.h @@ -33,7 +33,7 @@ namespace units { template concept Energy = QuantityOf; - struct joule : derived_unit {}; + struct joule : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/force.h b/src/include/units/dimensions/force.h index db67eccb..eaefeac4 100644 --- a/src/include/units/dimensions/force.h +++ b/src/include/units/dimensions/force.h @@ -33,7 +33,7 @@ namespace units { template concept Force = QuantityOf; - struct newton : derived_unit {}; + struct newton : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/frequency.h b/src/include/units/dimensions/frequency.h index b5151b56..60aeab12 100644 --- a/src/include/units/dimensions/frequency.h +++ b/src/include/units/dimensions/frequency.h @@ -32,23 +32,23 @@ namespace units { template concept Frequency = QuantityOf; - struct hertz : derived_unit {}; - struct millihertz : derived_unit> {}; - struct kilohertz : derived_unit> {}; - struct megahertz : derived_unit> {}; - struct gigahertz : derived_unit> {}; - struct terahertz : derived_unit> {}; + struct hertz : derived_unit {}; + struct millihertz : derived_unit> {}; + struct kilohertz : derived_unit> {}; + struct megahertz : derived_unit> {}; + struct gigahertz : derived_unit> {}; + struct terahertz : derived_unit> {}; inline namespace literals { - // mHz - constexpr auto operator""mHz(unsigned long long l) { return quantity(l); } - constexpr auto operator""mHz(long double l) { return quantity(l); } - // Hz constexpr auto operator""Hz(unsigned long long l) { return quantity(l); } constexpr auto operator""Hz(long double l) { return quantity(l); } + // mHz + constexpr auto operator""mHz(unsigned long long l) { return quantity(l); } + constexpr auto operator""mHz(long double l) { return quantity(l); } + // kHz constexpr auto operator""kHz(unsigned long long l) { return quantity(l); } constexpr auto operator""kHz(long double l) { return quantity(l); } diff --git a/src/include/units/dimensions/length.h b/src/include/units/dimensions/length.h index 1c6a0126..d43d1841 100644 --- a/src/include/units/dimensions/length.h +++ b/src/include/units/dimensions/length.h @@ -33,13 +33,17 @@ namespace units { concept Length = QuantityOf; // SI units - struct metre : derived_unit {}; - struct millimetre : derived_unit> {}; - struct centimetre : derived_unit> {}; - struct kilometre : derived_unit> {}; + struct metre : derived_unit {}; + struct millimetre : derived_unit> {}; + struct centimetre : derived_unit> {}; + struct kilometre : derived_unit> {}; inline namespace literals { + // m + constexpr auto operator""m(unsigned long long l) { return quantity(l); } + constexpr auto operator""m(long double l) { return quantity(l); } + // mm constexpr auto operator""mm(unsigned long long l) { return quantity(l); } constexpr auto operator""mm(long double l) { return quantity(l); } @@ -48,10 +52,6 @@ namespace units { constexpr auto operator""cm(unsigned long long l) { return quantity(l); } constexpr auto operator""cm(long double l) { return quantity(l); } - // m - constexpr auto operator""m(unsigned long long l) { return quantity(l); } - constexpr auto operator""m(long double l) { return quantity(l); } - // km constexpr auto operator""km(unsigned long long l) { return quantity(l); } constexpr auto operator""km(long double l) { return quantity(l); } @@ -59,10 +59,10 @@ namespace units { } // namespace literals // US customary units - struct yard : derived_unit> {}; - struct foot : derived_unit, yard::ratio>> {}; - struct inch : derived_unit, foot::ratio>> {}; - struct mile : derived_unit, yard::ratio>> {}; + struct yard : derived_unit> {}; + struct foot : derived_unit, yard::ratio>> {}; + struct inch : derived_unit, foot::ratio>> {}; + struct mile : derived_unit, yard::ratio>> {}; inline namespace literals { diff --git a/src/include/units/dimensions/luminous_intensity.h b/src/include/units/dimensions/luminous_intensity.h index 8d667ca6..c344bdef 100644 --- a/src/include/units/dimensions/luminous_intensity.h +++ b/src/include/units/dimensions/luminous_intensity.h @@ -32,7 +32,7 @@ namespace units { template concept LuminousIntensity = QuantityOf; - struct candela : derived_unit {}; + struct candela : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/mass.h b/src/include/units/dimensions/mass.h index 148eaa10..3a4c0047 100644 --- a/src/include/units/dimensions/mass.h +++ b/src/include/units/dimensions/mass.h @@ -32,8 +32,8 @@ namespace units { template concept Mass = QuantityOf; - struct gram : derived_unit> {}; - struct kilogram : derived_unit> {}; + struct gram : derived_unit> {}; + struct kilogram : derived_unit> {}; inline namespace literals { diff --git a/src/include/units/dimensions/power.h b/src/include/units/dimensions/power.h index 75b21cf1..ad76a4fa 100644 --- a/src/include/units/dimensions/power.h +++ b/src/include/units/dimensions/power.h @@ -32,7 +32,7 @@ namespace units { template concept Power = QuantityOf; - struct watt : derived_unit {}; + struct watt : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/pressure.h b/src/include/units/dimensions/pressure.h index cbb40ee8..5b560de3 100644 --- a/src/include/units/dimensions/pressure.h +++ b/src/include/units/dimensions/pressure.h @@ -33,7 +33,7 @@ namespace units { template concept Pressure = QuantityOf; - struct pascal : derived_unit {}; + struct pascal : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/substance.h b/src/include/units/dimensions/substance.h index 622b8d2c..a0a0eebb 100644 --- a/src/include/units/dimensions/substance.h +++ b/src/include/units/dimensions/substance.h @@ -32,7 +32,7 @@ namespace units { template concept Substance = QuantityOf; - struct mole : derived_unit {}; + struct mole : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/temperature.h b/src/include/units/dimensions/temperature.h index 1c6a1239..a51b17dc 100644 --- a/src/include/units/dimensions/temperature.h +++ b/src/include/units/dimensions/temperature.h @@ -32,7 +32,7 @@ namespace units { template concept ThermodynamicTemperature = QuantityOf; - struct kelvin : derived_unit {}; + struct kelvin : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/time.h b/src/include/units/dimensions/time.h index d031ad1c..950e120b 100644 --- a/src/include/units/dimensions/time.h +++ b/src/include/units/dimensions/time.h @@ -32,12 +32,12 @@ namespace units { template concept Time = QuantityOf; - struct second : derived_unit {}; - struct nanosecond : derived_unit> {}; - struct microsecond : derived_unit> {}; - struct millisecond : derived_unit> {}; - struct minute : derived_unit> {}; - struct hour : derived_unit> {}; + struct second : derived_unit {}; + struct nanosecond : derived_unit> {}; + struct microsecond : derived_unit> {}; + struct millisecond : derived_unit> {}; + struct minute : derived_unit> {}; + struct hour : derived_unit> {}; inline namespace literals { diff --git a/src/include/units/dimensions/velocity.h b/src/include/units/dimensions/velocity.h index 9c81a200..2b8d46f3 100644 --- a/src/include/units/dimensions/velocity.h +++ b/src/include/units/dimensions/velocity.h @@ -32,9 +32,9 @@ namespace units { template concept Velocity = QuantityOf; - struct metre_per_second : derived_unit {}; - struct kilometre_per_hour : derived_unit {}; - struct mile_per_hour : derived_unit {}; + struct metre_per_second : derived_unit {}; + struct kilometre_per_hour : derived_unit {}; + struct mile_per_hour : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/voltage.h b/src/include/units/dimensions/voltage.h index a72831fd..b06e217a 100644 --- a/src/include/units/dimensions/voltage.h +++ b/src/include/units/dimensions/voltage.h @@ -35,7 +35,7 @@ namespace units { template concept Voltage = QuantityOf; - struct volt : derived_unit {}; + struct volt : derived_unit {}; inline namespace literals { diff --git a/src/include/units/dimensions/volume.h b/src/include/units/dimensions/volume.h index 87c51f99..247a8e34 100644 --- a/src/include/units/dimensions/volume.h +++ b/src/include/units/dimensions/volume.h @@ -31,11 +31,11 @@ namespace units { template concept Volume = QuantityOf; - struct cubic_millimetre : derived_unit {}; - struct cubic_centimetre : derived_unit {}; - struct cubic_metre : derived_unit {}; - struct cubic_kilometre : derived_unit {}; - struct cubic_foot : derived_unit {}; + struct cubic_millimetre : derived_unit {}; + struct cubic_centimetre : derived_unit {}; + struct cubic_metre : derived_unit {}; + struct cubic_kilometre : derived_unit {}; + struct cubic_foot : derived_unit {}; inline namespace literals { @@ -55,6 +55,10 @@ namespace units { constexpr auto operator""cub_km(unsigned long long l) { return quantity(l); } constexpr auto operator""cub_km(long double l) { return quantity(l); } + // cub_ft + constexpr auto operator""cub_ft(unsigned long long l) { return quantity(l); } + constexpr auto operator""cub_ft(long double l) { return quantity(l); } + } // namespace literals } // namespace units diff --git a/src/include/units/unit.h b/src/include/units/unit.h index e7f33728..4eda4538 100644 --- a/src/include/units/unit.h +++ b/src/include/units/unit.h @@ -24,6 +24,7 @@ #include #include +#include #include namespace units { @@ -115,20 +116,54 @@ namespace units { // derived_unit - template + // TODO gcc:92101 + // Gated by the following gcc bug + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92101 + // template + // struct derived_unit; + + // template + // struct derived_unit : downcast_helper>> { + // static constexpr auto name = Name; + // }; + + // template + // struct derived_unit : downcast_helper> { + // static constexpr auto name = Name; + // }; + + // template + // struct derived_unit : downcast_helper { + // static constexpr auto name = Name; + // }; + + // template + // struct derived_unit : downcast_helper> { + // static constexpr auto name = Name; + // }; + + template struct derived_unit; + + template + struct derived_unit : downcast_helper>> { + static constexpr auto name = Name::c_str(); + }; - template - struct derived_unit : downcast_helper>> {}; + template + struct derived_unit : downcast_helper> { + static constexpr auto name = Name::c_str(); + }; - template - struct derived_unit : downcast_helper> {}; + template + struct derived_unit : downcast_helper { + static constexpr auto name = Name::c_str(); + }; - template - struct derived_unit : downcast_helper {}; - - template - struct derived_unit : downcast_helper> {}; + template + struct derived_unit : downcast_helper> { + static constexpr auto name = Name::c_str(); + }; // SI prefixes diff --git a/test/unit_test/runtime/print_helpers.h b/test/unit_test/runtime/print_helpers.h index c2b6a799..8d664129 100644 --- a/test/unit_test/runtime/print_helpers.h +++ b/test/unit_test/runtime/print_helpers.h @@ -21,21 +21,16 @@ // SOFTWARE. #include "units/dimensions/area.h" +#include // TODO Remove when a text formatting is implemented namespace units { - template - std::ostream& operator<<(std::ostream& os, const quantity& value) + template + std::ostream& operator<<(std::ostream& os, const quantity& value) { - return os << value.count() << "m"; - } - - template - std::ostream& operator<<(std::ostream& os, const quantity& value) - { - return os << value.count() << "m^2"; + return os << value.count() << Unit::name; } } diff --git a/test/unit_test/static/custom_unit_test.cpp b/test/unit_test/static/custom_unit_test.cpp index f2ac51fd..e2cf5bcd 100644 --- a/test/unit_test/static/custom_unit_test.cpp +++ b/test/unit_test/static/custom_unit_test.cpp @@ -35,8 +35,9 @@ namespace { template concept DigitalInformation = units::QuantityOf; - struct bit : units::derived_unit {}; - struct byte : units::derived_unit> {}; + using namespace units::hacks; + struct bit : units::derived_unit {}; + struct byte : units::derived_unit> {}; inline namespace literals { @@ -61,13 +62,13 @@ namespace { // power spectral density struct power_spectral_density : derived_dimension, units::exp> {}; - struct sq_volt_per_hertz : derived_unit {}; + struct sq_volt_per_hertz : derived_unit {}; // amplitude spectral density struct amplitude_spectral_density : derived_dimension, units::exp> {}; // todo: add support for derived_unit //struct volt_per_sq_hertz : derived_unit {}; - struct volt_per_sqrt_hertz : derived_unit {}; + struct volt_per_sqrt_hertz : derived_unit {}; } namespace {