Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 22

 

  Главная      Manuals     Working Draft, Standard for Programming Language C++ (N4713, 2017 year)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     20      21      22      23     ..

 

 

 

Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 22

 

 

Table 40 — Primary type category predicates
Template
Condition
Comments
template<class T>
T is void
struct is_void;
template<class T>
T is nullptr_t (6.7.1)
struct is_null_pointer;
template<class T>
T is an integral type (6.7.1)
struct is_integral;
template<class T>
T is a floating-point
struct is_floating_point;
type (6.7.1)
template<class T>
T is an array type (6.7.2) of
Class template
struct is_array;
known or unknown extent
array (26.3.7) is not an
array type.
template<class T>
T is a pointer type (6.7.2)
Includes pointers to
struct is_pointer;
functions but not pointers
to non-static members.
template<class T>
T is an lvalue reference
struct is_lvalue_reference;
type (11.3.2)
template<class T>
T is an rvalue reference
struct is_rvalue_reference;
type (11.3.2)
template<class T>
T is a pointer to data
struct is_member_object_pointer;
member
template<class T>
T is a pointer to member
struct
function
is_member_function_pointer;
template<class T>
T is an enumeration
struct is_enum;
type (6.7.2)
template<class T>
T is a union type (6.7.2)
struct is_union;
template<class T>
T is a non-union class
struct is_class;
type (6.7.2)
template<class T>
T is a function type (6.7.2)
struct is_function;
23.15.4.2
Composite type traits
[meta.unary.comp]
1
These templates provide convenient compositions of the primary type categories, corresponding to the
descriptions given in subclause 6.7.
2
For any given type T, the result of applying one of these templates to T and to cv T shall yield the same
result.
Table 41 — Composite type category predicates
Template
Condition
Comments
template<class T>
T is an lvalue reference or
struct is_reference;
an rvalue reference
template<class T>
T is an arithmetic
struct is_arithmetic;
type (6.7.1)
template<class T>
T is a fundamental
struct is_fundamental;
type (6.7.1)
template<class T>
T is an object type (6.7)
struct is_object;
template<class T>
T is a scalar type (6.7)
struct is_scalar;
template<class T>
T is a compound
struct is_compound;
type (6.7.2)
§ 23.15.4.2
622
Table 41 — Composite type category predicates (continued)
Template
Condition
Comments
template<class T>
T is a pointer-to-member
struct is_member_pointer;
type (6.7.2)
23.15.4.3
Type properties
[meta.unary.prop]
1
These templates provide access to some of the more important properties of types.
2
It is unspecified whether the library defines any full or partial specializations of any of these templates.
3
For all of the class templates X declared in this subclause, instantiating that template with a template-
argument that is a class template specialization may result in the implicit instantiation of the template
argument if and only if the semantics of X require that the argument is a complete type.
4
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any
type T is considered to be a trivial (6.7, Clause 15) function call that is not an odr-use (6.2) of declval in
the context of the corresponding definition notwithstanding the restrictions of 23.2.6.
Table
42
— Type property predicates
Template
Condition
Preconditions
template<class T>
T is const-qualified (6.7.3)
struct is_const;
template<class T>
T is
struct is_volatile;
volatile-qualified (6.7.3)
template<class T>
T is a trivial type (6.7)
remove_all_extents_-
struct is_trivial;
t<T> shall be a complete
type or cv void.
template<class T>
T is a trivially copyable
remove_all_extents_-
struct is_trivially_copyable;
type (6.7)
t<T> shall be a complete
type or cv void.
template<class T>
T is a standard-layout
remove_all_extents_-
struct is_standard_layout;
type (6.7)
t<T> shall be a complete
type or cv void.
template<class T>
T is a class type, but not a
If T is a non-union class
struct is_empty;
union type, with no
type, T shall be a complete
non-static data members
type.
other than bit-fields of
length 0, no virtual
member functions, no
virtual base classes, and no
base class B for which
is_empty_v<B> is false.
template<class T>
T is a polymorphic
If T is a non-union class
struct is_polymorphic;
class (13.3)
type, T shall be a complete
type.
template<class T>
T is an abstract class (13.4)
If T is a non-union class
struct is_abstract;
type, T shall be a complete
type.
template<class T>
T is a class type marked
If T is a class type, T shall
struct is_final;
with the class-virt-specifier
be a complete type.
final (Clause 12). [ Note:
A union is a class type
that can be marked with
final.
— end note ]
template<class T>
T is an aggregate
remove_all_extents_-
struct is_aggregate;
type (11.6.1)
t<T> shall be a complete
type or cv void.
§
23.15.4.3
623
Table 42 — Type property predicates (continued)
Template
Condition
Preconditions
template<class T>
If is_arithmetic_v<T> is
struct is_signed;
true, the same result as
T(-1) < T(0); otherwise,
false
template<class T>
If is_arithmetic_v<T> is
struct is_unsigned;
true, the same result as
T(0) < T(-1); otherwise,
false
template<class T, class... Args>
For a function type T or
T and all types in the
struct is_constructible;
for a cv void type T,
parameter pack Args shall
is_constructible_v<T,
be complete types,
Args...> is false,
cv void, or arrays of
otherwise see below
unknown bound.
template<class T>
is_constructible_v<T>
T shall be a complete type,
struct is_default_constructible;
is true.
cv void, or an array of
unknown bound.
template<class T>
For a referenceable type
T shall be a complete type,
struct is_copy_constructible;
T (20.3.18), the same result
cv void, or an array of
as
unknown bound.
is_constructible_v<T,
const T&>, otherwise
false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_move_constructible;
the same result as
cv void, or an array of
is_constructible_v<T,
unknown bound.
T&&>, otherwise false.
template<class T, class
U>
The expression
T and U shall be complete
struct
is_assignable;
declval<T>() =
types, cv void, or arrays
declval<U>() is
of unknown bound.
well-formed when treated
as an unevaluated
operand (8.2). Access
checking is performed as if
in a context unrelated to T
and U. Only the validity of
the immediate context of
the assignment expression
is considered. [ Note: The
compilation of the
expression can result in
side effects such as the
instantiation of class
template specializations
and function template
specializations, the
generation of
implicitly-defined
functions, and so on. Such
side effects are not in the
“immediate context” and
can result in the program
being ill-formed.
— end
note ]
§ 23.15.4.3
624
Table
42
— Type property predicates (continued)
Template
Condition
Preconditions
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_copy_assignable;
the same result as
cv void, or an array of
is_assignable_v<T&,
unknown bound.
const T&>, otherwise
false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_move_assignable;
the same result as
cv void, or an array of
is_assignable_v<T&,
unknown bound.
T&&>, otherwise false.
template<class T, class U>
The expressions
T and U shall be complete
struct
is_swappable_with;
swap(declval<T>(),
types, cv void, or arrays
declval<U>()) and
of unknown bound.
swap(declval<U>(),
declval<T>()) are each
well-formed when treated
as an unevaluated
operand (8.2) in an
overload-resolution context
for swappable
values (20.5.3.2). Access
checking is performed as if
in a context unrelated to T
and U. Only the validity of
the immediate context of
the swap expressions is
considered. [ Note: The
compilation of the
expressions can result in
side effects such as the
instantiation of class
template specializations
and function template
specializations, the
generation of
implicitly-defined
functions, and so on. Such
side effects are not in the
“immediate context” and
can result in the program
being ill-formed.
— end
note ]
template<class
T>
For a referenceable type T,
T shall be a complete type,
struct is_swappable;
the same result as is_-
cv void, or an array of
swappable_with_v<T&,
unknown bound.
T&>, otherwise false.
template<class T>
Either T is a reference
T shall be a complete type,
struct is_destructible;
type, or T is a complete
cv void, or an array of
object type for which the
unknown bound.
expression
declval<U&>().~U() is
well-formed when treated
as an unevaluated
operand (8.2), where U is
remove_all_extents_-
t<T>.
§
23.15.4.3
625
Table 42 — Type property predicates (continued)
Template
Condition
Preconditions
template<class T, class... Args>
is_constructible_v<T,
T and all types in the
struct
Args...> is true and the
parameter pack Args shall
is_trivially_constructible;
variable definition for
be complete types,
is_constructible, as
cv void, or arrays of
defined below, is known to
unknown bound.
call no operation that is
not trivial (6.7, Clause 15).
template<class T>
is_trivially_-
T shall be a complete type,
struct
constructible_v<T> is
cv void, or an array of
is_trivially_default_constructible;
true.
unknown bound.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_trivially_copy_constructible;
is_trivially_-
unknown bound.
constructible_v<T,
const T&>, otherwise
false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_trivially_move_constructible;
is_trivially_-
unknown bound.
constructible_v<T,
T&&>, otherwise false.
template<class T, class U>
is_assignable_v<T, U>
T and U shall be complete
struct is_trivially_assignable;
is true and the
types, cv void, or arrays
assignment, as defined by
of unknown bound.
is_assignable, is known
to call no operation that is
not trivial
(6.7, Clause
15).
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_trivially_copy_assignable;
is_trivially_-
unknown bound.
assignable_v<T&, const
T&>, otherwise false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_trivially_move_assignable;
is_trivially_-
unknown bound.
assignable_v<T&, T&&>,
otherwise false.
template<class T>
is_destructible_v<T> is
T shall be a complete type,
struct is_trivially_destructible;
true and remove_all_-
cv void, or an array of
extents_t<T> is either a
unknown bound.
non-class type or a class
type with a trivial
destructor.
template<class T, class... Args>
is_constructible_v<T,
T and all types in the
struct is_nothrow_constructible;
Args...> is true and the
parameter pack Args shall
variable definition for
be complete types,
is_constructible, as
cv void, or arrays of
defined below, is known
unknown bound.
not to throw any
exceptions (8.5.2.7).
template<class T>
is_nothrow_-
T shall be a complete type,
struct
constructible_v<T> is
cv void, or an array of
is_nothrow_default_constructible;
true.
unknown bound.
§ 23.15.4.3
626
Table 42 — Type property predicates (continued)
Template
Condition
Preconditions
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_nothrow_copy_constructible;
is_nothrow_-
unknown bound.
constructible_v<T,
const T&>, otherwise
false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct
the same result as
cv void, or an array of
is_nothrow_move_constructible;
is_nothrow_-
unknown bound.
constructible_v<T,
T&&>, otherwise false.
template<class T, class U>
is_assignable_v<T, U>
T and U shall be complete
struct is_nothrow_assignable;
is true and the assignment
types, cv void, or arrays
is known not to throw any
of unknown bound.
exceptions (8.5.2.7).
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_nothrow_copy_assignable;
the same result as
cv void, or an array of
is_nothrow_-
unknown bound.
assignable_v<T&, const
T&>, otherwise false.
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_nothrow_move_assignable;
the same result as
cv void, or an array of
is_nothrow_-
unknown bound.
assignable_v<T&, T&&>,
otherwise false.
template<class T, class U>
is_swappable_with_v<T,
T and U shall be complete
struct is_nothrow_swappable_with;
U> is true and each swap
types, cv void, or arrays
expression of the definition
of unknown bound.
of is_swappable_with<T,
U> is known not to throw
any exceptions (8.5.2.7).
template<class T>
For a referenceable type T,
T shall be a complete type,
struct is_nothrow_swappable;
the same result as
cv void, or an array of
is_nothrow_swappable_-
unknown bound.
with_v<T&, T&>,
otherwise false.
template<class T>
is_destructible_v<T> is
T shall be a complete type,
struct is_nothrow_destructible;
true and the indicated
cv void, or an array of
destructor is known not to
unknown bound.
throw any
exceptions (8.5.2.7).
template<class T>
T has a virtual
If T is a non-union class
struct has_virtual_destructor;
destructor (15.4)
type, T shall be a complete
type.
template<class T>
For an array type T, the
T shall be a complete type,
struct
same result as
cv void, or an array of
has_unique_object_representations;
has_unique_object_-
unknown bound.
representations_-
v<remove_all_extents_-
t<T>>, otherwise see
below.
5
[ Example:
§ 23.15.4.3
627
is_const_v<const volatile int>
// true
is_const_v<const int*>
// false
is_const_v<const int&>
// false
is_const_v<int[3]>
// false
is_const_v<const int[3]>
// true
— end example ]
6
[ Example:
remove_const_t<const volatile int>
// volatile int
remove_const_t<const int* const>
// const int*
remove_const_t<const int&>
// const int&
remove_const_t<const int[3]>
// int[3]
— end example ]
7
[ Example:
// Given:
struct P final { };
union U1 { };
union U2 final { };
// the following assertions hold:
static_assert(!is_final_v<int>);
static_assert(is_final_v<P>);
static_assert(!is_final_v<U1>);
static_assert(is_final_v<U2>);
— end example ]
8
The predicate condition for a template specialization is_constructible<T,
Args...> shall be satisfied if
and only if the following variable definition would be well-formed for some invented variable t:
T t(declval<Args>()...);
[Note: These tokens are never interpreted as a function declaration.
— end note ] Access checking is
performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context
of the variable initialization is considered.
[Note: The evaluation of the initialization can result in side
effects such as the instantiation of class template specializations and function template specializations, the
generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context”
and can result in the program being ill-formed.
— end note ]
9
The predicate condition for a template specialization has_unique_object_representations<T> shall be
satisfied if and only if:
(9.1)
T is trivially copyable, and
(9.2)
any two objects of type T with the same value have the same object representation, where two objects
of array or non-union class type are considered to have the same value if their respective sequences of
direct subobjects have the same values, and two objects of union type are considered to have the same
value if they have the same active member and the corresponding members have the same value.
The set of scalar types for which this condition holds is implementation-defined. [ Note: If a type has padding
bits, the condition does not hold; otherwise, the condition holds true for unsigned integral types.
— end
note ]
23.15.5
Type property queries
[meta.unary.prop.query]
1
This subclause contains templates that may be used to query properties of types at compile time.
Table 43 — Type property queries
Template
Value
template<class T>
alignof(T).
struct alignment_of;
Requires: alignof(T) shall be a valid expression (8.5.2.6)
template<class T>
If T names an array type, an integer value representing the number of
struct rank;
dimensions of T; otherwise, 0.
§ 23.15.5
628
Table 43 — Type property queries (continued)
Template
Value
template<class T,
If T is not an array type, or if it has rank less than or equal to I, or if
unsigned I = 0>
I is 0 and T has type “array of unknown bound of U”, then 0;
struct extent;
otherwise, the bound (11.3.4) of the I’th dimension of T, where
indexing of I is zero-based
2
Each of these templates shall be a UnaryTypeTrait (23.15.1) with a base characteristic of integral_-
constant<size_t, Value>.
3
[ Example:
// the following assertions hold:
assert(rank_v<int> == 0);
assert(rank_v<int[2]> == 1);
assert(rank_v<int[][4]> == 2);
— end example ]
4
[ Example:
// the following assertions hold:
assert(extent_v<int> == 0);
assert(extent_v<int[2]> == 2);
assert(extent_v<int[2][4]> == 2);
assert(extent_v<int[][4]> == 0);
assert((extent_v<int, 1>) == 0);
assert((extent_v<int[2], 1>) == 0);
assert((extent_v<int[2][4], 1>) == 4);
assert((extent_v<int[][4], 1>) == 4);
— end example ]
23.15.6
Relationships between types
[meta.rel]
1
This subclause contains templates that may be used to query relationships between types at compile time.
2
Each of these templates shall be a BinaryTypeTrait (23.15.1) with a base characteristic of true_type if the
corresponding condition is true, otherwise false_type.
Table 44 — Type relationship predicates
Template
Condition
Comments
template<class T, class U>
T and U name the same type
struct is_same;
with the same
cv-qualifications
template<class Base, class
Base is a base class of
If Base and Derived are
Derived>
Derived (Clause 13) without
non-union class types and are
struct is_base_of;
regard to cv-qualifiers or Base
not possibly cv-qualified
and Derived are not unions
versions of the same type,
and name the same class type
Derived shall be a complete
without regard to cv-qualifiers
type. [ Note: Base classes that
are private, protected, or
ambiguous are, nonetheless,
base classes.
— end note ]
template<class From, class To>
see below
From and To shall be complete
struct is_convertible;
types, arrays of unknown
bound, or cv void types.
template<class Fn, class...
The expression
Fn and all types in the
ArgTypes>
INVOKE(declval<Fn>(),
parameter pack ArgTypes shall
struct is_invocable;
declval<ArgTypes>()...)
be complete types, cv void, or
is well-formed when treated as
arrays of unknown bound.
an unevaluated operand
§ 23.15.6
629
Table 44 — Type relationship predicates (continued)
Template
Condition
Comments
template<class R, class Fn,
The expression
Fn, R, and all types in the
class... ArgTypes>
INVOKE<R>(declval<Fn>(),
parameter pack ArgTypes shall
struct is_invocable_r;
declval<ArgTypes>()...)
be complete types, cv void, or
is well-formed when treated as
arrays of unknown bound.
an unevaluated operand
template<class Fn, class...
is_invocable_v<
Fn and all types in the
ArgTypes>
Fn, ArgTypes...> is true
parameter pack ArgTypes shall
struct is_nothrow_invocable;
and the expression
be complete types, cv void, or
INVOKE(declval<Fn>(),
arrays of unknown bound.
declval<ArgTypes>()...)
is known not to throw any
exceptions
template<class R, class Fn,
is_invocable_r_v<
Fn, R, and all types in the
class... ArgTypes>
R, Fn, ArgTypes...> is
parameter pack ArgTypes shall
struct is_nothrow_invocable_r;
true and the expression
be complete types, cv void, or
INVOKE<R>(declval<Fn>(),
arrays of unknown bound.
declval<ArgTypes>()...)
is known not to throw any
exceptions
3
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any
type T is considered to be a trivial (6.7, Clause 15) function call that is not an odr-use (6.2) of declval in
the context of the corresponding definition notwithstanding the restrictions of 23.2.6.
4
[ Example:
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : private B1, private B2 {};
is_base_of_v<B, D>
// true
is_base_of_v<const B, D>
// true
is_base_of_v<B, const D>
// true
is_base_of_v<B, const B>
// true
is_base_of_v<D, B>
// false
is_base_of_v<B&, D&>
// false
is_base_of_v<B[3], D[3]>
// false
is_base_of_v<int, int>
// false
— end example ]
5
The predicate condition for a template specialization is_convertible<From, To> shall be satisfied if and
only if the return expression in the following code would be well-formed, including any implicit conversions
to the return type of the function:
To test() {
return declval<From>();
}
[ Note: This requirement gives well-defined results for reference types, void types, array types, and function
types. — end note ] Access checking is performed in a context unrelated to To and From. Only the validity of
the immediate context of the expression of the return statement (including initialization of the returned
object or reference) is considered. [ Note: The initialization can result in side effects such as the instantiation
of class template specializations and function template specializations, the generation of implicitly-defined
functions, and so on. Such side effects are not in the “immediate context” and can result in the program
being ill-formed.
— end note ]
§ 23.15.6
630
23.15.7
Transformations between types
[meta.trans]
1
This subclause contains templates that may be used to transform one type to another following some
predefined rule.
2
Each of the templates in this subclause shall be a TransformationTrait (23.15.1).
23.15.7.1
Const-volatile modifications
[meta.trans.cv]
Table 45 — Const-volatile modifications
Template
Comments
template<class T>
The member typedef type names the same type as T except that any
struct remove_const;
top-level const-qualifier has been removed. [ Example:
remove_const_t<const volatile int> evaluates to volatile int,
whereas remove_const_t<const int*> evaluates to const int*.
— end example ]
template<class T>
The member typedef type names the same type as T except that any
struct remove_volatile;
top-level volatile-qualifier has been removed. [ Example:
remove_volatile_t<const volatile int> evaluates to const int,
whereas remove_volatile_t<volatile int*> evaluates to
volatile int*. — end example ]
template<class T>
The member typedef type shall be the same as T except that any
struct remove_cv;
top-level cv-qualifier has been removed. [ Example:
remove_cv_t<const volatile int> evaluates to int, whereas
remove_cv_t<const volatile int*> evaluates to const volatile
int*.
— end example ]
template<class T>
If T is a reference, function, or top-level const-qualified type, then
struct add_const;
type names the same type as T, otherwise T const.
template<class T>
If T is a reference, function, or top-level volatile-qualified type, then
struct add_volatile;
type names the same type as T, otherwise T volatile.
template<class T>
The member typedef type names the same type as
struct add_cv;
add_const_t<add_volatile_t<T>>.
23.15.7.2
Reference modifications
[meta.trans.ref]
Table 46 — Reference modifications
Template
Comments
template<class T>
If T has type “reference to T1” then the member typedef type names
struct remove_reference;
T1; otherwise, type names T.
template<class T>
If T names a referenceable type (20.3.18) then the member typedef
struct
type names T&; otherwise, type names T. [ Note: This rule reflects
add_lvalue_reference;
the semantics of reference collapsing (11.3.2).
— end note ]
template<class T>
If T names a referenceable type then the member typedef type names
struct
T&&; otherwise, type names T. [ Note: This rule reflects the semantics
add_rvalue_reference;
of reference collapsing (11.3.2). For example, when a type T names a
type T1&, the type add_rvalue_reference_t<T> is not an rvalue
reference.
— end note ]
23.15.7.3
Sign modifications
[meta.trans.sign]
§ 23.15.7.3
631
Table 47 — Sign modifications
Template
Comments
template<class T>
If T names a (possibly cv-qualified) signed integer type (6.7.1) then
struct make_signed;
the member typedef type names the type T; otherwise, if T names a
(possibly cv-qualified) unsigned integer type then type names the
corresponding signed integer type, with the same cv-qualifiers as T;
otherwise, type names the signed integer type with smallest
rank (6.7.4) for which sizeof(T) == sizeof(type), with the same
cv-qualifiers as T.
Requires: T shall be a (possibly cv-qualified) integral type or
enumeration but not a bool type.
template<class T>
If T names a (possibly cv-qualified) unsigned integer type (6.7.1) then
struct make_unsigned;
the member typedef type names the type T; otherwise, if T names a
(possibly cv-qualified) signed integer type then type names the
corresponding unsigned integer type, with the same cv-qualifiers as T;
otherwise, type names the unsigned integer type with smallest
rank (6.7.4) for which sizeof(T) == sizeof(type), with the same
cv-qualifiers as T.
Requires: T shall be a (possibly cv-qualified) integral type or
enumeration but not a bool type.
23.15.7.4
Array modifications
[meta.trans.arr]
Table 48 — Array modifications
Template
Comments
template<class T>
If T names a type “array of U”, the member typedef type shall be U,
struct remove_extent;
otherwise T. [ Note: For multidimensional arrays, only the first array
dimension is removed. For a type “array of const U”, the resulting
type is const U. — end note ]
template<class T>
If T is “multi-dimensional array of U”, the resulting member typedef
struct remove_all_extents;
type is U, otherwise T.
1
[ Example:
// the following assertions hold:
assert((is_same_v<remove_extent_t<int>, int>));
assert((is_same_v<remove_extent_t<int[2]>, int>));
assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
— end example ]
2
[ Example:
// the following assertions hold:
assert((is_same_v<remove_all_extents_t<int>, int>));
assert((is_same_v<remove_all_extents_t<int[2]>, int>));
assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
— end example ]
23.15.7.5
Pointer modifications
[meta.trans.ptr]
Table 49 — Pointer modifications
Template
Comments
template<class T>
If T has type “(possibly cv-qualified) pointer to T1” then the member
struct remove_pointer;
typedef type names T1; otherwise, it names T.
§ 23.15.7.5
632
Table 49 — Pointer modifications (continued)
Template
Comments
template<class T>
If T names a referenceable type (20.3.18) or a cv void type then the
struct add_pointer;
member typedef type names the same type as
remove_reference_t<T>*; otherwise, type names T.
23.15.7.6
Other transformations
[meta.trans.other]
Table 50 — Other transformations
Template
Comments
template<size_t Len,
The value of default-alignment shall be the most stringent alignment
size_t Align
requirement for any C++ object type whose size is no greater than
= default-alignment >
Len (6.7). The member typedef type shall be a trivial type suitable
struct aligned_storage;
for use as uninitialized storage for any object whose size is at most
Len and whose alignment is a divisor of Align.
Requires: Len shall not be zero. Align shall be equal to alignof(T)
for some type T or to default-alignment.
template<size_t Len,
The member typedef type shall be a trivial type suitable for use as
class... Types>
uninitialized storage for any object whose type is listed in Types; its
struct aligned_union;
size shall be at least Len. The static member alignment_value shall
be an integral constant of type size_t whose value is the strictest
alignment of all types listed in Types.
Requires: At least one type is provided. Each type in the parameter
pack Types shall be a complete object type.
template<class T>
The member typedef type names the same type as
struct remove_cvref;
remove_cv_t<remove_reference_t<T>>.
template<class T>
Let U be remove_reference_t<T>. If is_array_v<U> is true, the
struct decay;
member typedef type shall equal remove_extent_t<U>*. If
is_function_v<U> is true, the member typedef type shall equal
add_pointer_t<U>. Otherwise the member typedef type equals
remove_cv_t<U>. [ Note: This behavior is similar to the
lvalue-to-rvalue (7.1), array-to-pointer (7.2), and
function-to-pointer (7.3) conversions applied when an lvalue
expression is used as an rvalue, but also strips cv-qualifiers from class
types in order to more closely model by-value argument passing.
— end note ]
template<bool B, class
T
=
If B is true, the member typedef type shall equal T; otherwise, there
void> struct enable_if;
shall be no member type.
template<bool B, class
T,
If B is true, the member typedef type shall equal T. If B is false,
class F>
the member typedef type shall equal F.
struct conditional;
template<class... T>
Unless this trait is specialized (as specified in Note B, below), the
struct common_type;
member type shall be defined or omitted as specified in Note A,
below. If it is omitted, there shall be no member type. Each type in
the parameter pack T shall be complete, cv void, or an array of
unknown bound.
template<class T>
The member typedef type names the underlying type of T.
struct underlying_type;
Requires: T shall be a complete enumeration type (10.2)
§ 23.15.7.6
633
Table 50 — Other transformations (continued)
Template
Comments
template<class Fn,
If the expression INVOKE(declval<Fn>(),
class... ArgTypes>
declval<ArgTypes>()...) is well-formed when treated as an
struct invoke_result;
unevaluated operand (8.2), the member typedef type names the type
decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));
otherwise, there shall be no member type. Access checking is
performed as if in a context unrelated to Fn and ArgTypes. Only the
validity of the immediate context of the expression is considered.
[ Note: The compilation of the expression can result in side effects
such as the instantiation of class template specializations and
function template specializations, the generation of implicitly-defined
functions, and so on. Such side effects are not in the “immediate
context” and can result in the program being ill-formed.
— end note ]
Requires: Fn and all types in the parameter pack ArgTypes shall be
complete types, cv void, or arrays of unknown bound.
1
[ Note: A typical implementation would define aligned_storage as:
template<size_t Len, size_t Alignment>
struct aligned_storage {
typedef struct {
alignas(Alignment) unsigned char __data[Len];
} type;
};
— end note ]
2
It is implementation-defined whether any extended alignment is supported (6.6.5).
3
Note A: For the common_type trait applied to a parameter pack T of types, the member type shall be either
defined or not present as follows:
(3.1)
If sizeof...(T) is zero, there shall be no member type.
(3.2)
If sizeof...(T) is one, let T0 denote the sole type constituting the pack T. The member typedef-name
type shall denote the same type, if any, as common_type_t<T0, T0>; otherwise there shall be no
member type.
(3.3)
If sizeof...(T) is two, let the first and second types constituting T be denoted by T1 and T2,
respectively, and let D1 and D2 denote the same types as decay_t<T1> and decay_t<T2>, respectively.
(3.3.1)
If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false, let C denote the same type, if
any, as common_type_t<D1, D2>.
(3.3.2)
Otherwise, let C denote the same type, if any, as
decay_t<decltype(false ? declval<D1>() : declval<D2>())>
[ Note: This will not apply if there is a specialization common_type<D1, D2>.
— end note ]
In either case, the member typedef-name type shall denote the same type, if any, as C. Otherwise, there
shall be no member type.
(3.4)
If sizeof...(T) is greater than two, let T1, T2, and R, respectively, denote the first, second, and
(pack of) remaining types constituting T. Let C denote the same type, if any, as common_type_t<T1,
T2>. If there is such a type C, the member typedef-name type shall denote the same type, if any, as
common_type_t<C, R...>. Otherwise, there shall be no member type.
4
Note B: Notwithstanding the provisions of 23.15.2, and pursuant to 20.5.4.2.1, a program may specialize
common_type<T1, T2> for types T1 and T2 such that is_same_v<T1, decay_t<T1>> and is_same_v<T2,
decay_t<T2>> are each true. [ Note: Such specializations are needed when only explicit conversions are
desired between the template arguments.
— end note ] Such a specialization need not have a member named
type, but if it does, that member shall be a typedef-name for an accessible and unambiguous cv-unqualified
§ 23.15.7.6
634
non-reference type C to which each of the types T1 and T2 is explicitly convertible. Moreover, common_type_-
t<T1, T2> shall denote the same type, if any, as does common_type_t<T2, T1>. No diagnostic is required
for a violation of this Note’s rules.
5
[ Example: Given these definitions:
using PF1 = bool
(&)();
using PF2 = short (*)(long);
struct S {
operator PF2() const;
double operator()(char, int&);
void fn(long) const;
char data;
};
using PMF = void (S::*)(long) const;
using PMD = char S::*;
the following assertions will hold:
static_assert(is_same_v<invoke_result_t<S, int>, short>);
static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
static_assert(is_same_v<invoke_result_t<PF1>, bool>);
static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
— end example ]
23.15.8
Logical operator traits
[meta.logical]
1
This subclause describes type traits for applying logical operators to other type traits.
template<class... B> struct conjunction : see below
{ };
2
The class template conjunction forms the logical conjunction of its template type arguments.
3
For a specialization conjunction<B1, ..., BN>, if there is a template type argument Bi for which
bool(Bi::value) is false, then instantiating conjunction<B1, ..., BN>::value does not require
the instantiation of Bj::value for j > i. [ Note: This is analogous to the short-circuiting behavior of
the built-in operator &&.
— end note ]
4
Every template type argument for which Bi::value is instantiated shall be usable as a base class and
shall have a member value which is convertible to bool, is not hidden, and is unambiguously available
in the type.
5
The specialization conjunction<B1, ..., BN> has a public and unambiguous base that is either
(5.1)
the first type Bi in the list true_type, B1, ..., BN for which bool(Bi::value) is false, or
(5.2)
if there is no such Bi, the last type in the list.
[ Note: This means a specialization of conjunction does not necessarily inherit from either true_type
or false_type.
— end note ]
6
The member names of the base class, other than conjunction and operator=, shall not be hidden
and shall be unambiguously available in conjunction.
template<class... B> struct disjunction : see below
{ };
7
The class template disjunction forms the logical disjunction of its template type arguments.
8
For a specialization disjunction<B1, ..., BN>, if there is a template type argument Bi for which
bool(Bi::value) is true, then instantiating disjunction<B1, ..., BN>::value does not require
the instantiation of Bj::value for j > i. [ Note: This is analogous to the short-circuiting behavior of
the built-in operator ||.
— end note ]
9
Every template type argument for which Bi::value is instantiated shall be usable as a base class and
shall have a member value which is convertible to bool, is not hidden, and is unambiguously available
in the type.
10
The specialization disjunction<B1, ..., BN> has a public and unambiguous base that is either
§ 23.15.8
635
(10.1)
the first type Bi in the list false_type, B1, ..., BN for which bool(Bi::value) is true, or
(10.2)
if there is no such Bi, the last type in the list.
[ Note: This means a specialization of disjunction does not necessarily inherit from either true_type
or false_type.
— end note ]
11
The member names of the base class, other than disjunction and operator=, shall not be hidden
and shall be unambiguously available in disjunction.
template<class B> struct negation : see below
{ };
12
The class template negation forms the logical negation of its template type argument. The type
negation<B> is a UnaryTypeTrait with a base characteristic of bool_constant<!bool(B::value)>.
23.15.9
Endian
[meta.endian]
1
Two common methods of byte ordering in multibyte scalar types are big-endian and little-endian in the
execution environment. Big-endian is a format for storage of binary data in which the most significant byte
is placed first, with the rest in descending order. Little-endian is a format for storage of binary data in
which the least significant byte is placed first, with the rest in ascending order. This subclause describes the
endianness of the scalar types of the execution environment.
enum class endian {
little = see below ,
big
= see below ,
native = see below
};
2
If all scalar types have size 1 byte, then all of endian::little, endian::big, and endian::native
have the same value. Otherwise, endian::little is not equal to endian::big. If all scalar types are big-
endian, endian::native is equal to endian::big. If all scalar types are little-endian, endian::native
is equal to endian::little. Otherwise, endian::native is not equal to either endian::big or
endian::little.
23.16
Compile-time rational arithmetic
[ratio]
23.16.1
In general
[ratio.general]
1
This subclause describes the ratio library. It provides a class template ratio which exactly represents any
finite rational number with a numerator and denominator representable by compile-time constants of type
intmax_t.
2
Throughout this subclause, the names of template parameters are used to express type requirements. If
a template parameter is named R1 or R2, and the template argument is not a specialization of the ratio
template, the program is ill-formed.
23.16.2
Header <ratio> synopsis
[ratio.syn]
namespace std {
// 23.16.3, class template ratio
template<intmax_t N, intmax_t D = 1> class ratio;
// 23.16.4, ratio arithmetic
template<class R1, class R2> using ratio_add = see below ;
template<class R1, class R2> using ratio_subtract = see below ;
template<class R1, class R2> using ratio_multiply = see below ;
template<class R1, class R2> using ratio_divide = see below ;
// 23.16.5, ratio comparison
template<class R1, class R2> struct ratio_equal;
template<class R1, class R2> struct ratio_not_equal;
template<class R1, class R2> struct ratio_less;
template<class R1, class R2> struct ratio_less_equal;
template<class R1, class R2> struct ratio_greater;
template<class R1, class R2> struct ratio_greater_equal;
§ 23.16.2
636
template<class R1, class R2>
inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
template<class R1, class R2>
inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
template<class R1, class R2>
inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
template<class R1, class R2>
inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
template<class R1, class R2>
inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
template<class R1, class R2>
inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1,
R2>::value;
// 23.16.6, convenience SI typedefs
using yocto = ratio<1, 1’000’000’000’000’000’000’000’000>;
// see below
using zepto = ratio<1,
1’000’000’000’000’000’000’000>;
// see below
using atto
= ratio<1,
1’000’000’000’000’000’000>;
using femto = ratio<1,
1’000’000’000’000’000>;
using pico
= ratio<1,
1’000’000’000’000>;
using nano
= ratio<1,
1’000’000’000>;
using micro = ratio<1,
1’000’000>;
using milli = ratio<1,
1’000>;
using centi = ratio<1,
100>;
using deci
= ratio<1,
10>;
using deca
= ratio<
10, 1>;
using hecto = ratio<
100, 1>;
using kilo
= ratio<
1’000, 1>;
using mega
= ratio<
1’000’000, 1>;
using giga
= ratio<
1’000’000’000, 1>;
using tera
= ratio<
1’000’000’000’000, 1>;
using peta
= ratio<
1’000’000’000’000’000, 1>;
using exa
= ratio<
1’000’000’000’000’000’000, 1>;
using zetta = ratio<
1’000’000’000’000’000’000’000, 1>;
// see below
using yotta = ratio<1’000’000’000’000’000’000’000’000, 1>;
// see below
}
23.16.3
Class template ratio
[ratio.ratio]
namespace std {
template<intmax_t N, intmax_t D = 1> class ratio {
public:
static constexpr intmax_t num;
static constexpr intmax_t den;
using type = ratio<num, den>;
};
}
1
If the template argument D is zero or the absolute values of either of the template arguments N and D is not
representable by type intmax_t, the program is ill-formed. [Note: These rules ensure that infinite ratios
are avoided and that for any negative input, there exists a representable value of its absolute value which is
positive. In a two’s complement representation, this excludes the most negative value.
— end note ]
2
The static data members num and den shall have the following values, where gcd represents the greatest
common divisor of the absolute values of N and D:
(2.1)
num shall have the value sign(N) * sign(D) * abs(N) / gcd.
(2.2)
den shall have the value abs(D) / gcd.
23.16.4
Arithmetic on ratios
[ratio.arithmetic]
1
Each of the alias templates ratio_add, ratio_subtract, ratio_multiply, and ratio_divide denotes the
result of an arithmetic computation on two ratios R1 and R2. With X and Y computed (in the absence of
arithmetic overflow) as specified by Table 51, each alias denotes a ratio<U, V> such that U is the same as
ratio<X, Y>::num and V is the same as ratio<X, Y>::den.
§ 23.16.4
637
2
If it is not possible to represent U or V with intmax_t, the program is ill-formed. Otherwise, an implementation
should yield correct values of U and V. If it is not possible to represent X or Y with intmax_t, the program is
ill-formed unless the implementation yields correct values of U and V.
Table 51 — Expressions used to perform ratio arithmetic
Type
Value of X
Value of Y
ratio_add<R1, R2>
R1::num * R2::den + R1::den * R2::den
R2::num * R1::den
ratio_subtract<R1, R2> R1::num * R2::den - R1::den * R2::den
R2::num * R1::den
ratio_multiply<R1, R2> R1::num * R2::num
R1::den * R2::den
ratio_divide<R1, R2>
R1::num * R2::den
R1::den * R2::num
3
[ Example:
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::num == 1, "1/3+1/6 == 1/2");
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::den == 2, "1/3*3/2 == 1/2");
// The following cases may cause the program to be ill-formed under some implementations
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::num == 2,
"1/MAX+1/MAX == 2/MAX");
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::den == INT_MAX,
"1/MAX+1/MAX == 2/MAX");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::num == 1,
"1/MAX * MAX/2 == 1/2");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::den == 2,
"1/MAX * MAX/2 == 1/2");
— end example ]
23.16.5
Comparison of ratios
[ratio.comparison]
template<class R1, class R2>
struct ratio_equal : bool_constant<R1::num == R2::num && R1::den == R2::den> { };
template<class R1, class R2>
struct ratio_not_equal : bool_constant<!ratio_equal_v<R1, R2>> { };
template<class R1, class R2>
struct ratio_less : bool_constant<see below > { };
1
If R1::num × R2::den is less than R2::num × R1::den, ratio_less<R1, R2> shall be derived from
bool_constant<true>; otherwise it shall be derived from bool_constant<false>. Implementations
may use other algorithms to compute this relationship to avoid overflow. If overflow occurs, the program
is ill-formed.
template<class R1, class R2>
struct ratio_less_equal : bool_constant<!ratio_less_v<R2, R1>> { };
template<class R1, class R2>
struct ratio_greater : bool_constant<ratio_less_v<R2, R1>> { };
template<class R1, class R2>
struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };
23.16.6
SI types for ratio
[ratio.si]
1
For each of the typedef-names yocto, zepto, zetta, and yotta, if both of the constants used in its specification
are representable by intmax_t, the typedef shall be defined; if either of the constants is not representable by
intmax_t, the typedef shall not be defined.
§ 23.16.6
638
23.17
Time utilities
[time]
23.17.1
In general
[time.general]
1
This subclause describes the chrono library (23.17.2) and various C functions (23.17.8) that provide generally
useful time utilities.
23.17.2
Header <chrono> synopsis
[time.syn]
namespace std {
namespace chrono {
// 23.17.5, class template duration
template<class Rep, class Period = ratio<1>> class duration;
// 23.17.6, class template time_point
template<class Clock, class Duration = typename Clock::duration>
class time_point;
}
// 23.17.4.3, common_type specializations
template<class Rep1, class Period1, class Rep2, class Period2>
struct common_type<chrono::duration<Rep1, Period1>,
chrono::duration<Rep2, Period2>>;
template<class Clock, class Duration1, class Duration2>
struct common_type<chrono::time_point<Clock, Duration1>,
chrono::time_point<Clock, Duration2>>;
namespace chrono {
// 23.17.4, customization traits
template<class Rep> struct treat_as_floating_point;
template<class Rep> struct duration_values;
template<class Rep>
inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<Rep>::value;
// 23.17.5.5, duration arithmetic
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>&
rhs);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>&
rhs);
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator*(const duration<Rep1, Period>& d, const Rep2& s);
template<class Rep1, class Rep2, class Period>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator*(const Rep1& s, const duration<Rep2, Period>& d);
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator/(const duration<Rep1, Period>& d, const Rep2& s);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<Rep1, Rep2>
operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>&
rhs);
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator%(const duration<Rep1, Period>& d, const Rep2& s);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>&
rhs);
// 23.17.5.6, duration comparisons
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator==(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
§ 23.17.2
639
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator< (const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator> (const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
// 23.17.5.7, duration_cast
template<class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
template<class ToDuration, class Rep, class Period>
constexpr ToDuration floor(const duration<Rep, Period>& d);
template<class ToDuration, class Rep, class Period>
constexpr ToDuration ceil(const duration<Rep, Period>& d);
template<class ToDuration, class Rep, class Period>
constexpr ToDuration round(const duration<Rep, Period>& d);
// convenience typedefs
using nanoseconds
= duration<signed integer type of at least 64 bits ,
nano>;
using microseconds = duration<signed integer type of at least 55 bits ,
micro>;
using milliseconds = duration<signed integer type of at least 45 bits ,
milli>;
using seconds
= duration<signed integer type of at least 35 bits >;
using minutes
= duration<signed integer type of at least 29 bits , ratio<
60>>;
using hours
= duration<signed integer type of at least 23 bits , ratio<3600>>;
// 23.17.6.5, time_point arithmetic
template<class Clock, class Duration1, class Rep2, class Period2>
constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>&
rhs);
template<class Rep1, class Period1, class Clock, class Duration2>
constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>&
rhs);
template<class Clock, class Duration1, class Rep2, class Period2>
constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>&
rhs);
template<class Clock, class Duration1, class Duration2>
constexpr common_type_t<Duration1, Duration2>
operator-(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
// 23.17.6.6, time_point comparisons
template<class Clock, class Duration1, class Duration2>
constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
template<class Clock, class Duration1, class Duration2>
constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
template<class Clock, class Duration1, class Duration2>
constexpr bool operator< (const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
template<class Clock, class Duration1, class Duration2>
constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
§ 23.17.2
640
template<class Clock, class Duration1, class Duration2>
constexpr bool operator> (const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
template<class Clock, class Duration1, class Duration2>
constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
// 23.17.6.7, time_point_cast
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration>
time_point_cast(const time_point<Clock, Duration>& t);
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> round(const time_point<Clock, Duration>& tp);
// 23.17.5.9, specialized algorithms
template<class Rep, class Period>
constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
// 23.17.7, clocks
class system_clock;
class steady_clock;
class high_resolution_clock;
}
inline namespace literals {
inline namespace chrono_literals {
// 23.17.5.8, suffixes for duration literals
constexpr chrono::hours
operator""h(unsigned long long);
constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double);
constexpr chrono::minutes
operator""min(unsigned long long);
constexpr chrono::duration<unspecified, ratio<60, 1>>
operator""min(long double);
constexpr chrono::seconds
operator""s(unsigned long long);
constexpr chrono::duration<unspecified >
operator""s(long double);
constexpr chrono::milliseconds
operator""ms(unsigned long long);
constexpr chrono::duration<unspecified, milli>
operator""ms(long double);
constexpr chrono::microseconds
operator""us(unsigned long long);
constexpr chrono::duration<unspecified, micro>
operator""us(long double);
constexpr chrono::nanoseconds
operator""ns(unsigned long long);
constexpr chrono::duration<unspecified, nano>
operator""ns(long double);
}
}
namespace chrono {
using namespace literals::chrono_literals;
}
}
23.17.3
Clock requirements
[time.clock.req]
1
A clock is a bundle consisting of a duration, a time_point, and a function now() to get the current
time_point. The origin of the clock’s time_point is referred to as the clock’s epoch. A clock shall meet the
requirements in Table 52.
2
In Table 52 C1 and C2 denote clock types. t1 and t2 are values returned by C1::now() where the call returning
t1 happens before (6.8.2) the call returning t2 and both of these calls occur before C1::time_point::max().
[ Note: This means C1 did not wrap around between t1 and t2. — end note ]
§ 23.17.3
641
Table 52 — Clock requirements
Expression
Return type
Operational semantics
C1::rep
An arithmetic type or a class
The representation type of
emulating an arithmetic type
C1::duration.
C1::period
a specialization of ratio
The tick period of the clock in
seconds.
C1::duration
chrono::duration<C1::rep,
The duration type of the
C1::period>
clock.
C1::time_point
chrono::time_point<C1> or
The time_point type of the
chrono::time_point<C2,
clock. C1 and C2 shall refer to
C1::duration>
the same epoch.
C1::is_steady
const bool
true if t1 <= t2 is always
true and the time between
clock ticks is constant,
otherwise false.
C1::now()
C1::time_point
Returns a time_point object
representing the current point
in time.
3
[ Note: The relative difference in durations between those reported by a given clock and the SI definition is a
measure of the quality of implementation.
— end note ]
4
A type TC meets the TrivialClock requirements if:
(4.1)
TC satisfies the Clock requirements (23.17.3),
(4.2)
the types TC::rep, TC::duration, and TC::time_point satisfy the requirements of EqualityCom-
parable (Table 20), LessThanComparable (Table 21), DefaultConstructible (Table 22), CopyCon-
structible (Table 24), CopyAssignable (Table 26), Destructible (Table 27), and the requirements
of numeric types (29.3). [ Note: This means, in particular, that operations on these types will not throw
exceptions.
— end note ]
(4.3)
lvalues of the types TC::rep, TC::duration, and TC::time_point are swappable (20.5.3.2),
(4.4)
the function TC::now() does not throw exceptions, and
(4.5)
the type TC::time_point::clock meets the TrivialClock requirements, recursively.
23.17.4
Time-related traits
[time.traits]
23.17.4.1
treat_as_floating_point
[time.traits.is_fp]
template<class Rep> struct treat_as_floating_point : is_floating_point<Rep> { };
1
The duration template uses the treat_as_floating_point trait to help determine if a duration object
can be converted to another duration with a different tick period. If treat_as_floating_point_v<Rep> is
true, then implicit conversions are allowed among durations. Otherwise, the implicit convertibility depends
on the tick periods of the durations. [ Note: 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. If treat_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.
— end note ]
23.17.4.2
duration_values
[time.traits.duration_values]
template<class Rep>
struct duration_values {
public:
static constexpr Rep zero();
static constexpr Rep min();
static constexpr Rep max();
};
1
The duration template uses the duration_values trait to construct special values of the durations repre-
sentation (Rep). This is done because the representation might be a class type with behavior which requires
§ 23.17.4.2
642
some other implementation to return these special values. In that case, the author of that class type should
specialize duration_values to return the indicated values.
static constexpr Rep zero();
2
Returns: Rep(0). [ Note: Rep(0) is specified instead of Rep() because Rep() may have some other
meaning, such as an uninitialized value.
— end note ]
3
Remarks: The value returned shall be the additive identity.
static constexpr Rep min();
4
Returns: numeric_limits<Rep>::lowest().
5
Remarks: The value returned shall compare less than or equal to zero().
static constexpr Rep max();
6
Returns: numeric_limits<Rep>::max().
7
Remarks: The value returned shall compare greater than zero().
23.17.4.3
Specializations of common_type
[time.traits.specializations]
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
The period of the duration indicated by this specialization of common_type shall be the greatest com-
mon divisor of Period1 and Period2.
[Note: 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. — end note ]
2
[ Note: The typedef name type is a synonym for the duration with the largest tick period possible where
both duration arguments will convert to it without requiring a division operation. 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 may have round-off errors.
— end note ]
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
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.
23.17.5
Class template duration
[time.duration]
1
A duration type measures time between two points in time (time_points). A duration has a representation
which holds a count of ticks and a tick period. The tick period is the amount of time which occurs from one
tick to the next, in units of seconds. It is expressed as a rational constant using the template ratio.
namespace std::chrono {
template<class Rep, class Period = ratio<1>>
class duration {
public:
using rep
= Rep;
using period = typename Period::type;
private:
rep rep_;
// exposition only
public:
// 23.17.5.1, construct/copy/destroy
constexpr duration() = default;
template<class Rep2>
constexpr explicit duration(const Rep2& r);
template<class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);
§ 23.17.5
643
~duration() = default;
duration(const duration&) = default;
duration& operator=(const duration&) = default;
// 23.17.5.2, observer
constexpr rep count() const;
// 23.17.5.3, arithmetic
constexpr common_type_t<duration> operator+() const;
constexpr common_type_t<duration> operator-() const;
constexpr duration& operator++();
constexpr duration operator++(int);
constexpr duration& operator--();
constexpr duration operator--(int);
constexpr duration& operator+=(const duration& d);
constexpr duration& operator-=(const duration& d);
constexpr duration& operator*=(const rep& rhs);
constexpr duration& operator/=(const rep& rhs);
constexpr duration& operator%=(const rep& rhs);
constexpr duration& operator%=(const duration& rhs);
// 23.17.5.4, special values
static constexpr duration zero();
static constexpr duration min();
static constexpr duration max();
};
}
2
Rep shall be an arithmetic type or a class emulating an arithmetic type. If duration is instantiated with a
duration type as the argument for the template parameter Rep, the program is ill-formed.
3
If Period is not a specialization of ratio, the program is ill-formed. If Period::num is not positive, the
program is ill-formed.
4
Members of duration shall not throw exceptions other than those thrown by the indicated operations on
their representations.
5
The defaulted copy constructor of duration shall be a constexpr function if and only if the required initialization
of the member rep_ for copy and move, respectively, would satisfy the requirements for a constexpr function.
6
[ Example:
duration<long, ratio<60>> d0;
// holds a count of minutes using a long
duration<long long, milli> d1;
// holds a count of milliseconds using a long long
1
duration<double, ratio<1, 30>> d2; // holds a count with a tick period of
f a second
30 o
// (30 Hz) using a double
— end example ]
23.17.5.1
duration constructors
[time.duration.cons]
template<class Rep2>
constexpr explicit duration(const Rep2& r);
1
Remarks: This constructor shall not participate in overload resolution unless Rep2 is implicitly
convertible to rep and
(1.1)
treat_as_floating_point_v<rep> is true or
(1.2)
treat_as_floating_point_v<Rep2> is false.
[ Example:
duration<int, milli> d(3);
// OK
duration<int, milli> d(3.5);
// error
— end example ]
2
Effects: Constructs an object of type duration.
§ 23.17.5.1
644
3
Postconditions: count() == static_cast<rep>(r).
template<class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);
4
Remarks: This constructor shall not participate in overload resolution unless no overflow is induced
in the conversion and treat_as_floating_point_v<rep> is true or both ratio_divide<Period2,
period>::den is 1 and treat_as_floating_point_v<Rep2> is false.
[Note: This requirement
prevents implicit truncation error when converting between integral-based duration types. Such a con-
struction could easily lead to confusion about the value of the duration.
— end note ] [ Example:
duration<int, milli> ms(3);
duration<int, micro> us = ms;
// OK
duration<int, milli> ms2 = us;
// error
— end example ]
5
Effects: Constructs an object of type duration, constructing rep_ from
duration_cast<duration>(d).count().
23.17.5.2
duration observer
[time.duration.observer]
constexpr rep count() const;
1
Returns: rep_.
23.17.5.3
duration arithmetic
[time.duration.arithmetic]
constexpr common_type_t<duration> operator+() const;
1
Returns: common_type_t<duration>(*this).
constexpr common_type_t<duration> operator-() const;
2
Returns: common_type_t<duration>(-rep_).
constexpr duration& operator++();
3
Effects: As if by ++rep_.
4
Returns: *this.
constexpr duration operator++(int);
5
Returns: duration(rep_++).
constexpr duration& operator--();
6
Effects: As if by --rep_.
7
Returns: *this.
constexpr duration operator--(int);
8
Returns: duration(rep_--).
constexpr duration& operator+=(const duration& d);
9
Effects: As if by: rep_ += d.count();
10
Returns: *this.
constexpr duration& operator-=(const duration& d);
11
Effects: As if by: rep_ -= d.count();
12
Returns: *this.
constexpr duration& operator*=(const rep& rhs);
13
Effects: As if by: rep_ *= rhs;
14
Returns: *this.
§ 23.17.5.3
645
constexpr duration& operator/=(const rep& rhs);
15
Effects: As if by: rep_ /= rhs;
16
Returns: *this.
constexpr duration& operator%=(const rep& rhs);
17
Effects: As if by: rep_ %= rhs;
18
Returns: *this.
constexpr duration& operator%=(const duration& rhs);
19
Effects: As if by: rep_ %= rhs.count();
20
Returns: *this.
23.17.5.4
duration special values
[time.duration.special]
static constexpr duration zero();
1
Returns: duration(duration_values<rep>::zero()).
static constexpr duration min();
2
Returns: duration(duration_values<rep>::min()).
static constexpr duration max();
3
Returns: duration(duration_values<rep>::max()).
23.17.5.5
duration non-member arithmetic
[time.duration.nonmember]
1
In the function descriptions that follow, CD represents the return type of the function. CR(A, B) represents
common_type_t<A, B>.
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
2
Returns: CD(CD(lhs).count() + CD(rhs).count()).
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
3
Returns: CD(CD(lhs).count() - CD(rhs).count()).
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator*(const duration<Rep1, Period>& d, const Rep2& s);
4
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2).
5
Returns: CD(CD(d).count() * s).
template<class Rep1, class Rep2, class Period>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator*(const Rep1& s, const duration<Rep2, Period>& d);
6
Remarks: This operator shall not participate in overload resolution unless Rep1 is implicitly convertible
to CR(Rep1, Rep2).
7
Returns: d * s.
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator/(const duration<Rep1, Period>& d, const Rep2& s);
8
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
9
Returns: CD(CD(d).count() / s).
§ 23.17.5.5
646
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<Rep1, Rep2>
operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
10
Returns: CD(lhs).count() / CD(rhs).count().
template<class Rep1, class Period, class Rep2>
constexpr duration<common_type_t<Rep1, Rep2>, Period>
operator%(const duration<Rep1, Period>& d, const Rep2& s);
11
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
12
Returns: CD(CD(d).count() % s).
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
13
Returns: CD(CD(lhs).count() % CD(rhs).count()).
23.17.5.6
duration comparisons
[time.duration.comparisons]
1
In the function descriptions that follow, CT represents common_type_t<A,
B>, where A and B are the types
of the two arguments to the function.
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator==(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
2
Returns: CT (lhs).count() == CT (rhs).count().
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
3
Returns: !(lhs == rhs).
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator<(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
4
Returns: CT (lhs).count() < CT (rhs).count().
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
5
Returns: !(rhs < lhs).
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
6
Returns: rhs < lhs.
template<class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
7
Returns: !(lhs < rhs).
23.17.5.7
duration_cast
[time.duration.cast]
template<class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>&
d);
1
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
2
Returns: Let CF be ratio_divide<Period, typename ToDuration::period>, and CR be common_-
type<typename ToDuration::rep, Rep, intmax_t>::type.
§ 23.17.5.7
647
(2.1)
If CF::num == 1 and CF::den == 1, returns
ToDuration(static_cast<typename ToDuration::rep>(d.count()))
(2.2)
otherwise, if CF::num != 1 and CF::den == 1, returns
ToDuration(static_cast<typename ToDuration::rep>(
static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
(2.3)
otherwise, if CF::num == 1 and CF::den != 1, returns
ToDuration(static_cast<typename ToDuration::rep>(
static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
(2.4)
otherwise, returns
ToDuration(static_cast<typename ToDuration::rep>(
static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
3
[ Note: This function does not use any implicit conversions; all conversions are done with static_cast.
It avoids multiplications and divisions when it is known at compile time that one or more arguments is
1. Intermediate computations are carried out in the widest representation and only converted to the
destination representation at the final step.
— end note ]
template<class ToDuration, class Rep, class Period>
constexpr ToDuration floor(const duration<Rep, Period>& d);
4
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
5
Returns: The greatest result t representable in ToDuration for which t <= d.
template<class ToDuration, class Rep, class Period>
constexpr ToDuration ceil(const duration<Rep, Period>& d);
6
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
7
Returns: The least result t representable in ToDuration for which t >= d.
template<class ToDuration, class Rep, class Period>
constexpr ToDuration round(const duration<Rep, Period>& d);
8
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration, and treat_as_floating_point_v<typename ToDuration::rep> is false.
9
Returns: The value of ToDuration that is closest to d. If there are two closest values, then return the
value t for which t % 2 == 0.
23.17.5.8
Suffixes for duration literals
[time.duration.literals]
1
This subclause describes literal suffixes for constructing duration literals. The suffixes h, min, s, ms, us, ns
denote duration values of the corresponding types hours, minutes, seconds, milliseconds, microseconds,
and nanoseconds respectively if they are applied to integral literals.
2
If any of these suffixes are applied to a floating-point literal the result is a chrono::duration literal with an
unspecified floating-point representation.
3
If any of these suffixes are applied to an integer literal and the resulting chrono::duration value cannot be
represented in the result type because of overflow, the program is ill-formed.
4
[ Example: The following code shows some duration literals.
using namespace std::chrono_literals;
auto constexpr aday=24h;
auto constexpr lesson=45min;
auto constexpr halfanhour=0.5h;
— end example ]
constexpr chrono::hours
operator""h(unsigned long long hours);
constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);
5
Returns: A duration literal representing hours hours.
§ 23.17.5.8
648
constexpr chrono::minutes
operator""min(unsigned long long minutes);
constexpr chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);
6
Returns: A duration literal representing minutes minutes.
constexpr chrono::seconds
operator""s(unsigned long long sec);
constexpr chrono::duration<unspecified > operator""s(long double sec);
7
Returns: A duration literal representing sec seconds.
8
[Note: The same suffix s is used for basic_string but there is no conflict, since duration suffixes
apply to numbers and string literal suffixes apply to character array literals.
— end note ]
constexpr chrono::milliseconds
operator""ms(unsigned long long msec);
constexpr chrono::duration<unspecified, milli> operator""ms(long double msec);
9
Returns: A duration literal representing msec milliseconds.
constexpr chrono::microseconds
operator""us(unsigned long long usec);
constexpr chrono::duration<unspecified, micro> operator""us(long double usec);
10
Returns: A duration literal representing usec microseconds.
constexpr chrono::nanoseconds
operator""ns(unsigned long long nsec);
constexpr chrono::duration<unspecified, nano> operator""ns(long double nsec);
11
Returns: A duration literal representing nsec nanoseconds.
23.17.5.9
duration algorithms
[time.duration.alg]
template<class Rep, class Period>
constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
1
Remarks: This function shall not participate in overload resolution unless numeric_limits<Rep>::is_-
signed is true.
2
Returns: If d >= d.zero(), return d, otherwise return -d.
23.17.6
Class template time_point
[time.point]
namespace std::chrono {
template<class Clock, class Duration = typename Clock::duration>
class time_point {
public:
using clock
= Clock;
using duration = Duration;
using rep
= typename duration::rep;
using period
= typename duration::period;
private:
duration d_;
// exposition only
public:
// 23.17.6.1, construct
constexpr time_point();
// has value epoch
constexpr explicit time_point(const duration& d);
// same as time_point() + d
template<class Duration2>
constexpr time_point(const time_point<clock, Duration2>& t);
// 23.17.6.2, observer
constexpr duration time_since_epoch() const;
// 23.17.6.3, arithmetic
constexpr time_point& operator+=(const duration& d);
constexpr time_point& operator-=(const duration& d);
// 23.17.6.4, special values
static constexpr time_point min();
static constexpr time_point max();
§
23.17.6
649
};
}
1
Clock shall meet the Clock requirements (23.17.3).
2
If Duration is not an instance of duration, the program is ill-formed.
23.17.6.1
time_point constructors
[time.point.cons]
constexpr time_point();
1
Effects: Constructs an object of type time_point, initializing d_ with duration::zero(). Such a
time_point object represents the epoch.
constexpr explicit time_point(const duration& d);
2
Effects: Constructs an object of type time_point, initializing d_ with d. Such a time_point object
represents the epoch + d.
template<class Duration2>
constexpr time_point(const time_point<clock, Duration2>& t);
3
Remarks: This constructor shall not participate in overload resolution unless Duration2 is implicitly
convertible to duration.
4
Effects: Constructs an object of type time_point, initializing d_ with t.time_since_epoch().
23.17.6.2
time_point observer
[time.point.observer]
constexpr duration time_since_epoch() const;
1
Returns: d_.
23.17.6.3
time_point arithmetic
[time.point.arithmetic]
constexpr time_point& operator+=(const duration& d);
1
Effects: As if by: d_ += d;
2
Returns: *this.
constexpr time_point& operator-=(const duration& d);
3
Effects: As if by: d_ -= d;
4
Returns: *this.
23.17.6.4
time_point special values
[time.point.special]
static constexpr time_point min();
1
Returns: time_point(duration::min()).
static constexpr time_point max();
2
Returns: time_point(duration::max()).
23.17.6.5
time_point non-member arithmetic
[time.point.nonmember]
template<class Clock, class Duration1, class Rep2, class Period2>
constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
1
Returns: CT (lhs.time_since_epoch() + rhs), where CT is the type of the return value.
template<class Rep1, class Period1, class Clock, class Duration2>
constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
2
Returns: rhs + lhs.
template<class Clock, class Duration1, class Rep2, class Period2>
constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
3
Returns: CT (lhs.time_since_epoch() - rhs), where CT is the type of the return value.
§ 23.17.6.5
650
template<class Clock, class Duration1, class Duration2>
constexpr common_type_t<Duration1, Duration2>
operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
4
Returns: lhs.time_since_epoch() - rhs.time_since_epoch().
23.17.6.6
time_point comparisons
[time.point.comparisons]
template<class Clock, class Duration1, class Duration2>
constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
1
Returns: lhs.time_since_epoch() == rhs.time_since_epoch().
template<class Clock, class Duration1, class Duration2>
constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
2
Returns: !(lhs == rhs).
template<class Clock, class Duration1, class Duration2>
constexpr bool operator<(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
3
Returns: lhs.time_since_epoch() < rhs.time_since_epoch().
template<class Clock, class Duration1, class Duration2>
constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
4
Returns: !(rhs < lhs).
template<class Clock, class Duration1, class Duration2>
constexpr bool operator>(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
5
Returns: rhs < lhs.
template<class Clock, class Duration1, class Duration2>
constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
const time_point<Clock, Duration2>& rhs);
6
Returns: !(lhs < rhs).
23.17.6.7
time_point_cast
[time.point.cast]
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> time_point_cast(const time_point<Clock,
Duration>& t);
1
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
2
Returns:
time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()))
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
3
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
4
Returns: time_point<Clock, ToDuration>(floor<ToDuration>(tp.time_since_epoch())).
template<class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
5
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization
of duration.
6
Returns: time_point<Clock, ToDuration>(ceil<ToDuration>(tp.time_since_epoch())).
§ 23.17.6.7
651

 

 

 

 

 

 

 

Content      ..     20      21      22      23     ..