<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>A New Interface for C++ std::duration Type</title>
</head><body>
<h1>A New Interface for C++ std::duration Type</h1>

<p>ISO/IEC JTC1 SC22 WG21 N2539 = 08-0049 - 2008-02-25

</p><p>Paul E. McKenney, paulmck@linux.vnet.ibm.com<BR>
Michael Wong, michaelw@ca.ibm.com

</p><h2>Disposition</h2>

<p>Consideration of this proposal is deferred until TR2.

</p><h2>Introduction</h2>

<p> This document presents a new interface
for time durations as proposed by the POSIX C++ Binding Working Group at the
2008 Bellevue meeting.
This document is based on the latest <I>Working Draft</I>
(<A HREF="http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">n2521</A>),
<I>Why duration Should Be a Type in C++0x</I>
(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>),
and <I>Custom Time Duration Support</I>
(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2498.html">n2498</A>).
It accepts the findings in n2526 for a need to minimize the number of distinct interfaces for time duration, and represents a follow-up on the alternatives as proposed in n2526.

<h3>Rationale</h3>

<P>
See Why duration Should Be a Type in C++0x
(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).

<h3>Prior Approaches</h3>

<P>
See See Why duration Should Be a Type in C++0x
(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).


<h3>Proposal</h3>

<P>
We propose maintaining a single implementation-defined type that holds
time durations, with member functions that permit conversions from that
implementation-defined type to and from nanoseconds, microseconds,
milliseconds, seconds, minutes, and hours.
We strongly suggest that implementations use the same units for
<code>duration</code> as are used for <code>system_time</code>.
We further propose that this type occupy the <code>std</code> namespace
rather then a part of <code>std::thread</code> namespace, as we see this
as a generally useful type rather then one that is specifically useful
to thread.

<pre><code>
namespace std {
    class duration
    {
    public:
	// traits information
        typedef implementation-defined tick_type;
        static const tick_type ticks_per_second = implementation-defined;
        static const tick_type seconds_per_tick = implementation-defined;
        static const bool is_subsecond = implementation-defined;
	typedef enum duration_unit {
		duration_native,
		duration_nanoseconds, duration_microseconds,
		duration_milliseconds, duration_seconds,
		duration_minutes, duration_hours
	} duration_unit;

	// construct/copy/destroy
	duration(duration_unit u, long long t = 0);
	duration(duration_unit u, double t = 0.0);
	duration(long long tps, long long stp, long long t = 0);
	duration(long long tps, long long stp, double t = 0.0);

	// modifiers
	duration&amp; operator+=(const duration &amp;d);
	duration&amp; operator-=(const duration &amp;d);
	duration&amp; operator*=(long multiplier);
	duration&amp; operator*=(double multiplier);
	duration&amp; operator/=(long divisor);
	duration&amp; operator/=(double divisor);

	// observers
        tick_type count() const;
	long long nanoseconds() const;
	double d_nanoseconds() const;
	long long microseconds() const;
	double d_microseconds() const;
	long long milliseconds() const;
	double d_milliseconds() const;
	long long seconds() const;
	double d_seconds() const;
	long long minutes() const;
	double d_minutes() const;
	long long hours() const;
	double d_hours() const;
	long long user_defined(long long tps, long long stp) const;
	double d_user_defined(long long tps, long long stp) const;

	// operations
	tick_type operator-() const;
    };
}
</code></pre>

<P>
<code>tick_type</code>
<BLOCKQUOTE>
	<P>Implementation-defined type that defines the underlying
	timer tick.
</BLOCKQUOTE>

<P>
<code>ticks_per_second</code>
<BLOCKQUOTE>
	<P>The number of ticks per second or zero when the number of
	ticks per second is less than one and the number of seconds
	per tick is integral.
</BLOCKQUOTE>

<P>
<code>seconds_per_tick</code>
<BLOCKQUOTE>
	<P>The number of seconds per tick or zero when the number of
	seconds per tick is less than one and the number of ticks
	per second is integral.
</BLOCKQUOTE>

<P>
<code>seconds_per_tick</code>
<BLOCKQUOTE>
	<P>The number of seconds per tick or zero when the number of
	seconds per tick is less than one and the number of ticks
	per second is integral.
</BLOCKQUOTE>

<P>
<code>is_subsecond</code>
<BLOCKQUOTE>
	<P>This is equal to 1 when <code>seconds_per_tick==0</code>.
</BLOCKQUOTE>

<P>
<code>duration_unit</code>
<BLOCKQUOTE>
	<P>Allows the user to specify a limited number of predefined
	time units, including nanoseconds, microseconds, milliseconds,
	seconds, minutes, hours, and an implementation-defined
	native time unit.
</BLOCKQUOTE>

<P>
<code>duration</code> (constructors)
<BLOCKQUOTE>
	<P>Allows constructing a native-time value from either a standard
	(nanoseconds through hours) or user-defined time value.
	The user can specify either an integral or a floating-point
	value.
	The <code>tps</code> and <code>stp</code> arguments are analogous
	to the <code>ticks_per_second</code> and
	<code>seconds_per_tick</code> members.
</BLOCKQUOTE>

<P>
<code>operator +=</code>
<BLOCKQUOTE>
	<P>Increments the specified <code>duration</code> object
	by the <code>duration</code> object passed in as the argument.
	The <code>duration</code> constructors may be used to add time
	durations in any desired units.
</BLOCKQUOTE>

<P>
<code>operator -=</code>
<BLOCKQUOTE>
	<P>Decrements the specified <code>duration</code> object
	by the <code>duration</code> object passed in as the argument.
	The <code>duration</code> constructors may be used to subtract time
	durations in any desired units.
</BLOCKQUOTE>

<P>
<code>operator *=</code>
<BLOCKQUOTE>
	<P>Multiplies the specified <code>duration</code> object
	by the specified integral or floating-point argument.
</BLOCKQUOTE>

<P>
<code>operator /=</code>
<BLOCKQUOTE>
	<P>Divides the specified <code>duration</code> object
	by the specified integral or floating-point argument.
</BLOCKQUOTE>

<P>
<code>count</code>
<BLOCKQUOTE>
	<P>Returns the implementation-defined number of ticks.
</BLOCKQUOTE>

<P>
<code>nanoseconds, d_nanoseconds</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in nanoseconds.
</BLOCKQUOTE>

<P>
<code>microseconds, d_microseconds</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in microseconds.
</BLOCKQUOTE>

<P>
<code>milliseconds, d_milliseconds</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in milliseconds.
</BLOCKQUOTE>

<P>
<code>seconds, d_seconds</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in seconds.
</BLOCKQUOTE>

<P>
<code>minutes, d_minutes</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in minutes.
</BLOCKQUOTE>

<P>
<code>hours, d_hours</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in hours.
</BLOCKQUOTE>

<P>
<code>user_defined, d_user_defined</code>
<BLOCKQUOTE>
	<P>Returns the <code>duration</code> in user-defined units.
</BLOCKQUOTE>


<h3>Differences From n2521</h3>

<P>
This proposal differs from the language in
<A HREF="http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">n2521</A>
in the following respects:
<OL>
<LI>	There are no separate types for the different time units.
	This proposal uses an enum which must be specified on the
	constructor to avoid unit-omission bugs.
<LI>	There are no conversion operators from one time unit to another,
	for example, from microseconds to milliseconds.
	This effect could be obtained via conversion through the
	<code>duration</code> class, but division by the constant
	1,000 should suffice given that the ratio of microseconds to
	milliseconds is unlikely to change in the foreseeable future.
	This latter approach also has the advantage of avoiding roundoff
	errors due to coarse-grained implementations.
<LI>	This proposal provides the additive, multiplicative, constancy of units,
	and library coherence and interoperability desiderata called out in
	<I>Why duration Should Be a Type in C++0x</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).
<LI>	There are floating-point arguments to the constructor, permitting
	easy specification of fractions of time units, while also permitting
	the implementation to avoid unnecessary round-off errors even in
	face of non-integral tick frequencies.
<LI>	This proposal allows the full range of rational-number time bases
	to be specified.
	For example, specifying <code>ticks_per_second==3</code> and
	<code>seconds_per_tick==2</code> would result in three ticks
	every two seconds.
</OL>



<h3>Alternatives Considered</h3>

<P>
<UL>
<LI>	Retain the proposal described in
	<I>Working Draft</I>
	(<A HREF="http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">n2521</A>).
	This alternative was rejected for the reasons called out in
	<I>Why duration Should  Be a Type in C++0x</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).
<LI>	The elaboration of the above proposal
	<I>Working Draft</I>
	(<A HREF="http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">n2521</A>)
	described in
	<I>Custom Time Duration Support</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2498.html">n2498</A>).
	This alternative was rejected for the same reasons as
	<I>Working Draft</I>
	(<A HREF="http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">n2521</A>),
	but the ability for user-defined time durations is noted as valuable
	and desireable, and resulted in the <code>tps</code> and
	<code>stp</code> constructor arguments.
<LI>	The alternative 1 in
	<I>Why duration Should  Be a Type in C++0x</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).
	This alternative was rejected due to the unnecessary round-off
	errors that could result from constructs such as
	<code>3.5 * std::threads::minute</code>.
	If the value of <code>std::threads::minute</code> was not integral,
	large multipliers could result in arbitrarily large errors.
<LI>	The alternative 2 in
	<I>Why duration Should  Be a Type in C++0x</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).
	This alternative was rejected due to the fact that there are
	already systems that can complete operations in a fraction of
	a nanosecond.
	Even though Moore's Law is no longer driving CPU core clock
	frequency, we cannot rule out the possibility of technological
	advances that require picosecond-scale time bases.
<LI>	The alternative 3 in
	<I>Why duration Should  Be a Type in C++0x</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2526.pdf">n2526</A>).
	This alternative was rejected due to the explosion in number of
	interfaces that take time specifications.
<LI>	It is also possible to use <I>User-Defined Literals</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2378.pdf">N2378</A>)
	to enumerate the separate duration types.
	This proposal would use the following syntax for the duration
	corresponding to five frames per second:
	<BLOCKQUOTE><P>
		//N2378 syntax <BR>
		duration operator&quot;ms&quot;(double ms){ . . . } <BR>
		duration frames_per_sec=200ms; <BR>
		//This paper&quot;s syntax <BR>
		duration frames_per_sec(duration_milliseconds, 200); <BR>
	</BLOCKQUOTE>
	<P>This approach could be attractive if it is possible to create
	a &quot;hub-and-spoke&quot; conversion regimen, so that the number of
	conversion functions is <I>O(N)</I> rather than
	<I>O(N<sup>2</sup>)</I>.
	The issues surrounding this are explored in the following
	appendix.
<LI>	Allow user-specified <code>tick_type</code>.
	This was felt to be out of scope for this proposal, but
	should be considered for TR2.
<LI>	Allow full support for the seven SI basic units, including
	derived units.
	This was felt to be out of scope for this proposal, but
	should be considered for TR2.
	A key challenge for this issue will be efficiently supporting
	basic units such as time in the format required for system
	calls.
	This same challenge is faced in use cases involving sensor
	inputs and control outputs in resource-constrained embedded
	systems.
</UL>

<H2>Appendix: User-Defined Literals to Specify Durations</H2>

<P>There are at least two ways to apply user-defined literals to specify
durations:

<OL>
<LI>	Specify a separate type for each unit type.
	To avoid an explosion of conversion methods, specify a superclass
	with implementation-defined units.
	For each subclass, there is a method to convert to the superclass
	and another to convert from the superclass.
	With this infrastructure in place, each subclass implements
	a <I>User-defined literals</I>
	(<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2378.pdf">n2378</A>)
	suffixes.
<LI>	Fold all units into the <code>duration</code> type.
	This places the conversions into the user-defined literal
	operators.
</OL>

<P>One issue with both of these approaches is that user-defined
literals have a global namespace.

</body></html>
