refactor: 💥 ! U::is_named removed from the unit types and replaced with NamedUnit concept

This commit is contained in:
Mateusz Pusz
2022-05-11 11:49:14 +02:00
parent 0522bae972
commit 725d193122
4 changed files with 41 additions and 19 deletions

View File

@@ -50,8 +50,7 @@ namespace units {
* @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support
* @tparam U a base unit to be used for this base dimension * @tparam U a base unit to be used for this base dimension
*/ */
template<basic_fixed_string Symbol, Unit U> template<basic_fixed_string Symbol, NamedUnit U>
requires U::is_named
struct base_dimension { struct base_dimension {
static constexpr auto symbol = Symbol; ///< Unique base dimension identifier static constexpr auto symbol = Symbol; ///< Unique base dimension identifier
using base_unit = U; ///< Base unit adopted for this dimension using base_unit = U; ///< Base unit adopted for this dimension

View File

@@ -96,9 +96,18 @@ void to_base_scaled_unit(const volatile scaled_unit<R, U>*);
template<typename T> template<typename T>
concept Unit = requires(T* t) { detail::to_base_scaled_unit(t); }; concept Unit = requires(T* t) { detail::to_base_scaled_unit(t); };
namespace detail {
template<typename>
inline constexpr bool is_named = false;
}
template<typename T>
concept NamedUnit = Unit<T> && detail::is_named<T>;
// BaseDimension // BaseDimension
template<basic_fixed_string Symbol, Unit U> template<basic_fixed_string Symbol, NamedUnit U>
requires U::is_named
struct base_dimension; struct base_dimension;
namespace detail { namespace detail {

View File

@@ -110,7 +110,7 @@ template<Exponent Exp>
constexpr auto exponent_list_with_named_units(Exp) constexpr auto exponent_list_with_named_units(Exp)
{ {
using dim = TYPENAME Exp::dimension; using dim = TYPENAME Exp::dimension;
if constexpr (dimension_unit<dim>::is_named) { if constexpr (NamedUnit<dimension_unit<dim>>) {
return exponent_list<Exp>(); return exponent_list<Exp>();
} else { } else {
using recipe = TYPENAME dim::recipe; using recipe = TYPENAME dim::recipe;

View File

@@ -79,7 +79,6 @@ struct same_unit_reference : is_same<typename U1::reference, typename U2::refere
*/ */
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF> template<typename Child, basic_symbol_text Symbol, PrefixFamily PF>
struct named_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> { struct named_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
static constexpr bool is_named = true;
static constexpr auto symbol = Symbol; static constexpr auto symbol = Symbol;
using prefix_family = PF; using prefix_family = PF;
}; };
@@ -101,7 +100,6 @@ struct named_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF, ratio R, Unit U> template<typename Child, basic_symbol_text Symbol, PrefixFamily PF, ratio R, Unit U>
requires UnitRatio<R> requires UnitRatio<R>
struct named_scaled_unit : downcast_dispatch<Child, scaled_unit<R * U::ratio, typename U::reference>> { struct named_scaled_unit : downcast_dispatch<Child, scaled_unit<R * U::ratio, typename U::reference>> {
static constexpr bool is_named = true;
static constexpr auto symbol = Symbol; static constexpr auto symbol = Symbol;
using prefix_family = PF; using prefix_family = PF;
}; };
@@ -117,10 +115,9 @@ struct named_scaled_unit : downcast_dispatch<Child, scaled_unit<R * U::ratio, ty
* @tparam P prefix to be appied to the reference unit * @tparam P prefix to be appied to the reference unit
* @tparam U reference unit * @tparam U reference unit
*/ */
template<typename Child, Prefix P, Unit U> template<typename Child, Prefix P, NamedUnit U>
requires U::is_named && std::same_as<typename P::prefix_family, typename U::prefix_family> requires std::same_as<typename P::prefix_family, typename U::prefix_family>
struct prefixed_unit : downcast_dispatch<Child, scaled_unit<P::ratio * U::ratio, typename U::reference>> { struct prefixed_unit : downcast_dispatch<Child, scaled_unit<P::ratio * U::ratio, typename U::reference>> {
static constexpr bool is_named = true;
static constexpr auto symbol = P::symbol + U::symbol; static constexpr auto symbol = P::symbol + U::symbol;
using prefix_family = no_prefix; using prefix_family = no_prefix;
}; };
@@ -135,7 +132,6 @@ struct prefixed_unit : downcast_dispatch<Child, scaled_unit<P::ratio * U::ratio,
*/ */
template<typename Child> template<typename Child>
struct derived_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> { struct derived_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
static constexpr bool is_named = false;
using prefix_family = no_prefix; using prefix_family = no_prefix;
}; };
@@ -152,11 +148,9 @@ struct derived_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
* @tparam U the unit of the first composite dimension from provided derived dimension's recipe * @tparam U the unit of the first composite dimension from provided derived dimension's recipe
* @tparam URest the units for the rest of dimensions from the recipe * @tparam URest the units for the rest of dimensions from the recipe
*/ */
template<typename Child, DerivedDimension Dim, Unit U, Unit... URest> template<typename Child, DerivedDimension Dim, NamedUnit U, NamedUnit... URest>
requires detail::same_scaled_units<typename Dim::recipe, U, URest...> && requires detail::same_scaled_units<typename Dim::recipe, U, URest...>
(U::is_named && (URest::is_named && ... && true))
struct derived_deduced_unit : downcast_dispatch<Child, detail::derived_deduced_unit<Dim, U, URest...>> { struct derived_deduced_unit : downcast_dispatch<Child, detail::derived_deduced_unit<Dim, U, URest...>> {
static constexpr bool is_named = false;
static constexpr auto symbol = detail::derived_symbol_text<Dim, U, URest...>(); static constexpr auto symbol = detail::derived_symbol_text<Dim, U, URest...>();
using prefix_family = no_prefix; using prefix_family = no_prefix;
}; };
@@ -176,7 +170,6 @@ struct derived_deduced_unit : downcast_dispatch<Child, detail::derived_deduced_u
*/ */
template<Unit U, basic_symbol_text Symbol, PrefixFamily PF> template<Unit U, basic_symbol_text Symbol, PrefixFamily PF>
struct alias_unit : U { struct alias_unit : U {
static constexpr bool is_named = true;
static constexpr auto symbol = Symbol; static constexpr auto symbol = Symbol;
using prefix_family = PF; using prefix_family = PF;
}; };
@@ -196,10 +189,9 @@ struct alias_unit : U {
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95015 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95015
// template<Unit U, Prefix P, AliasUnit AU> // template<Unit U, Prefix P, AliasUnit AU>
// requires (!AliasUnit<U>) && std::same_as<typename P::prefix_family, typename AU::prefix_family> // requires (!AliasUnit<U>) && std::same_as<typename P::prefix_family, typename AU::prefix_family>
template<Unit U, Prefix P, Unit AU> template<Unit U, Prefix P, NamedUnit AU>
requires AU::is_named && std::same_as<typename P::prefix_family, typename AU::prefix_family> requires std::same_as<typename P::prefix_family, typename AU::prefix_family>
struct prefixed_alias_unit : U { struct prefixed_alias_unit : U {
static constexpr bool is_named = true;
static constexpr auto symbol = P::symbol + AU::symbol; static constexpr auto symbol = P::symbol + AU::symbol;
using prefix_family = no_prefix; using prefix_family = no_prefix;
}; };
@@ -211,4 +203,26 @@ struct prefixed_alias_unit : U {
*/ */
struct unknown_coherent_unit : derived_unit<unknown_coherent_unit> {}; struct unknown_coherent_unit : derived_unit<unknown_coherent_unit> {};
namespace detail {
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF>
void is_named_impl(const volatile named_unit<Child, Symbol, PF>*);
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF, ratio R, Unit U>
void is_named_impl(const volatile named_scaled_unit<Child, Symbol, PF, R, U>*);
template<typename Child, typename P, typename U>
void is_named_impl(const volatile prefixed_unit<Child, P, U>*);
template<Unit U, basic_symbol_text Symbol, PrefixFamily PF>
void is_named_impl(const volatile alias_unit<U, Symbol, PF>*);
template<typename U, typename P, typename AU>
void is_named_impl(const volatile prefixed_alias_unit<U, P, AU>*);
template<Unit U>
inline constexpr bool is_named<U> = requires(U * u) { is_named_impl(u); };
} // namespace detail
} // namespace units } // namespace units