Scalar concept extended

Scalar concept extended with types that are not constructible from and integral type
This commit is contained in:
Mateusz Pusz
2020-03-25 22:06:07 +01:00
parent c2b851c92b
commit 9fbf17be06
2 changed files with 32 additions and 6 deletions

View File

@@ -70,4 +70,11 @@ Concepts
.. concept:: template<typename T> Scalar
A concept matching non-Quantity types. Satisfied by types that satisfy :expr:`(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>`.
A concept matching non-Quantity types. Satisfied by types that match
:expr:`(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>` and satisfy one of the
following:
- if type :expr:`T` is constructible from ``std::int64_t`` (which is the type that stores
the elements of `ratio`), :expr:`T * T` and :expr:`T / T` must be valid,
- otherwise, :expr:`T * std::int64_t`, :expr:`std::int64_t * T`, and :expr:`T / std::int64_t`
must be valid.

View File

@@ -248,6 +248,29 @@ template<typename T>
concept WrappedQuantity = detail::is_wrapped_quantity<T>;
// Scalar
namespace detail {
template<typename T>
concept constructible_from_integral =
// construction from an integral type
std::constructible_from<T, std::int64_t> &&
// unit scaling
std::regular_invocable<std::multiplies<>, T, T> &&
std::regular_invocable<std::divides<>, T, T>;
template<typename T>
concept not_constructible_from_integral =
// not construction from an integral type
(!std::constructible_from<T, std::int64_t>) &&
// scaling by the value from ratio
std::regular_invocable<std::multiplies<>, T, std::int64_t> &&
std::regular_invocable<std::multiplies<>, std::int64_t, T>; // &&
// std::regular_invocable<std::divides<>, T, std::int64_t>; // TODO Uncomment when a bug in LA is fixed
} // namesapce detail
/**
* @brief A concept matching non-Quantity types.
*
@@ -258,10 +281,6 @@ concept Scalar =
(!Quantity<T>) &&
(!WrappedQuantity<T>) &&
std::regular<T> &&
// construction from an integral type
std::constructible_from<T, std::int64_t> &&
// unit scaling
std::regular_invocable<std::multiplies<>, T, T> &&
std::regular_invocable<std::divides<>, T, T>;
(detail::constructible_from_integral<T> || detail::not_constructible_from_integral<T>);
} // namespace units