diff --git a/src/include/units/derived_dimension.h b/src/include/units/derived_dimension.h index 57323161..cf35b99d 100644 --- a/src/include/units/derived_dimension.h +++ b/src/include/units/derived_dimension.h @@ -229,6 +229,9 @@ using make_dimension = dim_consolidate::t * base and derived dimensions. This is called a "recipe" of the dimension and among others is used to print * unnamed coherent units of this dimension. * + * Coherent unit is a unit that, for a given system of quantities and for a chosen set of base units, is a product + * of powers of base units with no other proportionality factor than one. + * * The implementation is responsible for unpacking all of the dimensions into a list containing only base dimensions * and their factors and putting them to the other (private) units::derived_dimension class template partial * specialization. @@ -246,30 +249,6 @@ struct derived_dimension : downcast_child -concept PredefinedDimension = Dimension && requires { typename T::coherent_unit; }; - -template -auto unit_for_dimension_impl() -{ - if constexpr(PredefinedDimension) { - return downcast>{}; - } - else { - return scaled_unit{}; - } -} - -template -using unit_for_dimension = decltype(unit_for_dimension_impl()); - -} - // same_dim template inline constexpr bool same_dim = false; @@ -280,157 +259,4 @@ inline constexpr bool same_dim = std::is_same_v; template inline constexpr bool same_dim = std::is_same_v; -// dim_invert -namespace detail { - -template -struct dim_invert_impl; - -template -struct dim_invert_impl { - using type = downcast>>; -}; - -template -struct dim_invert_impl>> { - using type = D; -}; - -template -struct dim_invert_impl> { - using type = downcast...>>; -}; - -template -struct dim_invert_impl : dim_invert_impl> { -}; - -} // namespace detail - -template -using dim_invert = detail::dim_invert_impl::type; - -// dimension_multiply -namespace detail { - -template -struct dim_unpack { - using type = D; -}; - -template -struct dim_unpack>> { - using type = D; -}; - -/** - * @brief Merges 2 sorted derived dimensions into one units::derived_dimension - * - * A result of a dimensional calculation may result with many exponents of the same base dimension orginated - * from different parts of the equation. As the exponents lists of both operands it is enough to merge them - * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only - * one element being a base dimension with exponent 1. In such a case the final dimension should be the base - * dimension itself. - */ -template -using merge_dimension = dim_unpack>::type>::type; - -template -struct dimension_multiply_impl; - -template -struct dimension_multiply_impl { - using type = downcast>, derived_dimension>>>; -}; - -template -struct dimension_multiply_impl { - using type = downcast>, typename D2::downcast_base_type>>; -}; - -template -struct dimension_multiply_impl { - using type = dimension_multiply_impl::type; -}; - -template -struct dimension_multiply_impl { - using type = downcast>; -}; - -} // namespace detail - -template -using dimension_multiply = detail::dimension_multiply_impl::type; - -template -using dimension_divide = detail::dimension_multiply_impl>::type; - -// dimension_sqrt -namespace detail { - -template -struct dimension_sqrt_impl; - -template -struct dimension_sqrt_impl { - using type = derived_dimension>; -}; - -template -struct dimension_sqrt_impl>> { - using type = D; -}; - -template -struct dimension_sqrt_impl { - using type = dimension_sqrt_impl; -}; - -template -struct dimension_sqrt_impl> { - using type = downcast...>>; -}; - -} // namespace detail - -template -using dimension_sqrt = detail::dimension_sqrt_impl::type; - -// dimension_pow -namespace detail { - -template -struct dimension_pow_impl; - -template -struct dimension_pow_impl { - using type = downcast>>; -}; - -template -struct dimension_pow_impl { - using type = D; -}; - -template -struct dimension_pow_impl>, N> { - using type = D; -}; - -template -struct dimension_pow_impl { - using type = dimension_pow_impl, N>; -}; - -template -struct dimension_pow_impl, N> { - using type = downcast...>>; -}; - -} // namespace detail - -template -using dimension_pow = detail::dimension_pow_impl::type; - } // namespace units diff --git a/src/include/units/dimension_op.h b/src/include/units/dimension_op.h new file mode 100644 index 00000000..294de4b4 --- /dev/null +++ b/src/include/units/dimension_op.h @@ -0,0 +1,215 @@ +// 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 units { + +/** + * @brief Unknown dimension + * + * Sometimes a temporary partial result of a complex calculation may not result in a predefined + * dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_unit` + * and ratio<1>. + * + * @tparam Es zero or more exponents of a derived dimension + */ +template +struct unknown_dimension : derived_dimension, scaled_unit>, Es...> { + using coherent_unit = scaled_unit>; +}; + +namespace detail { + +template +struct downcast_dimension_impl { + using type = D; +}; + +// downcast did not find user predefined type +template +struct downcast_dimension_impl> { + using type = unknown_dimension; +}; + +} // namespace detail + +template +using downcast_dimension = detail::downcast_dimension_impl>::type; + +// dim_invert +namespace detail { + +template +struct dim_invert_impl; + +template +struct dim_invert_impl { + using type = downcast_dimension>>; +}; + +template +struct dim_invert_impl>> { + using type = D; +}; + +template +struct dim_invert_impl> { + using type = downcast_dimension...>>; +}; + +template +struct dim_invert_impl : dim_invert_impl> { +}; + +} // namespace detail + +template +using dim_invert = detail::dim_invert_impl::type; + +// dimension_multiply +namespace detail { + +template +struct dim_unpack { + using type = D; +}; + +template +struct dim_unpack>> { + using type = D; +}; + +/** + * @brief Merges 2 sorted derived dimensions into one units::derived_dimension + * + * A result of a dimensional calculation may result with many exponents of the same base dimension orginated + * from different parts of the equation. As the exponents lists of both operands it is enough to merge them + * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only + * one element being a base dimension with exponent 1. In such a case the final dimension should be the base + * dimension itself. + */ +template +using merge_dimension = dim_unpack>::type>::type; + +template +struct dimension_multiply_impl; + +template +struct dimension_multiply_impl { + using type = downcast_dimension>, derived_dimension>>>; +}; + +template +struct dimension_multiply_impl { + using type = downcast_dimension>, typename D2::downcast_base_type>>; +}; + +template +struct dimension_multiply_impl { + using type = dimension_multiply_impl::type; +}; + +template +struct dimension_multiply_impl { + using type = downcast_dimension>; +}; + +} // namespace detail + +template +using dimension_multiply = detail::dimension_multiply_impl::type; + +template +using dimension_divide = detail::dimension_multiply_impl>::type; + +// dimension_sqrt +namespace detail { + +template +struct dimension_sqrt_impl; + +template +struct dimension_sqrt_impl { + using type = derived_dimension>; +}; + +template +struct dimension_sqrt_impl>> { + using type = D; +}; + +template +struct dimension_sqrt_impl { + using type = dimension_sqrt_impl; +}; + +template +struct dimension_sqrt_impl> { + using type = downcast_dimension...>>; +}; + +} // namespace detail + +template +using dimension_sqrt = detail::dimension_sqrt_impl::type; + +// dimension_pow +namespace detail { + +template +struct dimension_pow_impl; + +template +struct dimension_pow_impl { + using type = downcast_dimension>>; +}; + +template +struct dimension_pow_impl { + using type = D; +}; + +template +struct dimension_pow_impl>, N> { + using type = D; +}; + +template +struct dimension_pow_impl { + using type = dimension_pow_impl, N>; +}; + +template +struct dimension_pow_impl, N> { + using type = downcast_dimension...>>; +}; + +} // namespace detail + +template +using dimension_pow = detail::dimension_pow_impl::type; + +} // namespace units diff --git a/src/include/units/dimensions/capacitance.h b/src/include/units/dimensions/capacitance.h deleted file mode 100644 index 736fc9a6..00000000 --- a/src/include/units/dimensions/capacitance.h +++ /dev/null @@ -1,46 +0,0 @@ -// 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 units { - - struct capacitance : derived_dimension, exp> {}; - - template - concept Capacitance = QuantityOf; - - struct farad : named_coherent_derived_unit {}; - - 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 units diff --git a/src/include/units/dimensions/energy.h b/src/include/units/dimensions/energy.h deleted file mode 100644 index 709a1b14..00000000 --- a/src/include/units/dimensions/energy.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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 units { - - struct energy : derived_dimension, exp> {}; - - template - concept Energy = QuantityOf; - - struct joule : named_coherent_derived_unit {}; - struct millijoule : prefixed_derived_unit {}; - struct kilojoule : prefixed_derived_unit {}; - struct megajoule : prefixed_derived_unit {}; - struct gigajoule : prefixed_derived_unit {}; - - 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); } - - // mJ - constexpr auto operator""mJ(unsigned long long l) { return quantity(l); } - constexpr auto operator""mJ(long double l) { return quantity(l); } - - // kJ - constexpr auto operator""kJ(unsigned long long l) { return quantity(l); } - constexpr auto operator""kJ(long double l) { return quantity(l); } - - // MJ - constexpr auto operator""MJ(unsigned long long l) { return quantity(l); } - constexpr auto operator""MJ(long double l) { return quantity(l); } - - // GJ - constexpr auto operator""GJ(unsigned long long l) { return quantity(l); } - constexpr auto operator""GJ(long double l) { return quantity(l); } - - } // namespace literals - -} // namespace units diff --git a/src/include/units/dimensions/force.h b/src/include/units/dimensions/force.h deleted file mode 100644 index 5ec11f3d..00000000 --- a/src/include/units/dimensions/force.h +++ /dev/null @@ -1,46 +0,0 @@ -// 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 units { - - struct force : derived_dimension, exp> {}; - - template - concept Force = QuantityOf; - - struct newton : named_coherent_derived_unit {}; - - 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 units diff --git a/src/include/units/dimensions/mass.h b/src/include/units/dimensions/mass.h deleted file mode 100644 index d5da2587..00000000 --- a/src/include/units/dimensions/mass.h +++ /dev/null @@ -1,50 +0,0 @@ -// 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 units { - - struct mass : derived_dimension> {}; - - template - concept Mass = QuantityOf; - - struct gram : named_scaled_derived_unit, si_prefix> {}; - struct kilogram : prefixed_derived_unit {}; - - inline namespace literals { - - // g - constexpr auto operator""g(unsigned long long l) { return quantity(l); } - constexpr auto operator""g(long double l) { return quantity(l); } - - // kg - constexpr auto operator""kg(unsigned long long l) { return quantity(l); } - constexpr auto operator""kg(long double l) { return quantity(l); } - - } // namespace literals - -} // namespace units diff --git a/src/include/units/dimensions/physical.h b/src/include/units/dimensions/physical.h deleted file mode 100644 index d92228a1..00000000 --- a/src/include/units/dimensions/physical.h +++ /dev/null @@ -1,124 +0,0 @@ -// 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 units { - - // base dimension - - template - struct base_dimension { - static constexpr auto name = Name; - }; - - template - concept BaseDimension = true; - - // base dimension - - template> - struct base_unit { - static constexpr auto symbol = Symbol; - using dimension = Dim; - using prefix_type = PT; - using ratio = R; - }; - - template - concept BaseUnit = true; - - template - concept BaseUnitOf = BaseUnit && BaseDimension && std::same_as; - - - - namespace physical { - - // base dimensions - struct base_dim_length : base_dimension<"length"> {}; - struct base_dim_mass : base_dimension<"mass"> {}; - struct base_dim_time : base_dimension<"time"> {}; - struct base_dim_current : base_dimension<"current"> {}; - struct base_dim_temperature : base_dimension<"temperature"> {}; - struct base_dim_substance : base_dimension<"substance"> {}; - struct base_dim_luminous_intensity : base_dimension<"luminous intensity"> {}; - - - // dimensions - template L> - struct length : derived_dimension> {}; - - template M> - struct mass : derived_dimension> {}; - - template T> - struct time : derived_dimension> {}; - - template L, UnitOf T> - struct velocity : derived_dimension, exp> {}; - - template L, UnitOf T> - struct acceleration : derived_dimension, exp> {}; - - template M, UnitOf A> - struct force : derived_dimension, exp> {}; - - } // physical - - // SI - namespace si { - struct si_prefix; - - // length - struct metre : base_unit<"m", base_dim_length, si_prefix> {}; - struct length : physical::length {}; - - // mass - struct kilogram : base_unit<"kg", base_dim_mass, si_prefix> {}; - struct mass : physical::mass {}; - - // time - struct second : base_unit<"s", base_dim_time, si_prefix> {}; - struct time : physical::time {}; - - struct nanosecond : prefixed_derived_unit {}; - struct microsecond : prefixed_derived_unit {}; - struct millisecond : prefixed_derived_unit {}; - struct minute : named_derived_unit> {}; - struct hour : named_derived_unit> {}; - - // velocity - struct velocity : physical::velocity; - - // acceleration - struct acceleration : physical::acceleration; - - // acceleration - struct acceleration : physical::acceleration; - - } - -} // namespace units diff --git a/src/include/units/dimensions/power.h b/src/include/units/dimensions/power.h deleted file mode 100644 index afffb2d2..00000000 --- a/src/include/units/dimensions/power.h +++ /dev/null @@ -1,66 +0,0 @@ -// 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 units { - - struct power : derived_dimension, exp> {}; - - template - concept Power = QuantityOf; - - struct watt : named_coherent_derived_unit {}; - struct milliwatt : prefixed_derived_unit {}; - struct kilowatt : prefixed_derived_unit {}; - struct megawatt : prefixed_derived_unit {}; - struct gigawatt : prefixed_derived_unit {}; - - 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); } - - // mW - constexpr auto operator""mW(unsigned long long l) { return quantity(l); } - constexpr auto operator""mW(long double l) { return quantity(l); } - - // kW - constexpr auto operator""kW(unsigned long long l) { return quantity(l); } - constexpr auto operator""kW(long double l) { return quantity(l); } - - // MW - constexpr auto operator""MW(unsigned long long l) { return quantity(l); } - constexpr auto operator""MW(long double l) { return quantity(l); } - - // GW - constexpr auto operator""GW(unsigned long long l) { return quantity(l); } - constexpr auto operator""GW(long double l) { return quantity(l); } - - } // namespace literals - -} // namespace units diff --git a/src/include/units/dimensions/pressure.h b/src/include/units/dimensions/pressure.h deleted file mode 100644 index 4302ed26..00000000 --- a/src/include/units/dimensions/pressure.h +++ /dev/null @@ -1,46 +0,0 @@ -// 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 units { - - struct pressure : derived_dimension, exp> {}; - - template - concept Pressure = QuantityOf; - - struct pascal : named_coherent_derived_unit {}; - - 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 units diff --git a/src/include/units/dimensions/surface_tension.h b/src/include/units/dimensions/surface_tension.h deleted file mode 100644 index 8a106301..00000000 --- a/src/include/units/dimensions/surface_tension.h +++ /dev/null @@ -1,45 +0,0 @@ -// 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 units { - - struct surface_tension : derived_dimension, exp> {}; - - template - concept SurfaceTension = QuantityOf; - - struct newton_per_metre : coherent_derived_unit {}; - - inline namespace literals { - - // Nm - constexpr auto operator""Npm(unsigned long long l) { return quantity(l); } - constexpr auto operator""Npm(long double l) { return quantity(l); } - - } // namespace literals - -} // namespace units diff --git a/src/include/units/dimensions/voltage.h b/src/include/units/dimensions/voltage.h deleted file mode 100644 index f862a873..00000000 --- a/src/include/units/dimensions/voltage.h +++ /dev/null @@ -1,48 +0,0 @@ -// 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 units { - - struct voltage : derived_dimension, exp> {}; - - template - concept Voltage = QuantityOf; - - struct volt : named_coherent_derived_unit {}; - - 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 units diff --git a/src/include/units/dimensions/volume.h b/src/include/units/dimensions/volume.h deleted file mode 100644 index 9cf72b53..00000000 --- a/src/include/units/dimensions/volume.h +++ /dev/null @@ -1,64 +0,0 @@ -// 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 units { - - struct volume : derived_dimension> {}; - - template - concept Volume = QuantityOf; - - struct cubic_metre : coherent_derived_unit {}; - struct cubic_millimetre : deduced_derived_unit {}; - struct cubic_centimetre : deduced_derived_unit {}; - struct cubic_kilometre : deduced_derived_unit {}; - struct cubic_foot : deduced_derived_unit {}; - - 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); } - - // 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/math.h b/src/include/units/math.h index c6bb2bc4..4632b693 100644 --- a/src/include/units/math.h +++ b/src/include/units/math.h @@ -39,7 +39,7 @@ namespace units { { using dim = dimension_pow; using ratio = ratio_pow; - using unit = detail::unit_for_dimension; + using unit = downcast_unit; return quantity(static_cast(std::pow(q.count(), N))); } @@ -48,7 +48,7 @@ namespace units { { using dim = dimension_sqrt; using ratio = ratio_sqrt; - using unit = detail::unit_for_dimension; + using unit = downcast_unit; return quantity(static_cast(std::sqrt(q.count()))); } diff --git a/src/include/units/physical/dimensions.h b/src/include/units/physical/dimensions.h index 26959f89..89a18f53 100644 --- a/src/include/units/physical/dimensions.h +++ b/src/include/units/physical/dimensions.h @@ -104,6 +104,13 @@ struct dim_area : derived_dimension> {}; template concept Area = QuantityOf; +// volume +template L> +struct dim_volume : derived_dimension> {}; + +template +concept Volume = QuantityOf; + // velocity template L, DimensionOf T> struct dim_velocity : derived_dimension, exp> {}; @@ -139,6 +146,34 @@ struct dim_power : derived_dimension, exp> {}; template concept Power = QuantityOf; +// voltage +template P, DimensionOf C> +struct dim_voltage : derived_dimension, exp> {}; + +template +concept Voltage = QuantityOf; + +// electric charge +template T, DimensionOf C> +struct dim_electric_charge : derived_dimension, exp> {}; + +template +concept ElectricCharge = QuantityOf; + +// capacitance +template C, DimensionOf V> +struct dim_capacitance : derived_dimension, exp> {}; + +template +concept Capacitance = QuantityOf; + +// surface tension +template F, DimensionOf L> +struct dim_surface_tension : derived_dimension, exp> {}; + +template +concept SurfaceTension = QuantityOf; + // pressure template F, DimensionOf A> struct dim_pressure : derived_dimension, exp> {}; diff --git a/src/include/units/physical/si/acceleration.h b/src/include/units/physical/si/acceleration.h index 9a31f537..b7d34653 100644 --- a/src/include/units/physical/si/acceleration.h +++ b/src/include/units/physical/si/acceleration.h @@ -24,6 +24,7 @@ #include #include +#include namespace units::si { diff --git a/src/include/units/physical/si/area.h b/src/include/units/physical/si/area.h index 52a915ed..4a53594d 100644 --- a/src/include/units/physical/si/area.h +++ b/src/include/units/physical/si/area.h @@ -24,6 +24,7 @@ #include #include +#include namespace units::si { diff --git a/src/include/units/physical/si/capacitance.h b/src/include/units/physical/si/capacitance.h new file mode 100644 index 00000000..eb71780f --- /dev/null +++ b/src/include/units/physical/si/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 +#include +#include + +namespace units::si { + +struct farad : named_unit {}; + +struct dim_capacitance : physical::dim_capacitance {}; + +template +using capacitance = quantity; + +inline namespace literals { + +// F +constexpr auto operator""F(unsigned long long l) { return capacitance(l); } +constexpr auto operator""_F(long double l) { return capacitance(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/dimensions/current.h b/src/include/units/physical/si/current.h similarity index 68% rename from src/include/units/dimensions/current.h rename to src/include/units/physical/si/current.h index 072f9a8e..57580451 100644 --- a/src/include/units/dimensions/current.h +++ b/src/include/units/physical/si/current.h @@ -22,24 +22,25 @@ #pragma once -#include +#include +#include #include -namespace units { +namespace units::si { - struct current : derived_dimension> {}; +struct ampere : named_unit {}; - template - concept Current = QuantityOf; +struct dim_current : physical::dim_current {}; - struct ampere : named_coherent_derived_unit {}; +template +using current = quantity; - inline namespace literals { +inline namespace literals { - // A - constexpr auto operator""A(unsigned long long l) { return quantity(l); } - constexpr auto operator""A(long double l) { return quantity(l); } +// A +constexpr auto operator""A(unsigned long long l) { return current(l); } +constexpr auto operator""A(long double l) { return current(l); } - } +} // namespace literals -} // namespace units +} // namespace units::si diff --git a/src/include/units/physical/si/electric_charge.h b/src/include/units/physical/si/electric_charge.h new file mode 100644 index 00000000..3b3c5de0 --- /dev/null +++ b/src/include/units/physical/si/electric_charge.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 +#include +#include + +namespace units::si { + +struct coulomb : named_unit {}; + +struct dim_electric_charge : physical::dim_electric_charge {}; + +template +using electric_charge = quantity; + +inline namespace literals { + +// C +constexpr auto operator""C(unsigned long long l) { return electric_charge(l); } +constexpr auto operator""C(long double l) { return electric_charge(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/energy.h b/src/include/units/physical/si/energy.h new file mode 100644 index 00000000..719d4539 --- /dev/null +++ b/src/include/units/physical/si/energy.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. + +#pragma once + +#include +#include +#include +#include + +namespace units::si { + +struct joule : named_unit {}; +struct millijoule : prefixed_unit {}; +struct kilojoule : prefixed_unit {}; +struct megajoule : prefixed_unit {}; +struct gigajoule : prefixed_unit {}; + +struct dim_energy : physical::dim_energy {}; + +template +using energy = quantity; + +inline namespace literals { + +// J +constexpr auto operator""_J(unsigned long long l) { return energy(l); } +constexpr auto operator""_J(long double l) { return energy(l); } + +// mJ +constexpr auto operator""mJ(unsigned long long l) { return energy(l); } +constexpr auto operator""mJ(long double l) { return energy(l); } + +// kJ +constexpr auto operator""kJ(unsigned long long l) { return energy(l); } +constexpr auto operator""kJ(long double l) { return energy(l); } + +// MJ +constexpr auto operator""MJ(unsigned long long l) { return energy(l); } +constexpr auto operator""MJ(long double l) { return energy(l); } + +// GJ +constexpr auto operator""GJ(unsigned long long l) { return energy(l); } +constexpr auto operator""GJ(long double l) { return energy(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/force.h b/src/include/units/physical/si/force.h new file mode 100644 index 00000000..e3f7cf19 --- /dev/null +++ b/src/include/units/physical/si/force.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 +#include +#include + +namespace units::si { + +struct newton : named_unit {}; + +struct dim_force : physical::dim_force {}; + +template +using force = quantity; + +inline namespace literals { + +// N +constexpr auto operator""N(unsigned long long l) { return force(l); } +constexpr auto operator""N(long double l) { return force(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/frequency.h b/src/include/units/physical/si/frequency.h index 902641d2..be896849 100644 --- a/src/include/units/physical/si/frequency.h +++ b/src/include/units/physical/si/frequency.h @@ -24,6 +24,7 @@ #include #include +#include namespace units::si { diff --git a/src/include/units/physical/si/length.h b/src/include/units/physical/si/length.h index 5143ba10..6bf17294 100644 --- a/src/include/units/physical/si/length.h +++ b/src/include/units/physical/si/length.h @@ -24,6 +24,7 @@ #include #include +#include namespace units::si { diff --git a/src/include/units/dimensions/luminous_intensity.h b/src/include/units/physical/si/luminous_intensity.h similarity index 64% rename from src/include/units/dimensions/luminous_intensity.h rename to src/include/units/physical/si/luminous_intensity.h index 736da752..d3bcd5e2 100644 --- a/src/include/units/dimensions/luminous_intensity.h +++ b/src/include/units/physical/si/luminous_intensity.h @@ -22,24 +22,25 @@ #pragma once -#include +#include +#include #include -namespace units { +namespace units::si { - struct luminous_intensity : derived_dimension> {}; +struct candela : named_unit {}; - template - concept LuminousIntensity = QuantityOf; +struct dim_luminous_intensity : physical::dim_luminous_intensity {}; - struct candela : named_coherent_derived_unit {}; +template +using luminous_intensity = quantity; - inline namespace literals { +inline namespace literals { - // cd - constexpr auto operator""cd(unsigned long long l) { return quantity(l); } - constexpr auto operator""cd(long double l) { return quantity(l); } +// cd +constexpr auto operator""cd(unsigned long long l) { return luminous_intensity(l); } +constexpr auto operator""cd(long double l) { return luminous_intensity(l); } - } // namespace literals +} // namespace literals -} // namespace units +} // namespace units::si diff --git a/src/include/units/dimensions/electric_charge.h b/src/include/units/physical/si/mass.h similarity index 59% rename from src/include/units/dimensions/electric_charge.h rename to src/include/units/physical/si/mass.h index 31cd410f..cd3fc4e8 100644 --- a/src/include/units/dimensions/electric_charge.h +++ b/src/include/units/physical/si/mass.h @@ -22,25 +22,29 @@ #pragma once -#include -#include -#include +#include +#include -namespace units { +namespace units::si { - struct electric_charge : derived_dimension, exp> {}; +struct gram : named_unit {}; +struct kilogram : prefixed_unit {}; - template - concept ElectricCharge = QuantityOf; +struct dim_mass : physical::dim_mass {}; - struct coulomb : named_coherent_derived_unit {}; +template +using mass = quantity; - inline namespace literals { +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); } + // g + constexpr auto operator""g(unsigned long long l) { return mass(l); } + constexpr auto operator""g(long double l) { return mass(l); } - } // namespace literals + // kg + constexpr auto operator""kg(unsigned long long l) { return mass(l); } + constexpr auto operator""kg(long double l) { return mass(l); } -} // namespace units +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/power.h b/src/include/units/physical/si/power.h new file mode 100644 index 00000000..072ede21 --- /dev/null +++ b/src/include/units/physical/si/power.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. + +#pragma once + +#include +#include +#include +#include + +namespace units::si { + +struct watt : named_unit {}; +struct milliwatt : prefixed_unit {}; +struct kilowatt : prefixed_unit {}; +struct megawatt : prefixed_unit {}; +struct gigawatt : prefixed_unit {}; + +struct dim_power : physical::dim_power {}; + +template +using power = quantity; + +inline namespace literals { + +// W +constexpr auto operator""W(unsigned long long l) { return power(l); } +constexpr auto operator""_W(long double l) { return power(l); } + +// mW +constexpr auto operator""mW(unsigned long long l) { return power(l); } +constexpr auto operator""mW(long double l) { return power(l); } + +// kW +constexpr auto operator""kW(unsigned long long l) { return power(l); } +constexpr auto operator""kW(long double l) { return power(l); } + +// MW +constexpr auto operator""MW(unsigned long long l) { return power(l); } +constexpr auto operator""MW(long double l) { return power(l); } + +// GW +constexpr auto operator""GW(unsigned long long l) { return power(l); } +constexpr auto operator""GW(long double l) { return power(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/pressure.h b/src/include/units/physical/si/pressure.h new file mode 100644 index 00000000..a4256305 --- /dev/null +++ b/src/include/units/physical/si/pressure.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 +#include +#include + +namespace units::si { + +struct pascal : named_unit {}; + +struct dim_pressure : physical::dim_pressure {}; + +template +using pressure = quantity; + +inline namespace literals { + +// Pa +constexpr auto operator""Pa(unsigned long long l) { return pressure(l); } +constexpr auto operator""Pa(long double l) { return pressure(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/dimensions/substance.h b/src/include/units/physical/si/substance.h similarity index 67% rename from src/include/units/dimensions/substance.h rename to src/include/units/physical/si/substance.h index 54b15fa4..285fc33f 100644 --- a/src/include/units/dimensions/substance.h +++ b/src/include/units/physical/si/substance.h @@ -22,24 +22,25 @@ #pragma once -#include +#include +#include #include -namespace units { +namespace units::si { - struct substance : derived_dimension> {}; +struct mole : named_unit {}; - template - concept Substance = QuantityOf; +struct dim_substance : physical::dim_substance {}; - struct mole : named_coherent_derived_unit {}; +template +using substance = quantity; - inline namespace literals { +inline namespace literals { - // mol - constexpr auto operator""mol(unsigned long long l) { return quantity(l); } - constexpr auto operator""mol(long double l) { return quantity(l); } +// mol +constexpr auto operator"" mol(unsigned long long l) { return substance(l); } +constexpr auto operator"" mol(long double l) { return substance(l); } - } // namespace literals +} // namespace literals -} // namespace units +} // namespace units::si diff --git a/src/include/units/physical/si/surface_tension.h b/src/include/units/physical/si/surface_tension.h new file mode 100644 index 00000000..3e4b01b2 --- /dev/null +++ b/src/include/units/physical/si/surface_tension.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 +#include +#include + +namespace units::si { + +struct newton_per_metre : unit {}; + +struct dim_surface_tension : physical::dim_surface_tension {}; + +template +using surface_tension = quantity; + +inline namespace literals { + + // Nm + constexpr auto operator""Npm(unsigned long long l) { return surface_tension(l); } + constexpr auto operator""Npm(long double l) { return surface_tension(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/dimensions/base_dimensions.h b/src/include/units/physical/si/temperature.h similarity index 65% rename from src/include/units/dimensions/base_dimensions.h rename to src/include/units/physical/si/temperature.h index ef2ea824..27e6ab33 100644 --- a/src/include/units/dimensions/base_dimensions.h +++ b/src/include/units/physical/si/temperature.h @@ -22,16 +22,24 @@ #pragma once -#include +#include +#include -namespace units { +namespace units::si { - struct base_dim_length : base_dimension<"length", "m"> {}; - struct base_dim_mass : base_dimension<"mass", "kg"> {}; - struct base_dim_time : base_dimension<"time", "s"> {}; - struct base_dim_current : base_dimension<"current", "A"> {}; - struct base_dim_temperature : base_dimension<"temperature", "K"> {}; - struct base_dim_substance : base_dimension<"substance", "mol"> {}; - struct base_dim_luminous_intensity : base_dimension<"luminous intensity", "cd"> {}; +struct kelvin : named_unit {}; -} // namespace units +struct dim_temperature : physical::dim_temperature {}; + +template +using temperature = quantity; + +inline namespace literals { + +// K +constexpr auto operator""K(unsigned long long l) { return temperature(l); } +constexpr auto operator""_K(long double l) { return temperature(l); } // TODO: conflicts with gcc GNU extension + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/physical/si/time.h b/src/include/units/physical/si/time.h index 56534eba..9bd60783 100644 --- a/src/include/units/physical/si/time.h +++ b/src/include/units/physical/si/time.h @@ -24,6 +24,7 @@ #include #include +#include namespace units::si { diff --git a/src/include/units/physical/si/velocity.h b/src/include/units/physical/si/velocity.h index bb551919..bcd168bd 100644 --- a/src/include/units/physical/si/velocity.h +++ b/src/include/units/physical/si/velocity.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace units::si { diff --git a/src/include/units/dimensions/temperature.h b/src/include/units/physical/si/voltage.h similarity index 64% rename from src/include/units/dimensions/temperature.h rename to src/include/units/physical/si/voltage.h index 5a26a56a..5e729032 100644 --- a/src/include/units/dimensions/temperature.h +++ b/src/include/units/physical/si/voltage.h @@ -22,24 +22,27 @@ #pragma once -#include +#include +#include +#include +#include #include -namespace units { +namespace units::si { - struct temperature : derived_dimension> {}; +struct volt : named_unit {}; - template - concept ThermodynamicTemperature = QuantityOf; +struct dim_voltage : physical::dim_voltage {}; - struct kelvin : named_coherent_derived_unit {}; +template +using voltage = quantity; - inline namespace literals { +inline namespace literals { - // K - constexpr auto operator""K(unsigned long long l) { return quantity(l); } - constexpr auto operator""_K(long double l) { return quantity(l); } // TODO: conflicts with gcc GNU extension +// V +constexpr auto operator""V(unsigned long long l) { return voltage(l); } +constexpr auto operator""V(long double l) { return voltage(l); } - } // namespace literals +} // namespace literals -} // namespace units +} // namespace units::si diff --git a/src/include/units/physical/si/volume.h b/src/include/units/physical/si/volume.h new file mode 100644 index 00000000..be80331a --- /dev/null +++ b/src/include/units/physical/si/volume.h @@ -0,0 +1,66 @@ +// 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 units::si { + +struct cubic_metre : unit {}; +struct dim_volume : physical::dim_volume {}; + +struct cubic_millimetre : deduced_unit {}; +struct cubic_centimetre : deduced_unit {}; +struct cubic_kilometre : deduced_unit {}; +struct cubic_foot : deduced_unit {}; + +template +using volume = quantity; + +inline namespace literals { + +// cub_mm +constexpr auto operator""cub_mm(unsigned long long l) { return volume(l); } +constexpr auto operator""cub_mm(long double l) { return volume(l); } + +// cub_cm +constexpr auto operator""cub_cm(unsigned long long l) { return volume(l); } +constexpr auto operator""cub_cm(long double l) { return volume(l); } + +// cub_m +constexpr auto operator""cub_m(unsigned long long l) { return volume(l); } +constexpr auto operator""cub_m(long double l) { return volume(l); } + +// cub_km +constexpr auto operator""cub_km(unsigned long long l) { return volume(l); } +constexpr auto operator""cub_km(long double l) { return volume(l); } + +// cub_ft +constexpr auto operator""cub_ft(unsigned long long l) { return volume(l); } +constexpr auto operator""cub_ft(long double l) { return volume(l); } + +} // namespace literals + +} // namespace units::si diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index b9d64bf5..340e6801 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -23,7 +23,7 @@ #pragma once #include -#include +#include #include #include @@ -73,9 +73,7 @@ struct common_quantity_impl, quantity, Rep> { template struct common_quantity_impl, quantity, Rep> { - using type = quantity< - D, downcast>>, - Rep>; + using type = quantity>, Rep>; }; } // namespace detail @@ -154,7 +152,7 @@ template { using c_ratio = ratio_divide; using c_rep = std::common_type_t; - using ret_unit = downcast>; + using ret_unit = downcast_unit; using ret = quantity; using cast = detail::quantity_cast_impl; return cast::cast(q); @@ -465,8 +463,10 @@ template { using dim = dimension_multiply; - using ratio = ratio_multiply; - using unit = detail::unit_for_dimension; + using ratio1 = ratio_divide; + using ratio2 = ratio_divide; + using ratio = ratio_multiply; + using unit = downcast_unit; using common_rep = decltype(lhs.count() * rhs.count()); using ret = quantity; return ret(lhs.count() * rhs.count()); @@ -480,7 +480,7 @@ template using dim = dim_invert; using ratio = ratio; - using unit = detail::unit_for_dimension; + using unit = downcast_unit; using common_rep = decltype(v / q.count()); using ret = quantity; return ret(v / q.count()); @@ -518,8 +518,10 @@ template; - using ratio = ratio_divide; - using unit = detail::unit_for_dimension; + using ratio1 = ratio_divide; + using ratio2 = ratio_divide; + using ratio = ratio_divide; + using unit = downcast_unit; using ret = quantity; return ret(lhs.count() / rhs.count()); } diff --git a/src/include/units/unit.h b/src/include/units/unit.h index 6f7342ca..20618c74 100644 --- a/src/include/units/unit.h +++ b/src/include/units/unit.h @@ -32,86 +32,35 @@ namespace units { -// scaled_unit +/** + * @brief A common point for a hierarchy of units + * + * A unit is an entity defined and adopted by convention, with which any other quantity of + * the same kind can be compared to express the ratio of the second quantity to the first + * one as a number. + * + * All units of the same dimension can be convereted between each other. To allow this all of + * them are expressed as different ratios of the same one proprietary chosen reference unit + * (i.e. all length units are expressed in terms of meter, all mass units are expressed in + * terms of gram, ...) + * + * @tparam U a unit to use as a reference for this dimension + * @tparam R a ratio of a reference unit + */ template struct scaled_unit : downcast_base> { using reference = U; using ratio = R; }; -// UnitOf -namespace detail { - -template -concept SameReference = std::same_as; - -} - -template -concept UnitOf = - Unit && - Dimension && - (std::same_as || detail::SameReference); - -namespace detail { - -// same_scaled_units -template -inline constexpr bool same_scaled_units = false; - -template -inline constexpr bool same_scaled_units, Us...> = (UnitOf && ...); - -// deduced_unit -template -struct ratio_op; - -template -struct ratio_op { - using ratio = Result; -}; - -template -struct ratio_op { - using calc_ratio = - conditional<(UnitExpNum * UnitExpDen > 0), ratio_multiply, ratio_divide>; - static constexpr int value = (UnitExpNum * UnitExpDen > 0) ? (UnitExpNum - UnitExpDen) : (UnitExpNum + UnitExpDen); - using ratio = ratio_op::ratio; -}; - -template -struct derived_ratio; - -template -struct derived_ratio, Us...> { - using ratio = ::units::ratio<1>; -}; - -template -struct derived_ratio, U, URest...> { - using rest_ratio = derived_ratio, URest...>::ratio; - using ratio = ratio_op::ratio; -}; - -template -using deduced_unit = - scaled_unit::ratio>; - -} // namespace detail +template +using downcast_unit = downcast>; /** * @brief A starting point for a new hierarchy of units * - * A unit is an entity defined and adopted by convention, with which any other quantity of - * the same kind can be compared to express the ratio of the second quantity to the first - * one as a number. - * - * Coherent unit is a unit that, for a given system of quantities and for a chosen set of - * base units, is a product of powers of base units with no other proportionality factor - * than one. - * - * This class allows definition of a new unnamed (in most cases coherent) derived unit of - * a specific derived dimension and it should be passed in this dimension's definition. + * Defines a new unnamed (in most cases coherent) derived unit of a specific derived dimension + * and it should be passed in this dimension's definition. * * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) */ @@ -121,6 +70,13 @@ struct unit : downcast_child>> { using prefix_type = no_prefix; }; +/** + * @brief Unknown unit + * + * Used as a reference unit of an unknown dimension. + */ +struct unknown_unit : unit {}; + /** * @brief A named unit * @@ -185,6 +141,59 @@ struct prefixed_unit : using prefix_type = P::prefix_type; }; +// UnitOf +template +concept UnitOf = + Unit && + Dimension && + std::same_as; + +namespace detail { + +// same_scaled_units +template +inline constexpr bool same_scaled_units = false; + +template +inline constexpr bool same_scaled_units, Us...> = (UnitOf && ...); + +// deduced_unit +template +struct ratio_op; + +template +struct ratio_op { + using ratio = Result; +}; + +template +struct ratio_op { + using calc_ratio = + conditional<(UnitExpNum * UnitExpDen > 0), ratio_multiply, ratio_divide>; + static constexpr int value = (UnitExpNum * UnitExpDen > 0) ? (UnitExpNum - UnitExpDen) : (UnitExpNum + UnitExpDen); + using ratio = ratio_op::ratio; +}; + +template +struct derived_ratio; + +template +struct derived_ratio, Us...> { + using ratio = ::units::ratio<1>; +}; + +template +struct derived_ratio, U, URest...> { + using rest_ratio = derived_ratio, URest...>::ratio; + using ratio = ratio_op::ratio; +}; + +template +using deduced_unit = + scaled_unit::ratio>; + +} // namespace detail + /** * @brief A unit with a deduced ratio and symbol * @@ -202,7 +211,7 @@ template (U::is_named && (URest::is_named && ... && true)) struct deduced_unit : downcast_child> { static constexpr bool is_named = false; - static constexpr auto symbol = basic_fixed_string{""}; // detail::deduced_symbol_text(); + static constexpr auto symbol = basic_fixed_string{""}; // detail::deduced_symbol_text(); // TODO implement this using prefix_type = no_prefix; }; diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 0babe95d..b448503c 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -23,13 +23,12 @@ add_library(unit_tests_static # cgs_test.cpp # custom_unit_test.cpp - dimension_test.cpp + dimension_op_test.cpp # fixed_string_test.cpp math_test.cpp -# new_design.cpp quantity_test.cpp ratio_test.cpp -# si_test.cpp + si_test.cpp type_list_test.cpp unit_test.cpp ) diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_op_test.cpp similarity index 87% rename from test/unit_test/static/dimension_test.cpp rename to test/unit_test/static/dimension_op_test.cpp index 94cf5ea5..b9d199c3 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_op_test.cpp @@ -20,7 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include "units/derived_dimension.h" +#include "units/dimension_op.h" #include "units/unit.h" #include @@ -63,9 +63,9 @@ static_assert(std::is_same_v, exp, exp>, // dim_invert static_assert(std::is_same_v>>, d0>); -static_assert(std::is_same_v>>, derived_dimension>>); +static_assert(std::is_same_v>>, unknown_dimension>>); static_assert( - std::is_same_v, exp>>, derived_dimension, exp>>); + std::is_same_v, exp>>, unknown_dimension, exp>>); // make_dimension @@ -94,33 +94,33 @@ static_assert(std::is_same_v, exp, exp, // dimension_multiply static_assert(std::is_same_v>, derived_dimension>>, - derived_dimension, exp>>); + unknown_dimension, exp>>); static_assert( - std::is_same_v>, d1>, derived_dimension, exp>>); + std::is_same_v>, d1>, unknown_dimension, exp>>); static_assert( - std::is_same_v>>, derived_dimension, exp>>); -static_assert(std::is_same_v, derived_dimension, exp>>); + std::is_same_v>>, unknown_dimension, exp>>); +static_assert(std::is_same_v, unknown_dimension, exp>>); static_assert(std::is_same_v< dimension_multiply, exp, exp>, derived_dimension>>, - derived_dimension, exp, exp, exp>>); + unknown_dimension, exp, exp, exp>>); static_assert(std::is_same_v< dimension_multiply, exp, exp>, derived_dimension>>, - derived_dimension, exp, exp>>); + unknown_dimension, exp, exp>>); static_assert(std::is_same_v< dimension_multiply, exp, exp>, derived_dimension>>, - derived_dimension, exp>>); + unknown_dimension, exp>>); static_assert(std::is_same_v>, derived_dimension>>, - derived_dimension<>>); -static_assert(std::is_same_v>, derived_dimension>>, d0>); + unknown_dimension<>>); +static_assert(std::is_same_v>, unknown_dimension>>, d0>); // dimension_divide static_assert(std::is_same_v>, derived_dimension>>, - derived_dimension, exp>>); + unknown_dimension, exp>>); static_assert(std::is_same_v>, derived_dimension>>, - derived_dimension<>>); + unknown_dimension<>>); static_assert(std::is_same_v>, derived_dimension>>, - derived_dimension<>>); -static_assert(std::is_same_v>, derived_dimension>>, d0>); + unknown_dimension<>>); +static_assert(std::is_same_v>, unknown_dimension>>, d0>); } // namespace diff --git a/test/unit_test/static/si_test.cpp b/test/unit_test/static/si_test.cpp new file mode 100644 index 00000000..c31d5886 --- /dev/null +++ b/test/unit_test/static/si_test.cpp @@ -0,0 +1,193 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + + using namespace units; + using namespace units::si; + + /* ************** BASE DIMENSIONS **************** */ + + // length + + static_assert(1km == 1000m); + static_assert(1m == 100cm); + static_assert(1m == 1000mm); + static_assert(1km + 1m == 1001m); + static_assert(10km / 5km == 2); + static_assert(100mm / 5cm == 2); + static_assert(10km / 2 == 5km); + + static_assert(1yd == 0.9144m); + static_assert(1yd == 3ft); + static_assert(1ft == 12in); + static_assert(1mi == 1760yd); + + static_assert(5in + 8cm == 207mm); + + static_assert(millimetre::symbol == "mm"); + static_assert(centimetre::symbol == "cm"); + static_assert(kilometre::symbol == "km"); + + // mass + + static_assert(1kg == 1000g); + + static_assert(kilogram::symbol == "kg"); + + // time + + static_assert(1h == 3600s); + + static_assert(nanosecond::symbol == "ns"); + static_assert(microsecond::symbol == "µs"); + static_assert(millisecond::symbol == "ms"); + + // current + + // temperature + + // substance + + // luminous intensity + + + /* ************** DERIVED DIMENSIONS WITH NAMED UNITS **************** */ + + // frequency + + static_assert(2 / 1s == 2Hz); + static_assert(120 / 1min == 2Hz); + static_assert(1000 / 1s == 1kHz); + static_assert(1 / 1ms == 1kHz); + static_assert(3.2GHz == 3'200'000'000Hz); + static_assert(10Hz * 1min == 600); + static_assert(2 / 1Hz == 2s); + + static_assert(millihertz::symbol == "mHz"); + static_assert(kilohertz::symbol == "kHz"); + static_assert(megahertz::symbol == "MHz"); + static_assert(gigahertz::symbol == "GHz"); + static_assert(terahertz::symbol == "THz"); + + // 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>>); + + static_assert(10m / 5s == 2mps); + static_assert(10 / 5s * 1m == 2mps); + static_assert(1km / 1s == 1000mps); + // static_assert(1km / 1h == 1kmph); // should not compile + static_assert(1.0km / 1h == 1kmph); + static_assert(1000.0m / 3600.0s == 1kmph); + + static_assert(10.0mi / 2h == 5mph); + + static_assert(2kmph * 2h == 4km); + // static_assert(2kmph * 15min == 500m); // should not compile + static_assert(2kmph * 15.0min == 500m); + static_assert(2.0kmph * 15min == 500m); + + static_assert(2km / 2kmph == 1h); + // static_assert(2000m / 2kmph == 1h); // should not compile + static_assert(quantity_cast>(2000m) / 2kmph == 1h); + +// static_assert(metre_per_second::symbol == basic_fixed_string("m/s")); + // static_assert(kilometre_per_hour::symbol == basic_fixed_string("km/h")); + + + // 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); + + + /* ************** DERIVED DIMENSIONS IN TERMS OF OTHER UNITS **************** */ + + static_assert(10N / 2m == 5Npm); + +} // namespace diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index 58eb8e9c..a23bee55 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -38,6 +38,9 @@ struct second : named_unit {}; struct hour : named_scaled_unit, second> {}; struct dim_time : base_dimension<"time", second> {}; +struct kelvin : named_unit {}; +// struct kilokelvin : prefixed_unit {}; // should not compile (prefix not allowed for this reference unit) + struct metre_per_second : unit {}; struct dim_velocity : derived_dimension, exp> {}; struct kilometre_per_hour : deduced_unit {};