diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e4c2e96fe..7b2bf7d35 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -46,6 +46,7 @@ add_mp_units_module( include/mp-units/bits/get_associated_quantity.h include/mp-units/bits/get_common_base.h include/mp-units/bits/magnitude.h + include/mp-units/bits/make_reference.h include/mp-units/bits/quantity_cast.h include/mp-units/bits/quantity_concepts.h include/mp-units/bits/quantity_point_concepts.h diff --git a/src/core/include/mp-units/bits/make_reference.h b/src/core/include/mp-units/bits/make_reference.h new file mode 100644 index 000000000..ed2f57187 --- /dev/null +++ b/src/core/include/mp-units/bits/make_reference.h @@ -0,0 +1,39 @@ +// 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 mp_units::detail { + +template +[[nodiscard]] consteval Reference auto make_reference(QS, U u) +{ + if constexpr (detail::QuantityKindSpec) + return u; + else + return reference{}; +} + +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h index def030c6c..72417f55a 100644 --- a/src/core/include/mp-units/quantity_spec.h +++ b/src/core/include/mp-units/quantity_spec.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -39,17 +40,6 @@ namespace mp_units { namespace detail { - -template - requires(!AssociatedUnit) || UnitOf -[[nodiscard]] consteval Reference auto make_reference(QS, U u) -{ - if constexpr (detail::QuantityKindSpec) - return u; - else - return reference{}; -} - // TODO revise the note in the below comment /** * @brief Returns the most restrictive character from the list diff --git a/src/core/include/mp-units/reference.h b/src/core/include/mp-units/reference.h index 505cd08bb..745290aec 100644 --- a/src/core/include/mp-units/reference.h +++ b/src/core/include/mp-units/reference.h @@ -22,8 +22,8 @@ #pragma once -#include #include +#include #include #include #include @@ -68,74 +68,44 @@ struct reference { } template - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator*(reference, reference) + [[nodiscard]] friend consteval Reference auto operator*(reference, reference) { - return {}; + return detail::make_reference(Q{} * Q2{}, U{} * U2{}); } template -#if MP_UNITS_COMP_MSVC - [[nodiscard]] friend consteval decltype(reference{}) operator*(reference, U2) -#else - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator*(reference, U2) -#endif + [[nodiscard]] friend consteval Reference auto operator*(reference, U2) { - return {}; + return detail::make_reference(Q{} * get_quantity_spec(U2{}), U{} * U2{}); } template -#if MP_UNITS_COMP_MSVC - [[nodiscard]] friend consteval decltype(reference{}) operator*(U1, reference) -#else - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator*(U1, reference) -#endif + [[nodiscard]] friend consteval Reference auto operator*(U1, reference) { - return {}; + return detail::make_reference(get_quantity_spec(U1{}) * Q{}, U1{} * U{}); } template - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator/(reference, reference) + [[nodiscard]] friend consteval Reference auto operator/(reference, reference) { - return {}; + return detail::make_reference(Q{} / Q2{}, U{} / U2{}); } template -#if MP_UNITS_COMP_MSVC - [[nodiscard]] friend consteval decltype(reference{}) operator/(reference, U2) -#else - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator/(reference, U2) -#endif + [[nodiscard]] friend consteval Reference auto operator/(reference, U2) { - return {}; + return detail::make_reference(Q{} / get_quantity_spec(U2{}), U{} / U2{}); } template -#if MP_UNITS_COMP_MSVC - [[nodiscard]] friend consteval decltype(reference{}) operator/(U1, reference) -#else - [[nodiscard]] friend consteval reference, - std::remove_const_t> - operator/(U1, reference) -#endif + [[nodiscard]] friend consteval Reference auto operator/(U1, reference) { - return {}; + return detail::make_reference(get_quantity_spec(U1{}) / Q{}, U1{} / U{}); } - [[nodiscard]] friend consteval reference, - std::remove_const_t> - inverse(reference) + [[nodiscard]] friend consteval Reference auto inverse(reference) { - return {}; + return detail::make_reference(inverse(Q{}), inverse(U{})); } /** @@ -149,11 +119,9 @@ struct reference { */ template requires detail::non_zero - [[nodiscard]] friend consteval reference(Q{}))>, - std::remove_const_t(U{}))>> - pow(reference) + [[nodiscard]] friend consteval Reference auto pow(reference) { - return {}; + return detail::make_reference(pow(Q{}), pow(U{})); } /** @@ -163,12 +131,7 @@ struct reference { * * @return The result of computation */ - [[nodiscard]] friend consteval reference, - std::remove_const_t> - sqrt(reference) - { - return {}; - } + [[nodiscard]] friend consteval Reference auto sqrt(reference) { return detail::make_reference(sqrt(Q{}), sqrt(U{})); } /** * @brief Computes the cubic root of a reference @@ -177,12 +140,7 @@ struct reference { * * @return The result of computation */ - [[nodiscard]] friend consteval reference, - std::remove_const_t> - cbrt(reference) - { - return {}; - } + [[nodiscard]] friend consteval Reference auto cbrt(reference) { return detail::make_reference(cbrt(Q{}), cbrt(U{})); } template [[nodiscard]] friend consteval bool convertible(reference, reference) @@ -289,9 +247,9 @@ template } template -[[nodiscard]] consteval reference> clone_reference_with(reference) +[[nodiscard]] consteval Reference auto clone_reference_with(reference) { - return {}; + return detail::make_reference(QS{}, To); } } // namespace detail