feat: 💥 from now on dimnensions have to be marked as final

This commit is contained in:
Mateusz Pusz
2024-06-12 14:17:32 +02:00
parent 8977739692
commit 6aa848a456
15 changed files with 59 additions and 62 deletions
@@ -62,9 +62,9 @@ namespace mp_units {
* For example:
*
* @code{.cpp}
* inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
* inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
* inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
* inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
* inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
* inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
* @endcode
*
* @note A common convention in this library is to assign the same name for a type and an object of this type.
@@ -87,6 +87,9 @@ struct base_dimension_less : std::bool_constant<(Lhs::symbol < Rhs::symbol)> {};
template<typename T1, typename T2>
using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
template<detail::DerivedDimensionExpr... Expr>
struct derived_dimension_impl : detail::expr_fractions<detail::is_dimension_one, Expr...> {};
} // namespace detail
/**
@@ -132,7 +135,7 @@ using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
*/
template<detail::DerivedDimensionExpr... Expr>
struct derived_dimension : detail::expr_fractions<detail::is_dimension_one, Expr...> {};
struct derived_dimension final : detail::derived_dimension_impl<Expr...> {};
/**
* @brief Dimension one
@@ -141,7 +144,7 @@ struct derived_dimension : detail::expr_fractions<detail::is_dimension_one, Expr
* dimensions are zero. It is a dimension of a quantity of dimension one also known as
* "dimensionless".
*/
MP_UNITS_EXPORT inline constexpr struct dimension_one : derived_dimension<> {
MP_UNITS_EXPORT inline constexpr struct dimension_one final : detail::derived_dimension_impl<> {
} dimension_one;
namespace detail {
@@ -280,13 +283,13 @@ constexpr Out dimension_symbol_impl(Out out, const type_list<Nums...>& nums, con
}
template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
constexpr Out dimension_symbol_impl(Out out, const derived_dimension<Expr...>&, const dimension_symbol_formatting& fmt,
bool negative_power)
constexpr Out dimension_symbol_impl(Out out, const derived_dimension_impl<Expr...>&,
const dimension_symbol_formatting& fmt, bool negative_power)
{
(void)negative_power;
MP_UNITS_EXPECTS(negative_power == false);
return dimension_symbol_impl<CharT>(out, typename derived_dimension<Expr...>::_num_{},
typename derived_dimension<Expr...>::_den_{}, fmt);
return dimension_symbol_impl<CharT>(out, typename derived_dimension_impl<Expr...>::_num_{},
typename derived_dimension_impl<Expr...>::_den_{}, fmt);
}
@@ -42,20 +42,13 @@ template<typename T>
inline constexpr bool is_derived_from_specialization_of_base_dimension =
requires(T* t) { to_base_specialization_of_base_dimension(t); };
template<typename T>
inline constexpr bool is_specialization_of_base_dimension = false;
template<symbol_text Symbol>
inline constexpr bool is_specialization_of_base_dimension<base_dimension<Symbol>> = true;
/**
* @brief A concept matching all named base dimensions in the library.
*
* Satisfied by all dimension types derived from a specialization of `base_dimension`.
*/
template<typename T>
concept BaseDimension =
is_derived_from_specialization_of_base_dimension<T> && (!is_specialization_of_base_dimension<T>);
concept BaseDimension = is_derived_from_specialization_of_base_dimension<T> && std::is_final_v<T>;
template<typename T>
struct is_dimension_one : std::false_type {};
@@ -91,7 +84,8 @@ namespace detail {
* being the `dimension_one`.
*/
template<typename T>
concept DerivedDimension = is_specialization_of<T, derived_dimension> || is_dimension_one<T>::value;
concept DerivedDimension =
(is_specialization_of<T, derived_dimension> || is_dimension_one<T>::value) && std::is_final_v<T>;
} // namespace detail
@@ -199,9 +199,9 @@ MP_UNITS_EXPORT_END
* For example:
*
* @code{.cpp}
* inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
* inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
* inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
* inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
* inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
* inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
*
* inline constexpr struct length : quantity_spec<dim_length> {} length;
* inline constexpr struct mass : quantity_spec<dim_mass> {} mass;
@@ -34,7 +34,7 @@ MP_UNITS_EXPORT
namespace mp_units::angular {
// clang-format off
inline constexpr struct dim_angle : base_dimension<"A"> {} dim_angle;
inline constexpr struct dim_angle final : base_dimension<"A"> {} dim_angle;
QUANTITY_SPEC(angle, dim_angle);
QUANTITY_SPEC(solid_angle, pow<2>(angle));
@@ -36,7 +36,7 @@ namespace mp_units::iec80000 {
// dimensions of base quantities
// clang-format off
inline constexpr struct dim_traffic_intensity : base_dimension<"A"> {} dim_traffic_intensity;
inline constexpr struct dim_traffic_intensity final : base_dimension<"A"> {} dim_traffic_intensity;
// clang-format on
// quantities
@@ -35,13 +35,13 @@ namespace mp_units::isq {
// clang-format off
// dimensions of base quantities
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_electric_current : base_dimension<"I"> {} dim_electric_current;
inline constexpr struct dim_thermodynamic_temperature : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
inline constexpr struct dim_amount_of_substance : base_dimension<"N"> {} dim_amount_of_substance;
inline constexpr struct dim_luminous_intensity : base_dimension<"J"> {} dim_luminous_intensity;
inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_electric_current final : base_dimension<"I"> {} dim_electric_current;
inline constexpr struct dim_thermodynamic_temperature final : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
inline constexpr struct dim_amount_of_substance final : base_dimension<"N"> {} dim_amount_of_substance;
inline constexpr struct dim_luminous_intensity final : base_dimension<"J"> {} dim_luminous_intensity;
// clang-format on
// base quantities