Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
duration.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_DURATION_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_DURATION_HPP_
7
8// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
9// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
10
11// IWYU pragma: private, include <chrono>
12// IWYU pragma: friend "stdlib_detail/.*"
13
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"
35
36namespace std {
37namespace chrono {
38
39/// @brief Forward declaration of duration class template
40template <typename Rep, typename Period = ratio<1>>
41class duration;
42
43} // namespace chrono
44
45/// @brief Specialization of common_type for two duration types
46/// @tparam Rep1 Representation type of the first duration
47/// @tparam Period1 Period type of the first duration
48/// @tparam Rep2 Representation type of the second duration
49/// @tparam Period2 Period type of the second duration
50template <typename Rep1, typename Period1, typename Rep2, typename Period2>
51class common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
52 private:
53 /// @brief The common representation type
54 using common_rep = common_type_t<Rep1, Rep2>;
55
56 /// @brief The greatest common divisor of the two periods
57 using gcd_period =
58 ratio<::arene::base::gcd(Period1::num, Period2::num), ::arene::base::lcm(Period1::den, Period2::den)>;
59
60 public:
61 /// @brief The common duration type with the gcd period and common representation
62 using type = chrono::duration<common_rep, gcd_period>;
63};
64
65namespace chrono {
66
67/// @brief Trait to indicate if a representation type should be treated as floating-point
68///
69/// This trait determines whether implicit conversions between duration types are allowed.
70/// If the representation type is treated as floating-point, implicit conversions that might
71/// lose precision are permitted. Otherwise, such conversions are forbidden.
72///
73/// @tparam Rep The representation type to check
74///
75/// @note This trait can be specialized by users for custom representation types
76template <typename Rep>
78
79/// @brief Helper variable template for treat_as_floating_point
80/// @tparam Rep The representation type to check
81template <typename Rep>
83
84/// @brief A customizable trait to indicate the zero, lowest, and highest values of a given representation type
85/// @tparam Rep The representation type
86template <typename Rep>
88 public:
89 /// @brief Get the zero value of the given Rep type (formally, its additive identity)
90 /// @return An instance of the zero value
91 static constexpr auto zero() noexcept(is_nothrow_move_constructible_v<Rep>) -> Rep {
92 // parasoft-begin-suppress AUTOSAR-A5_2_2-a "The C++14 standard specifies exactly this implementation."
93 return Rep(0); // explicit 0 following [time.traits.duration_values] to avoid uninitialized values
94 // parasoft-end-suppress AUTOSAR-A5_2_2-a
95 }
96
97 /// @brief Get the lowest value of the given Rep type, which must compare <c><= zero()</c>
98 /// @return An instance of the lowest value
99 static constexpr auto min() noexcept(noexcept(numeric_limits<Rep>::lowest())) -> Rep {
100 return numeric_limits<Rep>::lowest();
101 }
102
103 /// @brief Get the highest value of the given Rep type, which must compare <c>> zero()</c>
104 /// @return An instance of the highest value
105 static constexpr auto max() noexcept(noexcept(numeric_limits<Rep>::max())) -> Rep {
106 return numeric_limits<Rep>::max();
107 }
108};
109
110namespace chrono_detail {
111
112/// @brief Variable template indicating if the given operation is noexcept for the given duration types
113/// @tparam BinaryOp Function object representing the operation to check
114/// @tparam Duration1 The first duration type
115/// @tparam Duration2 The second duration type
116template <
117 typename BinaryOp,
118 typename Duration1,
119 typename Duration2,
121extern constexpr bool duration_op_noexcept_v =
123 ::arene::base::is_nothrow_invocable_v<BinaryOp, typename Common::rep const&, typename Common::rep const&>;
124
125/// @brief Variable template indicating if the given operation is noexcept for the given scalar types
126/// @tparam BinaryOp Function object representing the operation to check
127/// @tparam Rep1 The first scalar type
128/// @tparam Rep2 The second scalar type
129template <typename BinaryOp, typename Rep1, typename Rep2, typename Common = common_type_t<Rep1, Rep2>>
130extern constexpr bool duration_scalar_op_noexcept_v =
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&>;
133
134// parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
135
136/// @brief Helper for duration_cast implementation that handles different conversion cases
137/// @tparam ToDuration The target duration type
138/// @tparam ConversionFactor The conversion factor ratio
139/// @tparam CommonRep The common representation type used for the conversion
140/// @tparam Rep The representation type of the source duration
141/// @param count The current number of ticks
142/// @return The new duration
143///
144/// Note: This handles the case where ConversionFactor::num == 1 and ConversionFactor::den == 1 (section 2.1 of the C++
145/// standard).
146template <typename ToDuration, typename ConversionFactor, typename CommonRep, typename Rep>
147constexpr auto duration_cast_impl(
148 Rep const& count,
149 std::true_type /* ConversionFactor::num == 1 */,
150 std::true_type /* ConversionFactor::den == 1 */
151) noexcept(std::is_nothrow_constructible_v<ToDuration, typename ToDuration::rep>) -> ToDuration {
152 return ToDuration{static_cast<typename ToDuration::rep>(static_cast<CommonRep>(count))};
153}
154
155/// @brief Helper for duration_cast implementation that handles different conversion cases
156/// @tparam ToDuration The target duration type
157/// @tparam ConversionFactor The conversion factor ratio
158/// @tparam CommonRep The common representation type used for the conversion
159/// @tparam Rep The representation type of the source duration
160/// @param count The current number of ticks
161/// @return The new duration
162///
163/// Note: This handles the case where ConversionFactor::num != 1 and ConversionFactor::den == 1 (section 2.2 of the C++
164/// standard).
165template <typename ToDuration, typename ConversionFactor, typename CommonRep, typename Rep>
166constexpr auto duration_cast_impl(
167 Rep const& count,
168 std::false_type /* ConversionFactor::num != 1 */,
169 std::true_type /* ConversionFactor::den == 1 */
170) noexcept(noexcept(std::declval<CommonRep const&>() * std::declval<CommonRep const&>()) && //
172 -> ToDuration {
173 return ToDuration{static_cast<typename ToDuration::rep>(
174 static_cast<CommonRep>(count) * static_cast<CommonRep>(ConversionFactor::num)
175 )};
176}
177
178/// @brief Helper for duration_cast implementation that handles different conversion cases
179/// @tparam ToDuration The target duration type
180/// @tparam ConversionFactor The conversion factor ratio
181/// @tparam CommonRep The common representation type used for the conversion
182/// @tparam Rep The representation type of the source duration
183/// @param count The current number of ticks
184/// @return The new duration
185///
186/// Note: This handles the case where ConversionFactor::num == 1 and ConversionFactor::den != 1 (section 2.3 of the C++
187/// standard).
188template <typename ToDuration, typename ConversionFactor, typename CommonRep, typename Rep>
189constexpr auto duration_cast_impl(
190 Rep const& count,
191 std::true_type /* ConversionFactor::num == 1 */,
192 std::false_type /* ConversionFactor::den != 1 */
193) noexcept(noexcept(std::declval<CommonRep const&>() / std::declval<CommonRep const&>()) && //
195 -> ToDuration {
196 return ToDuration{static_cast<typename ToDuration::rep>(
197 static_cast<CommonRep>(count) / static_cast<CommonRep>(ConversionFactor::den)
198 )};
199}
200
201/// @brief Helper for duration_cast implementation that handles different conversion cases
202/// @tparam ToDuration The target duration type
203/// @tparam ConversionFactor The conversion factor ratio
204/// @tparam CommonRep The common representation type used for the conversion
205/// @tparam Rep The representation type of the source duration
206/// @param count The current number of ticks
207/// @return The new duration
208///
209/// Note: This handles the default case where ConversionFactor::num != 1 and ConversionFactor::den != 1 (section 2.4 of
210/// the C++ standard).
211template <typename ToDuration, typename ConversionFactor, typename CommonRep, typename Rep>
212constexpr auto duration_cast_impl(
213 Rep const& count,
214 std::false_type /* ConversionFactor::num != 1 */,
215 std::false_type /* ConversionFactor::den != 1 */
216) noexcept(noexcept(std::declval<CommonRep const&>() / std::declval<CommonRep const&>()) && //
217 noexcept(std::declval<CommonRep const&>() * std::declval<CommonRep const&>()) && //
219 -> ToDuration {
220 return ToDuration{static_cast<typename ToDuration::rep>(
221 static_cast<CommonRep>(count) * static_cast<CommonRep>(ConversionFactor::num) /
222 static_cast<CommonRep>(ConversionFactor::den)
223 )};
224}
225
226// parasoft-end-suppress CERT_C-EXP37-a-3
227
228/// @brief Helper to detect if duration conversion would cause overflow
229/// @tparam FromPeriod The period of the source duration
230/// @tparam ToPeriod The period of the target duration
231template <typename FromPeriod, typename ToPeriod>
233 private:
234 // parasoft-begin-suppress AUTOSAR-M0_1_3-c "False positive: gcd_num and gcd_den are used."
235 /// @brief The greatest common divisor of the numerators of the two periods
236 static constexpr auto gcd_num = ::arene::base::gcd(FromPeriod::num, ToPeriod::num);
237
238 /// @brief The greatest common divisor of the denominators of the two periods
239 static constexpr auto gcd_den = ::arene::base::gcd(FromPeriod::den, ToPeriod::den);
240 // parasoft-end-suppress AUTOSAR-M0_1_3-c
241
242 /// @brief The @c FromPeriod reduced by the greatest common divisors
244
245 /// @brief The @c ToPeriod reduced by the greatest common divisors
247
248 /// @brief The max representable value
249 static constexpr auto max = numeric_limits<intmax_t>::max();
250
251 public:
252 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public
253 // property,
254 /// @brief True if @c FromPeriod can be converted to @c ToPeriod without risk of overflow.
255 static constexpr auto value = reduced_from_period::num <= (max / reduced_to_period::den) &&
257 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
258};
259
260} // namespace chrono_detail
261
262/// @brief Convert a duration to a different duration type
263/// @tparam ToDuration The target duration type to convert to
264/// @tparam Rep The representation type of the source duration
265/// @tparam Period The period type of the source duration
266/// @param duration The source duration to convert
267/// @return A duration of type ToDuration converted from the source duration
268///
269/// @note This function only participates in overload resolution if ToDuration is an instantiation of duration
270template <
271 typename ToDuration,
272 typename Rep,
273 typename Period,
276 typename CommonRep = std::common_type_t<typename ToDuration::rep, Rep, intmax_t>>
290
291// parasoft-begin-suppress AUTOSAR-A14_5_1-a "False positive: The single
292// argument template constructor of 'duration' does not hide copy/move
293// constructors via use of SFINAE."
294// parasoft-begin-suppress AUTOSAR-A12_1_5-a "False positive: delegating constructors would not reduce duplication"
295// parasoft-begin-suppress AUTOSAR-M2_10_1-a "Similar names permitted by M2-10-1 Permit #1"
296
297/// @brief A time interval represented as a count of ticks of a given period
298///
299/// The duration class template represents a time interval. It consists of a count of ticks
300/// of type Rep and a tick period, where the tick period is a compile-time rational fraction
301/// representing the number of seconds from one tick to the next.
302///
303/// @tparam Rep An arithmetic type or a class emulating an arithmetic type, representing the
304/// type of the tick count. Must not be a specialization of duration.
305/// @tparam Period A specialization of std::ratio, representing the tick period in seconds.
306/// Must be positive. Defaults to std::ratio<1> (1 second).
307template <typename Rep, typename Period>
308class duration {
309 static_assert(
310 !::arene::base::is_instantiation_of_v<Rep, duration>,
311 "Rep must not be a specialization of std::chrono::duration"
312 );
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");
315
316 public:
317 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False positive: these declarations are scoped and do not hide anything"
318 /// @brief The arithmetic type representing the number of ticks
319 using rep = Rep;
320 /// @brief The period type representing the tick period in seconds
321 using period = Period;
322 // parasoft-end-suppress AUTOSAR-A2_10_1-e
323
324 /// @brief Default constructor
325 /// Initializes the duration with a zero tick count
327 : rep_{} {}
328
329 /// @brief Constructor from a representation value
330 /// @tparam Rep2 The type of the input representation value, must be convertible to Rep
331 /// @param rep_in The tick count value to initialize the duration with
332 template <
333 typename Rep2,
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)} {}
340
341 /// @brief Constructor from another duration type
342 /// @tparam Rep2 The representation type of the source duration
343 /// @tparam Period2 The period type of the source duration
344 /// @param other The source duration to convert from
345 ///
346 /// Note: The standard specifies that "This constructor shall not participate in overload resolution unless no
347 /// overflow is induced in the conversion". It is unclear what overflow should be checked, and different standard
348 /// library implementations take different approaches. This implementation aims for compatibility with the
349 /// approaches taken by libc++ and libstdc++.
350 template <
351 typename Rep2,
352 typename Period2,
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>,
356 enable_if_t<
357 treat_as_floating_point_v<rep> ||
358 (ratio_divide<Period2, period>::den == 1 && !treat_as_floating_point_v<Rep2>)>> = nullptr>
359 // NOLINTNEXTLINE(hicpp-explicit-conversions)
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()} {}
365
366 /// @brief Returns the tick count
367 /// @return The tick count as a value of type rep
368 constexpr auto count() const noexcept(is_nothrow_copy_constructible_v<rep>) -> rep { return rep_; }
369
370 /// @brief Unary plus operator
371 /// @return A copy of this duration
372 constexpr auto operator+() const noexcept(is_nothrow_copy_constructible_v<duration>) -> duration { return *this; }
373
374 /// @brief Unary minus operator
375 /// @return A duration with negated representation
376 constexpr auto operator-() const noexcept(is_nothrow_constructible_v<duration, rep>) -> duration {
377 return duration{-rep_};
378 }
379
380 /// @brief Pre-increment operator
381 /// @return Reference to this duration after incrementing
382 constexpr auto operator++() noexcept(noexcept(++declval<rep&>())) -> duration& {
383 ++rep_;
384 return *this;
385 }
386
387 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
388 // parasoft-begin-suppress AUTOSAR-A3_9_1-b "False positive: postincrement requires an int parameter"
389 // parasoft-begin-suppress AUTOSAR-M5_2_10-a "These operator definitions are written to follow the standard
390 // specification exactly."
391
392 /// @brief Post-increment operator
393 /// @return Copy of this duration before incrementing
394 constexpr auto operator++(int) noexcept(is_nothrow_copy_constructible_v<duration>&& noexcept(++declval<rep&>()))
395 -> duration {
396 return duration{rep_++};
397 }
398
399 /// @brief Pre-decrement operator
400 /// @return Reference to this duration after decrementing
401 constexpr auto operator--() noexcept(noexcept(--declval<rep&>())) -> duration& {
402 --rep_;
403 return *this;
404 }
405
406 /// @brief Post-decrement operator
407 /// @return Copy of this duration before decrementing
408 constexpr auto operator--(int) noexcept(is_nothrow_copy_constructible_v<duration>&& noexcept(--declval<rep&>()))
409 -> duration {
410 return duration{rep_--};
411 }
412
413 // parasoft-end-suppress AUTOSAR-A3_9_1-b
414 // parasoft-end-suppress CERT_C-EXP37-a-3
415 // parasoft-begin-suppress AUTOSAR-M5_2_10-a "These operator definitions are written to follow the standard
416 // specification exactly."
417
418 /// @brief Compound addition assignment operator
419 /// @param rhs The duration to add
420 /// @return Reference to this duration after addition
421 constexpr auto operator+=(duration const& rhs) noexcept(noexcept(declval<rep&>() += rhs.count())) -> duration& {
422 rep_ += rhs.count();
423 return *this;
424 }
425
426 /// @brief Compound subtraction assignment operator
427 /// @param rhs The duration to subtract
428 /// @return Reference to this duration after subtraction
429 constexpr auto operator-=(duration const& rhs) noexcept(noexcept(declval<rep&>() -= rhs.count())) -> duration& {
430 rep_ -= rhs.count();
431 return *this;
432 }
433
434 /// @brief Compound multiplication assignment operator
435 /// @param rhs The scalar to multiply by
436 /// @return Reference to this duration after multiplication
437 constexpr auto operator*=(rep const& rhs) noexcept(noexcept(declval<rep&>() *= rhs)) -> duration& {
438 rep_ *= rhs;
439 return *this;
440 }
441
442 /// @brief Compound division assignment operator
443 /// @param rhs The scalar to divide by
444 /// @return Reference to this duration after division
445 constexpr auto operator/=(rep const& rhs) noexcept(noexcept(declval<rep&>() /= rhs)) -> duration& {
446 rep_ /= rhs;
447 return *this;
448 }
449
450 /// @brief Compound modulo assignment operator with scalar
451 /// @param rhs The scalar to compute modulo with
452 /// @return Reference to this duration after modulo operation
453 constexpr auto operator%=(rep const& rhs) noexcept(noexcept(declval<rep&>() %= rhs)) -> duration& {
454 rep_ %= rhs;
455 return *this;
456 }
457
458 /// @brief Compound modulo assignment operator with duration
459 /// @param rhs The duration to compute modulo with
460 /// @return Reference to this duration after modulo operation
461 constexpr auto operator%=(duration const& rhs) noexcept(noexcept(declval<rep&>() %= rhs.count())) -> duration& {
462 rep_ %= rhs.count();
463 return *this;
464 }
465
466 /// @brief Get a duration of length zero, corresponding to no time passing
467 /// @return A duration of length zero
468 static constexpr auto zero() noexcept(noexcept(duration(duration_values<rep>::zero()))) -> duration {
469 return duration(duration_values<rep>::zero());
470 }
471
472 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False positive: these declarations are scoped and do not hide anything"
473 /// @brief Get a minimally positive duration (for signed representations, a maximally negative duration)
474 /// @return A minimal duration
475 static constexpr auto min() noexcept(noexcept(duration(duration_values<rep>::min()))) -> duration {
476 return duration(duration_values<rep>::min());
477 }
478
479 /// @brief Get a maximally positive duration
480 /// @return A maximal duration
481 static constexpr auto max() noexcept(noexcept(duration(duration_values<rep>::max()))) -> duration {
482 return duration(duration_values<rep>::max());
483 }
484 // parasoft-end-suppress AUTOSAR-A2_10_1-e
485
486 private:
487 /// @brief The current number of ticks
488 rep rep_;
489};
490
491// parasoft-end-suppress AUTOSAR-A14_5_1-a
492// parasoft-end-suppress AUTOSAR-A12_1_5-a
493// parasoft-end-suppress AUTOSAR-M2_10_1-a
494
495// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Mixed comparisons permitted by A13-5-5 Permit #1. These also cannot be
496// unconditionally noexcept because we do not control the rep type."
497// parasoft-begin-suppress AUTOSAR-M6_2_2-a "This comparison is defined by the standard."
498
499/// @brief Equality comparison operator for duration types
500/// @tparam Rep1 Representation type of the first duration
501/// @tparam Period1 Period type of the first duration
502/// @tparam Rep2 Representation type of the second duration
503/// @tparam Period2 Period type of the second duration
504/// @param lhs Left-hand side duration
505/// @param rhs Right-hand side duration
506/// @return True if the durations represent the same time interval, false otherwise
507template <typename Rep1, typename Period1, typename Rep2, typename Period2>
508constexpr auto operator==(
509 duration<Rep1, Period1> const& lhs,
510 duration<Rep2, Period2> const& rhs
512 -> bool {
513 using common_type = std::common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
514 return common_type{lhs}.count() == common_type{rhs}.count();
515}
516
517// parasoft-end-suppress AUTOSAR-M6_2_2-a
518
519/// @brief Inequality comparison operator for duration types
520/// @tparam Rep1 Representation type of the first duration
521/// @tparam Period1 Period type of the first duration
522/// @tparam Rep2 Representation type of the second duration
523/// @tparam Period2 Period type of the second duration
524/// @param lhs Left-hand side duration
525/// @param rhs Right-hand side duration
526/// @return True if the durations represent different time intervals, false otherwise
527template <typename Rep1, typename Period1, typename Rep2, typename Period2>
528constexpr auto operator!=(duration<Rep1, Period1> const& lhs, duration<Rep2, Period2> const& rhs) noexcept(
529 noexcept(lhs == rhs)
530) -> bool {
531 return !(lhs == rhs);
532}
533
534/// @brief Less-than comparison operator for duration types
535/// @tparam Rep1 Representation type of the first duration
536/// @tparam Period1 Period type of the first duration
537/// @tparam Rep2 Representation type of the second duration
538/// @tparam Period2 Period type of the second duration
539/// @param lhs Left-hand side duration
540/// @param rhs Right-hand side duration
541/// @return True if lhs represents a shorter time interval than rhs, false otherwise
542template <typename Rep1, typename Period1, typename Rep2, typename Period2>
543constexpr auto operator<(
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();
549}
550
551/// @brief Less-than-or-equal comparison operator for duration types
552/// @tparam Rep1 Representation type of the first duration
553/// @tparam Period1 Period type of the first duration
554/// @tparam Rep2 Representation type of the second duration
555/// @tparam Period2 Period type of the second duration
556/// @param lhs Left-hand side duration
557/// @param rhs Right-hand side duration
558/// @return True if lhs represents a shorter or equal time interval than rhs, false otherwise
559template <typename Rep1, typename Period1, typename Rep2, typename Period2>
560constexpr auto operator<=(duration<Rep1, Period1> const& lhs, duration<Rep2, Period2> const& rhs) noexcept(
561 noexcept(rhs < lhs)
562) -> bool {
563 return !(rhs < lhs);
564}
565
566/// @brief Greater-than comparison operator for duration types
567/// @tparam Rep1 Representation type of the first duration
568/// @tparam Period1 Period type of the first duration
569/// @tparam Rep2 Representation type of the second duration
570/// @tparam Period2 Period type of the second duration
571/// @param lhs Left-hand side duration
572/// @param rhs Right-hand side duration
573/// @return True if lhs represents a longer time interval than rhs, false otherwise
574template <typename Rep1, typename Period1, typename Rep2, typename Period2>
575constexpr auto operator>(duration<Rep1, Period1> const& lhs, duration<Rep2, Period2> const& rhs) noexcept(
576 noexcept(rhs < lhs)
577) -> bool {
578 return rhs < lhs;
579}
580
581/// @brief Greater-than-or-equal comparison operator for duration types
582/// @tparam Rep1 Representation type of the first duration
583/// @tparam Period1 Period type of the first duration
584/// @tparam Rep2 Representation type of the second duration
585/// @tparam Period2 Period type of the second duration
586/// @param lhs Left-hand side duration
587/// @param rhs Right-hand side duration
588/// @return True if lhs represents a longer or equal time interval than rhs, false otherwise
589template <typename Rep1, typename Period1, typename Rep2, typename Period2>
590constexpr auto operator>=(duration<Rep1, Period1> const& lhs, duration<Rep2, Period2> const& rhs) noexcept(
591 noexcept(lhs < rhs)
592) -> bool {
593 return !(lhs < rhs);
594}
595
596// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
597
598// parasoft-begin-suppress AUTOSAR-M5_17_1-a "These operator definitions are written to follow the standard
599// specification exactly."
600
601/// @brief Addition operator for duration types
602/// @tparam Rep1 Representation type of the first duration
603/// @tparam Period1 Period type of the first duration
604/// @tparam Rep2 Representation type of the second duration
605/// @tparam Period2 Period type of the second duration
606/// @param lhs Left-hand side duration
607/// @param rhs Right-hand side duration
608/// @return A duration representing the sum of the two durations
609template <typename Rep1, typename Period1, typename Rep2, typename Period2>
610constexpr auto operator+(
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()};
617}
618
619/// @brief Subtraction operator for duration types
620/// @tparam Rep1 Representation type of the first duration
621/// @tparam Period1 Period type of the first duration
622/// @tparam Rep2 Representation type of the second duration
623/// @tparam Period2 Period type of the second duration
624/// @param lhs Left-hand side duration
625/// @param rhs Right-hand side duration
626/// @return A duration representing the difference of the two durations
627template <typename Rep1, typename Period1, typename Rep2, typename Period2>
628constexpr auto operator-(
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()};
635}
636
637/// @brief Multiplication operator for duration and scalar
638/// @tparam Rep1 Representation type of the duration
639/// @tparam Period Period type of the duration
640/// @tparam Rep2 Type of the scalar
641/// @param dur The duration
642/// @param scalar The scalar
643/// @return A duration representing the duration multiplied by the scalar
644template <
645 typename Rep1,
646 typename Period,
647 typename Rep2,
657
658/// @brief Multiplication operator for scalar and duration
659/// @tparam Rep1 Type of the scalar
660/// @tparam Rep2 Representation type of the duration
661/// @tparam Period Period type of the duration
662/// @param scalar The scalar
663/// @param dur The duration
664/// @return A duration representing the scalar multiplied by the duration
665template <
666 typename Rep1,
667 typename Rep2,
668 typename Period,
670constexpr auto operator*(Rep1 const& scalar, duration<Rep2, Period> const& dur) noexcept(noexcept(dur * scalar))
672 return dur * scalar;
673}
674
675/// @brief Division operator for duration and scalar
676/// @tparam Rep1 Representation type of the duration
677/// @tparam Period Period type of the duration
678/// @tparam Rep2 Type of the scalar
679/// @param dur The duration
680/// @param scalar The scalar
681/// @return A duration representing the duration divided by the scalar
682template <
683 typename Rep1,
684 typename Period,
685 typename Rep2,
697
698/// @brief Division operator for two durations
699/// @tparam Rep1 Representation type of the first duration
700/// @tparam Period1 Period type of the first duration
701/// @tparam Rep2 Representation type of the second duration
702/// @tparam Period2 Period type of the second duration
703/// @param lhs Left-hand side duration
704/// @param rhs Right-hand side duration
705/// @return The ratio of the two durations as a scalar
706template <typename Rep1, typename Period1, typename Rep2, typename Period2>
707constexpr auto operator/(
708 duration<Rep1, Period1> const& lhs,
709 duration<Rep2, Period2> const& rhs
711 -> std::common_type_t<Rep1, Rep2> {
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()};
714}
715
716/// @brief Modulo operator for duration and scalar
717/// @tparam Rep1 Representation type of the duration
718/// @tparam Period Period type of the duration
719/// @tparam Rep2 Type of the scalar
720/// @param dur The duration
721/// @param scalar The scalar
722/// @return A duration representing the duration modulo the scalar
723template <
724 typename Rep1,
725 typename Period,
726 typename Rep2,
738
739/// @brief Modulo operator for two durations
740/// @tparam Rep1 Representation type of the first duration
741/// @tparam Period1 Period type of the first duration
742/// @tparam Rep2 Representation type of the second duration
743/// @tparam Period2 Period type of the second duration
744/// @param lhs Left-hand side duration
745/// @param rhs Right-hand side duration
746/// @return A duration representing the first duration modulo the second
747template <typename Rep1, typename Period1, typename Rep2, typename Period2>
748constexpr auto operator%(
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()};
755}
756
757// parasoft-end-suppress AUTOSAR-M5_17_1-a
758
759/// @brief Nanoseconds convenience type alias
761
762/// @brief Microseconds convenience type alias
764
765/// @brief Milliseconds convenience type alias
767
768/// @brief Seconds convenience type alias
770
771// NOLINTBEGIN(readability-magic-numbers) These are named constants to replace users' magic numbers
772/// @brief Seconds convenience type alias
774
775/// @brief Hours convenience type alias
776using hours = duration<std::int32_t, std::ratio<3600>>;
777// NOLINTEND(readability-magic-numbers)
778
779} // namespace chrono
780} // namespace std
781
782#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_DURATION_HPP_
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