Document number: N2447=07-0317

Howard E. Hinnant, Jeff Garland, Alisdair Meredith, Chris Kohlhoff, Dietmar Kühl, Nathan Myers, PremAnand M Rao, Nick Stoughton
2007-10-04

Multi-threading Library for Standard C++

Contents

Introduction

This is a revision of N2320 which removes cancellation/interruption and changes condition variables per the suggestions in N2406. This is the course of a action requested by the combined LWG/Concurrency working groups at the Kona meeting.

Proposed wording


20.5 Function objects [function.objects]

Modify paragraph 2 as follows:

Header functional synopsis

 namespace std {
   ...
   // Hash function specializations
   ...
   struct hash<std::thread::id>; //should not be in this header file ?
 }
 

20.5.15 Class template hash [unord.hash]

Modify paragraph 1 as follows:
The unordered associative containers defined in clause 23.4 use specializations of hash as the default hash function. This class template is only required to be instantiable for integer types (3.9.1), floating point types (3.9.1), pointer types (8.3.1), and std::string, std::u16string, std::u32string, and std::wstring, and std::thread::id.

Chapter 30   Multi-threading library


The following subclauses describe components to create and manage threads of execution [intro.execution? (N2334)], perform mutual exclusion and locking, and communicate between threads of execution.

Subclause Header(s)
Threads <thread>
Mutexs and locks <mutex>
Condition variables <cond_var>

Some functions described in this clause are specified to throw exceptions of type system_error ([syserr.syserr]). The error_category ([syserr.errcat.overview]) of the error_code reported by such exceptions code() member function is implementation-defined. [Note: The category is typically native_category ([syserr.errcat.overview]) since these error codes usually originate from the underlying operating system application program interface (API). -- end note]

Threads

<thread> synopsis

namespace std {

class thread;

void swap(thread&  x, thread&  y);
void swap(thread&& x, thread&  y);
void swap(thread&  x, thread&& y);

namespace this_thread
{
    thread::id get_id();
    
    void yield();
    template <class TimeDuration>
        void sleep(const TimeDuration& rel_t);

}  // this_thread

struct once_flag
{
    constexpr once_flag();

    once_flag(const once_flag&) = delete;
    once_flag& operator=(const once_flag&) = delete;
};

template<class Callable, class ...Args>
void call_once(once_flag& flag, Callable func, Args&&... args);

}  // std

Class thread

An object of class thread manages a thread of execution. It provides a mechanism to create a new thread of execution, for the current thread of execution to wait for completion of a thread of execution, and to perform other operations to manage and query the state of the thread of execution.

class thread
{
public:
    // types:
    class id;
    typedef implementation-defined native_handle_type;

    // construct/copy/destroy:
    thread();
    template <class F, class ...Args> explicit thread(F f, Args&&... args);
    ~thread();
    thread(const thread&) = delete;
    thread(thread&&);
    thread& operator=(const thread&) = delete;
    thread& operator=(thread&&);

    // members:
    void swap(thread&&);
    bool joinable() const;
    void join();
    void detach();
    id get_id() const;
    native_handle_type native_handle();

    // static members:
    static unsigned hardware_concurrency();
};

Class thread and class thread::id shall be standard-layout types ([?]).

If and only if the thread type is internally represented by a single data structure which can be passed to operating system specific interfaces, there shall be a nested implementation-defined typedef native_handle_type that is an alias to this native type if it is copyable. Otherwise, if the native type is not copyable, it is a pointer to this native type. The implementation shall document whether the native_handle_type typedef is present.

If the nested typedef native_handle_type exists, then there also shall be a member function native_handle() which returns the underlying representation.

thread types
Class thread::id
    class thread::id
    {
    public:
        id();
    };

    bool operator==(const thread::id& x, const thread::id& y);
    bool operator!=(const thread::id& x, const thread::id& y);
    bool operator<(const thread::id& x, const thread::id& y);
    bool operator<=(const thread::id& x, const thread::id& y);
    bool operator>(const thread::id& x, const thread::id& y);
    bool operator>=(const thread::id& x, const thread::id& y);

    template<class charT, class traits>
    basic_ostream<charT, traits>&
    operator<< (basic_ostream<charT, traits>&& out, const thread::id& id);

Objects of type thread::id uniquely identify threads of execution.

id();

Effects: Constructs an object of type id which compares equal to other default constructed id objects.

Throws: Nothing.

bool operator==(const thread::id& x, const thread::id& y);

Returns: If neither x nor y identifies a thread of execution, returns true. Otherwise if x and y identify the same thread of execution, returns true. Otherwise returns false.

Throws: Nothing.

bool operator!=(const thread::id& x, const thread::id& y);

Returns: !(x == y)

Throws: Nothing.

bool operator<(const thread::id& x, const thread::id& y);

Returns: a value such that operator< is a total ordering as described in [alg.sorting].

[Note: Defining a comparison operator allows thread::id objects to be used as keys in associative containers. --end note]

Throws: Nothing.

bool operator<=(const thread::id& x, const thread::id& y);

Returns: !(y < x)

Throws: Nothing.

bool operator>(const thread::id& x, const thread::id& y);

Returns: y < x

Throws: Nothing.

bool operator>=(const thread::id& x, const thread::id& y);

Returns: !(x < y)

Throws: Nothing.

template<class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>&& out, const thread::id& id);

Effects: Inserts an unspecified text representation of the thread::id into the stream out.

Returns: out.

thread constructors
thread();

Effects: Constructs a thread object not attached to any thread of execution. [Note: This is the state of a thread object after detach or join is successfully called. -- end note]

Postconditions:

get_id() == thread::id()
&& joinable() == false

Remarks: get_id() returns an identity that refers to not any thread. This identity compares equal to other non-joinable threads, and compares not equal to all other joinable threads.

Throws: Nothing.

template <class F, class ...Args> explicit thread(F f, Args&&... args);

Requires: F is a callable type [func.def]. If f is an lvalue, F must be CopyConstructible. If f is an rvalue, F must only be MoveConstructible.

Effects: Constructs an object of type thread and executes INVOKE(f, t1, t2, ..., tN) in a new thread of execution, where t1, t2, ..., tN are the values in args.... Any return value from f is ignored. If f terminates with an uncaught exception, std::terminate() shall be called.

Postconditions:

get_id() != thread::id()
&& joinable() == true

*this represents the newly started thread of execution.

Throws: system_error if unable to start the new thread of execution.

thread(thread&& x);

Effects: Constructs an object of type thread from x.

Postconditions: x.joinable() is false. x.get_id() == thread().get_id(). joinable() returns the value of x.joinable() prior to the start of construction. get_id() returns the value of x.get_id() prior to the start of construction.

Throws: Nothing.

thread destructor
~thread();

Effects: If joinable() then detach(), otherwise no effects.

Throws: Nothing.

thread assignment
thread& operator=(thread&& x);

Effects: If this currently refers to a joinable thread object, calls detach(). Then assigns the state of x to *this and sets x to a default constructed state.

Postconditions: x.joinable() is false. x.get_id() == thread().get_id(). joinable() returns the value of x.joinable() prior to the assignment. get_id() returns the value of x.get_id() prior to the assignment.

Throws: Nothing.

thread members
void swap(thread&& x);

Effects: Swaps the state of *this and x.

Throws: Nothing.

bool joinable() const;

Returns: get_id() != id().

Throws: Nothing.

void join();

Preconditions: joinable() is true.

Effects: The current thread of execution blocks until the thread of execution represented by *this completes.

Postconditions: After a normal return of join(), joinable() is false. If join() throws an exception, the thread of execution represented by *this remains joinable.

Throws: May throw system_error.

void detach();

Preconditions: joinable() is true.

Effects: The thread of execution represented by *this continues execution. When the thread of execution represented by *this ends execution it shall release any owned resources.

Postconditions: joinable() is false. *this does not represent a thread of execution.

Throws: Nothing.

id get_id() const;

Returns: An object of type thread::id which identifies the thread of execution represented by *this. If this thread is not joinable() returns a default constructed thread::id.

Throws: Nothing.

native_handle_type native_handle();

Returns: The underlying representation of the thread object.

Throws: Nothing.

thread static members
unsigned hardware_concurrency();

Returns: The number of threads of execution that can reasonably be expected to execute concurrently. [Note: This value should only be considered to be a hint. --end note] If this value is not computable or well defined a return value of 1 is recommended, but not required.

Throws: Nothing.

thread specialized algorithms
void swap(thread&  x, thread&  y);
void swap(thread&& x, thread&  y);
void swap(thread&  x, thread&& y);

Effects: x.swap(y).

Namespace this_thread

namespace this_thread
{
    thread::id get_id();
    
    void yield();
    template <class TimeDuration>
        void sleep(const TimeDuration& rel_t);

}  // this_thread
thread::id this_thread::get_id();

Returns: Returns an object of type thread::id that uniquely identifies the current thread of execution. The object returned shall not compare equal to a default constructed thread::id.

Throws: Nothing.

void yield();

Effects: Offers the operating system the opportunity to schedule another thread of execution.

Throws: Nothing.

template <class TimeDuration>
    void sleep(const TimeDuration& rel_t);

Requires: TimeDuration shall be explicitly convertible to nanoseconds.

Effects: The current thread of execution blocks for at least the amount of time specified.

Throws: Nothing.

struct once_flag

Objects of class once_flag are opaque data structures that allow call_once to initialize data without causing a data race or deadlock.

constexpr once_flag();

Effects: Constructs a object of type once_flag.

Postcondition: Internal state is set to indicate to an invocation of call_once with this once_flag as its initial argument that no function has been called.

non-member function call_once

template<class Callable, class Args...>
void call_once(once_flag& flag, Callable func, Args&&... args);

Requires: If the Callable argument func is an lvalue, F is CopyConstructible. Otherwise, func is an rvalue, and F is MoveConstructible. Copying or moving (as appropriate) shall have no side effects, and the effect of calling the copy shall be equivalent to calling the original.

Effects: The argument func (or a copy thereof) is called exactly once for the once_flag object specified by flag, as-if by invoking func(args), even if call_once is called multiple times for the same once_flag object. If multiple calls to call_once with the same once_flag object occur in separate threads of execution, only one thread of execution shall call func, and none shall proceed until the call to func has completed. If the invocation of func results in an exception being thrown, the exception is propagated to the caller and the effects are as-if this invocation of call_once did not occur.

Throws: system_error or any exception propagated from func.

Thread safety: Access to the same once_flag object by calls to call_once from different threads of execution shall not result in a data race or deadlock.

[Examples:

std::once_flag flag;

void init();

void f()
{
    std::call_once(flag,init);
}

struct initializer
{
    void operator()();
};

void g()
{
    static std::once_flag flag2;
    std::call_once(flag2,initializer());
}

-- end example]

Mutexs and locks

<mutex> synopsis

namespace std {

struct mutex;
struct recursive_mutex;
struct timed_mutex;
struct recursive_timed_mutex;

struct defer_lock_t;
struct try_to_lock_t;
struct adopt_lock_t;

extern const defer_lock_t  defer_lock;
extern const try_to_lock_t try_to_lock;
extern const adopt_lock_t  adopt_lock;

class lock_error;

template <class Mutex> class lock_guard;
template <class Mutex> class unique_lock;

template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&& x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&& y);

template <class L1, class L2, class ...L3> int try_lock(L1&, L2&, L3&...);
template <class L1, class L2, class ...L3> void lock(L1&, L2&, L3&...);

}  // std

Mutex concepts

Mutex objects provide synchronization operations to avoid data races. A mutex object supports mutual exclusion between threads of execution by limiting its ownership to a single thread of execution. A thread of execution obtains ownership of a mutex object by calling lock() and relinquishes ownership by calling unlock(). The thread of execution that calls lock() for a mutex object shall call unlock(). Mutexes may be either recursive or non-recursive. The syntax is the same for both recursive and non-recursive mutexes, but the semantics differ for the member functions as described below.

A mutex type shall be DefaultConstructible and Destructible. If initialization of a mutex type fails, an exception of type system_error shall be thrown. The destructor of a mutex type shall not exit by an exception. A mutex type is neither copyable nor movable. A mutex type shall have the following member functions:

void lock();

Precondition: For non-recursive mutexes the current thread of execution shall not own the mutex.

Effects: The current thread of execution will block until the mutex is not owned by another thread of execution. Upon successful completion, the current thread of execution owns the mutex.

Throws: system_error.

Thread safety: This is an acquire operation.

bool try_lock();

Precondition: For non-recursive mutexes the current thread of execution shall not own the mutex.

Effects: If ownership can be obtained without blocking, then ownership is obtained, else there is no effect and try_lock() immediately returns.

Returns: true if ownership was obtained, otherwise false.

Thread safety: This is an acquire operation if try_lock returns true.

Throws: Nothing.

void unlock();

Precondition: The current thread of execution shall own the mutex.

Effects: For a non-recursive mutex ownership is released. For a recursive mutex unlock() must be called the same number of times which the mutex was locked (via either lock() or try_lock() or by any other locking function) before ownership is released.

Thread safety: This is a release operation.

Throws: Nothing.

If and only if the mutex type is internally represented by a single data structure which can be passed to operating system specific interfaces, then there shall be a nested implementation-defined typedef native_handle_type that is an alias to this native type if it is copyable, otherwise if the native type is not copyable, is a pointer to this native type. The implementation shall document whether the native_handle_type typedef is present.

If the nested typedef native_handle_type exists, then there also shall be a member function native_handle() which returns native_handle_type. [Example:

class mutex
{
    pthread_mutex_t m;
public:
    typedef pthread_mutex_t* native_handle_type;
    native_handle_type native_handle() {return &m;}
    ...
};

--end example]

If there is no single operating system specific data structure which implements the mutex type, then neither the nested type native_handle_type nor the member function native_handle() shall not be present. [Example: if a recursive_mutex is implemented with both a pthread_mutex_t and a separate lock count, then there will be no native_handle_type. --end example]

Implementations may supply additional implementation defined constructors which allow further customization as afforded by the implementation or its environment.

Class mutex

namespace std {

struct mutex
{
public:
    mutex();
    ~mutex();

    mutex(const mutex&) = delete;
    mutex& operator=(const mutex&) = delete;

    void lock();
    bool try_lock();
    void unlock();

    typedef unspecified native_handle_type;  // conditionally present.  example: pthread_mutex_t*
    native_handle_type native_handle();      // conditionally present
};

}  // std

The class mutex is a non-recursive mutex which satisfies all of the Mutex requirements. It shall be a standard-layout type ([?]).

Class recursive_mutex

namespace std {

struct recursive_mutex
{
public:
    recursive_mutex();
    ~recursive_mutex();

    recursive_mutex(const recursive_mutex&) = delete;
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    void lock();
    bool try_lock();
    void unlock();

    typedef unspecified native_handle_type;  // conditionally present.  example: pthread_mutex_t*
    native_handle_type native_handle();      // conditionally present
};

}  // std

The class recursive_mutex shall be a recursive mutex which satisfies all of the Mutex requirements. It shall be a standard-layout type ([?]).

Timed Mutexes

Types that meet the requirements of the Timed Mutex concept also meet the requirements of the Mutex concept and add a single member function:

template <class TimeDuration>
    bool timed_lock(const TimeDuration& rel_time);

Precondition: For non-recursive mutexes the current thread of execution shall not own the mutex. The type TimeDuration provides resolution information (ticks_per_second) that allows conversion of the specified value into the native time resolution.

Effects: The function attempts to obtain ownership of the mutex within the specified time. If the indicated time is less than or equal to 0, the function still attempts to obtain ownership without blocking (as if by calling try_lock()). If the function returns within the specified time duration, it shall have obtained ownership.

Returns: true if ownership was obtained, otherwise false.

Thread safety: This is a synchronization operation.

Throws: Nothing.

Class timed_mutex

namespace std {

struct timed_mutex
{
public:
    timed_mutex();
    ~timed_mutex();

    timed_mutex(const timed_mutex&) = delete;
    timed_mutex& operator=(const timed_mutex&) = delete;

    void lock();
    bool try_lock();
    template <class TimeDuration>
        bool timed_lock(const TimeDuration& rel_time);
    void unlock();

    typedef unspecified native_handle_type;  // conditionally present.  example: pthread_mutex_t*
    native_handle_type native_handle();      // conditionally present
};

}  // std

The class timed_mutex is a non-recursive mutex that satisfies all of the Timed Mutex requirements. It shall be a standard-layout type ([?]).

Class recursive_timed_mutex

namespace std {

struct recursive_timed_mutex
{
public:
    recursive_timed_mutex();
    ~recursive_timed_mutex();

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

    void lock();
    bool try_lock();
    template <class TimeDuration>
        bool timed_lock(const TimeDuration& rel_time);
    void unlock();

    typedef unspecified native_handle_type;  // conditionally present.  example: pthread_mutex_t*
    native_handle_type native_handle();      // conditionally present
};

}  // std

The class recursive_timed_mutex shall be a recursive mutex that satisfies all of the Timed Mutex requirements. It shall be a standard-layout type ([?]).

Locks

Locks are objects that hold a reference to a mutex and unlock the mutex during the lock's destruction (such as when leaving block scope). The locks do not manage the lifetime of the mutex they reference, but only the ownership status of that mutex. [Note: Locks are intended to ease the burden of unlocking the mutex under both normal and exceptional circumstances. --end note]

Some locks may take tag types which describe what should be done with the mutex in the lock's constructor.

struct defer_lock_t  {};
struct try_to_lock_t {};
struct adopt_lock_t  {};

extern const defer_lock_t   defer_lock;
extern const try_to_lock_t  try_to_lock;
extern const adopt_lock_t   adopt_lock;

An exception class lock_error derives from exception and is used to indicate improper usage of locks such as locking a mutex that the lock already owns, or unlocking a mutex that the lock does not own.

class lock_error
    : public std::exception
{
public:
    virtual const char* what() const throw();
};

Class lock_guard

namespace std {

template <class Mutex>
class lock_guard
{
public:
    typedef Mutex mutex_type;

    explicit lock_guard(mutex_type& m);
    lock_guard(mutex_type& m, adopt_lock_t);
    ~lock_guard();

    lock_guard(lock_guard const&) = delete;
    lock_guard& operator=(lock_guard const&) = delete;
};

}  // std

lock_guard is used to control the ownership of a mutex within a single scope. An invariant of the lock_guard object is that it maintains the ownership of the mutex throughout the lock_guard's lifetime. Mutex ownership can not be deferred or transferred away from the lock_guard.

explicit lock_guard(mutex_type& m);

Precondition: If mutex_type is not a recursive mutex, the current thread of execution does not own the mutex. The lifetime of m is greater than the lifetime of the lock_guard object.

Effects: Stores a reference to m and calls m.lock().

lock_guard(mutex_type& m, adopt_lock_t);

Precondition: The current thread of execution has ownership of the mutex m. The lifetime of m is greater than the lifetime of the lock_guard object.

Effects: Stores a reference to m and performs no other operation on it.

~lock_guard();

Effects: m.unlock().

Throws: Nothing.

Class unique_lock

namespace std {

template <class Mutex>
class unique_lock
{
public:
    typedef Mutex mutex_type;

    unique_lock();
    explicit unique_lock(mutex_type& m);
    unique_lock(mutex_type& m, defer_lock_t);
    unique_lock(mutex_type& m, try_to_lock_t);
    unique_lock(mutex_type& m, adopt_lock_t);
    ~unique_lock();

    unique_lock(unique_lock const&) = delete;
    unique_lock& operator=(unique_lock const&) = delete;

    unique_lock(unique_lock&& u);
    unique_lock& operator=(unique_lock&& u);

    void lock();
    bool try_lock();

    template <class TimeDuration>
        bool timed_lock(const TimeDuration& rel_t);
    bool timed_lock(const system_time& abs_time);

    void unlock();

    bool owns_lock() const;
    operator unspecified-bool-type () const;
    mutex_type* mutex() const;

    void swap(unique_lock&& u);
    mutex_type* release();
};

template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&& x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&& y);

}  // std

unique_lock is used to control the ownership of a mutex within one or more scopes. Mutex ownership can be deferred or transferred away from the unique_lock. An object of type unique_lock is not copyable but is movable.

unique_lock();

Effects: Constructs an object of type unique_lock.

Postcondition:

mutex() == 0
owns_lock() == false
explicit unique_lock(mutex_type& m);

Precondition: If mutex_type is not a recursive mutex, the current thread of execution does not own the mutex. The lifetime of m is greater than the lifetime of the unique_lock object.

Effects: Stores a reference to m and calls m.lock().

Postcondition:

mutex() == &m
owns_lock() == true
unique_lock(mutex_type& m, defer_lock_t);

Precondition: If mutex_type is not a recursive mutex, the current thread of execution does not own the mutex. The lifetime of m is greater than the lifetime of the unique_lock object.

Effects: Stores a reference to m and performs no other operation on it.

Postcondition:

mutex() == &m
owns_lock() == false
unique_lock(mutex_type& m, try_to_lock_t);

Precondition: If mutex_type is not a recursive mutex, then the current thread of execution does not own the mutex. The lifetime of m is greater than the lifetime of the unique_lock object.

Effects: Stores a reference to m and calls m.try_lock().

Postcondition:

mutex() == &m
owns_lock() == The result of the call to m.try_lock()
unique_lock(mutex_type& m, adopt_lock_t);

Precondition: The current thread of execution has ownership of the mutex m. The lifetime of m is greater than the lifetime of the unique_lock object.

Effects: Stores a reference to m and performs no other operation on it.

Postcondition:

mutex() == &m
owns_lock() == true
~unique_lock();

Effects: If owns_lock() calls unlock() on the referenced mutex. Otherwise there are no effects.

Throws: Nothing.

unique_lock(unique_lock&& u);

Effects: Transfers mutex ownership (if any) from u to this.

Postcondition:

mutex() == The value of u.mutex() prior to the construction.
owns_lock() == The value of u.owns_lock() prior to the construction.
u.mutex() == 0
u.owns_lock() == false

Throws: Nothing.

unique_lock& operator=(unique_lock&& u);

Effects: If owns_lock() calls unlock(), and then transfers mutex ownership (if any) from u to this.

Postcondition:

mutex() == The value of u.mutex() prior to the construction.
owns_lock() == The value of u.owns_lock() prior to the construction.
u.mutex() == 0
u.owns_lock() == false

Throws: Nothing.

Note: With a recursive mutex it is possible that both this and u own the same mutex before the assignment. In this case, this will own the mutex after the assignment (and u will not), but the mutex's lock count will be decremented by one.

void lock();

Effects: Calls lock() on the referenced mutex.

Postcondition: owns_lock() == true.

Throws: lock_error, if on entry owns_lock() is true.

bool try_lock();

Effects: Calls try_lock() on the referenced mutex.

Returns: The result of the call to try_lock() on the referenced mutex.

Postcondition: owns_lock() == The result of the call to try_lock() on the referenced mutex.

Throws: lock_error, if on entry owns_lock() is true.

template <class TimeDuration>
   bool timed_lock(const TimeDuration& rel_t);

Effects: Calls timed_lock(rel_t) on the referenced mutex. If the resolution of TimeDuration is greater than the native resolution the time is rounded up to the nearest native resolution.

Returns: The result of the call to timed_lock(rel_t) on the referenced mutex.

Postcondition: owns_lock() == The result of the call to timed_lock(rel_t) on the referenced mutex.

Throws: lock_error, if on entry owns_lock() is true.

void unlock();

Effects: Calls void unlock() on the referenced mutex.

Postcondition: owns_lock() == false.

Throws: lock_error, if on entry owns_lock() is false.

bool owns_lock() const;

Returns: true if this owns a lock on a referenced mutex, else false.

Throws: Nothing.

operator unspecified-bool-type () const;

Returns: Non-null if owns_lock() would return true, else returns null.

Throws: Nothing.

mutex_type* mutex() const;

Returns: A pointer to the referenced mutex, or null if there is no referenced mutex.

Throws: Nothing.

void swap(unique_lock&& u);

Effects: Swaps state with u.

Throws: Nothing.

mutex_type* release();

Returns: A pointer to the referenced mutex, or null if there is no referenced mutex.

Postcondition:

mutex() == 0
owns_lock() == false

Throws: Nothing.

template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&& x, unique_lock<Mutex>&  y);
template <class Mutex> void swap(unique_lock<Mutex>&  x, unique_lock<Mutex>&& y);

Effects: x.swap(y).

Throws: Nothing.

Generic Locking Algorithms

template <class L1, class L2, class ...L3> int try_lock(L1&, L2&, L3&...);

Requires: Each template parameter type must supply the following member functions with semantics corresponding to the Mutex concept, except that try_lock is allowed to throw an exception. [Note: The unique_lock class template meets these requirements when suitable instantiated. --end note]

bool try_lock();
void unlock();

Effects: The functions attempts to lock all arguments without blocking by calling try_lock() on each of them. If any argument can not be locked, then all arguments which have already been locked will be unlocked. On return, either all arguments will be locked, or none of them will be locked. If an exception is thrown by a call to try_lock(), there are no effects.

Returns: If all arguments were successfully locked, returns -1. Otherwise returns a 0-based index value indicating which argument failed to lock.

template <class L1, class L2, class ...L3> void lock(L1&, L2&, L3&...);

Requires: Each template parameter type must supply the following member functions with semantics corresponding to the Mutex concept, except that try_lock is allowed to throw an exception [Note: The unique_lock class template meets these requirements when suitable instantiated. --end note]

void lock();
bool try_lock();
void unlock();

Effects: All arguments are locked with an algorithm that avoids deadlock. If an exception is thrown by a call to lock() or try_lock(), there are no effects.

Condition variables

<condition_variable> synopsis
namespace std {

class condition_variable;
class condition_variable_any;

}  // std

Class condition_variable

An object of class condition_variable is a synchronization primitive used to cause a thread of execution to wait until notified by some other thread of execution that some condition is met, or a UTC[(?)] time is reached.

If and only if the condition variable type is internally represented by an object which can be passed to operating system specific interfaces, then there shall be a implementation-defined member typedef native_handle_type that is an alias to this native type, if it is copyable, or if the native type is not copyable, a pointer to this native type. The implementation shall document whether the native_handle_type member typedef is present.

If the nested typedef native_handle_type exists, then there also shall be a member function native_handle() which returns the underlying representation.

namespace std {

class condition_variable
{
public:
    typedef implementation-defined native_handle_type;
    
    condition_variable();
    ~condition_variable();

    condition_variable(const condition_variable&) = delete;
    condition_variable& operator=(const condition_variable&) = delete;

    void notify_one();
    void notify_all();
    void wait(unique_lock<mutex>& lock);
    template <class Predicate>
        void wait(unique_lock<mutex>& lock, Predicate pred);
    bool timed_wait(unique_lock<mutex>& lock, const system_time& abs_time);
    template <class Predicate>
        bool timed_wait(unique_lock<mutex>& lock, const system_time& abs_time, Predicate pred);
    native_handle_type native_handle();
};

}  // std
condition_variable();

Effects: Constructs an object of class condition_variable.

~condition_variable();

Effects: Destroys the object.

Throws: Nothing.

void notify_one();

Effects: If any threads of execution are blocked waiting for *this, unblocks at least one those threads of execution.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable object from different threads of execution shall not result in data races or deadlocks.

void notify_all();

Effects: Unblock all threads of execution that are blocked waiting for *this.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable object from different threads of execution shall not result in data races or deadlocks.

void wait(unique_lock<mutex>& lock);

Precondition: lock is locked by the current thread of execution. No other thread of execution is waiting on this condition_variable object unless lock refers to the same underlying mutex object.

Effects: Atomically blocks and releases the lock on lock. If the wait should throw an exception for any reason, lock will be locked as the exception propagates. This thread of execution shall unblock when another threadof execution issues a notification to this blocked thread of execution. The current thread of execution may unblock and return even in the absence of a notification.

Postcondition: lock is locked by the current thread of execution.

Throws: May throw system_error if a precondition is not met.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable object from different threads of execution shall not result in data races or deadlocks.

template <class Predicate>
    void wait(unique_lock<mutex>& lock, Predicate pred);

Effects: While pred() returns false calls wait(lock).

Note: There is no blocking if pred() is initially true.

bool timed_wait(unique_lock<mutex>& lock, const system_time& abs_time);

Precondition: The lock is locked by the current thread of execution. No other thread of execution is waiting on this condition_variable object unless lock refers to, the same underlying mutex object.

Effects: Atomically blocks and releases the lock on lock. If the timed_wait should throw an exception for any reason, lock will be locked as the exception propagates out. If the absolute time specified by abs_time passes (that is, system time equals or exceeds abs_time) before the condition_variable is notified, or if the absolute time specified by abs_time has already been passed at the time of the call, then false is returned. This thread of execution shall unblock when another thread of execution issues a notification to this blocked thread of execution. The current thread of execution may unblock and return even in the absence of a notification.

Postcondition: lock is locked by the current thread of execution.

Returns: true if the call to timed_wait is notified prior to the indicated timeout, otherwise returns false.

Throws: May throw system_error if a precondition is not met.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable object from different threads of execution shall not result in data races or deadlocks.

template <class Predicate>
    bool timed_wait(unique_lock<mutex>& lock, const system_time& abs_time, Predicate pred);

Effects: As if:

while (!pred())
{
    if (!timed_wait(lock, abs_time))
        return pred();
}
return true;

Returns: pred().

Note: There is no blocking if pred() is initially true, even if the timeout has already expired. The return value indicates whether the predicate evaluates to true, regardless of whether the timeout was triggered.

native_handle_type native_handle();

Returns: the representation of the underlying object used to implement *this.

condition_variable shall be a standard-layout type ([?]).

Class condition_variable_any

An object of class condition_variable_any is a synchronization primitive used to cause a thread of execution to wait until notified by some other thread of execution that some condition is met, or a UTC[(?)] time is reached.

The Lock type must support member functions lock and unlock with the semantics of the mutex concept. All of the standard mutex types meet this requirement.

If and only if the condition_variable_any type is internally represented by an an object or objects which can be passed to operating system specific interfaces, then there shall be a nested implementation-defined typedef native_handle_type that is an alias to a type providing access to the object or objects. The type native_handle_type must be copyable; if the object or objects are not copyable, native_handle_type must be a pointer type. The implementation shall document whether the native_handle_type typedef is present.

If the nested typedef native_handle_type exists, then there also shall be a member function native_handle() which returns the underlying representation.

namespace std {

class condition_variable_any
{
public:
    typedef implementation-defined native_handle_type;
    condition_variable_any();
    ~condition_variable_any();

    condition_variable_any(const condition_variable_any&) = delete;
    condition_variable_any& operator=(const condition_variable_any&) = delete;

    void notify_one();
    void notify_all();
    template <class Lock>
        void wait(Lock& lock);
    template <class Lock, class Predicate>
        void wait(Lock& lock, Predicate pred);
    template <class Lock>
        bool timed_wait(Lock& lock, const system_time& abs_time);
    template <class Lock, class Predicate>
        bool timed_wait(Lock& lock, const system_time& abs_time, Predicate pred);
    native_handle_type native_handle();
};

}  // std
condition_variable_any();

Effects: Constructs an object of class condition_variable_any.

~condition_variable_any();

Effects: Destroys the object.

Throws: Nothing.

void notify_one();

Effects: If any threads of execution are blocked waiting for *this, unblocks at least one those threads of execution.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable_any object from different threads of execution shall not result in data races or deadlocks.

void notify_all();

Effects: Unblock all threads of execution that are blocked waiting for *this.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable_any object from different threads of execution shall not result in data races or deadlocks.

void wait(Lock& lock);

Precondition: lock is locked by the current thread of execution. If Lock supports recursive locking, the lock count is one. No other thread of execution is waiting on this condition_variable_any object unless lock is, or refers to, the same underlying mutex object.

Effects: Atomically blocks and releases the lock on lock. If the wait should throw an exception for any reason, lock will be locked as the exception propagates. This thread of execution shall unblock when another thread of execution issues a notification to this blocked thread of execution. The current thread of execution may unblock and return even in the absence of a notification.

Postcondition: lock is locked by the current thread of execution.

Throws: May throw system_error.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable_any object from different threads of execution shall not result in data races or deadlocks.

template <class Predicate>
    void wait(lock_type& lock, Predicate pred);

Effects: While pred() returns false, calls wait(lock).

Note: There is no blocking if pred() is initially true.

bool timed_wait(Lock& lock, const system_time& abs_time);

Precondition: The lock is locked by the current thread of execution. If Lock supports recursive locking, the lock count is one. No other thread of execution is waiting on this condition_variable_any object unless lock is, or refers to, the same underlying mutex object.

Effects: Atomically blocks and releases the lock on lock. If the timed_wait should throw an exception for any reason, lock will be locked as the exception propagates out. If the absolute time specified by abs_time passes (that is, system time equals or exceeds abs_time) before the condition_variable_any is notified, or if the absolute time specified by abs_time has already been passed at the time of the call, then false is returned. This thread of execution shall unblock when another thread of execution issues a notification to this blocked thread of execution. The current thread of execution may unblock and return even in the absence of a notification.

Postcondition: lock is locked by the current thread of execution.

Returns: true if the call to timed_wait is notified prior to the indicated timeout, otherwise returns false.

Throws: May throw system_error.

Thread safety: Calls to the wait, timed_wait, notify_one or notify_all member functions of the same condition_variable_any object from different threads of execution shall not result in data races or deadlocks.

template <class _Predicate>
    bool timed_wait(Lock& lock, const system_time& abs_time, Predicate pred);

Effects: As if:

while (!pred())
{
    if (!timed_wait(lock, abs_time))
        return pred();
}
return true;

Returns: pred().

Note: There is no blocking if pred() is initially true, even if the timeout has already expired. The return value indicates whether the predicate evaluates to true, regardless of whether the timeout was triggered.

native_handle_type native_handle();

Returns: the representation of the underlying object or objects used to implement *this.


Chapter ?   Date Time Library


This clause describes components for determining and manipulating temporal values. A time point represents a dimensionless instant in the time continuum. A time duration represents a length of time unattached to any time point. Time points and time durations have a resolution which is their smallest representable time duration. Time points have an epoch or start of a given time scale. For time_t the epoch is 1970-01-01 00:00:00.

Header <date_time> Synopsis

namespace std 
{

  //duration types
  class    hours;
  class    minutes;
  class    seconds;
  class    milliseconds;
  class    microseconds;
  class    nanoseconds;

  //timepoint   
  class system_time;

  //functions
  system_time get_system_time();

} //std

class system_time

The class system_time provides a time point that represents the current Coordinated Universal Time, known as UTC, time. system_time shall provide an epoch time of 1970-01-01 00:00:00.000000000 and a maximum time value of at least epoch time + 292 years.

class system_time shall be EqualityComparable, LessThanComparable, CopyConstructable, DefaultConstructable, and Assignable.

class system_time 
{
 public:

  system_time();
  system_time(time_t, nanoseconds ns);
  ~system_time();

  time_t seconds_since_epoch() const;
  nanoseconds nanoseconds_since_epoch() const;

  //traits 
  typedef 'implementation defined' tick_type;
  static tick_type ticks_per_second();
  static tick_type seconds_per_tick();
  static bool is_subsecond();

  //comparison functions
  bool operator==(const system_time& rhs) const;
  bool operator!=(const system_time& rhs) const;
  bool operator>(const system_time& rhs) const;
  bool operator>=(const system_time& rhs) const;
  bool operator<(const system_time& rhs) const;
  bool operator<=(const system_time& rhs) const;

  //arithmetic functions
  nanoseconds operator-(const system_time& rhs) const

  template<typename TimeDuration>
  system_time operator+(const TimeDuration& td) const;

  template<typename TimeDuration>
  system_time& operator+=(const TimeDuration& td);

  template<typename TimeDuration>
  system_time operator-(const TimeDuration& td) const;

  template<typename TimeDuration>
  system_time& operator-=(const TimeDuration& td) 

};

Note

292 years represents the number of nanoseconds that can be represented in a signed 64 bit integer.

system_time();

Effects: Constructs a system_time object representing the epoch time point 1970-01-01 00:00:00.000000000

Throws: Nothing.

system_time(time_t secs, nanoseconds ns);

Effects: Constructs a utc time object representing the time point that is secs + 1,000,000,000*ns after the epoch.

Remarks: If the total nanoseconds > 1 second the seconds are incremented appropriately.

Throws: Nothing.

time_t seconds_since_epoch() const;

Returns: The count of seconds since 1970-01-01 00:00:00.

Throws: Nothing.

nanoseconds nanoseconds_since_epoch() const;

Returns: The count of nanoseconds since 1970-01-01 00:00:00.

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 1000000000

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 0

Remarks: Since this is a subsecond type it returns 0 for seconds_per_tick.

Throws: Nothing.

static bool is_subsecond();

Returns: true.

Throws: Nothing.

bool operator==(const system_time& rhs) const;

Returns: True if the time represented by *this is equal to the time represented by rhs.

Throws: Nothing.

bool operator!=(const system_time& rhs) const;

Returns: True if the time represented by *this is not equal to the time represented by rhs

Throws: Nothing.

bool operator>(const system_time& rhs) const;

Returns: True if time represented by *this is greater than the time represented by rhs.

Throws: Nothing.

bool operator>=(const system_time& rhs) const;

Returns: True if time represented by *this is greater or equal than the time represented by rhs.

Throws: Nothing.

bool operator<(const system_time& rhs) const;

Returns: True if time represented by *this is less than the time represented by rhs.

Throws: Nothing.

bool operator<=(const system_time& rhs) const;

Returns: True if time represented by *this is less or equal than the time represented by rhs.

Throws: Nothing.

nanoseconds operator-(const system_time& rhs) const

Returns: The difference in nanoseconds between the time represented by *this and the time represented by rhs.

Remarks: If rhs is greater the result will be a negative nanosecond. count.

Throws: Nothing.

template<typename TimeDuration>
system_time operator+(const TimeDuration& td) const;

Returns: The duration converted to nanosecond resolution and added to the time represented by *this.

Throws: Nothing.

template<typename TimeDuration>
system_time& operator+=(const TimeDuration& td);

Effects: Convert the duration to nanosecond resolution add to nanoseconds to the time represented by *this.

Returns: Modified value of this.

Throws: Nothing.

template<typename TimeDuration>
system_time operator-(const TimeDuration& td) const;

Returns: The duration converted to nanosecond resolution and subtracted from the time represented by *this.

Throws: Nothing.

template<typename TimeDuration>
system_time& operator-=(const TimeDuration& td) 

Effects: Convert the duration to nanosecond resolution subtract and from the time represented by *this.

Returns: Modified value of this.

Throws: Nothing.

function get_system_time

The function get_system_time provides access to the system clock at a resolution up to nanoseconds. The actual resolution may vary from platform to platform.

  system_time get_system_time();

Comment (not for inclusion in WP)

Typical personal computer platforms currently achieve microsecond level resolution from calls to the clock. The Boost Date-Time Library has a class that portably implements the proposed interface, but it uses different C-level interfaces depending on the operating system.

Common Duration Functions

The following functions are common functions to all durations types. These functions provide the basis for durations to be EqualityComparable, LessThanComparable as well arithmetic operations.

In the following text duration_type refers to the containing duration type.

All duration types are EqualityComparable, LessThanComparable, CopyConstructable, DefaultConstructable, and Assignable for duration objects of the same type.

class TimeDuration { 

    //comparison operators
    template<typename RhsTimeDuration>
    bool operator<  (const RhsTimeDuration&) const;

    template<typename RhsTimeDuration>
    bool operator<= (const RhsTimeDuration&) const;

    template<typename RhsTimeDuration>
    bool operator>  (const RhsTimeDuration&) const;

    template<typename RhsTimeDuration>
    bool operator>= (const RhsTimeDuration&) const;

    template<typename RhsTimeDuration>
    bool operator== (const RhsTimeDuration&) const;

    template<typename RhsTimeDuration>
    bool operator!= (const RhsTimeDuration&) const;


    //sign inversion
    TimeDuration operator-() const

    //arithmetic operations
    template<typename RhsTimeDuration>
    TimeDuration operator- (const RhsTimeDuration& d) const

    template<typename RhsTimeDuration>
    TimeDuration operator-=(const RhsTimeDuration& d)

    template<typename RhsTimeDuration>
    TimeDuration operator+ (const RhsTimeDuration& d) const

    template<typename RhsTimeDuration>
    TimeDuration operator+=(const RhsTimeDuration& d)

    TimeDuration operator/ (int divisor) const
    TimeDuration operator/=(int divisor) 
    TimeDuration operator* (int rhs) const
    TimeDuration operator*=(int divisor) 

    tick_type get_count() const 

}

template<typename RhsTimeDuration>
bool operator==(const RhsTimeDuration& rhs) const;

Returns: True if rhs duration is greater.

Throws: Nothing.

template<typename RhsTimeDuration>
bool operator!=(const RhsTimeDuration& rhs) const;

Returns: True if rhs is not the same time.

Throws: Nothing.

template<typename RhsTimeDuration>
bool operator>(const RhsTimeDuration& rhs) const;

Returns: True if the rhs duration is larger.

Throws: Nothing.

template<typename RhsTimeDuration>
bool operator>=(const RhsTimeDuration& rhs) const;

Returns: True if greater or equal than the rhs duration.

Throws: Nothing.

template<typename RhsTimeDuration>
bool operator<(const RhsTimeDuration& rhs) const;

Returns: True if less than the rhs duration.

Throws: Nothing.

template<typename RhsTimeDuration>
bool operator<=(const RhsTimeDuration& rhs) const;

Returns: True if less or equal to the rhs duration.

Throws: Nothing.

//sign inversion
TimeDuration operator-() const

Returns: Negated value of the duration.

Throws: Nothing.

//arithmetic operations
template<typename RhsTimeDuration>
TimeDuration operator- (const RhsTimeDuration& d) const

Returns: A duration value equal to this-rhs_duration.

Remarks: This will fail to compiler if the RhsTimeDuration is of higher resolution.

Throws: Nothing.

template<typename RhsTimeDuration>
TimeDuration operator-=(const RhsTimeDuration& d)

Effects: Modifies to value equal to this-rhs_duration.

Returns: this

Remarks: This will fail to compiler if the RhsTimeDuration is of higher resolution.

Throws: Nothing.

template<typename RhsTimeDuration>
TimeDuration operator+ (const RhsTimeDuration& d) const

Returns: Duration equal to this+rhs_duration.

Remarks: This will fail to compiler if the RhsTimeDuration is of higher resolution.

Throws: Nothing.

template<typename RhsTimeDuration>
TimeDuration operator+=(const RhsTimeDuration& d)

Effects: Modifies to value equal to this+rhs_duration.

Returns: this

Remarks: This will fail to compiler if the RhsTimeDuration is of higher resolution.

Throws: Nothing.

TimeDuration operator/ (int divisor) const

Returns: Duration with value equal to this/divisor according to integer arithmetic rules.

Throws: Nothing.

TimeDuration operator/=(int divisor) 

Effects: Change value of this by this/divisor according to integer arithmetic rules.

Returns: this

Throws: Nothing.

TimeDuration operator* (int rhs) const

Returns: Duration with value equal to this*rhs

Throws: Nothing.

TimeDuration operator*=(int rhs) 

Effects: Modifies to value equal to this*rhs.

Returns: this

Throws: Nothing.

tick_type get_count() const 

Returns: The count at the resolution of the time duration type.

Throws: Nothing.

class nanoseconds

Objects of class nanoseconds can be used to represent a count of nanoseconds.

class nanoseconds 
{
 public:

   nanoseconds(long long=0);
   nanoseconds(const nanoseconds& rhs);
   ~nanoseconds();

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions

};
nanoseconds(long long=0);

Effects: Constructs an object with a count of nanoseconds - default is zero.

Throws: Nothing.

nanoseconds(const nanoseconds& rhs);

Effects: Copy construction.

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 1000000000

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 0

Throws: Nothing.

static bool is_subsecond();

Returns: true

Throws: Nothing.

class microseconds

Objects of class microseconds can be used to represent a count of microseconds.

class microseconds 
{
 public:

   microseconds(long long=0);
   microseconds(const microseconds& rhs);
   ~microseconds();

   //conversions
   operator nanoseconds() const

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions

};

microseconds(long long=0);

Effects: Constructs an object with a count of microseconds - default is zero.

Throws: Nothing.

microseconds(const microseconds& rhs);

Effects: Copy construction.

Throws: Nothing.

//conversions
operator nanoseconds() const

Returns: microsecond count converted to nanoseconds

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 1000000

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 0

Throws: Nothing.

static bool is_subsecond();

Returns: true

Throws: Nothing.

class milliseconds

Objects of class milliseconds can be used to represent a count of milliseconds.

class milliseconds
{
 public:
   milliseconds(long long=0);
   milliseconds(const milliseconds& rhs);
   ~milliseconds();

   //conversions
   operator nanoseconds() const;
   operator microseconds() const;

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions
};
milliseconds(long long=0);

Effects: Constructs an object with a count of milliseconds - default is zero.

Throws: Nothing.

milliseconds(const milliseconds& rhs);

Effects: Copy construction.

Throws: Nothing.

operator nanoseconds() const

Returns: millisecond count converted to nanoseconds

Throws: Nothing.

operator microseconds() const

Returns: millisecond count converted to microseconds

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 1000

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 0

Throws: Nothing.

static bool is_subsecond();

Returns: true

Throws: Nothing.

class seconds

Objects of class seconds can be used to represent a count of seconds.

class  seconds 
{ 
 public:
   seconds(long long s=0);
   seconds(const seconds& rhs);
   ~seconds();

   //conversions
   operator nanoseconds() const
   operator microseconds() const
   operator milliseconds() const

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions

};
seconds(long long=0);

Effects: Constructs an object with a count of seconds - default is zero.

Throws: Nothing.

seconds(const seconds& rhs);

Effects: Copy construction.

Throws: Nothing.

operator nanoseconds() const

Returns: second count converted to nanoseconds

Throws: Nothing.

operator microseconds() const

Returns: second count converted to microseconds

Throws: Nothing.

operator milliseconds() const

Returns: second count converted to milliseconds

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 1

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 1

Throws: Nothing.

static bool is_subsecond();

Returns: false

Throws: Nothing.

class minutes

Objects of class minutes can be used to represent a count of minutes.

class  minutes 
{
 public:
   minutes(long long s=0);
   minutes(const minutes& rhs);
   ~minutes();

   //conversions
   operator nanoseconds() const
   operator microseconds() const
   operator milliseconds() const
   operator seconds() const

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions

};
minutes(long long=0);

Effects: Constructs an object with a count of minutes - default is zero.

Throws: Nothing.

minutes(const minutes& rhs);

Effects: Copy construction.

Throws: Nothing.

operator nanoseconds() const

Returns: minute count converted to nanoseconds

Throws: Nothing.

operator microseconds() const

Returns: minute count converted to microseconds

Throws: Nothing.

operator milliseconds() const

Returns: minute count converted to milliseconds

Throws: Nothing.

operator seconds() const

Returns: minute count converted to seconds

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 0

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 60

Throws: Nothing.

static bool is_subsecond();

Returns: false

Throws: Nothing.

class hours

Objects of class hours can be used to represent a count of hours.

class  hours 
{
 public:
   hours(long long s=0);
   hours(const hours& rhs);
   ~hours();

   //conversions
   operator nanoseconds() const
   operator microseconds() const
   operator milliseconds() const
   operator seconds() const
   operator minutes() const

   //traits information
   static tick_type ticks_per_second();
   static tick_type seconds_per_tick();
   static bool is_subsecond();
   typedef implementation-defined tick_type;

   //+ common functions

};
hours(long long=0);

Effects: Constructs an object with a count of hours - default is zero.

Throws: Nothing.

hours(const hours& rhs);

Effects: Copy construction.

Throws: Nothing.

operator nanoseconds() const

Returns: hour count converted to nanoseconds

Throws: Nothing.

operator microseconds() const

Returns: hour count converted to microseconds

Throws: Nothing.

operator milliseconds() const

Returns: hour count converted to milliseconds

Throws: Nothing.

operator seconds() const

Returns: hour count converted to seconds

Throws: Nothing.

operator minutes() const

Returns: hour count converted to seconds.

Throws: Nothing.

static tick_type ticks_per_second();

Returns: 0

Throws: Nothing.

static tick_type seconds_per_tick();

Returns: 3600

Throws: Nothing.

static bool is_subsecond();

Returns: false

Throws: Nothing.

References

Acknowledgments

The overall design of this threading library is based on William Kempf's Boost.Thread Library, as refined by literally hundreds of other Boost users and contributors. Dinkumware and Metrowerks (now Freescale) implementations of Boost.Thread, developed respectively by Pete Becker and Howard Hinnant, created further existing practice. Proposals by Pete Becker, Peter Dimov, Ion Gazta´┐Żaga, and Anthony Williams were also influential. Peter, Ion, and Anthony also contributed numerous critiques, suggestions, and comments on the current proposal, as did other members of an ad hoc threads working group. Jeff Garland contributed the date time portions of the proposal based on the Boost.DateTime Library and his TR2 proposals.