refactor: Limited the equivalent trait usage

This commit is contained in:
Mateusz Pusz
2020-12-28 18:40:58 +01:00
parent c0197aec7d
commit 32391866be
3 changed files with 21 additions and 14 deletions

View File

@@ -33,24 +33,24 @@ template<typename T, typename U>
struct equivalent_impl : std::false_type {
};
template<typename T>
struct equivalent_impl<T, T> : std::true_type {
};
// units
template<Unit U1, Unit U2>
struct equivalent_impl<U1, U2> : std::disjunction<std::is_same<U1, U2>, std::is_base_of<U1, U2>, std::is_base_of<U2, U1>> {};
struct equivalent_impl<U1, U2> : std::is_base_of<U1, U2>, std::is_base_of<U2, U1> {};
// dimensions
template<BaseDimension D1, BaseDimension D2>
struct equivalent_base_dim :
std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
struct equivalent_impl<D1, D2> : std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
same_unit_reference<typename D1::base_unit, typename D2::base_unit>> {
};
template<BaseDimension D1, BaseDimension D2>
struct equivalent_impl<D1, D2> : std::disjunction<std::is_same<D1, D2>, equivalent_base_dim<D1, D2>> {
};
template<Exponent E1, Exponent E2>
struct equivalent_exp : std::false_type {
};
@@ -71,7 +71,7 @@ struct equivalent_derived_dim<derived_dimension_base<Es1...>, derived_dimension_
template<DerivedDimension D1, DerivedDimension D2>
struct equivalent_impl<D1, D2> :
std::disjunction<std::is_same<D1, D2>, std::is_base_of<D1, D2>, std::is_base_of<D2, D1>,
std::disjunction<std::is_base_of<D1, D2>, std::is_base_of<D2, D1>,
equivalent_derived_dim<downcast_base_t<D1>, downcast_base_t<D2>>> {
};
@@ -85,10 +85,9 @@ struct equivalent_unit : std::disjunction<equivalent_impl<U1, U2>,
template<typename Q1, typename Q2>
requires (Quantity<Q1> && Quantity<Q2>) || (QuantityPoint<Q1> && QuantityPoint<Q2>)
struct equivalent_impl<Q1, Q2> : std::disjunction<std::is_same<Q1, Q2>,
std::conjunction<equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension,
typename Q2::unit, typename Q2::dimension>>> {};
struct equivalent_impl<Q1, Q2> : std::conjunction<equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension,
typename Q2::unit, typename Q2::dimension>> {};
} // namespace detail

View File

@@ -133,7 +133,8 @@ public:
quantity(quantity&&) = default;
template<safe_convertible_to_<rep> Value>
explicit(!(equivalent<quantity, dimensionless<::units::one, rep>>)) constexpr quantity(const Value& v) : value_(static_cast<rep>(v)) {}
explicit(!(is_same_v<dimension, dim_one> && is_same_v<unit, ::units::one>))
constexpr quantity(const Value& v) : value_(static_cast<rep>(v)) {}
template<QuantityLike Q>
requires std::same_as<quantity, quantity_like_type<Q>>

View File

@@ -25,7 +25,14 @@
#include "units/bits/equivalent.h"
template<typename T, typename U>
inline constexpr bool compare_impl = UNITS_DOWNCAST_MODE != 0 ? std::is_same_v<T, U> : (std::is_same_v<T, U> || units::equivalent<T, U>);
inline constexpr bool compare_impl = false;
template<typename T>
inline constexpr bool compare_impl<T, T> = true;
template<typename T, typename U>
requires (UNITS_DOWNCAST_MODE == 0)
inline constexpr bool compare_impl<T, U> = units::equivalent<T, U>;
template<typename T, typename U>
inline constexpr bool compare = compare_impl<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;