From ce53df71fcf53402bcab80395ff995f42f01c28d Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 24 Jul 2019 16:55:21 +0200 Subject: [PATCH] Added a few more derived dimensions --- doc/DESIGN.md | 4 +- src/include/units/acceleration.h | 46 +++++++++++++++++++ src/include/units/capacitance.h | 48 ++++++++++++++++++++ src/include/units/electric_charge.h | 48 ++++++++++++++++++++ src/include/units/energy.h | 48 ++++++++++++++++++++ src/include/units/force.h | 49 ++++++++++++++++++++ src/include/units/power.h | 47 +++++++++++++++++++ src/include/units/pressure.h | 47 +++++++++++++++++++ src/include/units/voltage.h | 50 +++++++++++++++++++++ src/include/units/volume.h | 70 +++++++++++++++++++++++++++++ test/unit_test/test_units.cpp | 57 ++++++++++++++++++++++- 11 files changed, 511 insertions(+), 3 deletions(-) create mode 100644 src/include/units/acceleration.h create mode 100644 src/include/units/capacitance.h create mode 100644 src/include/units/electric_charge.h create mode 100644 src/include/units/energy.h create mode 100644 src/include/units/force.h create mode 100644 src/include/units/power.h create mode 100644 src/include/units/pressure.h create mode 100644 src/include/units/voltage.h create mode 100644 src/include/units/volume.h diff --git a/doc/DESIGN.md b/doc/DESIGN.md index 96eb128d..8a67dfa8 100644 --- a/doc/DESIGN.md +++ b/doc/DESIGN.md @@ -547,5 +547,7 @@ Additionally, it should make the error logs even shorter thus easier to understa 14. Do we need to support fractional exponents (i.e. `dimension>` as 2/3)? -15. `k` and `K` UDLs conflict with gcc GNU extensions (https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Fixed_002dPoint.html) +15. `k`, `K`, `W`, `F` UDLs conflict with gcc GNU extensions (https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Fixed_002dPoint.html) for floating point types. + +16. `J` imaginary constants are a GCC extension diff --git a/src/include/units/acceleration.h b/src/include/units/acceleration.h new file mode 100644 index 00000000..d1725be2 --- /dev/null +++ b/src/include/units/acceleration.h @@ -0,0 +1,46 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace std::experimental::units { + + struct dimension_acceleration : make_dimension_t, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Acceleration = Quantity && std::Same; + + struct meter_per_second_sq : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // mps_sq + constexpr auto operator""mps_sq(unsigned long long l) { return quantity(l); } + constexpr auto operator""mps_sq(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/capacitance.h b/src/include/units/capacitance.h new file mode 100644 index 00000000..a6afd445 --- /dev/null +++ b/src/include/units/capacitance.h @@ -0,0 +1,48 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace std::experimental::units { + + struct dimension_capacitance : make_dimension_t, exp, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Capacitance = Quantity && std::Same; + + struct farad : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // F + constexpr auto operator""F(unsigned long long l) { return quantity(l); } + constexpr auto operator""_F(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/electric_charge.h b/src/include/units/electric_charge.h new file mode 100644 index 00000000..dead8689 --- /dev/null +++ b/src/include/units/electric_charge.h @@ -0,0 +1,48 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace std::experimental::units { + + struct dimension_electric_charge : make_dimension_t, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool ElectricCharge = Quantity && std::Same; + + struct coulomb : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // C + constexpr auto operator""C(unsigned long long l) { return quantity(l); } + constexpr auto operator""C(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/energy.h b/src/include/units/energy.h new file mode 100644 index 00000000..f3f787cc --- /dev/null +++ b/src/include/units/energy.h @@ -0,0 +1,48 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace std::experimental::units { + + struct dimension_energy : make_dimension_t, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Energy = Quantity && std::Same; + + struct joule : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // J + constexpr auto operator""_J(unsigned long long l) { return quantity(l); } + constexpr auto operator""_J(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/force.h b/src/include/units/force.h new file mode 100644 index 00000000..fc5cebf9 --- /dev/null +++ b/src/include/units/force.h @@ -0,0 +1,49 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace std::experimental::units { + + struct dimension_force : make_dimension_t, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Force = Quantity && std::Same; + + struct newton : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // N + constexpr auto operator""N(unsigned long long l) { return quantity(l); } + constexpr auto operator""N(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/power.h b/src/include/units/power.h new file mode 100644 index 00000000..f6898d1a --- /dev/null +++ b/src/include/units/power.h @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace std::experimental::units { + + struct dimension_power : make_dimension_t, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Power = Quantity && std::Same; + + struct watt : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // W + constexpr auto operator""W(unsigned long long l) { return quantity(l); } + constexpr auto operator""_W(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/pressure.h b/src/include/units/pressure.h new file mode 100644 index 00000000..214a5d94 --- /dev/null +++ b/src/include/units/pressure.h @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace std::experimental::units { + + struct dimension_pressure : make_dimension_t, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Pressure = Quantity && std::Same; + + struct pascal : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // Pa + constexpr auto operator""Pa(unsigned long long l) { return quantity(l); } + constexpr auto operator""Pa(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/voltage.h b/src/include/units/voltage.h new file mode 100644 index 00000000..becd8669 --- /dev/null +++ b/src/include/units/voltage.h @@ -0,0 +1,50 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace std::experimental::units { + + struct dimension_voltage : make_dimension_t, exp, exp, exp> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Voltage = Quantity && std::Same; + + struct volt : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // V + constexpr auto operator""V(unsigned long long l) { return quantity(l); } + constexpr auto operator""V(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/src/include/units/volume.h b/src/include/units/volume.h new file mode 100644 index 00000000..d13d0dd7 --- /dev/null +++ b/src/include/units/volume.h @@ -0,0 +1,70 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace std::experimental::units { + + struct dimension_volume : make_dimension_t> {}; + template<> struct downcasting_traits> : downcast_to {}; + + template + concept bool Volume = Quantity && std::Same; + + struct cubic_millimeter : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + struct cubic_centimeter : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + struct cubic_meter : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + struct cubic_kilometer : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + struct cubic_foot : derived_unit {}; + template<> struct downcasting_traits> : downcast_to {}; + + inline namespace literals { + + // cub_mm + constexpr auto operator""cub_mm(unsigned long long l) { return quantity(l); } + constexpr auto operator""cub_mm(long double l) { return quantity(l); } + + // cub_cm + constexpr auto operator""cub_cm(unsigned long long l) { return quantity(l); } + constexpr auto operator""cub_cm(long double l) { return quantity(l); } + + // cub_m + constexpr auto operator""cub_m(unsigned long long l) { return quantity(l); } + constexpr auto operator""cub_m(long double l) { return quantity(l); } + + // cub_km + constexpr auto operator""cub_km(unsigned long long l) { return quantity(l); } + constexpr auto operator""cub_km(long double l) { return quantity(l); } + + } // namespace literals + +} // namespace std::experimental::units diff --git a/test/unit_test/test_units.cpp b/test/unit_test/test_units.cpp index 0247595e..459790b4 100644 --- a/test/unit_test/test_units.cpp +++ b/test/unit_test/test_units.cpp @@ -24,14 +24,23 @@ #include #include #include -#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + #include +#include #include +#include #include @@ -63,7 +72,7 @@ namespace { - /* ************** DERIVED DIMENSIONS **************** */ + /* ************** DERIVED DIMENSIONS WITH NAMED UNITS **************** */ // frequency @@ -73,6 +82,39 @@ namespace { static_assert(3.2GHz == 3'200'000'000Hz); // static_assert(10hz * 1min == 600); + // force + + static_assert(10kg * 10mps_sq == 100N); + + // pressure + + static_assert(10N / 10sq_m == 1Pa); + + // energy + + static_assert(10N * 10m == 100_J); + static_assert(10Pa * 10cub_m == 100_J); + + // power + + static_assert(10_J / 10s == 1W); + + // electric charge + + static_assert(10A * 10s == 100C); + + // voltage + + static_assert(10W / 10A == 1V); + static_assert(10_J / 10C == 1V); + + // capacitance + + static_assert(10C / 10V == 1F); + + + /* ************** DERIVED DIMENSIONS IN TERMS OF BASE UNITS **************** */ + // velocity static_assert(std::is_same_v>, std::int64_t>>); @@ -95,10 +137,21 @@ namespace { // static_assert(2000m / 2kmph == 1h); // should not compile static_assert(quantity_cast>(2000m) / 2kmph == 1h); + // acceleration + + static_assert(10mps / 10s == 1mps_sq); + // area static_assert(1m * 1m == 1sq_m); static_assert(10km * 10km == 100sq_km); static_assert(1sq_m == 10'000sq_cm); + // volume + + static_assert(1m * 1m * 1m == 1cub_m); + static_assert(10sq_m * 10m == 100cub_m); + static_assert(10km * 10km * 10km == 1000cub_km); + static_assert(1cub_m == 1'000'000cub_cm); + } // namespace