mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-31 10:57:16 +02:00
Do not use WeaklyRegular with Xcode 15 for type detection
Removing the `WeaklyRegular` requirement from the `Scalar`, `Complex`, and `Vector` concepts seems to address compiler crashes or long compilation times with apple-clang included in Xcode 15. I thought I had previously tried removing the `WeaklyRegular` requirement and it had not solved the problem but either I made a mistake with this test or some other changes after rebasing this work changed the situation.
This commit is contained in:
@ -153,6 +153,6 @@ MP_UNITS_DIAGNOSTIC_POP
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__) && defined(__apple_build_version__) && __apple_build_version__ < 16000026
|
#if defined(__clang__) && defined(__apple_build_version__) && __apple_build_version__ < 16000026
|
||||||
#define MP_UNITS_APPLE_CLANG_HACKS
|
#define MP_UNITS_XCODE15_HACKS
|
||||||
#endif
|
#endif
|
||||||
// NOLINTEND(bugprone-reserved-identifier, cppcoreguidelines-macro-usage)
|
// NOLINTEND(bugprone-reserved-identifier, cppcoreguidelines-macro-usage)
|
||||||
|
@ -88,7 +88,7 @@ concept Scalar = (!disable_scalar<T>) &&
|
|||||||
{ a + b } -> std::common_with<T>;
|
{ a + b } -> std::common_with<T>;
|
||||||
{ a - b } -> std::common_with<T>;
|
{ a - b } -> std::common_with<T>;
|
||||||
} && ScalableWith<T, T>
|
} && ScalableWith<T, T>
|
||||||
#if MP_UNITS_COMP_GCC != 12
|
#if MP_UNITS_COMP_GCC != 12 && !defined(MP_UNITS_XCODE15_HACKS)
|
||||||
&& WeaklyRegular<T>
|
&& WeaklyRegular<T>
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
@ -177,18 +177,23 @@ constexpr bool disable_complex = false;
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Complex = (!disable_complex<T>) && requires(const T a, const T b, const T& c) {
|
concept Complex = (!disable_complex<T>) &&
|
||||||
{ -a } -> std::common_with<T>;
|
requires(const T a, const T b, const T& c) {
|
||||||
{ a + b } -> std::common_with<T>;
|
{ -a } -> std::common_with<T>;
|
||||||
{ a - b } -> std::common_with<T>;
|
{ a + b } -> std::common_with<T>;
|
||||||
{ a* b } -> std::common_with<T>;
|
{ a - b } -> std::common_with<T>;
|
||||||
{ a / b } -> std::common_with<T>;
|
{ a* b } -> std::common_with<T>;
|
||||||
::mp_units::real(a);
|
{ a / b } -> std::common_with<T>;
|
||||||
::mp_units::imag(a);
|
::mp_units::real(a);
|
||||||
::mp_units::modulus(a);
|
::mp_units::imag(a);
|
||||||
requires ScalableWith<T, decltype(::mp_units::modulus(a))>;
|
::mp_units::modulus(a);
|
||||||
requires std::constructible_from<T, decltype(::mp_units::real(c)), decltype(::mp_units::imag(c))>;
|
requires ScalableWith<T, decltype(::mp_units::modulus(a))>;
|
||||||
} && WeaklyRegular<T>;
|
requires std::constructible_from<T, decltype(::mp_units::real(c)), decltype(::mp_units::imag(c))>;
|
||||||
|
}
|
||||||
|
#ifndef MP_UNITS_XCODE15_HACKS
|
||||||
|
&& WeaklyRegular<T>
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
namespace magnitude_impl {
|
namespace magnitude_impl {
|
||||||
|
|
||||||
@ -238,19 +243,24 @@ constexpr bool disable_vector = false;
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Vector = (!disable_vector<T>) && requires(const T a, const T b) {
|
concept Vector = (!disable_vector<T>) &&
|
||||||
{ -a } -> std::common_with<T>;
|
requires(const T a, const T b) {
|
||||||
{ a + b } -> std::common_with<T>;
|
{ -a } -> std::common_with<T>;
|
||||||
{ a - b } -> std::common_with<T>;
|
{ a + b } -> std::common_with<T>;
|
||||||
::mp_units::magnitude(a);
|
{ a - b } -> std::common_with<T>;
|
||||||
requires ScalableWith<T, decltype(::mp_units::magnitude(a))>;
|
::mp_units::magnitude(a);
|
||||||
// TODO should we also check for the below (e.g., when `size() > 1` or `2`)
|
requires ScalableWith<T, decltype(::mp_units::magnitude(a))>;
|
||||||
// ::mp_units::zero_vector<T>();
|
// TODO should we also check for the below (e.g., when `size() > 1` or `2`)
|
||||||
// ::mp_units::unit_vector(a);
|
// ::mp_units::zero_vector<T>();
|
||||||
// ::mp_units::scalar_product(a, b);
|
// ::mp_units::unit_vector(a);
|
||||||
// ::mp_units::vector_product(a, b);
|
// ::mp_units::scalar_product(a, b);
|
||||||
// ::mp_units::tensor_product(a, b);
|
// ::mp_units::vector_product(a, b);
|
||||||
} && WeaklyRegular<T>;
|
// ::mp_units::tensor_product(a, b);
|
||||||
|
}
|
||||||
|
#ifndef MP_UNITS_XCODE15_HACKS
|
||||||
|
&& WeaklyRegular<T>
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@ -313,42 +323,12 @@ concept Representation = detail::ScalarRepresentation<T> || detail::ComplexRepre
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
#ifdef MP_UNITS_APPLE_CLANG_HACKS
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_weakly_regular = std::copyable<T> && std::equality_comparable<T>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_scalar = !disable_scalar<T> && is_weakly_regular<T>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_complex = !disable_complex<T> && is_weakly_regular<T> && is_scalar<value_type_t<T>> &&
|
|
||||||
std::constructible_from<T, value_type_t<T>, value_type_t<T>>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
concept ComplexFunctionsAvailable = requires(T a) {
|
|
||||||
::mp_units::real(a);
|
|
||||||
::mp_units::imag(a);
|
|
||||||
::mp_units::modulus(a);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_vector = !disable_vector<T> && is_weakly_regular<T> && is_scalar<value_type_t<T>>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
concept VectorFunctionsAvailable = requires(T a) { ::mp_units::magnitude(a); };
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T, quantity_character Ch>
|
|
||||||
concept IsOfCharacter = ((Ch == quantity_character::scalar && is_scalar<T>) ||
|
|
||||||
(Ch == quantity_character::complex && is_complex<T> && ComplexFunctionsAvailable<T>) ||
|
|
||||||
(Ch == quantity_character::vector && is_vector<T> && VectorFunctionsAvailable<T>));
|
|
||||||
#else
|
|
||||||
template<typename T, quantity_character Ch>
|
template<typename T, quantity_character Ch>
|
||||||
concept IsOfCharacter =
|
concept IsOfCharacter =
|
||||||
(Ch == quantity_character::scalar && Scalar<T>) || (Ch == quantity_character::complex && Complex<T>) ||
|
(Ch == quantity_character::scalar && Scalar<T>) || (Ch == quantity_character::complex && Complex<T>) ||
|
||||||
(Ch == quantity_character::vector && Vector<T>); // || (Ch == quantity_character::tensor && Tensor<T>);
|
(Ch == quantity_character::vector && Vector<T>); // || (Ch == quantity_character::tensor && Tensor<T>);
|
||||||
#endif
|
|
||||||
} // namespace detail
|
}
|
||||||
|
|
||||||
MP_UNITS_EXPORT template<typename T, auto V>
|
MP_UNITS_EXPORT template<typename T, auto V>
|
||||||
concept RepresentationOf =
|
concept RepresentationOf =
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
#include <mp-units/bits/hacks.h>
|
|
||||||
#include <mp-units/systems/isq/space_and_time.h>
|
#include <mp-units/systems/isq/space_and_time.h>
|
||||||
#include <mp-units/systems/natural.h>
|
#include <mp-units/systems/natural.h>
|
||||||
#include <mp-units/systems/si.h>
|
#include <mp-units/systems/si.h>
|
||||||
@ -309,9 +308,7 @@ static_assert(!RepresentationOf<std::complex<double>, quantity_character::scalar
|
|||||||
static_assert(!RepresentationOf<std::complex<double>, quantity_character::vector>);
|
static_assert(!RepresentationOf<std::complex<double>, quantity_character::vector>);
|
||||||
static_assert(!RepresentationOf<std::complex<double>, quantity_character::tensor>);
|
static_assert(!RepresentationOf<std::complex<double>, quantity_character::tensor>);
|
||||||
static_assert(RepresentationOf<cartesian_vector<double>, quantity_character::vector>);
|
static_assert(RepresentationOf<cartesian_vector<double>, quantity_character::vector>);
|
||||||
#ifndef MP_UNITS_APPLE_CLANG_HACKS
|
|
||||||
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::scalar>);
|
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::scalar>);
|
||||||
#endif
|
|
||||||
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::complex>);
|
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::complex>);
|
||||||
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::tensor>);
|
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::tensor>);
|
||||||
static_assert(!RepresentationOf<std::chrono::seconds, quantity_character::scalar>);
|
static_assert(!RepresentationOf<std::chrono::seconds, quantity_character::scalar>);
|
||||||
|
@ -65,8 +65,6 @@ static_assert(sizeof(quantity<isq::length[m]>) == sizeof(double));
|
|||||||
static_assert(sizeof(quantity<si::metre, short>) == sizeof(short));
|
static_assert(sizeof(quantity<si::metre, short>) == sizeof(short));
|
||||||
static_assert(sizeof(quantity<isq::length[m], short>) == sizeof(short));
|
static_assert(sizeof(quantity<isq::length[m], short>) == sizeof(short));
|
||||||
|
|
||||||
#ifndef MP_UNITS_APPLE_CLANG_HACKS
|
|
||||||
|
|
||||||
template<template<auto, typename> typename Q>
|
template<template<auto, typename> typename Q>
|
||||||
concept invalid_types = requires {
|
concept invalid_types = requires {
|
||||||
requires !requires { typename Q<isq::dim_length, double>; }; // dimension instead of reference
|
requires !requires { typename Q<isq::dim_length, double>; }; // dimension instead of reference
|
||||||
@ -86,8 +84,6 @@ concept invalid_types = requires {
|
|||||||
};
|
};
|
||||||
static_assert(invalid_types<quantity>);
|
static_assert(invalid_types<quantity>);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static_assert(std::is_trivially_default_constructible_v<quantity<isq::length[m]>>);
|
static_assert(std::is_trivially_default_constructible_v<quantity<isq::length[m]>>);
|
||||||
static_assert(std::is_trivially_copy_constructible_v<quantity<isq::length[m]>>);
|
static_assert(std::is_trivially_copy_constructible_v<quantity<isq::length[m]>>);
|
||||||
static_assert(std::is_trivially_move_constructible_v<quantity<isq::length[m]>>);
|
static_assert(std::is_trivially_move_constructible_v<quantity<isq::length[m]>>);
|
||||||
|
Reference in New Issue
Block a user