PrefixType renamed to PrefixFamily + units hierarchy PNG fixed

This commit is contained in:
Mateusz Pusz
2020-03-19 14:44:56 +01:00
parent a9432b1407
commit 034f239f96
10 changed files with 146 additions and 68 deletions
+5 -5
View File
@@ -64,7 +64,7 @@ constexpr auto ratio_text()
}
}
template<typename Ratio, typename PrefixType>
template<typename Ratio, typename PrefixFamily>
constexpr auto prefix_or_ratio_text()
{
if constexpr(Ratio::num == 1 && Ratio::den == 1 && Ratio::exp == 0) {
@@ -72,11 +72,11 @@ constexpr auto prefix_or_ratio_text()
return basic_fixed_string("");
}
else {
if constexpr (!std::is_same_v<PrefixType, no_prefix>) {
if constexpr (!std::is_same_v<PrefixFamily, no_prefix>) {
// try to form a prefix
using prefix = downcast<detail::prefix_base<PrefixType, Ratio>>;
using prefix = downcast<detail::prefix_base<PrefixFamily, Ratio>>;
if constexpr(!std::is_same_v<prefix, prefix_base<PrefixType, Ratio>>) {
if constexpr(!std::is_same_v<prefix, prefix_base<PrefixFamily, Ratio>>) {
// print as a prefixed unit
return prefix::symbol;
}
@@ -149,7 +149,7 @@ constexpr auto unit_text()
// print as a prefix or ratio of a coherent unit
using coherent_unit = dimension_unit<Dim>;
using ratio = ratio_divide<typename U::ratio, typename coherent_unit::ratio>;
auto prefix_txt = prefix_or_ratio_text<ratio, typename U::reference::prefix_type>();
auto prefix_txt = prefix_or_ratio_text<ratio, typename U::reference::prefix_family>();
if constexpr(has_symbol<coherent_unit>) {
// use predefined coherent unit symbol
+76 -9
View File
@@ -42,11 +42,16 @@ concept basic_arithmetic = // exposition only
} // namespace detail
// PrefixType
struct prefix_type;
// PrefixFamily
struct prefix_family;
/**
* @brief A concept matching a prefix family
*
* Satisfied by all types derived from `prefix_family`
*/
template<typename T>
concept PrefixType = std::derived_from<T, prefix_type>;
concept PrefixFamily = std::derived_from<T, prefix_family>;
// Prefix
// TODO gcc:92150
@@ -56,11 +61,16 @@ concept PrefixType = std::derived_from<T, prefix_type>;
// template<typename T>
// inline constexpr bool is_prefix = false;
// template<typename PrefixType, Ratio R, basic_fixed_string Symbol>
// inline constexpr bool is_prefix<prefix<PrefixType, R, Symbol>> = true;
// template<typename PrefixFamily, Ratio R, basic_fixed_string Symbol>
// inline constexpr bool is_prefix<prefix<PrefixFamily, R, Symbol>> = true;
// } // namespace detail
/**
* @brief A concept matching a symbol prefix
*
* Satisfied by all instantiations of `prefix`.
*/
template<typename T>
// concept Prefix = detail::is_prefix<T>;
concept Prefix = true;
@@ -73,11 +83,19 @@ inline constexpr bool is_ratio = false;
} // namespace detail
/**
* @brief A concept matching a ratio
*
* Satisfied by all instantiations of `ratio`.
*/
template<typename T>
concept Ratio = detail::is_ratio<T>;
// UnitRatio
/**
* @brief A concept matching unit's ratio
*
* Satisfied by all types that satisfy `Ratio<R>` and for which `R::num > 0` and `R::den > 0`
*/
template<typename R>
concept UnitRatio = Ratio<R> && R::num > 0 && R::den > 0; // double negatives not allowed
@@ -85,10 +103,14 @@ concept UnitRatio = Ratio<R> && R::num > 0 && R::den > 0; // double negatives no
template<UnitRatio R, typename U>
struct scaled_unit;
/**
* @brief A concept matching all unit types in the library
*
* Satisfied by all unit types derived from the instantiation of :class:`scaled_unit`.
*/
template<typename T>
concept Unit = is_derived_from_instantiation<T, scaled_unit>;
// BaseDimension
template<basic_fixed_string Symbol, Unit U>
requires U::is_named
struct base_dimension;
@@ -112,6 +134,11 @@ inline constexpr bool is_base_dimension<base_dimension<Name, Params...>> = true;
} // namespace detail
/**
* @brief A concept matching all base dimensions in the library.
*
* Satisfied by all dimension types derived from the instantiation of `base_dimension`.
*/
template<typename T>
concept BaseDimension = detail::is_base_dimension<typename T::base_type_workaround>;
@@ -123,6 +150,11 @@ inline constexpr bool is_exp = false;
} // namespace detail
/**
* @brief A concept matching dimension's exponents.
*
* Satisfied by all instantiations of :class:`exp`.
*/
template<typename T>
concept Exponent = detail::is_exp<T>;
@@ -135,10 +167,20 @@ struct derived_dimension_base;
} // namespace detail
/**
* @brief A concept matching all derived dimensions in the library.
*
* Satisfied by all dimension types derived from the instantiation of `detail::derived_dimension_base`.
*/
template<typename T>
concept DerivedDimension = is_instantiation<downcast_base_t<T>, detail::derived_dimension_base>;
// Dimension
/**
* @brief A concept matching all dimensions in the library.
*
* Satisfied by all dimension types for which either `BaseDimension<T>` or `DerivedDimension<T>` is `true`.
*/
template<typename T>
concept Dimension = BaseDimension<T> || DerivedDimension<T>;
@@ -163,6 +205,15 @@ struct dimension_unit_impl<D> {
template<Dimension D>
using dimension_unit = detail::dimension_unit_impl<D>::type;
/**
* @brief A concept matching only units of a specified dimension.
*
* Satisfied by all unit types that satisfy `Unit<U>`, `Dimension<D>`, and for which
* `U::reference` and `dimension_unit<D>::reference` denote the same unit type.
*
* @tparam U Type to verify.
* @tparam D Dimension type to use for verification.
*/
template<typename U, typename D>
concept UnitOf =
Unit<U> &&
@@ -177,6 +228,11 @@ inline constexpr bool is_quantity = false;
} // namespace detail
/**
* @brief A concept matching all quantities in the library.
*
* Satisfied by all instantiations of :class:`quantity`.
*/
template<typename T>
concept Quantity = detail::is_quantity<T>;
@@ -193,11 +249,22 @@ inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::value_type>
} // namespace detail
/**
* @brief A concept matching types that wrap quantity objects.
*
* Satisfied by all wrapper types that satisfy `Quantity<typename T::value_type>`
* recursively (i.e. `std::optional<si::length<si::metre>>`).
*/
template<typename T>
concept WrappedQuantity = detail::is_wrapped_quantity<T>;
// Scalar
/**
* @brief A concept matching non-Quantity types.
*
* Satisfied by types that satisfy `(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>`.
*/
template<typename T>
concept Scalar = (!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>; // && std::totally_ordered<T>;// && detail::basic_arithmetic<T>;
concept Scalar = (!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>; // TODO: && std::totally_ordered<T>;// && detail::basic_arithmetic<T>;
} // namespace units
+1 -1
View File
@@ -26,7 +26,7 @@
namespace units::data {
struct prefix : prefix_type {};
struct prefix : prefix_family {};
struct kibi : units::prefix<kibi, prefix, "Ki", ratio< 1'024>> {};
struct mebi : units::prefix<mebi, prefix, "Mi", ratio< 1'048'576>> {};
+1 -1
View File
@@ -26,7 +26,7 @@
namespace units::si {
struct prefix : prefix_type {};
struct prefix : prefix_family {};
// clang-format off
struct yocto : units::prefix<yocto, prefix, "y", ratio<1, 1, -24>> {};
+7 -7
View File
@@ -29,11 +29,11 @@
namespace units {
/**
* @brief The base for all prefix types
* @brief The base for all prefix families
*
* Every prefix type should inherit from this type to satisfy PrefixType concept.
* Every prefix family should inherit from this type to satisfy PrefixFamily concept.
*/
struct prefix_type {};
struct prefix_family {};
/**
* @brief No prefix possible for the unit
@@ -41,13 +41,13 @@ struct prefix_type {};
* 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_type {};
struct no_prefix : prefix_family {};
namespace detail {
template<PrefixType PT, Ratio R>
template<PrefixFamily PT, Ratio R>
struct prefix_base : downcast_base<prefix_base<PT, R>> {
using prefix_type = PT;
using prefix_family = PT;
using ratio = R;
};
@@ -68,7 +68,7 @@ struct prefix_base : downcast_base<prefix_base<PT, R>> {
* @tparam Symbol a text representation of the prefix
* @tparam R factor to be used to scale a unit
*/
template<typename Child, PrefixType PT, basic_fixed_string Symbol, Ratio R>
template<typename Child, PrefixFamily PT, basic_fixed_string Symbol, Ratio R>
requires (!std::same_as<PT, no_prefix>)
struct prefix : downcast_child<Child, detail::prefix_base<PT, R>> {
static constexpr auto symbol = Symbol;
+10 -10
View File
@@ -72,7 +72,7 @@ struct same_unit_reference : std::is_same<typename U1::reference, typename U2::r
template<typename Child>
struct unit : downcast_child<Child, scaled_unit<ratio<1>, Child>> {
static constexpr bool is_named = false;
using prefix_type = no_prefix;
using prefix_family = no_prefix;
};
/**
@@ -94,11 +94,11 @@ struct unknown_coherent_unit : unit<unknown_coherent_unit> {};
* @tparam Symbol a short text representation of the unit
* @tparam PT no_prefix or a type of prefix family
*/
template<typename Child, basic_fixed_string Symbol, PrefixType PT>
template<typename Child, basic_fixed_string Symbol, PrefixFamily PT>
struct named_unit : downcast_child<Child, scaled_unit<ratio<1>, Child>> {
static constexpr bool is_named = true;
static constexpr auto symbol = Symbol;
using prefix_type = PT;
using prefix_family = PT;
};
/**
@@ -115,11 +115,11 @@ struct named_unit : downcast_child<Child, scaled_unit<ratio<1>, Child>> {
* @tparam R a scale to apply to U
* @tparam U a reference unit to scale
*/
template<typename Child, basic_fixed_string Symbol, PrefixType PT, UnitRatio R, Unit U>
template<typename Child, basic_fixed_string Symbol, PrefixFamily PT, UnitRatio R, Unit U>
struct named_scaled_unit : downcast_child<Child, scaled_unit<ratio_multiply<R, typename U::ratio>, typename U::reference>> {
static constexpr bool is_named = true;
static constexpr auto symbol = Symbol;
using prefix_type = PT;
using prefix_family = PT;
};
/**
@@ -134,12 +134,12 @@ struct named_scaled_unit : downcast_child<Child, scaled_unit<ratio_multiply<R, t
* @tparam U reference unit
*/
template<typename Child, Prefix P, Unit U>
requires U::is_named && std::same_as<typename P::prefix_type, typename U::prefix_type>
requires U::is_named && std::same_as<typename P::prefix_family, typename U::prefix_family>
struct prefixed_unit :
downcast_child<Child, scaled_unit<ratio_multiply<typename P::ratio, typename U::ratio>, typename U::reference>> {
static constexpr bool is_named = true;
static constexpr auto symbol = P::symbol + U::symbol;
using prefix_type = no_prefix;
using prefix_family = no_prefix;
};
/**
@@ -161,14 +161,14 @@ template<typename Child, DerivedDimension Dim, Unit U, Unit... URest>
struct deduced_unit : downcast_child<Child, detail::deduced_unit<Dim, U, URest...>> {
static constexpr bool is_named = false;
static constexpr auto symbol = detail::deduced_symbol_text<Dim, U, URest...>();
using prefix_type = no_prefix;
using prefix_family = no_prefix;
};
// template<typename Child, Dimension Dim, basic_fixed_string Symbol, PrefixType PT, Unit U, Unit... Us>
// template<typename Child, Dimension Dim, basic_fixed_string Symbol, PrefixFamily PT, Unit U, Unit... Us>
// struct named_deduced_derived_unit : downcast_child<Child, detail::deduced_derived_unit<Dim, U, Us...>> {
// static constexpr bool is_named = true;
// static constexpr auto symbol = Symbol;
// using prefix_type = PT;
// using prefix_family = PT;
// };
} // namespace units