diff --git a/example/glide_computer/include/glide_computer.h b/example/glide_computer/include/glide_computer.h index fe7cc734..ed34024c 100644 --- a/example/glide_computer/include/glide_computer.h +++ b/example/glide_computer/include/glide_computer.h @@ -66,7 +66,7 @@ using altitude = mp_units::quantity_point; using timestamp = mp_units::quantity_point{}>; + mp_units::chrono_point_origin>; // speed using velocity = mp_units::quantity / mp_units::si::hour]>; diff --git a/src/core/include/mp_units/quantity.h b/src/core/include/mp_units/quantity.h index 9ec4659a..72fe9e81 100644 --- a/src/core/include/mp_units/quantity.h +++ b/src/core/include/mp_units/quantity.h @@ -459,7 +459,8 @@ explicit quantity(Q) -> quantity::reference, typename qu // non-member binary operators template - requires(get_kind(Q1::quantity_spec) == get_kind(Q2::quantity_spec)) && + requires(implicitly_convertible_to(get_kind(Q1::quantity_spec), get_kind(Q2::quantity_spec)) || + implicitly_convertible_to(get_kind(Q2::quantity_spec), get_kind(Q1::quantity_spec))) && detail::InvokeResultOf, typename Q1::rep, typename Q2::rep> [[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs) @@ -470,7 +471,8 @@ template } template - requires(get_kind(Q1::quantity_spec) == get_kind(Q2::quantity_spec)) && + requires(implicitly_convertible_to(get_kind(Q1::quantity_spec), get_kind(Q2::quantity_spec)) || + implicitly_convertible_to(get_kind(Q2::quantity_spec), get_kind(Q1::quantity_spec))) && detail::InvokeResultOf, typename Q1::rep, typename Q2::rep> [[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs) diff --git a/src/utility/include/mp_units/chrono.h b/src/utility/include/mp_units/chrono.h index 9534211a..18485c60 100644 --- a/src/utility/include/mp_units/chrono.h +++ b/src/utility/include/mp_units/chrono.h @@ -66,14 +66,17 @@ struct quantity_like_traits> { }; template -struct chrono_point_origin : absolute_point_origin { +struct chrono_point_origin_ : absolute_point_origin { using clock = C; }; +template +inline constexpr chrono_point_origin_ chrono_point_origin; + template struct quantity_point_like_traits>> { static constexpr auto reference = isq::time[detail::time_unit_from_chrono_period()]; - static constexpr auto point_origin = chrono_point_origin{}; + static constexpr auto point_origin = chrono_point_origin; using rep = Rep; [[nodiscard]] static constexpr auto relative(const std::chrono::time_point>& qp) { @@ -90,7 +93,7 @@ template Q> } template QP> - requires is_specialization_of, chrono_point_origin> + requires is_specialization_of, chrono_point_origin_> [[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp) { using clock = TYPENAME decltype(QP::absolute_point_origin)::clock; @@ -98,7 +101,7 @@ template QP> constexpr auto canonical = detail::get_canonical_unit(QP::unit); constexpr ratio r = as_ratio(canonical.mag); using ret_type = std::chrono::time_point>>; - return ret_type(to_std_duration(qp.absolute())); + return ret_type(to_chrono_duration(qp.absolute())); } } // namespace mp_units diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index ea487f81..a4f263f9 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -37,7 +37,7 @@ add_library( dimension_test.cpp # angle_test.cpp # cgs_test.cpp - # chrono_test.cpp + chrono_test.cpp # concepts_test.cpp # custom_rep_test_min_expl.cpp # custom_unit_test.cpp diff --git a/test/unit_test/static/chrono_test.cpp b/test/unit_test/static/chrono_test.cpp index 952ce1fa..6886dc24 100644 --- a/test/unit_test/static/chrono_test.cpp +++ b/test/unit_test/static/chrono_test.cpp @@ -21,95 +21,96 @@ // SOFTWARE. #include "test_tools.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace { -using namespace units; -using namespace units::isq; -using namespace units::isq::si::literals; +using namespace mp_units; +using namespace mp_units::si::unit_symbols; using namespace std::chrono_literals; using sys_seconds = std::chrono::time_point; using sys_days = std::chrono::time_point, std::chrono::hours::period>>>; -template -using time_point = quantity_point, U, Rep>; +template +using time_point = quantity_point, Rep>; static_assert(QuantityLike); static_assert(QuantityPointLike); // construction - same rep type -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); static_assert( - std::constructible_from, sys_seconds>); + std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); static_assert( - !std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); + std::constructible_from, sys_seconds>); +static_assert( + !std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); // construction - different rep type (integral to a floating-point) -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); // CTAD -static_assert(compare>); -static_assert(compare>); -static_assert(compare>); -static_assert(compare>); +static_assert(is_of_type>); +static_assert(is_of_type>); +static_assert( + is_of_type>); +static_assert(is_of_type>); // operators -static_assert(quantity{1s} + 1_q_s == 2_q_s); -static_assert(quantity{1s} + 1_q_min == 61_q_s); -static_assert(10_q_m / quantity{2s} == 5_q_m_per_s); -static_assert(quantity_point{sys_seconds{1s}} + 1_q_s == time_point{2_q_s}); -static_assert(quantity_point{sys_seconds{1s}} + 1_q_min == time_point{61_q_s}); +static_assert(quantity{1s} + 1 * s == 2 * s); +static_assert(quantity{1s} + 1 * min == 61 * s); +static_assert(10 * m / quantity{2s} == 5 * (m / s)); +static_assert(quantity_point{sys_seconds{1s}} + 1 * s == + time_point{2 * s}); +static_assert(quantity_point{sys_seconds{1s}} + 1 * min == + time_point{61 * s}); // to_std_duration -static_assert(to_std_duration(1_q_s) == 1s); -static_assert(to_std_duration(2_q_h) == 2h); -static_assert(to_std_duration(3_q_ns) == 3ns); -static_assert(to_std_duration(quantity{1s}) == 1s); -static_assert(to_std_duration(quantity{2h}) == 2h); -static_assert(to_std_duration(quantity{3ns}) == 3ns); -static_assert(is_same_v>); -static_assert(is_same_v>); -static_assert(is_same_v); +static_assert(to_chrono_duration(1 * s) == 1s); +static_assert(to_chrono_duration(2 * h) == 2h); +static_assert(to_chrono_duration(3 * ns) == 3ns); +static_assert(to_chrono_duration(quantity{1s}) == 1s); +static_assert(to_chrono_duration(quantity{2h}) == 2h); +static_assert(to_chrono_duration(quantity{3ns}) == 3ns); +static_assert(is_same_v>); +static_assert(is_same_v>); +static_assert(is_same_v); // to_std_time_point -static_assert(to_std_time_point(quantity_point{sys_seconds{1s}}) == sys_seconds{1s}); -static_assert(to_std_time_point(quantity_point{sys_days{sys_days::duration{1}}}) == sys_days{sys_days::duration{1}}); +static_assert(to_chrono_time_point(quantity_point{sys_seconds{1s}}) == sys_seconds{1s}); +static_assert(to_chrono_time_point(quantity_point{sys_days{sys_days::duration{1}}}) == sys_days{sys_days::duration{1}}); } // namespace