refactor: 💥 ! PrefixFamily support removed
It doesn't have much sense to restrict prefixes usage for most units and in many places we were wrong to do so already.
This commit is contained in:
1 parent
725d193122
commit
32b36fb670
66 files changed
+221
-268
No files matched your search
@@ -37,25 +37,14 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
// PrefixFamily
|
||||
struct prefix_family;
|
||||
|
||||
/**
|
||||
* @brief A concept matching a prefix family
|
||||
*
|
||||
* Satisfied by all types derived from `prefix_family`
|
||||
*/
|
||||
template<typename T>
|
||||
concept PrefixFamily = std::derived_from<T, prefix_family>;
|
||||
|
||||
// Prefix
|
||||
namespace detail {
|
||||
|
||||
template<PrefixFamily PF, ratio R>
|
||||
template<ratio R>
|
||||
struct prefix_base;
|
||||
|
||||
template<PrefixFamily PF, ratio R>
|
||||
void to_prefix_base(const volatile prefix_base<PF, R>*);
|
||||
template<ratio R>
|
||||
void to_prefix_base(const volatile prefix_base<R>*);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -57,28 +57,19 @@ constexpr auto ratio_text()
|
||||
}
|
||||
}
|
||||
|
||||
template<ratio R, typename PrefixFamily, std::size_t SymbolLen>
|
||||
template<ratio R, std::size_t SymbolLen>
|
||||
constexpr auto prefix_or_ratio_text()
|
||||
{
|
||||
if constexpr (R.num == 1 && R.den == 1 && R.exp == 0) {
|
||||
// no ratio/prefix
|
||||
return basic_fixed_string("");
|
||||
} else {
|
||||
if constexpr (!is_same_v<PrefixFamily, no_prefix>) {
|
||||
// try to form a prefix
|
||||
using prefix = downcast<detail::prefix_base<PrefixFamily, R>>;
|
||||
// try to form a prefix
|
||||
using prefix = downcast<detail::prefix_base<R>>;
|
||||
|
||||
if constexpr (!is_same_v<prefix, prefix_base<PrefixFamily, R>>) {
|
||||
// print as a prefixed unit
|
||||
return prefix::symbol;
|
||||
} else {
|
||||
// print as a ratio of the coherent unit
|
||||
constexpr auto txt = ratio_text<R>();
|
||||
if constexpr (SymbolLen > 0 && txt.standard().size() > 0)
|
||||
return txt + basic_fixed_string(" ");
|
||||
else
|
||||
return txt;
|
||||
}
|
||||
if constexpr (!is_same_v<prefix, prefix_base<R>>) {
|
||||
// print as a prefixed unit
|
||||
return prefix::symbol;
|
||||
} else {
|
||||
// print as a ratio of the coherent unit
|
||||
constexpr auto txt = ratio_text<R>();
|
||||
@@ -151,15 +142,13 @@ constexpr auto unit_text()
|
||||
// use predefined coherent unit symbol
|
||||
constexpr auto symbol_text = coherent_unit::symbol;
|
||||
constexpr auto prefix_txt =
|
||||
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
|
||||
symbol_text.standard().size()>();
|
||||
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, symbol_text.standard().size()>();
|
||||
return prefix_txt + symbol_text;
|
||||
} else {
|
||||
// use derived dimension ingredients to create a unit symbol
|
||||
constexpr auto symbol_text = derived_dimension_unit_text<Dim>();
|
||||
constexpr auto prefix_txt =
|
||||
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
|
||||
symbol_text.standard().size()>();
|
||||
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, symbol_text.standard().size()>();
|
||||
return prefix_txt + symbol_text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
struct radian : named_unit<radian, "rad", isq::si::prefix> {};
|
||||
struct radian : named_unit<radian, "rad"> {};
|
||||
|
||||
template<Unit U = radian>
|
||||
struct dim_angle : base_dimension<"A", U> {};
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
struct one : named_unit<one, "", no_prefix> {};
|
||||
struct percent : named_scaled_unit<percent, "%", no_prefix, ratio(1, 100), one> {};
|
||||
struct one : named_unit<one, ""> {};
|
||||
struct percent : named_scaled_unit<percent, "%", ratio(1, 100), one> {};
|
||||
|
||||
/**
|
||||
* @brief Dimension one
|
||||
|
||||
@@ -31,26 +31,10 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
/**
|
||||
* @brief The base for all prefix families
|
||||
*
|
||||
* Every prefix family should inherit from this type to satisfy PrefixFamily concept.
|
||||
*/
|
||||
struct prefix_family {};
|
||||
|
||||
/**
|
||||
* @brief No prefix possible for the unit
|
||||
*
|
||||
* This is a special prefix type tag specifying that the unit can not be scaled with any kind
|
||||
* of the prefix.
|
||||
*/
|
||||
struct no_prefix : prefix_family {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<PrefixFamily PF, ratio R>
|
||||
struct prefix_base : downcast_base<prefix_base<PF, R>> {
|
||||
using prefix_family = PF;
|
||||
template<ratio R>
|
||||
struct prefix_base : downcast_base<prefix_base<R>> {
|
||||
static constexpr ::units::ratio ratio = R;
|
||||
};
|
||||
|
||||
@@ -63,17 +47,14 @@ struct prefix_base : downcast_base<prefix_base<PF, R>> {
|
||||
* - when defining a prefixed_unit its ratio is used to scale the reference unit and its
|
||||
* symbol is used to prepend to the symbol of referenced unit
|
||||
* - when printing the symbol of a scaled unit that was not predefined by the user but its
|
||||
* factor matches ratio of a prefix from the specified prefix family, its symbol will be
|
||||
* prepended to the symbol of the unit
|
||||
* factor matches ratio of a prefix, its symbol will be prepended to the symbol of the unit
|
||||
*
|
||||
* @tparam Child inherited class type used by the downcasting facility (CRTP Idiom)
|
||||
* @tparam PF a type of prefix family
|
||||
* @tparam Symbol a text representation of the prefix
|
||||
* @tparam R factor to be used to scale a unit
|
||||
*/
|
||||
template<typename Child, PrefixFamily PF, basic_symbol_text Symbol, ratio R>
|
||||
requires(!std::same_as<PF, no_prefix>)
|
||||
struct prefix : downcast_dispatch<Child, detail::prefix_base<PF, R>, downcast_mode::on> {
|
||||
template<typename Child, basic_symbol_text Symbol, ratio R>
|
||||
struct prefix : downcast_dispatch<Child, detail::prefix_base<R>, downcast_mode::on> {
|
||||
static constexpr auto symbol = Symbol;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename>
|
||||
inline constexpr bool can_be_prefixed = false;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief A common point for a hierarchy of units
|
||||
*
|
||||
@@ -69,39 +76,31 @@ struct same_unit_reference : is_same<typename U1::reference, typename U2::refere
|
||||
* @brief A named unit
|
||||
*
|
||||
* Defines a named (in most cases coherent) unit that is then passed to a dimension definition.
|
||||
* A named unit may be used by other units defined with the prefix of the same type, unless
|
||||
* no_prefix is provided for PF template parameter (in such a case it is impossible to define
|
||||
* a prefix unit based on this one).
|
||||
* A named unit may be composed with a prefix to create a prefixed_unit.
|
||||
*
|
||||
* @tparam Child inherited class type used by the downcasting facility (CRTP Idiom)
|
||||
* @tparam Symbol a short text representation of the unit
|
||||
* @tparam PF no_prefix or a type of prefix family
|
||||
*/
|
||||
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF>
|
||||
template<typename Child, basic_symbol_text Symbol>
|
||||
struct named_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
|
||||
static constexpr auto symbol = Symbol;
|
||||
using prefix_family = PF;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A scaled unit
|
||||
* @brief A named scaled unit
|
||||
*
|
||||
* Defines a new named unit that is a scaled version of another unit. Such unit can be used by
|
||||
* other units defined with the prefix of the same type, unless no_prefix is provided for PF
|
||||
* template parameter (in such a case it is impossible to define a prefix unit based on this
|
||||
* one).
|
||||
* Defines a new named unit that is a scaled version of another unit.
|
||||
* A named unit may be composed with a prefix to create a prefixed_unit.
|
||||
*
|
||||
* @tparam Child inherited class type used by the downcasting facility (CRTP Idiom)
|
||||
* @tparam Symbol a short text representation of the unit
|
||||
* @tparam PF no_prefix or a type of prefix family
|
||||
* @tparam R a scale to apply to U
|
||||
* @tparam U a reference unit to scale
|
||||
*/
|
||||
template<typename Child, basic_symbol_text Symbol, PrefixFamily PF, ratio R, Unit U>
|
||||
template<typename Child, basic_symbol_text Symbol, ratio R, Unit U>
|
||||
requires UnitRatio<R>
|
||||
struct named_scaled_unit : downcast_dispatch<Child, scaled_unit<R * U::ratio, typename U::reference>> {
|
||||
static constexpr auto symbol = Symbol;
|
||||
using prefix_family = PF;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -116,10 +115,9 @@ struct named_scaled_unit : downcast_dispatch<Child, scaled_unit<R * U::ratio, ty
|
||||
* @tparam U reference unit
|
||||
*/
|
||||
template<typename Child, Prefix P, NamedUnit U>
|
||||
requires std::same_as<typename P::prefix_family, typename U::prefix_family>
|
||||
requires detail::can_be_prefixed<U>
|
||||
struct prefixed_unit : downcast_dispatch<Child, scaled_unit<P::ratio * U::ratio, typename U::reference>> {
|
||||
static constexpr auto symbol = P::symbol + U::symbol;
|
||||
using prefix_family = no_prefix;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -131,9 +129,7 @@ struct prefixed_unit : downcast_dispatch<Child, scaled_unit<P::ratio * U::ratio,
|
||||
* @tparam Child inherited class type used by the downcasting facility (CRTP Idiom)
|
||||
*/
|
||||
template<typename Child>
|
||||
struct derived_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {
|
||||
using prefix_family = no_prefix;
|
||||
};
|
||||
struct derived_unit : downcast_dispatch<Child, scaled_unit<ratio(1), Child>> {};
|
||||
|
||||
/**
|
||||
* @brief A unit with a deduced ratio and symbol
|
||||
@@ -152,7 +148,6 @@ template<typename Child, DerivedDimension Dim, NamedUnit U, NamedUnit... URest>
|
||||
requires detail::same_scaled_units<typename Dim::recipe, U, URest...>
|
||||
struct derived_deduced_unit : downcast_dispatch<Child, detail::derived_deduced_unit<Dim, U, URest...>> {
|
||||
static constexpr auto symbol = detail::derived_symbol_text<Dim, U, URest...>();
|
||||
using prefix_family = no_prefix;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -160,18 +155,14 @@ struct derived_deduced_unit : downcast_dispatch<Child, detail::derived_deduced_u
|
||||
*
|
||||
* Defines a named alias for another unit. It is useful to assign alternative names and symbols
|
||||
* to the already predefined units (i.e. "tonne" for "megagram").
|
||||
* An alias unit may be used by other units defined with the prefix of the same type, unless
|
||||
* no_prefix is provided for PF template parameter (in such a case it is impossible to define
|
||||
* a prefix unit based on this one).
|
||||
* A alias unit may be composed with a prefix to create a prefixed_alias_unit.
|
||||
*
|
||||
* @tparam U Unit for which an alias is defined
|
||||
* @tparam Symbol a short text representation of the unit
|
||||
* @tparam PF no_prefix or a type of prefix family
|
||||
*/
|
||||
template<Unit U, basic_symbol_text Symbol, PrefixFamily PF>
|
||||
template<Unit U, basic_symbol_text Symbol>
|
||||
struct alias_unit : U {
|
||||
static constexpr auto symbol = Symbol;
|
||||
using prefix_family = PF;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -188,16 +179,15 @@ struct alias_unit : U {
|
||||
// TODO gcc bug: 95015
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95015
|
||||
// template<Unit U, Prefix P, AliasUnit AU>
|
||||
// requires (!AliasUnit<U>) && std::same_as<typename P::prefix_family, typename AU::prefix_family>
|
||||
// requires (!AliasUnit<U>)
|
||||
template<Unit U, Prefix P, NamedUnit AU>
|
||||
requires std::same_as<typename P::prefix_family, typename AU::prefix_family>
|
||||
requires detail::can_be_prefixed<AU>
|
||||
struct prefixed_alias_unit : U {
|
||||
static constexpr auto symbol = P::symbol + AU::symbol;
|
||||
using prefix_family = no_prefix;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Unknown unit
|
||||
* @brief Unknown coherent unit
|
||||
*
|
||||
* Used as a coherent unit of an unknown dimension.
|
||||
*/
|
||||
@@ -205,17 +195,17 @@ 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>
|
||||
void is_named_impl(const volatile named_unit<Child, Symbol>*);
|
||||
|
||||
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, basic_symbol_text Symbol, ratio R, typename U>
|
||||
void is_named_impl(const volatile named_scaled_unit<Child, Symbol, 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, basic_symbol_text Symbol>
|
||||
void is_named_impl(const volatile alias_unit<U, Symbol>*);
|
||||
|
||||
template<typename U, typename P, typename AU>
|
||||
void is_named_impl(const volatile prefixed_alias_unit<U, P, AU>*);
|
||||
@@ -223,6 +213,18 @@ 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); };
|
||||
|
||||
template<typename Child, basic_symbol_text Symbol>
|
||||
void can_be_prefixed_impl(const volatile named_unit<Child, Symbol>*);
|
||||
|
||||
template<typename Child, basic_symbol_text Symbol, ratio R, typename U>
|
||||
void can_be_prefixed_impl(const volatile named_scaled_unit<Child, Symbol, R, U>*);
|
||||
|
||||
template<typename U, basic_symbol_text Symbol>
|
||||
void can_be_prefixed_impl(const volatile alias_unit<U, Symbol>*);
|
||||
|
||||
template<Unit U>
|
||||
inline constexpr bool can_be_prefixed<U> = requires(U * u) { can_be_prefixed_impl(u); };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace units
|
||||
Reference in new issue
Block a user