fix: clang-17 specific compilation fixes (partially contributed by @JohelEGP)

This commit is contained in:
Mateusz Pusz
2023-06-16 14:54:22 +03:00
parent 5dcf87ac28
commit 7774466c1c
8 changed files with 29 additions and 23 deletions

View File

@@ -55,11 +55,11 @@ int main()
print_header(initial); print_header(initial);
state next = initial; state next = initial;
for (int index = 1; const auto& m : measurements) { for (int index = 1; const auto& v : measurements) {
const auto& previous = next; const auto& previous = next;
const auto gain = 1. / index * one; const auto gain = 1. / index * one;
const auto current = state_update(previous, m, gain); const auto current = state_update(previous, v, gain);
next = current; next = current;
print(index++, gain, m, current, next); print(index++, gain, v, current, next);
} }
} }

View File

@@ -194,7 +194,7 @@ template<MagnitudeSpec Element>
} }
template<MagnitudeSpec Element> template<MagnitudeSpec Element>
[[nodiscard]] consteval ratio get_exponent(Element) [[nodiscard]] CONSTEVAL ratio get_exponent(Element)
{ {
if constexpr (detail::is_specialization_of_power_v<Element>) if constexpr (detail::is_specialization_of_power_v<Element>)
return Element::exponent; return Element::exponent;

View File

@@ -39,7 +39,7 @@ void to_base_specialization_of_quantity(const volatile quantity<R, Rep>*);
template<typename T> template<typename T>
inline constexpr bool is_derived_from_specialization_of_quantity = inline constexpr bool is_derived_from_specialization_of_quantity =
requires(T* t) { to_base_specialization_of_quantity(t); }; requires(std::remove_reference_t<T>* t) { to_base_specialization_of_quantity(t); };
} // namespace detail } // namespace detail

View File

@@ -59,7 +59,8 @@ template<Quantity To, typename From>
// TODO how to constrain the second part here? // TODO how to constrain the second part here?
[[nodiscard]] constexpr Quantity auto sudo_cast(From&& q) [[nodiscard]] constexpr Quantity auto sudo_cast(From&& q)
{ {
if constexpr (std::remove_reference_t<From>::unit == To::unit) { constexpr auto q_unit = std::remove_reference_t<From>::unit;
if constexpr (q_unit == To::unit) {
// no scaling of the number needed // no scaling of the number needed
return make_quantity<To::reference>( return make_quantity<To::reference>(
static_cast<TYPENAME To::rep>(std::forward<From>(q).number())); // this is the only (and recommended) way to do static_cast<TYPENAME To::rep>(std::forward<From>(q).number())); // this is the only (and recommended) way to do
@@ -68,7 +69,7 @@ template<Quantity To, typename From>
// warnings on conversions // warnings on conversions
} else { } else {
// scale the number // scale the number
constexpr Magnitude auto c_mag = get_canonical_unit(q.unit).mag / get_canonical_unit(To::unit).mag; constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag;
constexpr Magnitude auto num = numerator(c_mag); constexpr Magnitude auto num = numerator(c_mag);
constexpr Magnitude auto den = denominator(c_mag); constexpr Magnitude auto den = denominator(c_mag);
constexpr Magnitude auto irr = c_mag * (den / num); constexpr Magnitude auto irr = c_mag * (den / num);

View File

@@ -42,7 +42,7 @@ namespace mp_units {
*/ */
template<Unit auto ToU, typename Q> template<Unit auto ToU, typename Q>
[[nodiscard]] constexpr Quantity auto value_cast(Q&& q) [[nodiscard]] constexpr Quantity auto value_cast(Q&& q)
requires Quantity<std::remove_cvref_t<Q>> && (convertible(q.reference, ToU)) requires Quantity<std::remove_cvref_t<Q>> && (convertible(std::remove_reference_t<Q>::reference, ToU))
{ {
using q_type = std::remove_reference_t<Q>; using q_type = std::remove_reference_t<Q>;
constexpr auto r = [] { constexpr auto r = [] {
@@ -71,7 +71,7 @@ template<Representation ToRep, typename Q>
std::constructible_from<ToRep, typename std::remove_reference_t<Q>::rep> std::constructible_from<ToRep, typename std::remove_reference_t<Q>::rep>
[[nodiscard]] constexpr quantity<std::remove_reference_t<Q>::reference, ToRep> value_cast(Q&& q) [[nodiscard]] constexpr quantity<std::remove_reference_t<Q>::reference, ToRep> value_cast(Q&& q)
{ {
return detail::sudo_cast<quantity<q.reference, ToRep>>(std::forward<Q>(q)); return detail::sudo_cast<quantity<std::remove_reference_t<Q>::reference, ToRep>>(std::forward<Q>(q));
} }
} // namespace mp_units } // namespace mp_units

View File

@@ -326,7 +326,7 @@ public:
private: private:
template<Reference auto R2, typename Rep2> template<Reference auto R2, typename Rep2>
requires quantity<R2, std::remove_cvref_t<Rep2>>::_rep_safe_constructible_ requires quantity<R2, std::remove_cvref_t<Rep2>>::_rep_safe_constructible_
friend constexpr quantity<R2, std::remove_cvref_t<Rep2>> make_quantity(Rep2&& v); friend constexpr quantity<R2, std::remove_cvref_t<Rep2>> make_quantity(Rep2&&);
template<typename Value> template<typename Value>
requires detail::RepSafeConstructibleFrom<rep, Value&&, unit> requires detail::RepSafeConstructibleFrom<rep, Value&&, unit>

View File

@@ -115,15 +115,15 @@ struct quantity_spec_interface {
return make_quantity<reference<self, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<self, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number());
} }
#else #else
template<UnitOf<Self{}> U> template<typename Self_ = Self, UnitOf<Self_{}> U>
[[nodiscard]] consteval Reference auto operator[](U u) const [[nodiscard]] consteval Reference auto operator[](U u) const
{ {
return reference<Self{}, u>{}; return reference<Self{}, u>{};
} }
template<typename Q> template<typename Q, typename Self_ = Self>
requires Quantity<std::remove_cvref_t<Q>> && requires Quantity<std::remove_cvref_t<Q>> &&
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number());
@@ -291,15 +291,15 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
static constexpr quantity_character character = detail::quantity_character_init<Args...>(QS.character); static constexpr quantity_character character = detail::quantity_character_init<Args...>(QS.character);
#ifndef __cpp_explicit_this_parameter #ifndef __cpp_explicit_this_parameter
template<UnitOf<Self{}> U> template<typename Self_ = Self, UnitOf<Self_{}> U>
[[nodiscard]] consteval Reference auto operator[](U u) const [[nodiscard]] consteval Reference auto operator[](U u) const
{ {
return reference<Self{}, u>{}; return reference<Self{}, u>{};
} }
template<typename Q> template<typename Q, typename Self_ = Self>
requires Quantity<std::remove_cvref_t<Q>> && requires Quantity<std::remove_cvref_t<Q>> &&
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number());
@@ -438,9 +438,6 @@ QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{});
* *
* Specifies that the provided `Q` should be treated as a quantity kind. * Specifies that the provided `Q` should be treated as a quantity kind.
*/ */
template<auto Q>
struct kind_of_;
namespace detail { namespace detail {
template<typename T> template<typename T>
@@ -448,13 +445,21 @@ concept QuantitySpecWithNoSpecifiers = detail::NamedQuantitySpec<T> || detail::I
} // namespace detail } // namespace detail
#ifdef __cpp_explicit_this_parameter
template<detail::QuantitySpecWithNoSpecifiers auto Q> template<detail::QuantitySpecWithNoSpecifiers auto Q>
requires(get_kind(Q) == Q) requires(get_kind(Q) == Q)
#ifdef __cpp_explicit_this_parameter
struct kind_of_<Q> : Q { struct kind_of_<Q> : Q {
static constexpr auto _quantity_spec_ = Q; static constexpr auto _quantity_spec_ = Q;
}; };
#else #else
#if UNITS_COMP_CLANG
template<auto Q>
requires detail::QuantitySpecWithNoSpecifiers<std::remove_cvref_t<decltype(Q)>> && (get_kind(Q) == Q)
#else
template<detail::QuantitySpecWithNoSpecifiers auto Q>
requires(get_kind(Q) == Q)
#endif
struct kind_of_<Q> : quantity_spec<kind_of_<Q>, Q> { struct kind_of_<Q> : quantity_spec<kind_of_<Q>, Q> {
static constexpr auto _quantity_spec_ = Q; static constexpr auto _quantity_spec_ = Q;
}; };
@@ -867,8 +872,8 @@ struct extract_results {
#if UNITS_COMP_CLANG #if UNITS_COMP_CLANG
template<typename... Ts> template<QuantitySpec From = struct dimensionless, QuantitySpec To = struct dimensionless, typename Elem = int>
extract_results(bool, Ts...) -> extract_results<Ts...>; extract_results(bool, From = {}, To = {}, prepend_rest = {}, Elem = {}) -> extract_results<From, To, Elem>;
#endif #endif

View File

@@ -850,7 +850,7 @@ static_assert(10 * isq::mechanical_energy[J] == 5 * isq::force[N] * (2 * isq::le
static_assert(1 * si::si2019::speed_of_light_in_vacuum == 299'792'458 * isq::speed[m / s]); static_assert(1 * si::si2019::speed_of_light_in_vacuum == 299'792'458 * isq::speed[m / s]);
// Different named dimensions // Different named dimensions
template<Reference auto R1, Reference auto R2> template</*Reference*/ auto R1, /*Reference*/ auto R2> // TODO Use `Reference` when Clang supports it.
concept invalid_comparison = !requires { 2 * R1 == 2 * R2; } && !requires { 2 * R2 == 2 * R1; }; concept invalid_comparison = !requires { 2 * R1 == 2 * R2; } && !requires { 2 * R2 == 2 * R1; };
static_assert(invalid_comparison<activity[Bq], isq::frequency[Hz]>); static_assert(invalid_comparison<activity[Bq], isq::frequency[Hz]>);