diff --git a/doc/DESIGN.md b/doc/DESIGN.md index 169e3197..535c6740 100644 --- a/doc/DESIGN.md +++ b/doc/DESIGN.md @@ -881,11 +881,16 @@ concept basic-arithmetic = // exposition only template concept Scalar = (!Quantity) && + (!WrappedQuantity) && std::regular && std::totally_ordered && basic-arithmetic; ``` +Where `WrappedQuantity` is a concept that applies `Quantity` recursively +on all nested types to check if `T` is not actually a wrapped quantity type (i.e. a vector or +matrix of quantities). + The above implies that the `Rep` type should provide at least: - default constructor, destructor, copy-constructor, and copy-assignment operator - `operator==(Rep, Rep)`, `operator!=(Rep, Rep)` @@ -893,7 +898,8 @@ The above implies that the `Rep` type should provide at least: - `operator-(Rep)` - `operator+(Rep, Rep)`, `operator-(Rep, Rep)`, `operator*(Rep, Rep)`, `operator*(Rep, Rep)` -Above also requires that the `Rep` should be implicitly convertible from integral types (i.e. `int`) so a proper implicit converting constructor should be provided. +Above also requires that the `Rep` should be implicitly convertible from integral types +(i.e. `int`) so a proper implicit converting constructor should be provided. Moreover, in most cases to observe expected behavior `Rep` will have to be registered as a floating-point representation type by specializing `units::treat_as_floating_point` type diff --git a/src/include/units/concepts.h b/src/include/units/concepts.h index 76f8c654..11714e22 100644 --- a/src/include/units/concepts.h +++ b/src/include/units/concepts.h @@ -180,8 +180,24 @@ inline constexpr bool is_quantity = false; template concept Quantity = detail::is_quantity; + +// WrappedQuantity +namespace detail { + +template +inline constexpr bool is_wrapped_quantity = false; + +template + requires requires { typename T::value_type; } +inline constexpr bool is_wrapped_quantity = Quantity || is_wrapped_quantity; + +} // namespace detail + +template +concept WrappedQuantity = detail::is_wrapped_quantity; + // Scalar template -concept Scalar = (!Quantity) && std::regular && std::totally_ordered && detail::basic_arithmetic; +concept Scalar = (!Quantity) && (!WrappedQuantity) && std::regular; // && std::totally_ordered;// && detail::basic_arithmetic; } // namespace units