diff --git a/src/core/include/mp-units/bits/hacks.h b/src/core/include/mp-units/bits/hacks.h index 3b8c9a89..f27c5438 100644 --- a/src/core/include/mp-units/bits/hacks.h +++ b/src/core/include/mp-units/bits/hacks.h @@ -150,5 +150,9 @@ MP_UNITS_DIAGNOSTIC_POP #define MP_UNITS_API_NO_CRTP 1 +#endif + +#if defined(__clang__) && defined(__apple_build_version__) && __apple_build_version__ < 16000026 +#define MP_UNITS_APPLE_CLANG_HACKS #endif // NOLINTEND(bugprone-reserved-identifier, cppcoreguidelines-macro-usage) diff --git a/src/core/include/mp-units/framework/representation_concepts.h b/src/core/include/mp-units/framework/representation_concepts.h index ff99bd96..5ff83189 100644 --- a/src/core/include/mp-units/framework/representation_concepts.h +++ b/src/core/include/mp-units/framework/representation_concepts.h @@ -190,6 +190,7 @@ concept Complex = (!disable_complex) && requires(const T a, const T b, const requires std::constructible_from; } && WeaklyRegular; + namespace magnitude_impl { void magnitude() = delete; // poison pill @@ -309,15 +310,45 @@ concept VectorRepresentation = (!is_quantity) && Vector && requires(const MP_UNITS_EXPORT template concept Representation = detail::ScalarRepresentation || detail::ComplexRepresentation || - detail::VectorRepresentation; // || detail::TensorRepresentation; + detail::VectorRepresentation; // || detail::TensorRepresentation; */ namespace detail { +#ifdef MP_UNITS_APPLE_CLANG_HACKS +template +constexpr bool is_weakly_regular = std::copyable && std::equality_comparable; + +template +constexpr bool is_scalar = !disable_scalar && is_weakly_regular; + +template +constexpr bool is_complex = !disable_complex && is_weakly_regular && is_scalar> && + std::constructible_from, value_type_t>; + +template +concept ComplexFunctionsAvailable = requires(T a) { + ::mp_units::real(a); + ::mp_units::imag(a); + ::mp_units::modulus(a); +}; + +template +constexpr bool is_vector = !disable_vector && is_weakly_regular && is_scalar>; + +template +concept VectorFunctionsAvailable = requires(T a) { ::mp_units::magnitude(a); }; + + +template +concept IsOfCharacter = ((Ch == quantity_character::scalar && is_scalar) || + (Ch == quantity_character::complex && is_complex && ComplexFunctionsAvailable) || + (Ch == quantity_character::vector && is_vector && VectorFunctionsAvailable)); +#else template concept IsOfCharacter = (Ch == quantity_character::scalar && Scalar) || (Ch == quantity_character::complex && Complex) || (Ch == quantity_character::vector && Vector); // || (Ch == quantity_character::tensor && Tensor); - +#endif } MP_UNITS_EXPORT template diff --git a/test/static/concepts_test.cpp b/test/static/concepts_test.cpp index 0b1a7bab..2cf15448 100644 --- a/test/static/concepts_test.cpp +++ b/test/static/concepts_test.cpp @@ -20,6 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#include #include #include #include @@ -308,7 +309,9 @@ static_assert(!RepresentationOf, quantity_character::scalar static_assert(!RepresentationOf, quantity_character::vector>); static_assert(!RepresentationOf, quantity_character::tensor>); static_assert(RepresentationOf, quantity_character::vector>); +#ifndef MP_UNITS_APPLE_CLANG_HACKS static_assert(!RepresentationOf, quantity_character::scalar>); +#endif static_assert(!RepresentationOf, quantity_character::complex>); static_assert(!RepresentationOf, quantity_character::tensor>); static_assert(!RepresentationOf); diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index 3b8d14d5..40948a2d 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -65,6 +65,8 @@ static_assert(sizeof(quantity) == sizeof(double)); static_assert(sizeof(quantity) == sizeof(short)); static_assert(sizeof(quantity) == sizeof(short)); +#ifndef MP_UNITS_APPLE_CLANG_HACKS + template typename Q> concept invalid_types = requires { requires !requires { typename Q; }; // dimension instead of reference @@ -77,13 +79,15 @@ concept invalid_types = requires { }; // vector representation expected requires !requires { typename Q>; - }; // scalar representation expected + }; // scalar representation expected requires !requires { typename Q>; }; // incompatible character requires !requires { typename Q; }; // incompatible character #endif }; static_assert(invalid_types); +#endif + static_assert(std::is_trivially_default_constructible_v>); static_assert(std::is_trivially_copy_constructible_v>); static_assert(std::is_trivially_move_constructible_v>);