This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

214
cppdraft/time/traits.md Normal file
View File

@@ -0,0 +1,214 @@
[time.traits]
# 30 Time library [[time]](./#time)
## 30.4 Time-related traits [time.traits]
### [30.4.1](#is.fp) treat_as_floating_point [[time.traits.is.fp]](time.traits.is.fp)
[🔗](#lib:treat_as_floating_point)
`template<class Rep> struct treat_as_floating_point : is_floating_point<Rep> { };
`
[1](#is.fp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1071)
The duration template uses the treat_as_floating_point trait to
help determine if a duration object can be converted to anotherduration with a different tick period[.](#is.fp-1.sentence-1)
Iftreat_as_floating_point_v<Rep> is true, then implicit conversions
are allowed among durations[.](#is.fp-1.sentence-2)
Otherwise, the implicit convertibility
depends on the tick periods of the durations[.](#is.fp-1.sentence-3)
[*Note [1](#is.fp-note-1)*:
The intention of this trait is to indicate whether a given class behaves like a floating-point
type, and thus allows division of one value by another with acceptable loss of precision[.](#is.fp-1.sentence-4)
Iftreat_as_floating_point_v<Rep> is false, Rep will be treated as
if it behaved like an integral type for the purpose of these conversions[.](#is.fp-1.sentence-5)
— *end note*]
### [30.4.2](#duration.values) duration_values [[time.traits.duration.values]](time.traits.duration.values)
[🔗](#lib:duration_values)
`template<class Rep>
struct duration_values {
public:
static constexpr Rep zero() noexcept;
static constexpr Rep min() noexcept;
static constexpr Rep max() noexcept;
};
`
[1](#duration.values-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1098)
The duration template uses the duration_values trait to
construct special values of the duration's representation (Rep)[.](#duration.values-1.sentence-1)
This is
done because the representation can be a class type with behavior that
requires some other implementation to return these special values[.](#duration.values-1.sentence-2)
In that case,
the author of that class type should specialize duration_values to
return the indicated values[.](#duration.values-1.sentence-3)
[🔗](#lib:zero,duration_values)
`static constexpr Rep zero() noexcept;
`
[2](#duration.values-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1112)
*Returns*: Rep(0)[.](#duration.values-2.sentence-1)
[*Note [1](#duration.values-note-1)*:
Rep(0) is specified instead ofRep() because Rep() can have some other meaning, such as an
uninitialized value[.](#duration.values-2.sentence-2)
— *end note*]
[3](#duration.values-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1121)
*Remarks*: The value returned shall be the additive identity[.](#duration.values-3.sentence-1)
[🔗](#lib:min,duration_values)
`static constexpr Rep min() noexcept;
`
[4](#duration.values-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1132)
*Returns*: numeric_limits<Rep>::lowest()[.](#duration.values-4.sentence-1)
[5](#duration.values-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1136)
*Remarks*: The value returned shall compare less than or equal to zero()[.](#duration.values-5.sentence-1)
[🔗](#lib:max,duration_values)
`static constexpr Rep max() noexcept;
`
[6](#duration.values-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1147)
*Returns*: numeric_limits<Rep>::max()[.](#duration.values-6.sentence-1)
[7](#duration.values-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1151)
*Remarks*: The value returned shall compare greater than zero()[.](#duration.values-7.sentence-1)
### [30.4.3](#specializations) Specializations of common_type [[time.traits.specializations]](time.traits.specializations)
[🔗](#lib:common_type)
`template<class Rep1, class Period1, class Rep2, class Period2>
struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
using type = chrono::duration<common_type_t<Rep1, Rep2>, see below>;
};
`
[1](#specializations-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1166)
The period of the duration indicated by this specialization ofcommon_type is the greatest common divisor of Period1 andPeriod2[.](#specializations-1.sentence-1)
[*Note [1](#specializations-note-1)*:
This can be computed by forming a ratio of the
greatest common divisor of Period1::num and Period2::num and the
least common multiple of Period1::den and Period2::den[.](#specializations-1.sentence-2)
— *end note*]
[2](#specializations-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1176)
[*Note [2](#specializations-note-2)*:
The typedef name type is a synonym for theduration with the largest tick period possible where bothduration arguments will convert to it without requiring a division
operation[.](#specializations-2.sentence-1)
The representation of this type is intended to be able to hold any
value resulting from this conversion with no truncation error, although
floating-point durations can have round-off errors[.](#specializations-2.sentence-2)
— *end note*]
[🔗](#lib:common_type,duration)
`template<class Clock, class Duration1, class Duration2>
struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>> {
using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
};
`
[3](#specializations-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1194)
The common type of two time_point types is a time_point with the same
clock as the two types and the common type of their two durations[.](#specializations-3.sentence-1)
### [30.4.4](#is.clock) Class template is_clock [[time.traits.is.clock]](time.traits.is.clock)
[🔗](#lib:is_clock)
`template<class T> struct is_clock;
`
[1](#is.clock-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1205)
is_clock is a [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2Requirements[meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2Requirements"))
with a base characteristic of true_type if T meets the [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3Cpp17Clock requirements[time.clock.req]") requirements ([[time.clock.req]](time.clock.req "30.3Cpp17Clock requirements")),
otherwise false_type[.](#is.clock-1.sentence-1)
For the purposes of the specification of this trait,
the extent to which an implementation determines
that a type cannot meet the [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3Cpp17Clock requirements[time.clock.req]") requirements is unspecified,
except that as a minimum
a type T shall not qualify as a [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3Cpp17Clock requirements[time.clock.req]") unless it meets all of the following conditions:
- [(1.1)](#is.clock-1.1)
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")*s*T::rep,T::period,T::duration, andT::time_point are valid and each denotes a type ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction")),
- [(1.2)](#is.clock-1.2)
the expressionT::is_steady is well-formed when treated as an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3Context dependence[expr.context]"),
- [(1.3)](#is.clock-1.3)
the expressionT::now() is well-formed when treated as an unevaluated operand[.](#is.clock-1.sentence-2)
[2](#is.clock-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1231)
The behavior of a program that adds specializations for is_clock is undefined[.](#is.clock-2.sentence-1)