fix: prefixed_alias_unit constraints fixed

This commit is contained in:
Mateusz Pusz
2022-08-03 11:29:20 +02:00
parent 0f37d0af60
commit 9aa3fd4d00
3 changed files with 25 additions and 7 deletions

View File

@@ -45,6 +45,11 @@ Concepts
A concept matching all unit types that have an atomic text symbol that can be used to aggregate it with A concept matching all unit types that have an atomic text symbol that can be used to aggregate it with
other named units to form a final symbol of a derived unit. other named units to form a final symbol of a derived unit.
.. concept:: template<typename T> AliasUnit
A concept matching all alias unit types in the library. Satisfied by all unit types derived
from the instantiation of :class:`alias_unit`.
.. concept:: template<typename U, typename D> UnitOf .. concept:: template<typename U, typename D> UnitOf
A concept matching only units of a specified dimension. Satisfied by all unit types that A concept matching only units of a specified dimension. Satisfied by all unit types that

View File

@@ -29,6 +29,7 @@
#include <units/bits/external/type_traits.h> #include <units/bits/external/type_traits.h>
#include <units/customization_points.h> #include <units/customization_points.h>
#include <units/magnitude.h> #include <units/magnitude.h>
#include <units/symbol_text.h>
// IWYU pragma: end_exports // IWYU pragma: end_exports
#include <cstdint> #include <cstdint>
@@ -86,6 +87,20 @@ inline constexpr bool is_named = false;
template<typename T> template<typename T>
concept NamedUnit = Unit<T> && detail::is_named<T>; concept NamedUnit = Unit<T> && detail::is_named<T>;
template<Unit U, basic_symbol_text Symbol>
struct alias_unit;
// TODO: Remove when P1985 accepted
namespace detail {
template<Unit U, basic_symbol_text Symbol>
void to_base_alias_unit(const volatile alias_unit<U, Symbol>*);
} // namespace detail
template<typename T>
concept AliasUnit = requires(T* t) { detail::to_base_alias_unit(t); };
// BaseDimension // BaseDimension
template<basic_fixed_string Symbol, NamedUnit U> template<basic_fixed_string Symbol, NamedUnit U>
struct base_dimension; struct base_dimension;

View File

@@ -58,8 +58,10 @@ inline constexpr bool can_be_prefixed = false;
* *
* @tparam M a Magnitude representing the (relative) size of this unit * @tparam M a Magnitude representing the (relative) size of this unit
* @tparam U a unit to use as a reference for this dimension * @tparam U a unit to use as a reference for this dimension
*
* @note U cannot be constrained with Unit as for some specializations (i.e. named_unit)
* it gets the incomplete child's type with the CRTP idiom.
*/ */
// TODO Replace `typename` with `Unit`
template<Magnitude auto M, typename U> template<Magnitude auto M, typename U>
struct scaled_unit : downcast_base<scaled_unit<M, U>> { struct scaled_unit : downcast_base<scaled_unit<M, U>> {
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M; static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M;
@@ -175,12 +177,8 @@ struct alias_unit : U {
* @tparam P prefix to be appied to the reference unit * @tparam P prefix to be appied to the reference unit
* @tparam AU reference alias unit * @tparam AU reference alias unit
*/ */
// TODO gcc bug: 95015 template<Unit U, Prefix P, AliasUnit AU>
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95015 requires(!AliasUnit<U>)
// template<Unit U, Prefix P, AliasUnit AU>
// requires (!AliasUnit<U>)
template<Unit U, Prefix P, NamedUnit AU>
requires detail::can_be_prefixed<AU>
struct prefixed_alias_unit : U { struct prefixed_alias_unit : U {
static constexpr auto symbol = P::symbol + AU::symbol; static constexpr auto symbol = P::symbol + AU::symbol;
}; };