Constexpr Library Additions: chrono
ISO/IEC JTC1 SC22 WG21 N3229 = 10-0219 - 2010-11-24
Benjamin Kosnik, bkoz@redhat.com
Addresses: LWG 2013, LWG 20xx “time_point constexpr member functions need constexpr conversion constructor”
Introduction
This paper details use of the ISO C++0x constexpr feature, as initially introduced in “Generalized Constant Expressions — Revision 5” (N2235) and incorporating all other subsequent changes as per ISO C++ draft N3126. Several CWG issues also influence the language with respect to constexpr: see issues 1099, 1125, 1194, 1195, 1197, 1198, 1199 and c++-std-core postings number 17890 and 17912. Additional implementation experience has motivated the following changes and additions to the library specification.
Proposed Changes
A list of additional places in 20.11 Time Utilities aka std::chrono that can exploit the constexpr language feature is below. For the changes listed, the new text is put in place in bold and green with the older text it is replacing struckthrough in red.
Remove the following:
- Remove explicitly defaulted duration default constructor, and add default
constructor that can initialize possible (rep) member data with an initialization
list. (As constexpr defaulted constructors are only well formed for classes
where all member data have constexpr default constructors. Scalars, for
instance, do not.)
Add the following:
- Mark duration copy constructor constexpr.
- Mark comparison operator templates ==, !=, <, <=, >, >= for duration
constexpr
- Mark all constructors in time_point constexpr
- Mark member function time_point::time_since_epoc constexpr
- Mark function templates duration_cast and timepoint_cast constexpr
- Mark comparison operator templates ==, !=, <, <=, >, >= for time_point
constexpr
- Mark system_clock::is_monotonic, monotonic_clock::is_monotonic, and
high_resolution_clock::is_monotonic constexpr.
Proposed wording
a) Modify 20.11 as follows:
// duration comparisons
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);
template <class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs);
// duration_cast
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
// 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);
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);
// time_point_cast
template <class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration>
time_point_cast(const time_point<Clock, Duration>& t);
b) Modify 20.11.3 as follows:
constexpr duration() = default;
constexpr duration(const duration&) = default;
c) Add to 20.11.3.1 as follows:
constexpr duration();
Effects: Constructs an object of type duration, default initializing rep_.
d) Modify 20.11.4.1 as follows:
constexpr time_point();
constexpr time_point(const duration& d);
template <class Duration2>
constexpr time_point(const time_point<clock, Duration2>& t);
e) Modify 20.11.4.2 as follows:
constexpr duration time_since_epoch() const;
f) Modify 20.11.5.1 as follows:
static const constexpr bool is_monotonic = unspecified;
g) Modify 20.11.5.2 as follows:
static const constexpr bool is_monotonic = unspecified;
h) Modify 20.11.5.3 as follows:
static const constexpr bool is_monotonic = unspecified;
Acknowledgments
Many thanks to Jason Merrill, Paolo Carlini, and Jonathan Wakely for reviewing this document and providing assistance.