diff --git a/docs/reference/core/concepts.rst b/docs/reference/core/concepts.rst index 2fd5e130..e835c0bd 100644 --- a/docs/reference/core/concepts.rst +++ b/docs/reference/core/concepts.rst @@ -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 other named units to form a final symbol of a derived unit. +.. concept:: template 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 UnitOf A concept matching only units of a specified dimension. Satisfied by all unit types that diff --git a/src/core/include/units/bits/basic_concepts.h b/src/core/include/units/bits/basic_concepts.h index 28776ab9..ac073b28 100644 --- a/src/core/include/units/bits/basic_concepts.h +++ b/src/core/include/units/bits/basic_concepts.h @@ -29,6 +29,7 @@ #include #include #include +#include // IWYU pragma: end_exports #include @@ -86,6 +87,20 @@ inline constexpr bool is_named = false; template concept NamedUnit = Unit && detail::is_named; +template +struct alias_unit; + +// TODO: Remove when P1985 accepted +namespace detail { + +template +void to_base_alias_unit(const volatile alias_unit*); + +} // namespace detail + +template +concept AliasUnit = requires(T* t) { detail::to_base_alias_unit(t); }; + // BaseDimension template struct base_dimension; diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index dbba2ecf..c388369c 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -58,8 +58,10 @@ inline constexpr bool can_be_prefixed = false; * * @tparam M a Magnitude representing the (relative) size of this unit * @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 struct scaled_unit : downcast_base> { 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 AU reference alias unit */ -// TODO gcc bug: 95015 -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95015 -// template -// requires (!AliasUnit) -template - requires detail::can_be_prefixed +template + requires(!AliasUnit) struct prefixed_alias_unit : U { static constexpr auto symbol = P::symbol + AU::symbol; };