Boost logo

Boost-Commit :

From: hinnant_at_[hidden]
Date: 2007-11-10 16:04:01


Author: hinnant
Date: 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
New Revision: 41003
URL: http://svn.boost.org/trac/boost/changeset/41003

Log:
updated paper and added posix reference implementation
Added:
   sandbox/committee/LWG/ref_impl/condition_variable (contents, props changed)
   sandbox/committee/LWG/ref_impl/condition_variable.cpp (contents, props changed)
   sandbox/committee/LWG/ref_impl/hdate_time (contents, props changed)
   sandbox/committee/LWG/ref_impl/hdate_time.cpp (contents, props changed)
   sandbox/committee/LWG/ref_impl/mutex (contents, props changed)
   sandbox/committee/LWG/ref_impl/mutex.cpp (contents, props changed)
   sandbox/committee/LWG/ref_impl/mutex_base (contents, props changed)
   sandbox/committee/LWG/ref_impl/thread (contents, props changed)
   sandbox/committee/LWG/ref_impl/thread.cpp (contents, props changed)
Text files modified:
   sandbox/committee/LWG/thread_library.html | 286 ++++++++++++++++++++++++++++++++-------
   1 files changed, 230 insertions(+), 56 deletions(-)

Added: sandbox/committee/LWG/ref_impl/condition_variable
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/condition_variable 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,221 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// condition_variable
+
+#ifndef _CONDITION_VARIABLE
+#define _CONDITION_VARIABLE
+
+/*
+ condition_variable synopsis
+
+ namespace std {
+
+ class condition_variable
+ {
+ public:
+
+ 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);
+
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle();
+ };
+
+ class condition_variable_any
+ {
+ public:
+
+ 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);
+ };
+
+ } // std
+
+*/
+
+#include <mutex_base>
+#include <system_error>
+#include <hdate_time>
+#include <type_traits>
+
+namespace std
+{
+
+struct __lock_external
+{
+ template <class _Lock>
+ void operator()(_Lock* __m) {__m->lock();}
+};
+
+class condition_variable
+{
+ pthread_cond_t cv_;
+public:
+
+ condition_variable();
+ ~condition_variable();
+private:
+ condition_variable(const condition_variable&); // = delete;
+ condition_variable& operator=(const condition_variable&); // = delete;
+public:
+ 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);
+
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle() {return &cv_;}
+private:
+ void __do_wait(pthread_mutex_t*);
+ bool __do_timed_wait(pthread_mutex_t*, const system_time& abs_time);
+
+};
+
+inline
+void
+condition_variable::wait(unique_lock<mutex>& lock)
+{
+ __do_wait(lock.mutex()->native_handle());
+}
+
+template <class Predicate>
+void
+condition_variable::wait(unique_lock<mutex>& lock, Predicate pred)
+{
+ while (!pred())
+ __do_wait(lock.mutex()->native_handle());
+}
+
+inline
+bool
+condition_variable::timed_wait(unique_lock<mutex>& lock, const system_time& abs_time)
+{
+ return __do_timed_wait(lock.mutex()->native_handle(), abs_time);
+}
+
+template <class Predicate>
+bool
+condition_variable::timed_wait(unique_lock<mutex>& lock, const system_time& abs_time, Predicate pred)
+{
+ while (!pred())
+ if (!__do_timed_wait(lock.mutex()->native_handle(), abs_time))
+ return pred();
+ return true;
+}
+
+class condition_variable_any
+{
+ condition_variable cv_;
+ mutex mut_;
+public:
+
+ // condition_variable_any() = default;
+ // ~condition_variable_any() = default;
+
+ // 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);
+};
+
+inline
+void
+condition_variable_any::notify_one()
+{
+ lock_guard<mutex> _(mut_);
+ cv_.notify_one();
+}
+
+inline
+void
+condition_variable_any::notify_all()
+{
+ lock_guard<mutex> _(mut_);
+ cv_.notify_all();
+}
+
+template <class Lock>
+void
+condition_variable_any::wait(Lock& lock)
+{
+ unique_lock<mutex> lk(mut_);
+ lock.unlock();
+ unique_ptr<Lock, __lock_external> external_guard(&lock);
+ lock_guard<unique_lock<mutex>> internal_guard(lk, adopt_lock);
+ cv_.wait(lk);
+} // mut_.unlock(), lock.lock()
+
+template <class Lock, class Predicate>
+inline
+void
+condition_variable_any::wait(Lock& lock, Predicate pred)
+{
+ while (!pred())
+ wait(lock);
+}
+
+template <class Lock>
+bool
+condition_variable_any::timed_wait(Lock& lock, const system_time& abs_time)
+{
+ unique_lock<mutex> lk(mut_);
+ lock.unlock();
+ unique_ptr<Lock, __lock_external> external_guard(&lock);
+ lock_guard<unique_lock<mutex>> internal_guard(lk, adopt_lock);
+ return cv_.timed_wait(lk, abs_time);
+} // mut_.unlock(), lock.lock()
+
+template <class Lock, class Predicate>
+inline
+bool
+condition_variable_any::timed_wait(Lock& lock, const system_time& abs_time, Predicate pred)
+{
+ while (!pred())
+ if (!timed_wait(lock, abs_time))
+ return pred();
+ return true;
+}
+
+} // std
+
+#endif

Added: sandbox/committee/LWG/ref_impl/condition_variable.cpp
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/condition_variable.cpp 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,76 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// condition_variable.cpp
+
+#include "condition_variable"
+#include "hdate_time"
+#undef NDEBUG
+#include <cassert>
+
+namespace std
+{
+
+template <>
+struct __make<timespec>
+{
+ static
+ timespec
+ from(const system_time& t)
+ {
+ timespec ts;
+ ts.tv_sec = t.seconds_since_epoch();
+ ts.tv_nsec = static_cast<long>(t.nanoseconds_since_epoch().get_count() % system_time::ticks_per_second());
+ return ts;
+ }
+
+};
+
+condition_variable::condition_variable()
+{
+ error_code::value_type ec = pthread_cond_init(&cv_, 0);
+ if (ec)
+ throw system_error(ec, native_category, "condition_variable constructor failed");
+}
+
+condition_variable::~condition_variable()
+{
+ int e = pthread_cond_destroy(&cv_);
+ assert(e == 0);
+}
+
+void
+condition_variable::notify_one()
+{
+ error_code::value_type ec = pthread_cond_signal(&cv_);
+ if (ec)
+ throw system_error(ec, native_category, "condition_variable notify_one failed");
+}
+
+void
+condition_variable::notify_all()
+{
+ error_code::value_type ec = pthread_cond_broadcast(&cv_);
+ if (ec)
+ throw system_error(ec, native_category, "condition_variable notify_all failed");
+}
+
+void
+condition_variable::__do_wait(pthread_mutex_t* mut)
+{
+ error_code::value_type ec = pthread_cond_wait(&cv_, mut);
+ if (ec)
+ throw system_error(ec, native_category, "condition_variable wait failed");
+}
+
+bool
+condition_variable::__do_timed_wait(pthread_mutex_t* mut, const system_time& abs_time)
+{
+ timespec __tm = __make<timespec>::from(abs_time);
+ error_code::value_type ec = pthread_cond_timedwait(&cv_, mut, &__tm);
+ if (ec != 0 && ec != ETIMEDOUT)
+ throw system_error(ec, native_category, "condition_variable timed_wait failed");
+ return ec == 0;
+}
+
+} // std

Added: sandbox/committee/LWG/ref_impl/hdate_time
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/hdate_time 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,1563 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// hdate_time
+
+#ifndef _HDATE_TIME
+#define _HDATE_TIME
+
+/*
+
+ hdate_time synopsis
+
+ namespace std {
+
+ class nanoseconds
+ {
+ public:
+ typedef long long tick_type;
+
+ nanoseconds(long long ns = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ nanoseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ nanoseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ nanoseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ nanoseconds& operator+=(const RhsDuration& d);
+
+ nanoseconds operator-() const;
+
+ nanoseconds operator/ (int divisor) const;
+ nanoseconds& operator/=(int divisor);
+
+ nanoseconds operator* (int rhs) const;
+ nanoseconds& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+ class microseconds
+ {
+ public:
+ typedef long long tick_type;
+
+ microseconds(long long us = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // conversions
+ operator nanoseconds() const;
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ microseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ microseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ microseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ microseconds& operator+=(const RhsDuration& d);
+
+ microseconds operator-() const;
+
+ microseconds operator/ (int divisor) const;
+ microseconds& operator/=(int divisor);
+
+ microseconds operator* (int rhs) const;
+ microseconds& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+ class milliseconds
+ {
+ public:
+ typedef long long tick_type;
+
+ milliseconds(long long ms = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // conversions
+ operator nanoseconds() const;
+ operator microseconds() const;
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ milliseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ milliseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ milliseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ milliseconds& operator+=(const RhsDuration& d);
+
+ milliseconds operator-() const;
+
+ milliseconds operator/ (int divisor) const;
+ milliseconds& operator/=(int divisor);
+
+ milliseconds operator* (int rhs) const;
+ milliseconds& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+ class seconds
+ {
+ public:
+ typedef long long tick_type;
+
+ seconds(long long s = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // conversions
+ operator nanoseconds() const;
+ operator microseconds() const;
+ operator milliseconds() const;
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ seconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ seconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ seconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ seconds& operator+=(const RhsDuration& d);
+
+ seconds operator-() const;
+
+ seconds operator/ (int divisor) const;
+ seconds& operator/=(int divisor);
+
+ seconds operator* (int rhs) const;
+ seconds& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+ class minutes
+ {
+ public:
+ typedef long tick_type;
+
+ minutes(long long mn = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // conversions
+ operator nanoseconds() const;
+ operator microseconds() const;
+ operator milliseconds() const;
+ operator seconds() const;
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ minutes operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ minutes& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ minutes operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ minutes& operator+=(const RhsDuration& d);
+
+ minutes operator-() const;
+
+ minutes operator/ (int divisor) const;
+ minutes& operator/=(int divisor);
+
+ minutes operator* (int rhs) const;
+ minutes& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+ class hours
+ {
+ public:
+ typedef long tick_type;
+
+ hours(long long hr = 0);
+
+ // traits information
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
+ // conversions
+ operator nanoseconds() const;
+ operator microseconds() const;
+ operator milliseconds() const;
+ operator seconds() const;
+ operator minutes() const;
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ hours operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ hours& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ hours operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ hours& operator+=(const RhsDuration& d);
+
+ hours operator-() const;
+
+ hours operator/ (int divisor) const;
+ hours& operator/=(int divisor);
+
+ hours operator* (int rhs) const;
+ hours& operator*=(int rhs);
+
+ tick_type get_count() const;
+ };
+
+
+ class system_time
+ {
+ public:
+ typedef long long tick_type;
+
+ system_time();
+ system_time(time_t secs, nanoseconds ns);
+
+ time_t seconds_since_epoch() const;
+ nanoseconds nanoseconds_since_epoch() const;
+
+ // traits
+ 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 Duration>
+ system_time operator+(const Duration& td) const;
+
+ template<typename Duration>
+ system_time& operator+=(const Duration& td);
+
+ template<typename Duration>
+ system_time operator-(const Duration& td) const;
+
+ template<typename Duration>
+ system_time& operator-=(const Duration& td);
+
+ };
+
+ system_time get_system_time();
+
+ }
+
+*/
+
+#include <ctime>
+
+namespace std {
+
+template <class T>
+class __is_duration
+{
+ struct two {char x; char y;};
+ template <class U> static two test(...);
+ template <class U> static char test(typename U::tick_type* = 0);
+public:
+ static const bool value = sizeof(test<T>(0)) == 1;
+};
+
+class nanoseconds
+{
+public:
+ typedef long long tick_type;
+private:
+ tick_type ns_;
+public:
+ nanoseconds(long long ns = 0) : ns_(ns) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 1000000000;}
+ static tick_type seconds_per_tick() {return 0;}
+ static bool is_subsecond() {return true;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ nanoseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ nanoseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ nanoseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ nanoseconds& operator+=(const RhsDuration& d);
+
+ nanoseconds operator-() const {return -ns_;}
+
+ nanoseconds operator/ (int divisor) const {return ns_ / divisor;}
+ nanoseconds& operator/=(int divisor) {ns_ /= divisor; return *this;}
+
+ nanoseconds operator* (int rhs) const {return ns_ * rhs;}
+ nanoseconds& operator*=(int rhs) {ns_ *= rhs; return *this;}
+
+ tick_type get_count() const {return ns_;}
+};
+
+class microseconds
+{
+public:
+ typedef long long tick_type;
+private:
+ tick_type us_;
+public:
+ microseconds(long long us = 0) : us_(us) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 1000000;}
+ static tick_type seconds_per_tick() {return 0;}
+ static bool is_subsecond() {return true;}
+
+ // conversions
+ operator nanoseconds() const {return us_ * 1000LL;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ microseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ microseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ microseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ microseconds& operator+=(const RhsDuration& d);
+
+ microseconds operator-() const {return -us_;}
+
+ microseconds operator/ (int divisor) const {return us_ / divisor;}
+ microseconds& operator/=(int divisor) {us_ /= divisor; return *this;}
+
+ microseconds operator* (int rhs) const {return us_ * rhs;}
+ microseconds& operator*=(int rhs) {us_ *= rhs; return *this;}
+
+ tick_type get_count() const {return us_;}
+};
+
+class milliseconds
+{
+public:
+ typedef long long tick_type;
+private:
+ tick_type ms_;
+public:
+ milliseconds(long long ms = 0) : ms_(ms) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 1000;}
+ static tick_type seconds_per_tick() {return 0;}
+ static bool is_subsecond() {return true;}
+
+ // conversions
+ operator nanoseconds() const {return ms_ * 1000000LL;}
+ operator microseconds() const {return ms_ * 1000LL;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ milliseconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ milliseconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ milliseconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ milliseconds& operator+=(const RhsDuration& d);
+
+ milliseconds operator-() const {return -ms_;}
+
+ milliseconds operator/ (int divisor) const {return ms_ / divisor;}
+ milliseconds& operator/=(int divisor) {ms_ /= divisor; return *this;}
+
+ milliseconds operator* (int rhs) const {return ms_ * rhs;}
+ milliseconds& operator*=(int rhs) {ms_ *= rhs; return *this;}
+
+ tick_type get_count() const {return ms_;}
+};
+
+class seconds
+{
+public:
+ typedef long long tick_type;
+private:
+ tick_type s_;
+public:
+ seconds(long long s = 0) : s_(s) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 1;}
+ static tick_type seconds_per_tick() {return 1;}
+ static bool is_subsecond() {return false;}
+
+ // conversions
+ operator nanoseconds() const {return s_ * 1000000000LL;}
+ operator microseconds() const {return s_ * 1000000LL;}
+ operator milliseconds() const {return s_ * 1000LL;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ seconds operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ seconds& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ seconds operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ seconds& operator+=(const RhsDuration& d);
+
+ seconds operator-() const {return -s_;}
+
+ seconds operator/ (int divisor) const {return s_ / divisor;}
+ seconds& operator/=(int divisor) {s_ /= divisor; return *this;}
+
+ seconds operator* (int rhs) const {return s_ * rhs;}
+ seconds& operator*=(int rhs) {s_ *= rhs; return *this;}
+
+ tick_type get_count() const {return s_;}
+};
+
+class minutes
+{
+public:
+ typedef long tick_type;
+private:
+ tick_type mn_;
+public:
+ minutes(long long mn = 0) : mn_(static_cast<tick_type>(mn)) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 0;}
+ static tick_type seconds_per_tick() {return 60;}
+ static bool is_subsecond() {return false;}
+
+ // conversions
+ operator nanoseconds() const {return mn_ * 60000000000LL;}
+ operator microseconds() const {return mn_ * 60000000LL;}
+ operator milliseconds() const {return mn_ * 60000LL;}
+ operator seconds() const {return mn_ * 60LL;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ minutes operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ minutes& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ minutes operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ minutes& operator+=(const RhsDuration& d);
+
+ minutes operator-() const {return -mn_;}
+
+ minutes operator/ (int divisor) const {return mn_ / divisor;}
+ minutes& operator/=(int divisor) {mn_ /= divisor; return *this;}
+
+ minutes operator* (int rhs) const {return mn_ * rhs;}
+ minutes& operator*=(int rhs) {mn_ *= rhs; return *this;}
+
+ tick_type get_count() const {return mn_;}
+};
+
+class hours
+{
+public:
+ typedef long tick_type;
+private:
+ tick_type hr_;
+public:
+ hours(long long hr = 0) : hr_(static_cast<tick_type>(hr)) {}
+
+ // traits information
+ static tick_type ticks_per_second() {return 0;}
+ static tick_type seconds_per_tick() {return 3600;}
+ static bool is_subsecond() {return false;}
+
+ // conversions
+ operator nanoseconds() const {return hr_ * 3600000000000LL;}
+ operator microseconds() const {return hr_ * 3600000000LL;}
+ operator milliseconds() const {return hr_ * 3600000LL;}
+ operator seconds() const {return hr_ * 3600LL;}
+ operator minutes() const {return hr_ * 60LL;}
+
+ // + common functions
+
+ template <class RhsDuration>
+ bool operator< (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator<=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator> (const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator>=(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator==(const RhsDuration& rhs) const;
+
+ template <class RhsDuration>
+ bool operator!=(const RhsDuration& rhs) const;
+
+ template<typename RhsDuration>
+ hours operator- (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ hours& operator-=(const RhsDuration& d);
+
+ template<typename RhsDuration>
+ hours operator+ (const RhsDuration& d) const;
+
+ template<typename RhsDuration>
+ hours& operator+=(const RhsDuration& d);
+
+ hours operator-() const {return -hr_;}
+
+ hours operator/ (int divisor) const {return hr_ / divisor;}
+ hours& operator/=(int divisor) {hr_ /= divisor; return *this;}
+
+ hours operator* (int rhs) const {return hr_ * rhs;}
+ hours& operator*=(int rhs) {hr_ *= rhs; return *this;}
+
+ tick_type get_count() const {return hr_;}
+};
+
+template <class To>
+struct __make
+{
+ template <class Duration>
+ static
+ To
+ from(const Duration& t)
+ {
+ long long r;
+ if (To::Duration::is_subsecond() && Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * To::ticks_per_second() / Duration::ticks_per_second());
+ }
+ else if (!To::Duration::is_subsecond() && Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() / To::seconds_per_tick() / Duration::ticks_per_second());
+ }
+ else if (To::Duration::is_subsecond() && !Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * To::ticks_per_second() * Duration::seconds_per_tick());
+ }
+ else // if (!To::Duration::is_subsecond() && !Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * Duration::seconds_per_tick() / To::seconds_per_tick());
+ }
+ return r;
+ }
+};
+
+template <>
+struct __make<nanoseconds>
+{
+ template <class Duration>
+ static
+ nanoseconds
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * nanoseconds::ticks_per_second() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * nanoseconds::ticks_per_second() * Duration::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ nanoseconds
+ from(const hours& t)
+ {
+ return t.get_count() * 3600000000000LL;
+ }
+
+ static
+ nanoseconds
+ from(const minutes& t)
+ {
+ return t.get_count() * 60000000000LL;
+ }
+
+ static
+ nanoseconds
+ from(const seconds& t)
+ {
+ return t.get_count() * 1000000000LL;
+ }
+
+ static
+ nanoseconds
+ from(const milliseconds& t)
+ {
+ return t.get_count() * 1000000LL;
+ }
+
+ static
+ nanoseconds
+ from(const microseconds& t)
+ {
+ return t.get_count() * 1000LL;
+ }
+
+ static
+ nanoseconds
+ from(const nanoseconds& t)
+ {
+ return t.get_count();
+ }
+
+};
+
+template <>
+struct __make<microseconds>
+{
+ template <class Duration>
+ static
+ microseconds
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * microseconds::ticks_per_second() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * microseconds::ticks_per_second() * Duration::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ microseconds
+ from(const hours& t)
+ {
+ return t.get_count() * 3600000000LL;
+ }
+
+ static
+ microseconds
+ from(const minutes& t)
+ {
+ return t.get_count() * 60000000LL;
+ }
+
+ static
+ microseconds
+ from(const seconds& t)
+ {
+ return t.get_count() * 1000000LL;
+ }
+
+ static
+ microseconds
+ from(const milliseconds& t)
+ {
+ return t.get_count() * 1000LL;
+ }
+
+ static
+ microseconds
+ from(const microseconds& t)
+ {
+ return t.get_count();
+ }
+
+ static
+ microseconds
+ from(const nanoseconds& t)
+ {
+ return t.get_count() / 1000LL;
+ }
+
+};
+
+template <>
+struct __make<milliseconds>
+{
+ template <class Duration>
+ static
+ milliseconds
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * milliseconds::ticks_per_second() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * milliseconds::ticks_per_second() * Duration::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ milliseconds
+ from(const hours& t)
+ {
+ return t.get_count() * 3600000LL;
+ }
+
+ static
+ milliseconds
+ from(const minutes& t)
+ {
+ return t.get_count() * 60000LL;
+ }
+
+ static
+ milliseconds
+ from(const seconds& t)
+ {
+ return t.get_count() * 1000LL;
+ }
+
+ static
+ milliseconds
+ from(const milliseconds& t)
+ {
+ return t.get_count();
+ }
+
+ static
+ milliseconds
+ from(const microseconds& t)
+ {
+ return t.get_count() / 1000LL;
+ }
+
+ static
+ milliseconds
+ from(const nanoseconds& t)
+ {
+ return t.get_count() / 1000000LL;
+ }
+
+};
+
+template <>
+struct __make<seconds>
+{
+ template <class Duration>
+ static
+ seconds
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * Duration::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ seconds
+ from(const hours& t)
+ {
+ return t.get_count() * 3600LL;
+ }
+
+ static
+ seconds
+ from(const minutes& t)
+ {
+ return t.get_count() * 60LL;
+ }
+
+ static
+ seconds
+ from(const seconds& t)
+ {
+ return t.get_count();
+ }
+
+ static
+ seconds
+ from(const milliseconds& t)
+ {
+ return t.get_count() / 1000LL;
+ }
+
+ static
+ seconds
+ from(const microseconds& t)
+ {
+ return t.get_count() / 1000000LL;
+ }
+
+ static
+ seconds
+ from(const nanoseconds& t)
+ {
+ return t.get_count() / 1000000000LL;
+ }
+
+};
+
+template <>
+struct __make<minutes>
+{
+ template <class Duration>
+ static
+ minutes
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() / minutes::seconds_per_tick() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * Duration::seconds_per_tick() / minutes::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ minutes
+ from(const hours& t)
+ {
+ return t.get_count() * 60LL;
+ }
+
+ static
+ minutes
+ from(const minutes& t)
+ {
+ return t.get_count();
+ }
+
+ static
+ minutes
+ from(const seconds& t)
+ {
+ return t.get_count() / 60LL;
+ }
+
+ static
+ minutes
+ from(const milliseconds& t)
+ {
+ return t.get_count() / 60000LL;
+ }
+
+ static
+ minutes
+ from(const microseconds& t)
+ {
+ return t.get_count() / 60000000LL;
+ }
+
+ static
+ minutes
+ from(const nanoseconds& t)
+ {
+ return t.get_count() / 60000000000LL;
+ }
+
+};
+
+template <>
+struct __make<hours>
+{
+ template <class Duration>
+ static
+ hours
+ from(const Duration& t)
+ {
+ long long r;
+ if (Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() / hours::seconds_per_tick() / Duration::ticks_per_second());
+ }
+ else // if (!Duration::is_subsecond())
+ {
+ r = static_cast<long long>(t.get_count() * Duration::seconds_per_tick() / hours::seconds_per_tick());
+ }
+ return r;
+ }
+
+ static
+ hours
+ from(const hours& t)
+ {
+ return t.get_count();
+ }
+
+ static
+ hours
+ from(const minutes& t)
+ {
+ return t.get_count() / 60LL;
+ }
+
+ static
+ hours
+ from(const seconds& t)
+ {
+ return t.get_count() / 3600LL;
+ }
+
+ static
+ hours
+ from(const milliseconds& t)
+ {
+ return t.get_count() / 3600000LL;
+ }
+
+ static
+ hours
+ from(const microseconds& t)
+ {
+ return t.get_count() / 3600000000LL;
+ }
+
+ static
+ hours
+ from(const nanoseconds& t)
+ {
+ return t.get_count() / 3600000000000LL;
+ }
+
+};
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator< (const RhsDuration& rhs) const
+ {return ns_ < __make<nanoseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator<=(const RhsDuration& rhs) const
+ {return ns_ <= __make<nanoseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator> (const RhsDuration& rhs) const
+ {return ns_ > __make<nanoseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator>=(const RhsDuration& rhs) const
+ {return ns_ >= __make<nanoseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator==(const RhsDuration& rhs) const
+ {return ns_ == __make<nanoseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool nanoseconds::operator!=(const RhsDuration& rhs) const
+ {return ns_ != __make<nanoseconds>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+nanoseconds nanoseconds::operator- (const RhsDuration& d) const
+ {return ns_ - __make<nanoseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+nanoseconds& nanoseconds::operator-=(const RhsDuration& d)
+ {ns_ -= __make<nanoseconds>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+nanoseconds nanoseconds::operator+ (const RhsDuration& d) const
+ {return ns_ + __make<nanoseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+nanoseconds& nanoseconds::operator+=(const RhsDuration& d)
+ {ns_ += __make<nanoseconds>::from(d).get_count(); return *this;}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator< (const RhsDuration& rhs) const
+ {return us_ < __make<microseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator<=(const RhsDuration& rhs) const
+ {return us_ <= __make<microseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator> (const RhsDuration& rhs) const
+ {return us_ > __make<microseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator>=(const RhsDuration& rhs) const
+ {return us_ >= __make<microseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator==(const RhsDuration& rhs) const
+ {return us_ == __make<microseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool microseconds::operator!=(const RhsDuration& rhs) const
+ {return us_ != __make<microseconds>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+microseconds microseconds::operator- (const RhsDuration& d) const
+ {return us_ - __make<microseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+microseconds& microseconds::operator-=(const RhsDuration& d)
+ {us_ -= __make<microseconds>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+microseconds microseconds::operator+ (const RhsDuration& d) const
+ {return us_ + __make<microseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+microseconds& microseconds::operator+=(const RhsDuration& d)
+ {us_ += __make<microseconds>::from(d).get_count(); return *this;}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator< (const RhsDuration& rhs) const
+ {return ms_ < __make<milliseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator<=(const RhsDuration& rhs) const
+ {return ms_ <= __make<milliseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator> (const RhsDuration& rhs) const
+ {return ms_ > __make<milliseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator>=(const RhsDuration& rhs) const
+ {return ms_ >= __make<milliseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator==(const RhsDuration& rhs) const
+ {return ms_ == __make<milliseconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool milliseconds::operator!=(const RhsDuration& rhs) const
+ {return ms_ != __make<milliseconds>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+milliseconds milliseconds::operator- (const RhsDuration& d) const
+ {return ms_ - __make<milliseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+milliseconds& milliseconds::operator-=(const RhsDuration& d)
+ {ms_ -= __make<milliseconds>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+milliseconds milliseconds::operator+ (const RhsDuration& d) const
+ {return ms_ + __make<milliseconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+milliseconds& milliseconds::operator+=(const RhsDuration& d)
+ {ms_ += __make<milliseconds>::from(d).get_count(); return *this;}
+
+template <class RhsDuration>
+inline
+bool seconds::operator< (const RhsDuration& rhs) const
+ {return s_ < __make<seconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool seconds::operator<=(const RhsDuration& rhs) const
+ {return s_ <= __make<seconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool seconds::operator> (const RhsDuration& rhs) const
+ {return s_ > __make<seconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool seconds::operator>=(const RhsDuration& rhs) const
+ {return s_ >= __make<seconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool seconds::operator==(const RhsDuration& rhs) const
+ {return s_ == __make<seconds>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool seconds::operator!=(const RhsDuration& rhs) const
+ {return s_ != __make<seconds>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+seconds seconds::operator- (const RhsDuration& d) const
+ {return s_ - __make<seconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+seconds& seconds::operator-=(const RhsDuration& d)
+ {s_ -= __make<seconds>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+seconds seconds::operator+ (const RhsDuration& d) const
+ {return s_ + __make<seconds>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+seconds& seconds::operator+=(const RhsDuration& d)
+ {s_ += __make<seconds>::from(d).get_count(); return *this;}
+
+template <class RhsDuration>
+inline
+bool minutes::operator< (const RhsDuration& rhs) const
+ {return mn_ < __make<minutes>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool minutes::operator<=(const RhsDuration& rhs) const
+ {return mn_ <= __make<minutes>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool minutes::operator> (const RhsDuration& rhs) const
+ {return mn_ > __make<minutes>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool minutes::operator>=(const RhsDuration& rhs) const
+ {return mn_ >= __make<minutes>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool minutes::operator==(const RhsDuration& rhs) const
+ {return mn_ == __make<minutes>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool minutes::operator!=(const RhsDuration& rhs) const
+ {return mn_ != __make<minutes>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+minutes minutes::operator- (const RhsDuration& d) const
+ {return mn_ - __make<minutes>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+minutes& minutes::operator-=(const RhsDuration& d)
+ {mn_ -= __make<minutes>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+minutes minutes::operator+ (const RhsDuration& d) const
+ {return mn_ + __make<minutes>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+minutes& minutes::operator+=(const RhsDuration& d)
+ {mn_ += __make<minutes>::from(d).get_count(); return *this;}
+
+template <class RhsDuration>
+inline
+bool hours::operator< (const RhsDuration& rhs) const
+ {return hr_ < __make<hours>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool hours::operator<=(const RhsDuration& rhs) const
+ {return hr_ <= __make<hours>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool hours::operator> (const RhsDuration& rhs) const
+ {return hr_ > __make<hours>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool hours::operator>=(const RhsDuration& rhs) const
+ {return hr_ >= __make<hours>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool hours::operator==(const RhsDuration& rhs) const
+ {return hr_ == __make<hours>::from(rhs).get_count();}
+
+template <class RhsDuration>
+inline
+bool hours::operator!=(const RhsDuration& rhs) const
+ {return hr_ != __make<hours>::from(rhs).get_count();}
+
+template<typename RhsDuration>
+inline
+hours hours::operator- (const RhsDuration& d) const
+ {return hr_ - __make<hours>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+hours& hours::operator-=(const RhsDuration& d)
+ {hr_ -= __make<hours>::from(d).get_count(); return *this;}
+
+template<typename RhsDuration>
+inline
+hours hours::operator+ (const RhsDuration& d) const
+ {return hr_ + __make<hours>::from(d).get_count();}
+
+template<typename RhsDuration>
+inline
+hours& hours::operator+=(const RhsDuration& d)
+ {hr_ += __make<hours>::from(d).get_count(); return *this;}
+
+class system_time
+{
+public:
+ typedef long long tick_type;
+private:
+ tick_type ns_;
+public:
+
+ system_time() : ns_(0) {}
+ system_time(time_t secs, nanoseconds ns)
+ : ns_(secs * 1000000000LL + ns.get_count()) {}
+
+ // ~system_time() = default;
+
+ time_t seconds_since_epoch() const { return static_cast<time_t>(ns_ / 1000000000);}
+ nanoseconds nanoseconds_since_epoch() const {return static_cast<nanoseconds>(ns_);}
+
+ // traits
+ static tick_type ticks_per_second() {return 1000000000;}
+ static tick_type seconds_per_tick() {return 0;}
+ static bool is_subsecond() {return true;}
+
+ // comparison functions
+ bool operator==(const system_time& rhs) const {return ns_ == rhs.ns_;}
+ bool operator!=(const system_time& rhs) const {return ns_ != rhs.ns_;}
+ bool operator> (const system_time& rhs) const {return ns_ > rhs.ns_;}
+ bool operator>=(const system_time& rhs) const {return ns_ >= rhs.ns_;}
+ bool operator< (const system_time& rhs) const {return ns_ < rhs.ns_;}
+ bool operator<=(const system_time& rhs) const {return ns_ <= rhs.ns_;}
+
+ // arithmetic functions
+ nanoseconds operator-(const system_time& rhs) const {return ns_ - rhs.ns_;}
+
+ template<typename Duration>
+ system_time operator+(const Duration& td) const {system_time t(*this); t += td; return t;}
+
+ template<typename Duration>
+ system_time& operator+=(const Duration& td) {ns_ += __make<nanoseconds>::from(td).get_count(); return *this;}
+
+ template<typename Duration>
+ system_time operator-(const Duration& td) const {system_time t(*this); t -= td; return t;}
+
+ template<typename Duration>
+ system_time& operator-=(const Duration& td) {ns_ -= __make<nanoseconds>::from(td).get_count(); return *this;}
+
+};
+
+system_time get_system_time();
+
+}
+
+#endif

Added: sandbox/committee/LWG/ref_impl/hdate_time.cpp
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/hdate_time.cpp 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,31 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// hdate_time.cpp
+
+#define _POSIX_C_SOURCE 200112L
+#include "hdate_time"
+#include <unistd.h>
+#include <time.h> //for clock_gettime and timespec
+#include <sys/time.h> //for gettimeofday and timeval
+
+namespace std {
+
+system_time get_system_time()
+{
+#if _POSIX_TIMERS >= 0
+ if (sysconf(_SC_TIMERS) == -1) {
+#endif
+ timeval tv;
+ gettimeofday(&tv, 0);
+ return system_time(tv.tv_sec, tv.tv_usec * 1000LL);
+#if _POSIX_TIMERS >= 0
+ } else {
+ timespec tv;
+ clock_gettime(CLOCK_REALTIME, &tv);
+ return system_time(tv.tv_sec, tv.tv_nsec);
+ }
+#endif
+}
+
+} // std

Added: sandbox/committee/LWG/ref_impl/mutex
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/mutex 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,276 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// mutex
+
+#ifndef _MUTEX
+#define _MUTEX
+
+/*
+ mutex synopsis
+
+ 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; // optional. example: pthread_mutex_t*
+ native_handle_type native_handle(); // optional
+ };
+
+ 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; // optional. example: pthread_mutex_t*
+ native_handle_type native_handle(); // optional
+ };
+
+ 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 elapsed_time>
+ bool timed_lock(const elapsed_time& rel_time);
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; // optional. example: pthread_mutex_t*
+ native_handle_type native_handle(); // optional
+ };
+
+ 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 elapsed_time>
+ bool timed_lock(const elapsed_time& rel_time);
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; // optional. example: pthread_mutex_t*
+ native_handle_type native_handle(); // optional
+ };
+
+ 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
+ : public std::exception
+ {
+ public:
+ virtual const char* what() const throw();
+ };
+
+ 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;
+
+ mutex_type* mutex() const;
+ };
+
+ 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(mutex_type& m, const system_time& abs_time);
+ template <class Duration>
+ unique_lock(mutex_type& m, const Duration& rel_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 Duration>
+ bool timed_lock(const Duration& rel_t);
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+
+ bool owns() 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);
+
+ 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&...);
+
+ 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
+*/
+
+#include <mutex_base>
+#include <condition_variable>
+#include <hdate_time>
+#include <functional>
+
+namespace std
+{
+
+class timed_mutex
+{
+ mutex mut_;
+ condition_variable gate1_;
+ bool locked_;
+
+ timed_mutex(const timed_mutex&); // = delete;
+ timed_mutex& operator=(const timed_mutex&); // = delete;
+public:
+
+ timed_mutex();
+ // ~timed_mutex() = default;
+
+ void lock();
+ bool try_lock();
+ template <class Duration>
+ bool timed_lock(const Duration& rel_time)
+ {return timed_lock(get_system_time() + rel_time);}
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+};
+
+class recursive_timed_mutex
+{
+ mutex mut_;
+ condition_variable gate1_;
+ unsigned state_;
+ pthread_t id_;
+
+ recursive_timed_mutex(const recursive_timed_mutex&); // = delete;
+ recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete;
+public:
+
+ recursive_timed_mutex();
+ // ~recursive_timed_mutex() = default;
+
+ void lock();
+ bool try_lock();
+ template <class Duration>
+ bool timed_lock(const Duration& rel_time)
+ {return timed_lock(get_system_time() + rel_time);}
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+};
+
+struct once_flag;
+
+template<class Callable, class ...Args>
+void
+call_once(once_flag& flag, Callable&& func, Args&&... args);
+
+struct once_flag
+{
+private:
+ mutex m_;
+ bool completed_;
+
+ template <class F> void run(F f);
+
+ template<class Callable, class ...Args>
+ friend
+ void
+ call_once(once_flag& flag, Callable&& func, Args&&... args);
+
+public:
+ //constexpr
+ once_flag() : completed_(false) {}
+};
+
+template <class F>
+void
+once_flag::run(F f)
+{
+ lock_guard<mutex> _(m_);
+ if (!completed_)
+ {
+ f();
+ completed_ = true;
+ }
+}
+
+template<class Callable, class ...Args>
+void
+call_once(once_flag& flag, Callable&& func, Args&&... args)
+{
+ flag.run(bind(std::forward<Callable>(func), std::forward<Args>(args)...));
+}
+
+} // std
+
+#endif

Added: sandbox/committee/LWG/ref_impl/mutex.cpp
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/mutex.cpp 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,257 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// mutex.cpp
+
+#include "mutex"
+#include "system_error"
+#undef NDEBUG
+#include <cassert>
+
+namespace std
+{
+
+using namespace roundhouse;
+
+///////////
+// mutex //
+///////////
+
+mutex::mutex()
+{
+ error_code::value_type ec = pthread_mutex_init(&m_, 0);
+ if (ec)
+ throw system_error(ec, native_category, "mutex constructor failed");
+}
+
+mutex::~mutex()
+{
+ int e = pthread_mutex_destroy(&m_);
+ assert(e == 0);
+}
+
+void
+mutex::lock()
+{
+ error_code::value_type ec = pthread_mutex_lock(&m_);
+ if (ec)
+ throw system_error(ec, native_category, "mutex lock failed");
+}
+
+void
+mutex::unlock()
+{
+ int e = pthread_mutex_unlock(&m_);
+ assert(e == 0);
+}
+
+bool
+mutex::try_lock()
+{
+ return pthread_mutex_trylock(&m_) == 0;
+}
+
+/////////////////////
+// recursive_mutex //
+/////////////////////
+
+recursive_mutex::recursive_mutex()
+{
+ pthread_mutexattr_t attr;
+ error_code::value_type ec = pthread_mutexattr_init(&attr);
+ if (ec)
+ goto fail;
+ ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ if (ec)
+ {
+ pthread_mutexattr_destroy(&attr);
+ goto fail;
+ }
+ ec = pthread_mutex_init(&m_, &attr);
+ if (ec)
+ {
+ pthread_mutexattr_destroy(&attr);
+ goto fail;
+ }
+ ec = pthread_mutexattr_destroy(&attr);
+ if (ec)
+ {
+ pthread_mutex_destroy(&m_);
+ goto fail;
+ }
+ return;
+fail:
+ throw system_error(ec, native_category, "recursive_mutex constructor failed");
+}
+
+recursive_mutex::~recursive_mutex()
+{
+ int e = pthread_mutex_destroy(&m_);
+ assert(e == 0);
+}
+
+void
+recursive_mutex::lock()
+{
+ error_code::value_type ec = pthread_mutex_lock(&m_);
+ if (ec)
+ throw system_error(ec, native_category, "recursive_mutex lock failed");
+}
+
+void
+recursive_mutex::unlock()
+{
+ int e = pthread_mutex_unlock(&m_);
+ assert(e == 0);
+}
+
+bool
+recursive_mutex::try_lock()
+{
+ return pthread_mutex_trylock(&m_) == 0;
+}
+
+/////////////////
+// timed_mutex //
+/////////////////
+
+timed_mutex::timed_mutex()
+ : locked_(false)
+{
+}
+
+void
+timed_mutex::lock()
+{
+ unique_lock<mutex> lk(mut_);
+ while (locked_)
+ gate1_.wait(lk);
+ locked_ = true;
+}
+
+bool
+timed_mutex::try_lock()
+{
+ unique_lock<mutex> lk(mut_, try_to_lock);
+ if (lk.owns() && !locked_)
+ {
+ locked_ = true;
+ return true;
+ }
+ return false;
+}
+
+bool
+timed_mutex::timed_lock(const system_time& abs_time)
+{
+ unique_lock<mutex> lk(mut_);
+ bool timed_out = get_system_time() > abs_time;
+ while (!timed_out && locked_)
+ timed_out = gate1_.timed_wait(lk, abs_time);
+ if (!locked_)
+ {
+ locked_ = true;
+ return true;
+ }
+ return false;
+}
+
+void
+timed_mutex::unlock()
+{
+ {
+ lock_guard<mutex> _(mut_);
+ locked_ = false;
+ }
+ gate1_.notify_one();
+}
+
+///////////////////////////
+// recursive_timed_mutex //
+///////////////////////////
+
+recursive_timed_mutex::recursive_timed_mutex()
+ : state_(0),
+ id_(0)
+{
+}
+
+void
+recursive_timed_mutex::lock()
+{
+ pthread_t id = pthread_self();
+ unique_lock<mutex> lk(mut_);
+ if (pthread_equal(id, id_))
+ {
+ if (state_ == numeric_limits<unsigned>::max())
+ throw system_error(EAGAIN, native_category, "recursive_timed_mutex lock failed");
+ ++state_;
+ return;
+ }
+ while (state_ != 0)
+ gate1_.wait(lk);
+ state_ = 1;
+ id_ = id;
+}
+
+bool
+recursive_timed_mutex::try_lock()
+{
+ pthread_t id = pthread_self();
+ unique_lock<mutex> lk(mut_, try_to_lock);
+ if (lk.owns() && (state_ == 0 || pthread_equal(id, id_)))
+ {
+ if (state_ == numeric_limits<unsigned>::max())
+ return false;
+ ++state_;
+ id_ = id;
+ return true;
+ }
+ return false;
+}
+
+bool
+recursive_timed_mutex::timed_lock(const system_time& abs_time)
+{
+ pthread_t id = pthread_self();
+ unique_lock<mutex> lk(mut_);
+ if (pthread_equal(id, id_))
+ {
+ if (state_ == numeric_limits<unsigned>::max())
+ return false;
+ ++state_;
+ return true;
+ }
+ bool timed_out = get_system_time() > abs_time;
+ while (!timed_out && state_ != 0)
+ timed_out = gate1_.timed_wait(lk, abs_time);
+ if (state_ == 0)
+ {
+ state_ = 1;
+ id_ = id;
+ return true;
+ }
+ return false;
+}
+
+void
+recursive_timed_mutex::unlock()
+{
+ unique_lock<mutex> lk(mut_);
+ if (--state_ == 0)
+ {
+ id_ = 0;
+ lk.unlock();
+ gate1_.notify_one();
+ }
+}
+
+///////////////////
+// lock commands //
+///////////////////
+
+const defer_lock_t defer_lock = defer_lock_t();
+const try_to_lock_t try_to_lock = try_to_lock_t();
+const adopt_lock_t adopt_lock = adopt_lock_t();
+
+} // std

Added: sandbox/committee/LWG/ref_impl/mutex_base
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/mutex_base 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,373 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// mutex_base
+
+#ifndef _MUTEX_BASE
+#define _MUTEX_BASE
+
+#include <pthread.h>
+#include <stdexcept>
+#include <hdate_time>
+#include <type_traits>
+
+namespace std
+{
+
+class mutex
+{
+ pthread_mutex_t m_;
+
+public:
+ mutex();
+ ~mutex();
+
+ private: mutex(const mutex&); public : // = delete;
+ private: mutex& operator=(const mutex&); public : // = delete;
+
+ void lock();
+ bool try_lock();
+ void unlock();
+
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle() {return &m_;}
+};
+
+class recursive_mutex
+{
+ pthread_mutex_t m_;
+
+public:
+ recursive_mutex();
+ ~recursive_mutex();
+
+ private: recursive_mutex(const recursive_mutex&); public : // = delete;
+ private: recursive_mutex& operator=(const recursive_mutex&); public : // = delete;
+
+ void lock();
+ bool try_lock();
+ void unlock();
+
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle() {return &m_;}
+};
+
+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
+ : public std::exception
+{
+public:
+ virtual const char* what() const throw() {return "lock_error";}
+};
+
+template <class Mutex>
+class lock_guard
+{
+public:
+ typedef Mutex mutex_type;
+private:
+ mutex_type& m_;
+
+public:
+ explicit lock_guard(mutex_type& m) : m_(m) {m_.lock();}
+ lock_guard(mutex_type& m, adopt_lock_t) : m_(m) {}
+ ~lock_guard() {m_.unlock();}
+
+private:
+ lock_guard(lock_guard const&);// = delete;
+ lock_guard& operator=(lock_guard const&);// = delete;
+};
+
+template <class Mutex>
+class unique_lock
+{
+public:
+ typedef Mutex mutex_type;
+private:
+ mutex_type* m_;
+ bool owns_lock_;
+
+ unique_lock(unique_lock const&);// = delete;
+ unique_lock& operator=(unique_lock const&);// = delete;
+
+ struct __nat {int _;};
+
+public:
+ unique_lock()
+ : m_(0),
+ owns_lock_(false)
+ {}
+
+ explicit unique_lock(mutex_type& m)
+ : m_(&m),
+ owns_lock_(true)
+ {
+ m_->lock();
+ }
+
+ unique_lock(mutex_type& m, defer_lock_t)
+ : m_(&m),
+ owns_lock_(false)
+ {}
+
+ unique_lock(mutex_type& m, try_to_lock_t)
+ : m_(&m),
+ owns_lock_(m_->try_lock())
+ {}
+
+ unique_lock(mutex_type& m, adopt_lock_t)
+ : m_(&m),
+ owns_lock_(true)
+ {}
+
+ unique_lock(mutex_type& m, const system_time& abs_time)
+ : m_(&m),
+ owns_lock_(m_->timed_lock(abs_time))
+ {}
+
+ template <class Duration>
+ unique_lock(mutex_type& m, const Duration& rel_t,
+ typename enable_if<__is_duration<Duration>::value>::type* = 0)
+ : m_(&m),
+ owns_lock_(m_->timed_lock(rel_t))
+ {}
+
+ ~unique_lock()
+ {
+ if (owns_lock_)
+ m_->unlock();
+ }
+
+ unique_lock(unique_lock&& u)
+ : m_(u.m_),
+ owns_lock_(u.owns_lock_)
+ {
+ u.m_ = 0;
+ u.owns_lock_ = false;
+ }
+
+ unique_lock& operator=(unique_lock&& u)
+ {
+ if (owns_lock_)
+ m_->unlock();
+ owns_lock_ = u.owns_lock_;
+ m_ = u.m_;
+ u.owns_lock_ = false;
+ u.m_ = 0;
+ return *this;
+ }
+
+ void lock();
+ bool try_lock();
+ template <class Duration>
+ bool timed_lock(const Duration& rel_t);
+ bool timed_lock(const system_time& abs_time);
+ void unlock();
+
+ bool owns() const {return owns_lock_;}
+ operator int __nat::* () const {return owns_lock_ ? &__nat::_ : 0;}
+ mutex_type* mutex() const {return m_;}
+
+ void swap(unique_lock&& u)
+ {
+ mutex_type* t1 = m_;
+ m_ = u.m_;
+ u.m_ = t1;
+ bool t2 = owns_lock_;
+ owns_lock_ = u.owns_lock_;
+ u.owns_lock_ = t2;
+ }
+
+ mutex_type* release()
+ {
+ mutex_type* r = m_;
+ m_ = 0;
+ owns_lock_ = false;
+ return r;
+ }
+};
+
+template <class Mutex>
+void
+unique_lock<Mutex>::lock()
+{
+ if (m_ == 0 || owns_lock_)
+ throw lock_error();
+ m_->lock();
+ owns_lock_ = true;
+}
+
+template <class Mutex>
+bool
+unique_lock<Mutex>::try_lock()
+{
+ if (m_ == 0 || owns_lock_)
+ throw lock_error();
+ owns_lock_ = m_->try_lock();
+ return owns_lock_;
+}
+
+template <class Mutex>
+template <class Duration>
+bool
+unique_lock<Mutex>::timed_lock(const Duration& rel_t)
+{
+ if (m_ == 0 || owns_lock_)
+ throw lock_error();
+ owns_lock_ = m_->timed_lock(rel_t);
+ return owns_lock_;
+}
+
+template <class Mutex>
+bool
+unique_lock<Mutex>::timed_lock(const system_time& abs_time)
+{
+ if (m_ == 0 || owns_lock_)
+ throw lock_error();
+ owns_lock_ = m_->timed_lock(abs_time);
+ return owns_lock_;
+}
+
+template <class Mutex>
+void
+unique_lock<Mutex>::unlock()
+{
+ if (!owns_lock_)
+ throw lock_error();
+ m_->unlock();
+ owns_lock_ = false;
+}
+
+template <class Mutex> inline void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) {x.swap(y);}
+template <class Mutex> inline void swap(unique_lock<Mutex>&& x, unique_lock<Mutex>& y) {x.swap(y);}
+template <class Mutex> inline void swap(unique_lock<Mutex>& x, unique_lock<Mutex>&& y) {x.swap(y);}
+
+// returns index of failed lock or -1 on success
+template <class L1, class L2>
+int
+try_lock(L1& l1, L2& l2)
+{
+ unique_lock<L1> u(l1, try_to_lock);
+ if (u.owns())
+ {
+ if (l2.try_lock())
+ {
+ u.release();
+ return -1;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+template <class L1, class L2, class ...L3>
+int
+try_lock(L1& l1, L2& l2, L3& l3...)
+{
+ unsigned r = 0;
+ unique_lock<L1> u(l1, try_to_lock);
+ if (u.owns())
+ {
+ r = try_lock(l2, l3...);
+ if (r == -1)
+ u.release();
+ else
+ ++r;
+ }
+ return r;
+}
+
+namespace this_thread
+{
+inline void yield() {sched_yield();}
+}
+
+template <class L1, class L2>
+void
+lock(L1& l1, L2& l2)
+{
+ while (true)
+ {
+ {
+ unique_lock<L1> __u1(l1);
+ if (l2.try_lock())
+ {
+ __u1.release();
+ break;
+ }
+ }
+ std::this_thread::yield();
+ {
+ unique_lock<L2> __u2(l2);
+ if (l1.try_lock())
+ {
+ __u2.release();
+ break;
+ }
+ }
+ std::this_thread::yield();
+ }
+}
+
+template <class L1, class L2, class ...L3>
+void
+__lock_first(int __i, L1& l1, L2& l2, L3& l3...)
+{
+ while (true)
+ {
+ switch (__i)
+ {
+ case 0:
+ {
+ unique_lock<L1> __u1(l1);
+ __i = try_lock(l2, l3...);
+ if (__i == -1)
+ {
+ __u1.release();
+ return;
+ }
+ }
+ ++__i;
+ std::this_thread::yield();
+ break;
+ case 1:
+ {
+ unique_lock<L2> __u2(l2);
+ __i = try_lock(l3..., l1);
+ if (__i == -1)
+ {
+ __u2.release();
+ return;
+ }
+ }
+ if (__i == sizeof...(L3))
+ __i = 0;
+ else
+ __i += 2;
+ std::this_thread::yield();
+ break;
+ default:
+ __lock_first(__i - 2, l3..., l1, l2);
+ return;
+ }
+ }
+}
+
+template <class L1, class L2, class ...L3>
+inline
+void
+lock(L1& l1, L2& l2, L3& l3...)
+{
+ __lock_first(0, l1, l2, l3...);
+}
+
+} // std
+
+#endif

Added: sandbox/committee/LWG/ref_impl/thread
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/thread 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,252 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// thread
+
+#ifndef THREAD
+#define THREAD
+
+/*
+ thread synopsis
+
+ namespace std {
+
+ class thread
+ {
+ public:
+ thread();
+ explicit template <class F> explicit thread(F f);
+ template <class F, class ...Args> thread(F&& f, Args&&... args);
+ ~thread();
+
+ thread(const thread&) = delete;
+ thread& operator=(const thread&) = delete;
+
+ thread(thread&&);
+ thread& operator=(thread&&);
+
+ void swap(thread&&);
+
+ bool joinable() const;
+ void join();
+ void detach();
+
+ class id;
+ id get_id() const;
+
+ typedef implementation-defined native_handle_type;
+ native_handle_type native_handle();
+
+ static unsigned hardware_concurrency();
+ };
+
+ void swap(thread& x, thread& y);
+ void swap(thread&& x, thread& y);
+ void swap(thread& x, thread&& y);
+
+ 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);
+
+ namespace this_thread
+ {
+
+ thread::id get_id();
+
+ void yield();
+ template <class Duration>
+ void sleep(const Duration& rel_t);
+
+ } // this_thread
+
+ } // std
+*/
+
+#include <pthread.h>
+#include <mutex_base>
+#include <condition_variable>
+#include <functional>
+#include <ostream>
+#include <exception>
+
+namespace std
+{
+
+class __thread_id;
+class thread;
+
+namespace this_thread
+{
+
+__thread_id get_id();
+
+} // this_thread
+
+class __thread_id
+{
+ pthread_t id_;
+
+ friend __thread_id this_thread::get_id();
+ friend class thread;
+ explicit __thread_id(pthread_t t) : id_(t) {}
+public:
+ __thread_id() : id_(0) {}
+
+ friend bool operator==(const __thread_id& x, const __thread_id& y) {return x.id_ == y.id_;}
+ friend bool operator!=(const __thread_id& x, const __thread_id& y) {return !(x == y);}
+ friend bool operator< (const __thread_id& x, const __thread_id& y) {return x.id_ < y.id_;}
+ friend bool operator<=(const __thread_id& x, const __thread_id& y) {return !(y < x);}
+ friend bool operator> (const __thread_id& x, const __thread_id& y) {return y < x ;}
+ friend bool operator>=(const __thread_id& x, const __thread_id& y) {return !(x < y);}
+
+ template<class charT, class traits> friend
+ basic_ostream<charT, traits>&
+ operator<< (basic_ostream<charT, traits>&& out, const __thread_id& x)
+ {return out << x.id_;}
+};
+
+class thread
+{
+ pthread_t id_;
+public:
+ thread() : id_(0) {}
+ template <class F> explicit thread(F f);
+ template <class F, class ...Args> thread(F&& f, Args&&... args)
+ : thread(bind(std::forward<F>(f), std::forward<Args>(args)...)) {}
+
+ ~thread()
+ {
+ __detach();
+ }
+
+ private: thread(const thread&); public:// = delete;
+ private: thread& operator=(const thread&); public:// = delete;
+
+ thread(thread&& t) : id_(t.id_) {t.id_ = 0;}
+ thread& operator=(thread&& t)
+ {
+ __detach();
+ swap(t);
+ return *this;
+ }
+
+ void swap(thread&& t)
+ {
+ pthread_t temp = id_;
+ id_ = t.id_;
+ t.id_ = temp;
+ }
+
+ bool joinable() const {return id_ != 0;}
+ void join();
+ void detach();
+
+ typedef __thread_id id;
+ id get_id() const {return id(id_);}
+
+ typedef pthread_t native_handle_type;
+ native_handle_type native_handle() {return id_;}
+
+ static unsigned hardware_concurrency();
+
+private:
+ int __detach();
+};
+
+inline void swap(thread& x, thread& y) {x.swap(y);}
+inline void swap(thread&& x, thread& y) {x.swap(y);}
+inline void swap(thread& x, thread&& y) {x.swap(y);}
+
+namespace this_thread
+{
+
+inline __thread_id get_id() {return __thread_id(pthread_self());}
+
+void sleep(const nanoseconds&);
+template <class Duration>
+inline
+void sleep(const Duration& rel_t) {this_thread::sleep(__make<nanoseconds>::from(rel_t));}
+
+} // this_thread
+
+template <class F>
+class __thread_param
+{
+private:
+ void (*f1_)(void*);
+ F* f2_;
+ mutex mut_;
+ condition_variable cv_;
+ bool started_;
+
+public:
+ __thread_param(void (*f1)(void*), F* f2) : f1_(f1), f2_(f2), started_(false) {}
+ void wait();
+ void start();
+};
+
+template <class F>
+void
+__thread_param<F>::wait()
+{
+ unique_lock<mutex> lk(mut_);
+ while (!started_)
+ cv_.wait(lk);
+}
+
+template <class F>
+void
+__thread_param<F>::start()
+{
+ F f(std::move(*f2_));
+ {
+ lock_guard<mutex> _(mut_);
+ started_ = true;
+ }
+ cv_.notify_one();
+ try
+ {
+ f();
+ }
+ catch (...)
+ {
+ terminate();
+ }
+}
+
+extern "C" void* __thread_proxy(void*);
+
+template <class F>
+void
+__cpp_proxy(void* vp)
+{
+ __thread_param<F>* p = static_cast<__thread_param<F>*>(vp);
+ p->start();
+}
+
+template <class F>
+thread::thread(F f)
+{
+ __thread_param<F> p(&__cpp_proxy<F>, &f);
+ error_code::value_type ec = pthread_create(&id_, 0, &__thread_proxy, &p);
+ if (ec)
+ throw system_error(ec, native_category, "thread constructor failed");
+ p.wait();
+}
+
+} // std
+
+#endif

Added: sandbox/committee/LWG/ref_impl/thread.cpp
==============================================================================
--- (empty file)
+++ sandbox/committee/LWG/ref_impl/thread.cpp 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,79 @@
+// Copyright Howard Hinnant 2007. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+
+// thread.cpp
+
+#include "thread"
+#include <sys/sysctl.h>
+
+namespace std
+{
+
+void
+thread::join()
+{
+ error_code::value_type ec = pthread_join(id_, 0);
+ if (ec)
+ throw system_error(ec, native_category, "thread::join failed");
+ id_ = 0;
+}
+
+int
+thread::__detach()
+{
+ int ec = EINVAL;
+ if (id_ != 0)
+ {
+ ec = pthread_detach(id_);
+ if (ec == 0)
+ id_ = 0;
+ }
+ return ec;
+}
+
+void
+thread::detach()
+{
+ error_code::value_type ec = __detach();
+ if (ec)
+ throw system_error(ec, native_category, "thread::detach failed");
+}
+
+unsigned
+thread::hardware_concurrency()
+{
+ int n;
+ int mib[2] = {CTL_HW, HW_NCPU};
+ std::size_t s = sizeof(n);
+ sysctl(mib, 2, &n, &s, 0, 0);
+ return n;
+}
+
+typedef void (*FP)(void*);
+
+extern "C"
+void*
+__thread_proxy(void* p)
+{
+ FP fp = *static_cast<FP*>(p);
+ fp(p);
+ return 0;
+}
+
+namespace this_thread
+{
+
+void
+sleep(const nanoseconds& rel_time)
+{
+ system_time limit = get_system_time() + rel_time;
+ mutex mut;
+ unique_lock<mutex> lk(mut);
+ condition_variable cv;
+ while (get_system_time() < limit)
+ cv.timed_wait(lk, limit);
+}
+
+} // this_thread
+
+} // std

Modified: sandbox/committee/LWG/thread_library.html
==============================================================================
--- sandbox/committee/LWG/thread_library.html (original)
+++ sandbox/committee/LWG/thread_library.html 2007-11-10 16:03:59 EST (Sat, 10 Nov 2007)
@@ -29,7 +29,7 @@
 <h1>Multi-threading Library for Standard C++</h1>
 
 <p>
-ISO/IEC JTC1 SC22 WG21 N???? = 07-???? - 2007-10-29
+ISO/IEC JTC1 SC22 WG21 N???? = 07-???? - 2007-11-10
 </p>
 
 <address>
@@ -100,13 +100,7 @@
 
 <p>
 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.
+N2447.
 </p>
 
 <h2><a name="utilities">Chapter 20&nbsp;&nbsp; General utilities library [utilities]</a></h2>
@@ -127,7 +121,7 @@
     ...
     // <em>Hash function specializations</em>
     ...
- <ins>struct hash&lt;std::thread::id&gt;; // <b>should not be in this header file ?</b></ins>
+ <ins>struct hash&lt;std::thread::id&gt;;</ins>
 }
 </code></pre>
 </blockquote>
@@ -148,8 +142,9 @@
 types
 (3.9.1), pointer types (8.3.1), and <code>std::string</code>,
 <code>std::u16string</code>, <code>std::u32string</code>,
+<code>std::wstring</code>,
 <del>and</del>
-<code>std::wstring</code><ins>, and
+<code>std::error_code</code><ins>, and
 <code>std::thread::id</code></ins>.
 </p>
 </blockquote>
@@ -158,9 +153,7 @@
 
 <p>
 The following subclauses describe components to create and manage threads
-([<cite>reference
-to the new section from N2429 to be inserted between 1.9 and 1.10, titled
-"Multi-threaded executions and data races"</cite>]),
+([<cite>1.10 [intro.multithread]</cite>]),
 perform mutual exclusion and locking, and communicate
 between threads.
 </p>
@@ -180,7 +173,7 @@
   </tr>
   <tr>
     <td>Condition variables</td>
- <td><code>&lt;cond_var&gt;</code></td>
+ <td><code>&lt;condition_variable&gt;</code></td>
   </tr>
 </tbody></table>
 
@@ -287,7 +280,8 @@
 
     // <em>construct/copy/destroy:</em>
     thread();
- template &lt;class F, class ...Args&gt; explicit thread(F f, Args&amp;&amp;... args);
+ template &lt;class F&gt; explicit thread(F f);
+ template &lt;class F, class ...Args&gt; thread(F&amp;&amp; f, Args&amp;&amp;... args);
     ~thread();
     thread(const thread&amp;) = delete;
     thread(thread&amp;&amp;);
@@ -527,7 +521,8 @@
 </dl>
 
 <pre><code>
-template &lt;class F, class ...Args&gt; explicit thread(F f, Args&amp;&amp;... args);
+template &lt;class F&gt; explicit thread(F f);
+template &lt;class F, class ...Args&gt; thread(F&amp;&amp; f, Args&amp;&amp;... args);
 </code></pre>
 
 <dl>
@@ -538,7 +533,6 @@
 is <code>CopyConstructible</code>.
 If <code>f</code> is an rvalue,
 <code>F</code> is <code>MoveConstructible</code>.
-<b>[Crowl: Is this enforced by code?]</b>
 </dd>
 
 <dt>Effects:</dt>
@@ -581,7 +575,7 @@
 <dd>
 <code><var>x</var>.joinable() == false</code>
 <br>
-<code><var>x</var>.get_id() == thread().get_id().joinable()</code>
+<code><var>x</var>.get_id() == thread().get_id()</code>. &nbsp; &nbsp;<code>joinable()</code>
 returns the value of <code><var>x</var>.joinable()</code>
 prior to the start of construction.
 <br>
@@ -635,7 +629,7 @@
 <dd>
 <code><var>x</var>.joinable() == false</code>
 <br>
-<code><var>x</var>.get_id() == thread().get_id().joinable()</code> returns the
+<code><var>x</var>.get_id() == thread().get_id()</code>. &nbsp; &nbsp;<code>joinable()</code> returns the
 value of <code><var>x</var>.joinable()</code> prior to the
 assignment.
 <br>
@@ -696,11 +690,8 @@
 
 <dt>Effects:</dt>
 <dd>
-The current thread blocks until the thread
-represented by <code>*this</code> completes.
-<b>[Crowl: I.e. upon completion the thread does on a release
-on a memory location that the joiner does an acquire on.
-I.e. there is a happens before relationship.]</b>
+The completion of the thread represented by <code>*this</code> happens before
+[<cite>intro.multithread</cite>] <tt>join()</tt> returns.
 </dd>
 
 <dt>Postconditions:</dt>
@@ -708,8 +699,8 @@
 After a normal return of <code>join()</code>,
 <code>joinable()</code> is <code>false</code>.
 <br>
-If <code>join()</code> throws an exception, the thread represented by
-<code>*this</code> remains <code>joinable</code>.
+If <code>join()</code> throws an exception, the <code>joinable()</code> status remains
+unchanged.
 </dd>
 
 <dt>Throws:</dt>
@@ -735,9 +726,7 @@
 The thread represented by
 <code>*this</code> continues execution.
 When the thread represented by
-<code>*this</code> ends execution it shall release any owned resources.
-<b>[Crowl: The programmer shall or the implementation shall?
-Which resources?]</b>
+<code>*this</code> ends execution the implementation shall release any owned resources.
 </dd>
 
 <dt>Postconditions:</dt>
@@ -750,7 +739,8 @@
 
 <dt>Throws:</dt>
 <dd>
-Nothing.
+<code>system_error</code> when an error condition occurs.
+The possible error conditions are implementation defined.
 </dd>
 </dl>
 
@@ -872,12 +862,6 @@
 </code></pre>
 
 <dl>
-<dt>Requires:</dt>
-<dd>
-<code>Duration</code>
-shall be explicitly convertible to <code>nanoseconds</code>.
-</dd>
-
 <dt>Effects:</dt>
 <dd>
 The current thread blocks for at least the amount of time specified.
@@ -982,7 +966,6 @@
 <dt>Effects:</dt>
 <dd>
 The current thread will block until the mutex is not owned by another thread.
-<b>[Crowl: I.e. happens before?]</b>
 Upon successful completion, the current thread owns the mutex.
 </dd>
 
@@ -995,7 +978,7 @@
 
 <dt>Thread safety:</dt>
 <dd>
-This is an acquire operation.
+This is an acquire operation [<cite>intro.multithread</cite>].
 </dd>
 </dl>
 
@@ -1034,7 +1017,7 @@
 
 <dt>Thread safety:</dt>
 <dd>
-This is an acquire operation if <code>try_lock</code> returns <code>true</code>.
+This is an acquire operation if <code>try_lock</code> returns <code>true</code> [<cite>intro.multithread</cite>].
 </dd>
 
 <dt>Throws:</dt>
@@ -1065,7 +1048,7 @@
 
 <dt>Thread safety:</dt>
 <dd>
-This is a release operation.
+This is a release operation [<cite>intro.multithread</cite>].
 </dd>
 
 <dt>Throws:</dt>
@@ -1145,7 +1128,7 @@
 <p>
 To meet the requirements of the Timed Mutex concept,
 types are required to meet the requirements of the Mutex concept
-and to provide the member function <code>timed_lock</code>.
+and to provide the member functions <code>timed_lock</code>.
 </p>
 
 <pre><code>
@@ -1158,7 +1141,8 @@
 <dd>
 For non-recursive mutexes the current thread shall not own
 the mutex.
-<b>[Crowl: Roundup here instead of under various locks.]</b>
+If the resolution of <code>Duration</code> is greater than the native resolution
+the time is rounded up to the nearest native resolution.
 </dd>
 
 <dt>Effects:</dt>
@@ -1185,8 +1169,51 @@
 
 <dt>Thread safety:</dt>
 <dd>
-This is a synchronization operation.
-<b>[Crowl: on the memory locations of the lock.]</b>
+This is an acquire operation if <code>timed_lock</code> returns <code>true</code> [<cite>intro.multithread</cite>].
+</dd>
+
+<dt>Throws:</dt>
+<dd>
+Nothing.
+</dd>
+</dl>
+
+<pre><code>
+bool timed_lock(const system_time&amp; abs_time);
+</code></pre>
+
+<dl>
+<dt>Precondition:</dt>
+<dd>
+For non-recursive mutexes the current thread shall not own
+the mutex.
+</dd>
+
+<dt>Effects:</dt>
+<dd>
+The function attempts to obtain ownership of the mutex
+by the specified time.
+If the indicated time has already passed,
+the function still attempts to obtain ownership without
+blocking (as if by calling <code>try_lock()</code>).
+If the function returns by the specified time,
+it shall have obtained ownership.
+[<i>Note:</i>
+As with <code>try_lock()</code>,
+there is no guarantee that ownership will be obtained
+if the lock is available,
+but implementations are expected to make a strong effort to do so.
+&mdash;<i>end note</i>]
+</dd>
+
+<dt>Returns:</dt>
+<dd>
+<code>true</code> if ownership was obtained, otherwise <code>false</code>.
+</dd>
+
+<dt>Thread safety:</dt>
+<dd>
+This is an acquire operation if <code>timed_lock</code> returns <code>true</code> [<cite>intro.multithread</cite>].
 </dd>
 
 <dt>Throws:</dt>
@@ -1214,6 +1241,7 @@
     bool try_lock();
     template &lt;class Duration&gt;
         bool timed_lock(const Duration&amp; rel_time);
+ bool timed_lock(const system_time&amp; abs_time);
     void unlock();
 
     typedef <var><strong>implemenation-defined</strong></var> native_handle_type; // <em>See [frontmatter]</em>
@@ -1249,6 +1277,7 @@
     bool try_lock();
     template &lt;class Duration&gt;
         bool timed_lock(const Duration&amp; rel_time);
+ bool timed_lock(const system_time&amp; abs_time);
     void unlock();
 
     typedef <var><strong>implemenation-defined</strong></var> native_handle_type; // <em>See [frontmatter]</em>
@@ -1367,7 +1396,6 @@
 <dd>
 Stores a reference to <code><var>m</var></code>
 and calls <code><var>m</var>.lock()</code>.
-<b>[Crowl: An acquire specification is not necessary because of m.lock().]</b>
 </dd>
 </dl>
 
@@ -1423,6 +1451,9 @@
     unique_lock(mutex_type&amp; <var>m</var>, defer_lock_t);
     unique_lock(mutex_type&amp; <var>m</var>, try_to_lock_t);
     unique_lock(mutex_type&amp; <var>m</var>, adopt_lock_t);
+ unique_lock(mutex_type&amp; <var>m</var>, const system_time&amp; <var>abs_time</var>);
+ template &lt;class Duration&gt;
+ unique_lock(mutex_type&amp; <var>m</var>, const Duration&amp; <var>rel_time</var>);
     ~unique_lock();
 
     unique_lock(unique_lock const&amp;) = delete;
@@ -1592,6 +1623,69 @@
 </dl>
 
 <pre><code>
+unique_lock(mutex_type&amp; <var>m</var>, const system_time&amp; <var>abs_time</var>);
+</code></pre>
+
+<dl>
+<dt>Precondition:</dt>
+<dd>
+If <code>mutex_type</code> is not a recursive mutex, then the current thread
+does not own the mutex.
+The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
+unique_lock</code> object.
+</dd>
+
+<dt>Effects:</dt>
+<dd>
+Stores a reference to <code><var>m</var></code>
+and calls <code><var>m</var>.timed_lock(abs_time)</code>.
+</dd>
+
+<dt>Postconditions:</dt>
+<dd>
+<code>mutex() == &amp;<var>m</var></code>
+<br>
+<code>owns_lock() ==</code>
+the result of the call to <code><var>m</var>.timed_lock(<var>abs_time</var>)</code>
+</dd>
+</dl>
+
+<pre><code>
+template &lt;class Duration&gt;
+ unique_lock(mutex_type&amp; <var>m</var>, const Duration&amp; <var>rel_time</var>);
+</code></pre>
+
+<dt>Remarks:</dt>
+<dd>
+The implementation must ensure that only <code>Duration</code> types [<cite>reference to date-time library clause</cite>]
+will bind to this constructor.
+</dd>
+
+<dl>
+<dt>Precondition:</dt>
+<dd>
+If <code>mutex_type</code> is not a recursive mutex, then the current thread
+does not own the mutex.
+The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
+unique_lock</code> object.
+</dd>
+
+<dt>Effects:</dt>
+<dd>
+Stores a reference to <code><var>m</var></code>
+and calls <code><var>m</var>.timed_lock(rel_time)</code>.
+</dd>
+
+<dt>Postconditions:</dt>
+<dd>
+<code>mutex() == &amp;<var>m</var></code>
+<br>
+<code>owns_lock() ==</code>
+the result of the call to <code><var>m</var>.timed_lock(<var>rel_time</var>)</code>
+</dd>
+</dl>
+
+<pre><code>
 ~unique_lock();
 </code></pre>
 
@@ -1744,9 +1838,36 @@
 <dt>Effects:</dt>
 <dd>
 Calls <code>timed_lock(rel_t)</code> on the referenced mutex.
-If the resolution of Duration is greater <b>[Crowl: less]</b> than
-the native
-resolution the time is rounded up to the nearest native resolution.
+</dd>
+
+<dt>Returns:</dt>
+<dd>
+The result of the call to <code>timed_lock(rel_t)</code>
+on the referenced mutex.
+</dd>
+
+<dt>Postconditions:</dt>
+<dd>
+<code>owns_lock() == </code>
+the result
+of the call to <code>timed_lock(rel_t)</code> on the referenced mutex.
+</dd>
+
+<dt>Throws:</dt>
+<dd>
+<code>lock_error</code>,
+if on entry <code>owns_lock()</code> is <code>true</code> or if <code>mutex() == 0</code>.
+</dd>
+</dl>
+
+<pre><code>
+bool timed_lock(const system_time&amp; abs_t);
+</code></pre>
+
+<dl>
+<dt>Effects:</dt>
+<dd>
+Calls <code>timed_lock(abs_t)</code> on the referenced mutex.
 </dd>
 
 <dt>Returns:</dt>
@@ -2046,10 +2167,8 @@
 If multiple calls to <code>call_once</code>
 with the same <code>once_flag</code> object
 occur in separate threads,
-only one thread shall call <code>func</code>,
-and none shall proceed until the call to <code>func</code> has completed.
-<b>[Crowl: I.e. the return of <code>func</code> happens before
-the return of <code>call_once</code>.]</b>
+the single non-exceptional return of <code>func</code> happens before [<cite>intro.multithreading</cite>]
+every non-exceptional <code>call_once</code> return.
 If the invocation of <code>func</code> results in an exception being thrown,
 the exception is propagated to the caller
 and the effects are as-if this invocation of <code>call_once</code>
@@ -2064,10 +2183,9 @@
 <dt>Thread safety:</dt>
 <dd>
 <p>
-Access to the same <code>once_flag</code> object
-by calls to <code>call_once</code> from different threads
-shall not result in a data race or deadlock.
-<b>[Crowl: The implementation shall not introduce these.]</b>
+The implememtation shall not introduce a data race or deadlock
+if different threads simultaneously use the same <code>once_flag</code> object
+to call <code>call_once</code>.
 </p>
 
 <p>
@@ -3252,6 +3370,12 @@
 <pre><code>
 class Duration {
 
+ // <em>traits information</em>
+ typedef <var><strong>implementation-defined</strong></var> tick_type;
+ static tick_type ticks_per_second();
+ static tick_type seconds_per_tick();
+ static bool is_subsecond();
+
     // <em>comparison operators</em>
     template&lt;typename RhsDuration&gt;
     bool operator&lt; (const RhsDuration&amp;) const;
@@ -3300,6 +3424,56 @@
 </blockquote>
 
 <pre><code>
+static tick_type ticks_per_second();
+</code></pre>
+
+<dl>
+<dt>Returns:</dt>
+<dd>
+A constant defined separately for each <tt>Duration</tt> type indicating the
+number of ticks per second (or 0 for types which are not <code>is_subsecond</code>).
+</dd>
+
+<dt>Throws:</dt>
+<dd>
+Nothing.
+</dd>
+</dl>
+
+<pre><code>
+static tick_type seconds_per_tick();
+</code></pre>
+
+<dl>
+<dt>Returns:</dt>
+<dd>
+A constant defined separately for each <tt>Duration</tt> type indicating the
+number of seconds per tick (or 0 for types which are <code>is_subsecond</code>).
+</dd>
+
+<dt>Throws:</dt>
+<dd>
+Nothing.
+</dd>
+</dl>
+
+<pre><code>
+static bool is_subsecond();
+</code></pre>
+
+<dl>
+<dt>Returns:</dt>
+<dd>
+<code>true</code> if the resolution of this Duration is greater than 1 second, and otherwise <code>false</code>.
+</dd>
+
+<dt>Throws:</dt>
+<dd>
+Nothing.
+</dd>
+</dl>
+
+<pre><code>
 template&lt;typename RhsDuration&gt;
 bool operator==(const RhsDuration&amp; rhs) const;
 </code></pre>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk