5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_DURATION_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_DURATION_HPP_
14#include "arene/base/constraints.hpp"
15#include "arene/base/math/gcd.hpp"
16#include "arene/base/math/lcm.hpp"
17#include "arene/base/type_traits/is_instantiation_of.hpp"
18#include "arene/base/type_traits/is_invocable.hpp"
19#include "stdlib/include/stdlib_detail/common_type.hpp"
20#include "stdlib/include/stdlib_detail/cstdint.hpp"
21#include "stdlib/include/stdlib_detail/divides.hpp"
22#include "stdlib/include/stdlib_detail/enable_if.hpp"
23#include "stdlib/include/stdlib_detail/equal_to.hpp"
24#include "stdlib/include/stdlib_detail/is_convertible.hpp"
25#include "stdlib/include/stdlib_detail/is_copy_constructible.hpp"
26#include "stdlib/include/stdlib_detail/is_default_constructible.hpp"
27#include "stdlib/include/stdlib_detail/is_floating_point.hpp"
28#include "stdlib/include/stdlib_detail/less.hpp"
29#include "stdlib/include/stdlib_detail/minus.hpp"
30#include "stdlib/include/stdlib_detail/modulus.hpp"
31#include "stdlib/include/stdlib_detail/multiplies.hpp"
32#include "stdlib/include/stdlib_detail/numeric_limits.hpp"
33#include "stdlib/include/stdlib_detail/plus.hpp"
34#include "stdlib/include/stdlib_detail/ratio.hpp"
40template <
typename Rep,
typename Period = ratio<1>>
50template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
51class common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
54 using common_rep = common_type_t<Rep1, Rep2>;
58 ratio<::arene::base::gcd(Period1::num, Period2::num), ::arene::base::lcm(Period1::den, Period2::den)>;
62 using type = chrono::duration<common_rep, gcd_period>;
76template <
typename Rep>
81template <
typename Rep>
86template <
typename Rep>
100 return numeric_limits<Rep>::lowest();
106 return numeric_limits<Rep>::max();
131 is_nothrow_constructible_v<Common, Rep1
const&> && is_nothrow_constructible_v<Common, Rep2
const&> &&
132 ::arene::base::is_nothrow_invocable_v<BinaryOp, Rep1
const&,
Rep2 const&>;
146template <
typename ToDuration,
typename ConversionFactor,
typename CommonRep,
typename Rep>
152 return ToDuration{
static_cast<
typename ToDuration::rep>(
static_cast<CommonRep>(count))};
165template <
typename ToDuration,
typename ConversionFactor,
typename CommonRep,
typename Rep>
173 return ToDuration{
static_cast<
typename ToDuration::rep>(
174 static_cast<CommonRep>(count) *
static_cast<CommonRep>(ConversionFactor::num)
188template <
typename ToDuration,
typename ConversionFactor,
typename CommonRep,
typename Rep>
196 return ToDuration{
static_cast<
typename ToDuration::rep>(
197 static_cast<CommonRep>(count) /
static_cast<CommonRep>(ConversionFactor::den)
211template <
typename ToDuration,
typename ConversionFactor,
typename CommonRep,
typename Rep>
220 return ToDuration{
static_cast<
typename ToDuration::rep>(
221 static_cast<CommonRep>(count) *
static_cast<CommonRep>(ConversionFactor::num) /
222 static_cast<CommonRep>(ConversionFactor::den)
231template <
typename FromPeriod,
typename ToPeriod>
307template <
typename Rep,
typename Period>
310 !::arene::base::is_instantiation_of_v<Rep, duration>,
311 "Rep must not be a specialization of std::chrono::duration"
313 static_assert(ratio_detail::is_ratio<Period>::value,
"Period must be a specialization of std::ratio");
314 static_assert(Period::num > 0,
"Period must be positive");
321 using period = Period;
334 arene::base::constraints<
335 enable_if_t<is_convertible_v<Rep2
const&, rep>>,
336 enable_if_t<treat_as_floating_point_v<rep> || !treat_as_floating_point_v<Rep2>>> =
nullptr>
337 constexpr explicit duration(Rep2
const& rep_in
338 )
noexcept(is_nothrow_copy_constructible_v<rep> && is_nothrow_constructible_v<rep, Rep2
const&>)
339 : rep_{
static_cast<rep>(rep_in)} {}
353 arene::base::constraints<
354 enable_if_t<is_convertible_v<Rep2
const&, rep>>,
355 enable_if_t<chrono_detail::check_conversion_overflow<Period2, period>::value>,
357 treat_as_floating_point_v<rep> ||
358 (ratio_divide<Period2, period>::den == 1 && !treat_as_floating_point_v<Rep2>)>> =
nullptr>
360 constexpr duration(duration<Rep2, Period2>
const& other
361 )
noexcept(
noexcept(duration_cast<duration>(std::declval<duration<Rep2, Period2>
const&>()).count()) &&
362 is_nothrow_constructible_v<rep,
decltype(duration_cast<duration>(
363 std::declval<duration<Rep2, Period2>
const&>()).count())>)
364 : rep_{duration_cast<duration>(other).count()} {}
368 constexpr auto count()
const noexcept(is_nothrow_copy_constructible_v<rep>) -> rep {
return rep_; }
372 constexpr auto operator+()
const noexcept(is_nothrow_copy_constructible_v<duration>) -> duration {
return *
this; }
376 constexpr auto operator-()
const noexcept(is_nothrow_constructible_v<duration, rep>) -> duration {
377 return duration{-rep_};
382 constexpr auto operator++()
noexcept(
noexcept(++declval<rep&>())) -> duration& {
394 constexpr auto operator++(
int)
noexcept(is_nothrow_copy_constructible_v<duration>&&
noexcept(++declval<rep&>()))
396 return duration{rep_++};
401 constexpr auto operator--()
noexcept(
noexcept(--declval<rep&>())) -> duration& {
408 constexpr auto operator--(
int)
noexcept(is_nothrow_copy_constructible_v<duration>&&
noexcept(--declval<rep&>()))
410 return duration{rep_--};
421 constexpr auto operator+=(duration
const& rhs)
noexcept(
noexcept(declval<rep&>() += rhs.count())) -> duration& {
429 constexpr auto operator-=(duration
const& rhs)
noexcept(
noexcept(declval<rep&>() -= rhs.count())) -> duration& {
437 constexpr auto operator*=(rep
const& rhs)
noexcept(
noexcept(declval<rep&>() *= rhs)) -> duration& {
445 constexpr auto operator/=(rep
const& rhs)
noexcept(
noexcept(declval<rep&>() /= rhs)) -> duration& {
453 constexpr auto operator%=(rep
const& rhs)
noexcept(
noexcept(declval<rep&>() %= rhs)) -> duration& {
461 constexpr auto operator%=(duration
const& rhs)
noexcept(
noexcept(declval<rep&>() %= rhs.count())) -> duration& {
468 static constexpr auto zero()
noexcept(
noexcept(duration(duration_values<rep>::zero()))) -> duration {
469 return duration(duration_values<rep>::zero());
475 static constexpr auto min()
noexcept(
noexcept(duration(duration_values<rep>::min()))) -> duration {
476 return duration(duration_values<rep>::min());
481 static constexpr auto max()
noexcept(
noexcept(duration(duration_values<rep>::max()))) -> duration {
482 return duration(duration_values<rep>::max());
507template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
509 duration<Rep1, Period1>
const& lhs,
510 duration<Rep2, Period2>
const& rhs
513 using common_type = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
514 return common_type{lhs}.count() == common_type{rhs}.count();
527template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
528constexpr auto operator!=(duration<Rep1, Period1>
const& lhs, duration<Rep2, Period2>
const& rhs)
noexcept(
531 return !(lhs == rhs);
542template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
544 duration<Rep1, Period1>
const& lhs,
545 duration<Rep2, Period2>
const& rhs
547 using common_type = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
548 return common_type{lhs}.count() < common_type{rhs}.count();
559template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
560constexpr auto operator<=(duration<Rep1, Period1>
const& lhs, duration<Rep2, Period2>
const& rhs)
noexcept(
574template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
575constexpr auto operator>(duration<Rep1, Period1>
const& lhs, duration<Rep2, Period2>
const& rhs)
noexcept(
589template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
590constexpr auto operator>=(duration<Rep1, Period1>
const& lhs, duration<Rep2, Period2>
const& rhs)
noexcept(
609template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
611 duration<Rep1, Period1>
const& lhs,
612 duration<Rep2, Period2>
const& rhs
615 using common_duration = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
616 return common_duration{common_duration{lhs}.count() + common_duration{rhs}.count()};
627template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
629 duration<Rep1, Period1>
const& lhs,
630 duration<Rep2, Period2>
const& rhs
633 using common_duration = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
634 return common_duration{common_duration{lhs}.count() - common_duration{rhs}.count()};
706template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
708 duration<Rep1, Period1>
const& lhs,
709 duration<Rep2, Period2>
const& rhs
712 using common_duration = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
713 return std::common_type_t<Rep1, Rep2>{common_duration{lhs}.count() / common_duration{rhs}.count()};
747template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
749 duration<Rep1, Period1>
const& lhs,
750 duration<Rep2, Period2>
const& rhs
753 using common_duration = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
754 return common_duration{common_duration{lhs}.count() % common_duration{rhs}.count()};
Helper to detect if duration conversion would cause overflow.
Definition duration.hpp:232
static constexpr auto value
True if FromPeriod can be converted to ToPeriod without risk of overflow.
Definition duration.hpp:255
A customizable trait to indicate the zero, lowest, and highest values of a given representation type.
Definition duration.hpp:87
static constexpr auto max() noexcept(noexcept(numeric_limits< Rep >::max())) -> Rep
Get the highest value of the given Rep type, which must compare > zero()
Definition duration.hpp:105
static constexpr auto zero() noexcept(is_nothrow_move_constructible_v< Rep >) -> Rep
Get the zero value of the given Rep type (formally, its additive identity)
Definition duration.hpp:91
static constexpr auto min() noexcept(noexcept(numeric_limits< Rep >::lowest())) -> Rep
Get the lowest value of the given Rep type, which must compare <= zero()
Definition duration.hpp:99
constexpr duration() noexcept(is_nothrow_default_constructible_v< rep >)
Default constructor Initializes the duration with a zero tick count.
Definition duration.hpp:326
Trait to indicate if a representation type should be treated as floating-point.
Definition duration.hpp:77
Definition duration.hpp:110
constexpr auto duration_cast_impl(Rep const &count, std::true_type, std::true_type) noexcept(std::is_nothrow_constructible_v< ToDuration, typename ToDuration::rep >) -> ToDuration
Helper for duration_cast implementation that handles different conversion cases.
Definition duration.hpp:147
constexpr bool duration_op_noexcept_v
Variable template indicating if the given operation is noexcept for the given duration types.
constexpr bool duration_scalar_op_noexcept_v
Variable template indicating if the given operation is noexcept for the given scalar types.
Definition duration.hpp:37
constexpr auto operator!=(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(noexcept(lhs==rhs)) -> bool
Inequality comparison operator for duration types.
Definition duration.hpp:528
constexpr auto operator>=(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(noexcept(lhs< rhs)) -> bool
Greater-than-or-equal comparison operator for duration types.
Definition duration.hpp:590
constexpr auto operator<=(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(noexcept(rhs< lhs)) -> bool
Less-than-or-equal comparison operator for duration types.
Definition duration.hpp:560
constexpr auto operator==(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< equal_to<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> bool
Equality comparison operator for duration types.
Definition duration.hpp:508
constexpr bool treat_as_floating_point_v
Helper variable template for treat_as_floating_point.
Definition duration.hpp:82
constexpr auto operator/(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< divides<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> std::common_type_t< Rep1, Rep2 >
Division operator for two durations.
Definition duration.hpp:707
constexpr auto operator>(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(noexcept(rhs< lhs)) -> bool
Greater-than comparison operator for duration types.
Definition duration.hpp:575
constexpr auto operator<(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< less<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> bool
Less-than comparison operator for duration types.
Definition duration.hpp:543
constexpr auto operator%(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< modulus<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> std::common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > >
Modulo operator for two durations.
Definition duration.hpp:748
constexpr auto operator-(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< minus<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> std::common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > >
Subtraction operator for duration types.
Definition duration.hpp:628
constexpr auto operator+(duration< Rep1, Period1 > const &lhs, duration< Rep2, Period2 > const &rhs) noexcept(chrono_detail::duration_op_noexcept_v< plus<>, duration< Rep1, Period1 >, duration< Rep2, Period2 > >) -> std::common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > >
Addition operator for duration types.
Definition duration.hpp:610
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827