mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-02 11:54:27 +02:00
feat: interoperability with other libraries redesigned
This commit is contained in:
@@ -427,7 +427,12 @@ for which an instantiation of `quantity_like_traits` type trait yields a valid t
|
|||||||
- Static data member `reference` that matches the [`Reference`](#Reference) concept,
|
- Static data member `reference` that matches the [`Reference`](#Reference) concept,
|
||||||
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
|
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
|
||||||
in `reference`,
|
in `reference`,
|
||||||
- `value(T)` static member function returning a raw value of the quantity.
|
- `to_numerical_value(T)` static member function returning a raw value of the quantity packed in
|
||||||
|
either `convert_explicitly` or `convert_implicitly` wrapper that enables implicit conversion in
|
||||||
|
the latter case,
|
||||||
|
- `from_numerical_value(rep)` static member function returning `T` packed in either `convert_explicitly`
|
||||||
|
or `convert_implicitly` wrapper that enables implicit conversion in the latter case.
|
||||||
|
|
||||||
|
|
||||||
??? abstract "Examples"
|
??? abstract "Examples"
|
||||||
|
|
||||||
@@ -438,10 +443,20 @@ for which an instantiation of `quantity_like_traits` type trait yields a valid t
|
|||||||
struct mp_units::quantity_like_traits<std::chrono::seconds> {
|
struct mp_units::quantity_like_traits<std::chrono::seconds> {
|
||||||
static constexpr auto reference = si::second;
|
static constexpr auto reference = si::second;
|
||||||
using rep = std::chrono::seconds::rep;
|
using rep = std::chrono::seconds::rep;
|
||||||
[[nodiscard]] static constexpr rep value(const std::chrono::seconds& q) { return q.count(); }
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<rep> to_numerical_value(const std::chrono::seconds& q)
|
||||||
|
{
|
||||||
|
return q.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<std::chrono::seconds> from_numerical_value(const rep& v)
|
||||||
|
{
|
||||||
|
return std::chrono::seconds(v);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quantity q(42s);
|
quantity q = 42s;
|
||||||
|
std::chrono::seconds dur = 42 * s;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -454,8 +469,13 @@ for which an instantiation of `quantity_point_like_traits` type trait yields a v
|
|||||||
- Static data member `point_origin` that matches the [`PointOrigin`](#PointOrigin) concept
|
- Static data member `point_origin` that matches the [`PointOrigin`](#PointOrigin) concept
|
||||||
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
|
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
|
||||||
in `reference`
|
in `reference`
|
||||||
- `quantity_from_origin(T)` static member function returning the `quantity` being the offset of the point
|
- `to_quantity(T)` static member function returning the `quantity` being the offset of the point
|
||||||
from the origin
|
from the origin packed in either `convert_explicitly` or `convert_implicitly` wrapper that enables
|
||||||
|
implicit conversion in the latter case,
|
||||||
|
- `from_quantity(quantity<reference, rep>)` static member function returning `T` packed in either
|
||||||
|
`convert_explicitly` or `convert_implicitly` wrapper that enables implicit conversion in the latter
|
||||||
|
case.
|
||||||
|
|
||||||
|
|
||||||
??? abstract "Examples"
|
??? abstract "Examples"
|
||||||
|
|
||||||
@@ -464,14 +484,22 @@ for which an instantiation of `quantity_point_like_traits` type trait yields a v
|
|||||||
```cpp
|
```cpp
|
||||||
template<typename C>
|
template<typename C>
|
||||||
struct mp_units::quantity_point_like_traits<std::chrono::time_point<C, std::chrono::seconds>> {
|
struct mp_units::quantity_point_like_traits<std::chrono::time_point<C, std::chrono::seconds>> {
|
||||||
|
using T = std::chrono::time_point<C, std::chrono::seconds>;
|
||||||
static constexpr auto reference = si::second;
|
static constexpr auto reference = si::second;
|
||||||
static constexpr auto point_origin = chrono_point_origin;
|
static constexpr struct point_origin : absolute_point_origin<isq::time> {} point_origin{};
|
||||||
using rep = std::chrono::seconds::rep;
|
using rep = std::chrono::seconds::rep;
|
||||||
[[nodiscard]] static constexpr auto quantity_from_origin(const std::chrono::time_point<C, std::chrono::seconds>& qp)
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<quantity<reference, rep>> to_quantity(const T& qp)
|
||||||
{
|
{
|
||||||
return quantity{std::chrono::duration_cast<std::chrono::seconds>(qp.time_since_epoch())};
|
return quantity{qp.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<T> from_quantity(const quantity<reference, rep>& q)
|
||||||
|
{
|
||||||
|
return T(q);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quantity_point qp(time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()));
|
quantity_point qp = time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now());
|
||||||
|
std::chrono::sys_seconds q = qp + 42 * s;
|
||||||
```
|
```
|
||||||
|
@@ -74,15 +74,19 @@ concept QuantityOf = Quantity<Q> && ReferenceOf<std::remove_const_t<decltype(Q::
|
|||||||
* all quantity-specific information.
|
* all quantity-specific information.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept QuantityLike = requires(T q) {
|
concept QuantityLike = requires {
|
||||||
quantity_like_traits<T>::reference;
|
quantity_like_traits<T>::reference;
|
||||||
requires Reference<std::remove_const_t<decltype(quantity_like_traits<T>::reference)>>;
|
requires Reference<std::remove_const_t<decltype(quantity_like_traits<T>::reference)>>;
|
||||||
typename quantity_like_traits<T>::rep;
|
typename quantity_like_traits<T>::rep;
|
||||||
requires RepresentationOf<typename quantity_like_traits<T>::rep,
|
requires RepresentationOf<typename quantity_like_traits<T>::rep,
|
||||||
get_quantity_spec(quantity_like_traits<T>::reference).character>;
|
get_quantity_spec(quantity_like_traits<T>::reference).character>;
|
||||||
|
} && requires(T q, typename quantity_like_traits<T>::rep v) {
|
||||||
{
|
{
|
||||||
make_quantity<quantity_like_traits<T>::reference>(quantity_like_traits<T>::value(q))
|
quantity_like_traits<T>::to_numerical_value(q)
|
||||||
} -> std::same_as<quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>>;
|
} -> detail::ConversionSpecOf<typename quantity_like_traits<T>::rep>;
|
||||||
|
{
|
||||||
|
quantity_like_traits<T>::from_numerical_value(v)
|
||||||
|
} -> detail::ConversionSpecOf<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mp_units
|
} // namespace mp_units
|
||||||
|
@@ -173,7 +173,7 @@ concept QuantityPointOf =
|
|||||||
* all quantity_point-specific information.
|
* all quantity_point-specific information.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept QuantityPointLike = requires(T qp) {
|
concept QuantityPointLike = requires {
|
||||||
quantity_point_like_traits<T>::reference;
|
quantity_point_like_traits<T>::reference;
|
||||||
requires Reference<std::remove_const_t<decltype(quantity_point_like_traits<T>::reference)>>;
|
requires Reference<std::remove_const_t<decltype(quantity_point_like_traits<T>::reference)>>;
|
||||||
quantity_point_like_traits<T>::point_origin;
|
quantity_point_like_traits<T>::point_origin;
|
||||||
@@ -181,13 +181,15 @@ concept QuantityPointLike = requires(T qp) {
|
|||||||
typename quantity_point_like_traits<T>::rep;
|
typename quantity_point_like_traits<T>::rep;
|
||||||
requires RepresentationOf<typename quantity_point_like_traits<T>::rep,
|
requires RepresentationOf<typename quantity_point_like_traits<T>::rep,
|
||||||
get_quantity_spec(quantity_point_like_traits<T>::reference).character>;
|
get_quantity_spec(quantity_point_like_traits<T>::reference).character>;
|
||||||
requires Quantity<std::remove_cvref_t<decltype(quantity_point_like_traits<T>::quantity_from_origin(qp))>>;
|
} && requires(T qp, quantity<quantity_point_like_traits<T>::reference, typename quantity_point_like_traits<T>::rep> q) {
|
||||||
{
|
{
|
||||||
make_quantity_point<quantity_point_like_traits<T>::point_origin>(
|
quantity_point_like_traits<T>::to_quantity(qp)
|
||||||
quantity_point_like_traits<T>::quantity_from_origin(qp))
|
} -> detail::ConversionSpecOf<
|
||||||
}
|
quantity<quantity_point_like_traits<T>::reference, typename quantity_point_like_traits<T>::rep>>;
|
||||||
-> std::same_as<quantity_point<quantity_point_like_traits<T>::reference, quantity_point_like_traits<T>::point_origin,
|
|
||||||
typename quantity_point_like_traits<T>::rep>>;
|
{
|
||||||
|
quantity_point_like_traits<T>::from_quantity(q)
|
||||||
|
} -> detail::ConversionSpecOf<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mp_units
|
} // namespace mp_units
|
||||||
|
@@ -132,11 +132,42 @@ struct quantity_values {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct convert_explicitly {
|
||||||
|
using value_type = T;
|
||||||
|
T value;
|
||||||
|
constexpr explicit(false) convert_explicitly(T v) noexcept(std::is_nothrow_constructible_v<T>) : value(std::move(v))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct convert_implicitly {
|
||||||
|
using value_type = T;
|
||||||
|
T value;
|
||||||
|
constexpr explicit(false) convert_implicitly(T v) noexcept(std::is_nothrow_constructible_v<T>) : value(std::move(v))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept ConversionSpec = is_specialization_of<T, convert_explicitly> || is_specialization_of<T, convert_implicitly>;
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
concept ConversionSpecOf = ConversionSpec<T> && std::same_as<typename T::value_type, U>;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Provides support for external quantity-like types
|
* @brief Provides support for external quantity-like types
|
||||||
*
|
*
|
||||||
* The type trait should provide the @c reference object, a type alias @c rep,
|
* The type trait should provide the @c reference object, a type alias @c rep,
|
||||||
* and a static member function @c value(T) that returns the raw value of the quantity.
|
* and static member functions @c to_numerical_value(T) that returns the raw value
|
||||||
|
* of the quantity and @c from_numerical_value(rep) that returns @c T from @c rep.
|
||||||
|
* Both return types should be encapsulated in either @c convert_explicitly or
|
||||||
|
* @c convert_implicitly to specify if the conversion is allowed to happen implicitly.
|
||||||
*
|
*
|
||||||
* Usage example can be found in @c units/chrono.h header file.
|
* Usage example can be found in @c units/chrono.h header file.
|
||||||
*
|
*
|
||||||
@@ -149,8 +180,11 @@ struct quantity_like_traits;
|
|||||||
* @brief Provides support for external quantity point-like types
|
* @brief Provides support for external quantity point-like types
|
||||||
*
|
*
|
||||||
* The type trait should provide nested @c reference and @c origin objects,
|
* The type trait should provide nested @c reference and @c origin objects,
|
||||||
* a type alias @c rep, and a static member function @c quantity_from_origin(T) that will
|
* a type alias @c rep, and static member functions @c to_quantity(T) that returns
|
||||||
* return the quantity being the offset of the point from the origin.
|
* the quantity being the offset of the point from the origin and
|
||||||
|
* @c from_quantity(quantity<reference, rep>) that returns @c T form this quantity.
|
||||||
|
* Both return types should be encapsulated in either @c convert_explicitly or
|
||||||
|
* @c convert_implicitly to specify if the conversion is allowed to happen implicitly.
|
||||||
*
|
*
|
||||||
* Usage example can be found in @c units/chrono.h header file.
|
* Usage example can be found in @c units/chrono.h header file.
|
||||||
*
|
*
|
||||||
|
@@ -133,8 +133,10 @@ public:
|
|||||||
template<QuantityLike Q>
|
template<QuantityLike Q>
|
||||||
requires detail::QuantityConvertibleTo<
|
requires detail::QuantityConvertibleTo<
|
||||||
quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>, quantity>
|
quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>, quantity>
|
||||||
constexpr explicit quantity(const Q& q) :
|
constexpr explicit(
|
||||||
quantity(make_quantity<quantity_like_traits<Q>::reference>(quantity_like_traits<Q>::value(q)))
|
is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())), convert_explicitly>)
|
||||||
|
quantity(const Q& q) :
|
||||||
|
quantity(make_quantity<quantity_like_traits<Q>::reference>(quantity_like_traits<Q>::to_numerical_value(q).value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +191,25 @@ public:
|
|||||||
return (*this).force_in(U{}).numerical_value_;
|
return (*this).force_in(U{}).numerical_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// conversion operators
|
||||||
|
template<QuantityLike Q>
|
||||||
|
[[nodiscard]] explicit(is_specialization_of<decltype(quantity_like_traits<Q>::from_numerical_value(numerical_value_)),
|
||||||
|
convert_explicitly>) constexpr
|
||||||
|
operator Q() const& noexcept(noexcept(quantity_like_traits<Q>::from_numerical_value(numerical_value_)) &&
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return quantity_like_traits<Q>::from_numerical_value(numerical_value_).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<QuantityLike Q>
|
||||||
|
[[nodiscard]] explicit(is_specialization_of<decltype(quantity_like_traits<Q>::from_numerical_value(numerical_value_)),
|
||||||
|
convert_explicitly>) constexpr
|
||||||
|
operator Q() const&& noexcept(noexcept(quantity_like_traits<Q>::from_numerical_value(numerical_value_)) &&
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return quantity_like_traits<Q>::from_numerical_value(std::move(numerical_value_)).value;
|
||||||
|
}
|
||||||
|
|
||||||
// member unary operators
|
// member unary operators
|
||||||
[[nodiscard]] constexpr Quantity auto operator+() const
|
[[nodiscard]] constexpr Quantity auto operator+() const
|
||||||
requires requires(rep v) {
|
requires requires(rep v) {
|
||||||
@@ -365,7 +386,9 @@ private:
|
|||||||
|
|
||||||
// CTAD
|
// CTAD
|
||||||
template<QuantityLike Q>
|
template<QuantityLike Q>
|
||||||
explicit quantity(Q) -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>;
|
explicit(
|
||||||
|
is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())), convert_explicitly>)
|
||||||
|
quantity(Q) -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>;
|
||||||
|
|
||||||
// binary operators on quantities
|
// binary operators on quantities
|
||||||
template<auto R1, typename Rep1, auto R2, typename Rep2>
|
template<auto R1, typename Rep1, auto R2, typename Rep2>
|
||||||
|
@@ -128,8 +128,10 @@ public:
|
|||||||
std::convertible_to<
|
std::convertible_to<
|
||||||
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>,
|
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>,
|
||||||
quantity_type>
|
quantity_type>
|
||||||
constexpr explicit quantity_point(const QP& qp) :
|
constexpr explicit(
|
||||||
quantity_from_origin_(quantity_point_like_traits<QP>::quantity_from_origin(qp))
|
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())), convert_explicitly>)
|
||||||
|
quantity_point(const QP& qp) :
|
||||||
|
quantity_from_origin_(quantity_point_like_traits<QP>::to_quantity(qp).value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +184,27 @@ public:
|
|||||||
return make_quantity_point<PO>(quantity_ref_from(PO).force_in(U{}));
|
return make_quantity_point<PO>(quantity_ref_from(PO).force_in(U{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// conversion operators
|
||||||
|
template<QuantityPointLike QP>
|
||||||
|
[[nodiscard]] explicit(
|
||||||
|
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
|
||||||
|
convert_explicitly>) constexpr
|
||||||
|
operator QP() const& noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<QuantityPointLike QP>
|
||||||
|
[[nodiscard]] explicit(
|
||||||
|
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
|
||||||
|
convert_explicitly>) constexpr
|
||||||
|
operator QP() const&& noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_)).value;
|
||||||
|
}
|
||||||
|
|
||||||
// member unary operators
|
// member unary operators
|
||||||
template<typename QP>
|
template<typename QP>
|
||||||
friend constexpr decltype(auto) operator++(QP&& qp)
|
friend constexpr decltype(auto) operator++(QP&& qp)
|
||||||
@@ -249,7 +272,9 @@ private:
|
|||||||
|
|
||||||
// CTAD
|
// CTAD
|
||||||
template<QuantityPointLike QP>
|
template<QuantityPointLike QP>
|
||||||
explicit quantity_point(QP)
|
explicit(
|
||||||
|
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())), convert_explicitly>)
|
||||||
|
quantity_point(QP)
|
||||||
-> quantity_point<quantity_point_like_traits<QP>::reference, quantity_point_like_traits<QP>::point_origin,
|
-> quantity_point<quantity_point_like_traits<QP>::reference, quantity_point_like_traits<QP>::point_origin,
|
||||||
typename quantity_point_like_traits<QP>::rep>;
|
typename quantity_point_like_traits<QP>::rep>;
|
||||||
|
|
||||||
|
@@ -64,7 +64,18 @@ template<typename Rep, typename Period>
|
|||||||
struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
|
struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
|
||||||
static constexpr auto reference = detail::time_unit_from_chrono_period<Period>();
|
static constexpr auto reference = detail::time_unit_from_chrono_period<Period>();
|
||||||
using rep = Rep;
|
using rep = Rep;
|
||||||
[[nodiscard]] static constexpr rep value(const std::chrono::duration<Rep, Period>& q) { return q.count(); }
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<rep> to_numerical_value(
|
||||||
|
const std::chrono::duration<Rep, Period>& q) noexcept(std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return q.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<std::chrono::duration<Rep, Period>> from_numerical_value(
|
||||||
|
const rep& v) noexcept(std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return std::chrono::duration<Rep, Period>(v);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename C>
|
template<typename C>
|
||||||
@@ -77,14 +88,22 @@ inline constexpr chrono_point_origin_<C> chrono_point_origin;
|
|||||||
|
|
||||||
template<typename C, typename Rep, typename Period>
|
template<typename C, typename Rep, typename Period>
|
||||||
struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::duration<Rep, Period>>> {
|
struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::duration<Rep, Period>>> {
|
||||||
|
using T = std::chrono::time_point<C, std::chrono::duration<Rep, Period>>;
|
||||||
static constexpr auto reference = detail::time_unit_from_chrono_period<Period>();
|
static constexpr auto reference = detail::time_unit_from_chrono_period<Period>();
|
||||||
static constexpr auto point_origin = chrono_point_origin<C>;
|
static constexpr auto point_origin = chrono_point_origin<C>;
|
||||||
using rep = Rep;
|
using rep = Rep;
|
||||||
[[nodiscard]] static constexpr quantity<reference, rep> quantity_from_origin(
|
|
||||||
const std::chrono::time_point<C, std::chrono::duration<Rep, Period>>& qp)
|
[[nodiscard]] static constexpr convert_implicitly<quantity<reference, rep>> to_quantity(const T& qp) noexcept(
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
{
|
{
|
||||||
return quantity{qp.time_since_epoch()};
|
return quantity{qp.time_since_epoch()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static constexpr convert_implicitly<T> from_quantity(const quantity<reference, rep>& q) noexcept(
|
||||||
|
std::is_nothrow_copy_constructible_v<rep>)
|
||||||
|
{
|
||||||
|
return T(q);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<QuantityOf<isq::time> Q>
|
template<QuantityOf<isq::time> Q>
|
||||||
@@ -92,7 +111,7 @@ template<QuantityOf<isq::time> Q>
|
|||||||
{
|
{
|
||||||
constexpr auto canonical = detail::get_canonical_unit(Q::unit);
|
constexpr auto canonical = detail::get_canonical_unit(Q::unit);
|
||||||
constexpr ratio r = as_ratio(canonical.mag);
|
constexpr ratio r = as_ratio(canonical.mag);
|
||||||
return std::chrono::duration<typename Q::rep, std::ratio<r.num, r.den>>{q.numerical_value_ref_in(Q::unit)};
|
return std::chrono::duration<typename Q::rep, std::ratio<r.num, r.den>>{q};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<QuantityPointOf<isq::time> QP>
|
template<QuantityPointOf<isq::time> QP>
|
||||||
|
@@ -52,40 +52,40 @@ static_assert(!QuantityPoint<sys_seconds>);
|
|||||||
// construction - same rep type
|
// construction - same rep type
|
||||||
static_assert(
|
static_assert(
|
||||||
std::constructible_from<quantity<isq::time[si::second], std::chrono::seconds::rep>, std::chrono::seconds>);
|
std::constructible_from<quantity<isq::time[si::second], std::chrono::seconds::rep>, std::chrono::seconds>);
|
||||||
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second], std::chrono::seconds::rep>>);
|
static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second], std::chrono::seconds::rep>>);
|
||||||
static_assert(std::constructible_from<quantity<isq::time[si::hour], std::chrono::hours::rep>, std::chrono::hours>);
|
static_assert(std::constructible_from<quantity<isq::time[si::hour], std::chrono::hours::rep>, std::chrono::hours>);
|
||||||
static_assert(!std::convertible_to<std::chrono::hours, quantity<isq::time[si::hour], std::chrono::hours::rep>>);
|
static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::hour], std::chrono::hours::rep>>);
|
||||||
static_assert(std::constructible_from<quantity<isq::time[si::second], std::chrono::hours::rep>, std::chrono::hours>);
|
static_assert(std::constructible_from<quantity<isq::time[si::second], std::chrono::hours::rep>, std::chrono::hours>);
|
||||||
static_assert(!std::convertible_to<std::chrono::hours, quantity<isq::time[si::second], std::chrono::hours::rep>>);
|
static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::second], std::chrono::hours::rep>>);
|
||||||
static_assert(!std::constructible_from<quantity<isq::time[si::hour], std::chrono::seconds::rep>, std::chrono::seconds>);
|
static_assert(!std::constructible_from<quantity<isq::time[si::hour], std::chrono::seconds::rep>, std::chrono::seconds>);
|
||||||
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour], std::chrono::seconds::rep>>);
|
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour], std::chrono::seconds::rep>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
|
std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
|
||||||
static_assert(
|
static_assert(
|
||||||
!std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_seconds::rep>, sys_seconds>);
|
!std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_seconds::rep>, sys_seconds>);
|
||||||
static_assert(!std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock, sys_seconds::rep>>);
|
static_assert(std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock, sys_seconds::rep>>);
|
||||||
static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_days::rep>, sys_days>);
|
static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_days::rep>, sys_days>);
|
||||||
static_assert(!std::constructible_from<time_point<si::day, std::chrono::steady_clock, sys_days::rep>, sys_days>);
|
static_assert(!std::constructible_from<time_point<si::day, std::chrono::steady_clock, sys_days::rep>, sys_days>);
|
||||||
static_assert(!std::convertible_to<sys_days, time_point<si::day, std::chrono::system_clock, sys_days::rep>>);
|
static_assert(std::convertible_to<sys_days, time_point<si::day, std::chrono::system_clock, sys_days::rep>>);
|
||||||
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_days::rep>, sys_days>);
|
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_days::rep>, sys_days>);
|
||||||
static_assert(!std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_days::rep>, sys_days>);
|
static_assert(!std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_days::rep>, sys_days>);
|
||||||
static_assert(!std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock, sys_days::rep>>);
|
static_assert(std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock, sys_days::rep>>);
|
||||||
static_assert(!std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
|
static_assert(!std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
|
||||||
static_assert(!std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock, sys_seconds::rep>>);
|
static_assert(!std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock, sys_seconds::rep>>);
|
||||||
|
|
||||||
// construction - different rep type (integral to a floating-point)
|
// construction - different rep type (integral to a floating-point)
|
||||||
static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::seconds>);
|
static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::seconds>);
|
||||||
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second]>>);
|
static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second]>>);
|
||||||
static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::hours>);
|
static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::hours>);
|
||||||
static_assert(!std::convertible_to<std::chrono::hours, quantity<isq::time[si::second]>>);
|
static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::second]>>);
|
||||||
static_assert(std::constructible_from<quantity<isq::time[si::hour]>, std::chrono::seconds>);
|
static_assert(std::constructible_from<quantity<isq::time[si::hour]>, std::chrono::seconds>);
|
||||||
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour]>>);
|
static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour]>>);
|
||||||
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_seconds>);
|
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_seconds>);
|
||||||
static_assert(!std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock>>);
|
static_assert(std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock>>);
|
||||||
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_days>);
|
static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_days>);
|
||||||
static_assert(!std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock>>);
|
static_assert(std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock>>);
|
||||||
static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock>, sys_seconds>);
|
static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock>, sys_seconds>);
|
||||||
static_assert(!std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock>>);
|
static_assert(std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock>>);
|
||||||
|
|
||||||
static_assert(quantity<si::second>{1s} == 1 * s);
|
static_assert(quantity<si::second>{1s} == 1 * s);
|
||||||
static_assert(quantity<isq::time[si::second]>{1s} == 1 * s);
|
static_assert(quantity<isq::time[si::second]>{1s} == 1 * s);
|
||||||
|
@@ -525,7 +525,7 @@ static_assert(!std::convertible_to<quantity_point<isq::height[m], ground_level>,
|
|||||||
static_assert(
|
static_assert(
|
||||||
std::constructible_from<quantity_point<isq::time[s], chrono_point_origin<std::chrono::system_clock>>, sys_seconds>);
|
std::constructible_from<quantity_point<isq::time[s], chrono_point_origin<std::chrono::system_clock>>, sys_seconds>);
|
||||||
static_assert(
|
static_assert(
|
||||||
!std::convertible_to<sys_seconds, quantity_point<isq::time[s], chrono_point_origin<std::chrono::system_clock>>>);
|
std::convertible_to<sys_seconds, quantity_point<isq::time[s], chrono_point_origin<std::chrono::system_clock>>>);
|
||||||
|
|
||||||
// incompatible origin
|
// incompatible origin
|
||||||
static_assert(
|
static_assert(
|
||||||
|
Reference in New Issue
Block a user