[complement-svn] SF.net SVN: complement: [1817] branches/wg21-thread
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2008-02-26 14:39:48
|
Revision: 1817 http://complement.svn.sourceforge.net/complement/?rev=1817&view=rev Author: complement Date: 2008-02-26 06:39:44 -0800 (Tue, 26 Feb 2008) Log Message: ----------- core implementation of JTC1/SC22/WG21 working draft, suggested as replacement for xmt Modified Paths: -------------- branches/wg21-thread/include/mt/mutex branches/wg21-thread/include/mt/system_error branches/wg21-thread/include/mt/thread branches/wg21-thread/lib/mt/ChangeLog branches/wg21-thread/lib/mt/Makefile.inc branches/wg21-thread/lib/mt/thread.cc branches/wg21-thread/lib/mt/ut/Makefile.inc branches/wg21-thread/lib/mt/ut/mt_test_suite.cc Added Paths: ----------- branches/wg21-thread/include/mt/condition_variable branches/wg21-thread/include/mt/date_time branches/wg21-thread/lib/mt/date_time.cc branches/wg21-thread/lib/mt/ut/mt_test_wg21.cc branches/wg21-thread/lib/mt/ut/mt_test_wg21.h Property Changed: ---------------- branches/wg21-thread/ branches/wg21-thread/include/ branches/wg21-thread/lib/ Property changes on: branches/wg21-thread ___________________________________________________________________ Name: svn:externals + Makefiles https://complement.svn.sourceforge.net/svnroot/complement/trunk/complement/explore/Makefiles Property changes on: branches/wg21-thread/include ___________________________________________________________________ Name: svn:externals + config https://complement.svn.sourceforge.net/svnroot/complement/trunk/complement/explore/include/config exam https://complement.svn.sourceforge.net/svnroot/complement/trunk/complement/explore/include/exam misc https://complement.svn.sourceforge.net/svnroot/complement/trunk/complement/explore/include/misc Copied: branches/wg21-thread/include/mt/condition_variable (from rev 1813, branches/wg21-thread/include/mt/xmt.h) =================================================================== --- branches/wg21-thread/include/mt/condition_variable (rev 0) +++ branches/wg21-thread/include/mt/condition_variable 2008-02-26 14:39:44 UTC (rev 1817) @@ -0,0 +1,773 @@ +// -*- C++ -*- Time-stamp: <08/02/25 13:09:15 ptr> + +/* + * Copyright (c) 1997-1999, 2002-2008 + * Petr Ovtchenkov + * + * Portion Copyright (c) 1999-2001 + * Parallel Graphics Ltd. + * + * Licensed under the Academic Free License version 3.0 + * + * Derived from original <mt/xmt.h> of 'complement' project + * [http://complement.sourceforge.net] + * to make it close to JTC1/SC22/WG21 working draft + * [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html] + */ + +#ifndef __MT_CONDITION_VARIABLE +#define __MT_CONDITION_VARIABLE + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <mt/date_time> +#include <mt/mutex> + +namespace std { + +namespace tr2 { + +template <bool SCOPE> +class __condition_variable +{ + public: + __condition_variable() + { +#ifdef __FIT_WIN32THREADS + _cond = CreateEvent( 0, TRUE, TRUE, 0 ); +#endif +#ifdef __FIT_PTHREADS + if ( SCOPE ) { + pthread_condattr_t attr; + pthread_condattr_init( &attr ); + pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ); + pthread_cond_init( &_cond, &attr ); + pthread_condattr_destroy( &attr ); + } else { + pthread_cond_init( &_cond, 0 ); + } +#endif + } + + ~__condition_variable() + { +#ifdef __FIT_WIN32THREADS + CloseHandle( _cond ); +#endif +#ifdef __FIT_PTHREADS + pthread_cond_destroy( &_cond ); +#endif + } + +#ifdef __FIT_PTHREADS + typedef pthread_cond_t* native_handle_type; +#endif +#ifdef __FIT_WIN32THREADS + typedef HANDLE native_handle_type; +#endif + + void notify_one() + { +#ifdef __FIT_WIN32THREADS + SetEvent( _cond ); +#endif +#ifdef __FIT_PTHREADS + pthread_cond_signal( &_cond ); +#endif + } + + void notify_all() + { +#ifdef __FIT_PTHREADS + pthread_cond_broadcast( &_cond ); +#endif + } + + void wait( unique_lock<__mutex<false,SCOPE> >& lock ) + { +#ifdef __FIT_WIN32THREADS + ResetEvent( _cond ); + lock.unlock(); + if ( WaitForSingleObject( _cond, -1 ) == WAIT_FAILED ) { + lock.lock(); + // throw system_error + } + lock.lock(); +#endif +#ifdef __FIT_PTHREADS + int ret = pthread_cond_wait( &_cond, &lock.m->_M_lock ); + if ( ret ) { + lock.lock(); + // throw system_error + } +#endif + } + + template <class Predicate> + void wait( unique_lock<__mutex<false,SCOPE> >& lock, Predicate pred ) + { + while ( !pred() ) { + wait( lock ); + } + } + + bool timed_wait( unique_lock<__mutex<false,SCOPE> >& lock, const system_time& abs_time ) + { +#ifdef __FIT_PTHREADS + ::timespec t; + t.tv_sec = abs_time.seconds_since_epoch(); + t.tv_nsec = static_cast<long>( abs_time.nanoseconds_since_epoch().count() % nanoseconds::ticks_per_second ); + int ret = pthread_cond_timedwait( &_cond, &lock.m->_M_lock, &t ); + if ( ret != 0 ) { + if ( ret == ETIMEDOUT ) { + return false; + } + // throw system_error + } +#endif + return true; + } + + template <class Duration> + bool timed_wait( unique_lock<__mutex<false,SCOPE> >& lock, const Duration& rel_time ) + { +#ifdef __FIT_PTHREADS + return timed_wait( lock, get_system_time() + rel_time ); +#endif + } + + template <class Predicate> + bool timed_wait( unique_lock<__mutex<false,SCOPE> >& lock, const system_time& abs_time, Predicate pred ) + { + while ( !pred() ) { + if ( !timed_wait( lock, abs_time ) ) { + return pred(); + } + } + return true; + } + + template <class Duration, class Predicate> + bool timed_wait( unique_lock<__mutex<false,SCOPE> >& lock, const Duration& rel_time, Predicate pred ) + { +#ifdef __FIT_PTHREADS + return timed_wait( lock, get_system_time() + rel_time, pred ); +#endif + } + + native_handle_type native_handle() + { +#ifdef __FIT_PTHREADS + return &_cond; +#endif +#ifdef __FIT_WIN32THREADS + return _cond; +#endif + } + + protected: +#ifdef __FIT_PTHREADS + pthread_cond_t _cond; +#endif +#ifdef __FIT_WIN32THREADS + HANDLE _cond; +#endif + + private: + __condition_variable( const __condition_variable& ) + { } +}; + +typedef __condition_variable<false> condition_variable; +typedef __condition_variable<true> condition_variable_ip; + +template <bool SCOPE> +class __condition_variable_any +{ + public: + __condition_variable_any() + { +#ifdef __FIT_WIN32THREADS + _cond = CreateEvent( 0, TRUE, TRUE, 0 ); +#endif +#ifdef __FIT_PTHREADS + if ( SCOPE ) { + pthread_condattr_t attr; + pthread_condattr_init( &attr ); + pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ); + pthread_cond_init( &_cond, &attr ); + pthread_condattr_destroy( &attr ); + } else { + pthread_cond_init( &_cond, 0 ); + } +#endif + } + + ~__condition_variable_any() + { +#ifdef __FIT_WIN32THREADS + CloseHandle( _cond ); +#endif +#ifdef __FIT_PTHREADS + pthread_cond_destroy( &_cond ); +#endif + } + +#ifdef __FIT_PTHREADS + typedef pthread_cond_t* native_handle_type; +#endif +#ifdef __FIT_WIN32THREADS + typedef HANDLE native_handle_type; +#endif + + void notify_one() + { +#ifdef __FIT_WIN32THREADS + SetEvent( _cond ); +#endif +#ifdef __FIT_PTHREADS + pthread_cond_signal( &_cond ); +#endif + } + + void notify_all() + { +#ifdef __FIT_PTHREADS + pthread_cond_broadcast( &_cond ); +#endif + } + + template <class Lock> + void wait( Lock& lock ) + { +#ifdef __FIT_WIN32THREADS + ResetEvent( _cond ); + lock.unlock(); + if ( WaitForSingleObject( _cond, -1 ) == WAIT_FAILED ) { + lock.lock(); + // throw system_error + } + lock.lock(); +#endif +#ifdef __FIT_PTHREADS + int ret = pthread_cond_wait( &_cond, lock.native_handle() ); + if ( ret ) { + lock.lock(); + // throw system_error + } +#endif + } + + template <class Lock, class Predicate> + void wait( Lock& lock, Predicate pred ) + { + while ( !pred() ) { + wait( lock ); + } + } + + template <class Lock> + bool timed_wait( Lock& lock, const system_time& abs_time ) + { +#ifdef __FIT_PTHREADS + ::timespec t; + t.tv_sec = abs_time.seconds_since_epoch(); + t.tv_nsec = static_cast<long>( abs_time.nanoseconds_since_epoch().count() % nanoseconds::ticks_per_second ); + int ret = pthread_cond_timedwait( &_cond, lock.native_handle(), &t ); + if ( ret != 0 ) { + if ( ret == ETIMEDOUT ) { + return false; + } + // throw system_error + } +#endif +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / std::tr2::milliseconds::ticks_per_second; + ResetEvent( _cond ); + lock.unlock(); + int ret = WaitForSingleObject( _cond, (abs_time - get_system_time()).count() / _th ); + lock.lock(); + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + SetEvent( _cond ); + return _val; + } +#endif + + return true; + } + + template <class Lock, class Duration> + bool timed_wait( Lock& lock, const Duration& rel_time ) + { +#ifdef __FIT_PTHREADS + return timed_wait( lock, get_system_time() + rel_time ); +#endif +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / Duration::ticks_per_second; + + ResetEvent( _cond ); + lock.unlock(); + int ret = WaitForSingleObject( _cond, rel_time.count() / _th ); + lock.lock(); + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + SetEvent( _cond ); + return _val; + } + + return true; +#endif + } + + template <class Lock, class Predicate> + bool timed_wait( Lock& lock, const system_time& abs_time, Predicate pred ) + { + while ( !pred() ) { + if ( !timed_wait( lock, abs_time ) ) { + return pred(); + } + } + return true; + } + + template <class Lock, class Duration, class Predicate> + bool timed_wait( Lock& lock, const Duration& rel_time, Predicate pred ) + { +#ifdef __FIT_PTHREADS + return timed_wait( lock, get_system_time() + rel_time, pred ); +#endif + } + + native_handle_type native_handle() + { +#ifdef __FIT_PTHREADS + return &_cond; +#endif +#ifdef __FIT_WIN32THREADS + return _cond; +#endif + } + + protected: +#ifdef __FIT_PTHREADS + pthread_cond_t _cond; +#endif +#ifdef __FIT_WIN32THREADS + HANDLE _cond; +#endif + + private: + __condition_variable_any( const __condition_variable_any& ) + { } +}; + +typedef __condition_variable_any<false> condition_variable_any; +typedef __condition_variable_any<true> condition_variable_any_ip; + +template <bool SCOPE> +class __condition_event +{ + public: + __condition_event() : + _val( false ) + { +#ifdef __FIT_WIN32THREADS + _cond = CreateEvent( 0, TRUE, TRUE, 0 ); +#endif +#ifdef __FIT_PTHREADS + if ( SCOPE ) { + pthread_condattr_t attr; + pthread_condattr_init( &attr ); + pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ); + pthread_cond_init( &_cond, &attr ); + pthread_condattr_destroy( &attr ); + } else { + pthread_cond_init( &_cond, 0 ); + } +#endif + } + + ~__condition_event() + { +#ifdef __FIT_WIN32THREADS + CloseHandle( _cond ); +#endif +#ifdef __FIT_PTHREADS + pthread_cond_destroy( &_cond ); +#endif + } + + void notify_one() + { + { + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + + if ( _val ) { + return; + } + + _val = true; + } + +#ifdef __FIT_WIN32THREADS + SetEvent( _cond ); +#endif +#ifdef __FIT_PTHREADS + if ( pthread_cond_signal( &_cond ) ) { + // throw system_error + } +#endif + } + + void notify_all() + { + { + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + + if ( _val ) { + return; + } + + _val = true; + } + +#ifdef __FIT_WIN32THREADS + if ( SetEvent( _cond ) == FALSE ) { + // throw system_error + } +#endif +#ifdef __FIT_PTHREADS + if ( pthread_cond_broadcast( &_cond ) ) { + // throw system_error + } +#endif + } + + void reset() + { + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + _val = false; + } + + void wait() + { + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + +#ifdef __FIT_WIN32THREADS + ResetEvent( _cond ); + lk.unlock(); + if ( WaitForSingleObject( _cond, -1 ) == WAIT_FAILED ) { + lk.lock(); + // throw system_error + } + lk.lock(); +#endif +#ifdef __FIT_PTHREADS + int ret; + while ( !_val ) { + ret = pthread_cond_wait( &_cond, &_lock._M_lock ); + if ( ret ) { + // throw system_error + } + } +#endif + } + + bool timed_wait(const system_time& abs_time ) + { + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + +#ifdef __FIT_PTHREADS + ::timespec t; + t.tv_sec = abs_time.seconds_since_epoch(); + t.tv_nsec = static_cast<long>( abs_time.nanoseconds_since_epoch().count() % nanoseconds::ticks_per_second ); + while ( !_val ) { + int ret = pthread_cond_timedwait( &_cond, _lock.native_handle(), &t ); + if ( ret != 0 ) { + if ( ret == ETIMEDOUT ) { + return _val; + } + // throw system_error + } + } +#endif + +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / std::tr2::milliseconds::ticks_per_second; + ResetEvent( _cond ); + lk.unlock(); + int ret = WaitForSingleObject( _cond, (abs_time - get_system_time()).count() / _th ); + lk.lock(); + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + SetEvent( _cond ); + return _val; + } +#endif + + return true; + } + + template <class Duration> + bool timed_wait( const Duration& rel_time ) + { +#ifdef __FIT_PTHREADS + return timed_wait( get_system_time() + rel_time ); +#endif +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / Duration::ticks_per_second; + + unique_lock<__mutex<false,SCOPE> > lk( _lock ); + + ResetEvent( _cond ); + lk.unlock(); + int ret = WaitForSingleObject( _cond, rel_time.count() / _th ); + lk.lock(); + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + SetEvent( _cond ); + return _val; + } + + return true; +#endif + } + + protected: +#ifdef __FIT_WIN32THREADS + HANDLE _cond; +#endif +#ifdef __FIT_PTHREADS + pthread_cond_t _cond; +#endif + __mutex<false,SCOPE> _lock; + bool _val; + + private: + __condition_event( const __condition_event& ) + { } +}; + +typedef __condition_event<false> condition_event; +typedef __condition_event<true> condition_event_ip; + +template <bool SCOPE> +class __semaphore +{ + public: + __semaphore( int cnt = 1 ) + { +#ifdef __FIT_WIN32THREADS + _sem = CreateSemaphore( NULL, cnt, INT_MAX, 0 ); // check! + _cnt = cnt; +#endif +#ifdef __FIT_PTHREADS + sem_init( &_sem, SCOPE ? 1 : 0, cnt ); +#endif + } + + ~__semaphore() + { +#ifdef __FIT_WIN32THREADS + CloseHandle( _sem ); +#endif +#ifdef __FIT__PTHREADS + sem_destroy( &_sem ); +#endif + } + + void wait() + { +#ifdef __FIT_WIN32THREADS + --_cnt; + if ( WaitForSingleObject( _sem, -1 ) == WAIT_FAILED ) { + ++_cnt; + // throw system_error + } +#endif +#ifdef __FIT_PTHREADS + int ret = sem_wait( &_sem ); + if ( ret != 0 ) { + // throw system_error + } +#endif + } + + bool try_wait() + { +#ifdef __FIT_WIN32THREADS + return _cnt > 0 ? (--_cnt, this->wait()) : -1; +#endif +#ifdef __FIT_PTHREADS + int ret = sem_trywait( &_sem ); + if ( ret != 0 ) { + if ( ret == EBUSY ) { + return false; + } + // throw system_error + } + return true; +#endif + } + + bool timed_wait(const system_time& abs_time ) + { +#ifdef __FIT_PTHREADS + ::timespec t; + t.tv_sec = abs_time.seconds_since_epoch(); + t.tv_nsec = static_cast<long>( abs_time.nanoseconds_since_epoch().count() % nanoseconds::ticks_per_second ); +# if !(defined(__FreeBSD__) || defined(__OpenBSD__)) + int ret = sem_timedwait( &_sem, &t ); + if ( ret != 0 ) { + if ( ret == ETIMEDOUT ) { + return false; + } + // throw system_error + } +# endif +#endif +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / std::tr2::milliseconds::ticks_per_second; + int ret = WaitForSingleObject( _sem, (abs_time - get_system_time()).count() / _th ); + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + return false; + } +#endif + return true; + } + + template <class Duration> + bool timed_wait( const Duration& rel_time ) + { +#ifdef __FIT_PTHREADS + return timed_wait( get_system_time() + rel_time ); +#endif +#ifdef __FIT_WIN32THREADS + static const std::tr2::nanoseconds::tick_type _th = std::tr2::nanoseconds::ticks_per_second / Duration::ticks_per_second; + + int ret = WaitForSingleObject( _sem, rel_time.count() / _th ); + + if ( ret == WAIT_OBJECT_0 ) { + return true; + } + + if ( ret == WAIT_FAILED ) { + // throw system_error + } + if ( ret == WAIT_TIMEOUT ) { + return false; + } + + return true; +#endif + } + + + void notify_one() + { +#ifdef __FIT_WIN32THREADS + int ret = ReleaseSemaphore( _sem, 1, &_cnt ) != 0 ? (++_cnt, 0) : -1; + if ( ret != 0 ) { + // throw system_error + } +#endif +#ifdef __FIT_PTHREADS + int ret = sem_post( &_sem ); + if ( ret != 0 ) { + // throw system_error + } +#endif + } + + int value() + { +#ifdef __FIT_WIN32THREADS + return static_cast<int>(_cnt); +#endif +#ifdef __FIT_PTHREADS + int v; + int e = sem_getvalue( &_sem, &v ); + if ( e != 0 ) { + // throw system_error + } + + return v; +#endif + } + + protected: +#ifdef __FIT_WIN32THREADS + HANDLE _sem; + long _cnt; +#endif +#ifdef __FIT_PTHREADS + sem_t _sem; +#endif + private: + __semaphore( const __semaphore& ) + { } +}; + +typedef __semaphore<false> semaphore; +typedef __semaphore<true> semaphore_ip; + +template <bool SCOPE> +class __barrier +{ + public: + __barrier( unsigned cnt = 2 ) + { +#ifdef _PTHREADS + pthread_barrierattr_t attr; + pthread_barrierattr_init( &attr ); + pthread_barrierattr_setpshared( &attr, SCOPE ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE ); + pthread_barrier_init( &_barr, &attr, cnt ); + pthread_barrierattr_destroy( &attr ); +#endif + } + + ~__barrier() + { +#ifdef __FIT_PTHREADS + pthread_barrier_destroy( &_barr ); +#endif + } + + void wait() + { +#ifdef __FIT_PTHREADS + int ret = pthread_barrier_wait( &_barr ); + if ( ret != 0 ) { + // throw system_error + } +#endif + } + + private: +#ifdef __FIT_PTHREADS + pthread_barrier_t _barr; +#endif +}; + +typedef __barrier<false> barrier; +typedef __barrier<false> barrier_ip; + +} // namespace tr2 + +} // namespace std + +#endif // __MT_CONDITION_VARIABLE Copied: branches/wg21-thread/include/mt/date_time (from rev 1813, branches/wg21-thread/include/mt/time.h) =================================================================== --- branches/wg21-thread/include/mt/date_time (rev 0) +++ branches/wg21-thread/include/mt/date_time 2008-02-26 14:39:44 UTC (rev 1817) @@ -0,0 +1,1116 @@ +// -*- C++ -*- Time-stamp: <08/02/25 13:08:13 ptr> + +/* + * Copyright (c) 2002, 2006-2008 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + * Derived from original <mt/time.h> of 'complement' project + * [http://complement.sourceforge.net] + * to make it close to JTC1/SC22/WG21 working draft + * [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html] + */ + +#ifndef __MT_DATE_TIME +#define __MT_DATE_TIME + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <string> +#include <misc/type_traits.h> +#include <functional> + +namespace std { + +namespace tr2 { + +class system_time; +class nanoseconds; +class microseconds; +class milliseconds; +class seconds; +class minutes; +class hours; + +namespace detail { + +typedef long long signed_tick_type; // int64_t +typedef unsigned long long unsigned_tick_type; // uint64_t + +template <class _Tp1, class _Tp2> +struct __is_more_precise : + public std::tr1::false_type +{ + typedef _Tp2 finest_type; +}; + +template <class _Tp> +struct __is_more_precise<std::tr2::nanoseconds,_Tp> : + public std::tr1::true_type +{ + typedef std::tr2::nanoseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::microseconds,milliseconds> : + public std::tr1::true_type +{ + typedef std::tr2::microseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::microseconds,seconds> : + public std::tr1::true_type +{ + typedef std::tr2::microseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::microseconds,minutes> : + public std::tr1::true_type +{ + typedef std::tr2::microseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::microseconds,hours> : + public std::tr1::true_type +{ + typedef std::tr2::microseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::milliseconds,seconds> : + public std::tr1::true_type +{ + typedef std::tr2::milliseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::milliseconds,minutes> : + public std::tr1::true_type +{ + typedef std::tr2::milliseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::milliseconds,hours> : + public std::tr1::true_type +{ + typedef std::tr2::milliseconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::seconds,minutes> : + public std::tr1::true_type +{ + typedef std::tr2::seconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::seconds,hours> : + public std::tr1::true_type +{ + typedef std::tr2::seconds finest_type; +}; + +template <> +struct __is_more_precise<std::tr2::minutes,hours> : + public std::tr1::true_type +{ + typedef std::tr2::minutes finest_type; +}; + +template <class LhsDuration, class RhsDuration, class Op, bool Pre> +struct __op_aux +{ + bool operator()( const LhsDuration& lhs, const RhsDuration& rhs ) const + { return Op()( static_cast<RhsDuration>(lhs).count(), rhs.count()); } +}; + +template <class LhsDuration, class RhsDuration, class Op> +struct __op_aux<LhsDuration,RhsDuration,Op,true> +{ + bool operator()( const LhsDuration& lhs, const RhsDuration& rhs ) const + { return Op()(lhs.count(), static_cast<LhsDuration>(rhs).count() ); } +}; + +template <class LhsDuration, class RhsDuration, class Op, bool Pre> +struct __op_aux2 +{ + signed_tick_type operator()( const LhsDuration& lhs, const RhsDuration& rhs ) const + { return Op()( static_cast<RhsDuration>(lhs).count(), rhs.count()); } +}; + +template <class LhsDuration, class RhsDuration, class Op> +struct __op_aux2<LhsDuration,RhsDuration,Op,true> +{ + signed_tick_type operator()( const LhsDuration& lhs, const RhsDuration& rhs ) const + { return Op()(lhs.count(), static_cast<LhsDuration>(rhs).count() ); } +}; + +struct add : + public std::binary_function<signed_tick_type,signed_tick_type,signed_tick_type> +{ + signed_tick_type operator()(signed_tick_type __x, signed_tick_type __y) const + { return __x + __y; } +}; + +struct sub : + public std::binary_function<signed_tick_type,signed_tick_type,signed_tick_type> +{ + signed_tick_type operator()(signed_tick_type __x, signed_tick_type __y) const + { return __x - __y; } +}; + +} // namespace detail + +class nanoseconds +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + nanoseconds( long long ns = 0LL ) : + tv( ns ) + { } + + tick_type count() const + { return tv; } + + template <typename Duration> + nanoseconds& operator -=( const Duration& d ) + { + static const tick_type factor = Duration::is_subsecond ? nanoseconds::ticks_per_second / Duration::ticks_per_second : nanoseconds::ticks_per_second * Duration::seconds_per_tick; + + tv -= d.tv * factor; + return *this; + } + + template <typename Duration> + nanoseconds& operator +=( const Duration& d ) + { + static const tick_type factor = Duration::is_subsecond ? nanoseconds::ticks_per_second / Duration::ticks_per_second : nanoseconds::ticks_per_second * Duration::seconds_per_tick; + + tv += d.tv * factor; + return *this; + } + + nanoseconds& operator *=( long v ) + { + tv *= v; + return *this; + } + + nanoseconds& operator /=( long v ) + { + tv /= v; + return *this; + } + + nanoseconds operator -() const + { return nanoseconds( -tv ); } + + bool operator ==( const nanoseconds& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return tv == static_cast<nanoseconds>(r).count(); } + + bool operator !=( const nanoseconds& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return tv != static_cast<nanoseconds>(r).count(); } + + bool operator <( const nanoseconds& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return tv < static_cast<nanoseconds>(r).count(); } + + bool operator <=( const nanoseconds& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return tv <= static_cast<nanoseconds>(r).count(); } + + bool operator >( const nanoseconds& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return tv > static_cast<nanoseconds>(r).count(); } + + bool operator >=( const nanoseconds& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return tv >= static_cast<nanoseconds>(r).count(); } + + nanoseconds operator +( const nanoseconds& r ) const + { return nanoseconds( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + nanoseconds operator +(const Duration& r) const + { return nanoseconds( tv + static_cast<nanoseconds>(r).count() ); } + + nanoseconds operator -( const nanoseconds& r ) const + { return nanoseconds( tv - r.tv ); } + + template <class Duration> + nanoseconds operator -(const Duration& r) const + { return nanoseconds( tv - static_cast<nanoseconds>(r).count() ); } + + nanoseconds operator *( long r ) const + { return nanoseconds( tv * r ); } + + nanoseconds operator /( long r ) const + { return nanoseconds( tv / r ); } + + private: + tick_type tv; + + friend class microseconds; + friend class milliseconds; + friend class seconds; + friend class minutes; + friend class hours; +}; + +class microseconds +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + microseconds( long long us = 0LL ) : + tv( us ) + { } + + tick_type count() const + { return tv; } + + template <typename RhsDuration> + microseconds& operator -=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv -= d.tv * factor / 1000LL; + return *this; + } + + + template <typename RhsDuration> + microseconds& operator +=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv += d.tv * factor / 1000LL; + return *this; + } + + + microseconds& operator *=( long v ) + { + tv *= v; + return *this; + } + + microseconds& operator /=( long v ) + { + tv /= v; + return *this; + } + + microseconds operator -() const + { return microseconds( -tv ); } + + operator nanoseconds() const + { return nanoseconds(tv * 1000LL); } + + bool operator ==( const microseconds& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::equal_to<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + bool operator !=( const microseconds& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::not_equal_to<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + bool operator <( const microseconds& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::less<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + bool operator <=( const microseconds& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::less_equal<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + bool operator >( const microseconds& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::greater<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + bool operator >=( const microseconds& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return std::tr2::detail::__op_aux<microseconds,Duration,std::greater_equal<tick_type>,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ); } + + microseconds operator +( const microseconds& r ) const + { return microseconds( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + typename std::tr2::detail::__is_more_precise<microseconds,Duration>::finest_type operator +(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<microseconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<microseconds,Duration,std::tr2::detail::add,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ) ); + } + + microseconds operator -( const microseconds& r ) const + { return microseconds( tv - r.tv ); } + + template <class Duration> + typename std::tr2::detail::__is_more_precise<microseconds,Duration>::finest_type operator -(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<microseconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<microseconds,Duration,std::tr2::detail::sub,std::tr2::detail::__is_more_precise<microseconds,Duration>::value>()( *this, r ) ); + } + + microseconds operator *( long r ) const + { return microseconds( tv * r ); } + + microseconds operator /( long r ) const + { return microseconds( tv / r ); } + + private: + tick_type tv; + + friend class nanoseconds; + friend class milliseconds; + friend class seconds; + friend class minutes; + friend class hours; +}; + +class milliseconds +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + milliseconds( long long ms = 0LL ) : + tv( ms ) + { } + + tick_type count() const + { return tv; } + + template <typename RhsDuration> + milliseconds& operator -=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv -= d.tv * factor / 1000000LL; + return *this; + } + + + template <typename RhsDuration> + milliseconds& operator +=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv += d.tv * factor / 1000000LL; + return *this; + } + + + milliseconds& operator *=( long v ) + { + tv *= v; + return *this; + } + + milliseconds& operator /=( long v ) + { + tv /= v; + return *this; + } + + milliseconds operator -() const + { return milliseconds( -tv ); } + + operator nanoseconds() const + { return nanoseconds(tv * 1000000LL); } + + operator microseconds() const + { return microseconds(tv * 1000LL); } + + bool operator ==( const milliseconds& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::equal_to<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + bool operator !=( const milliseconds& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::not_equal_to<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + bool operator <( const milliseconds& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::less<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + bool operator <=( const milliseconds& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::less_equal<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + bool operator >( const milliseconds& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::greater<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + bool operator >=( const milliseconds& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return std::tr2::detail::__op_aux<milliseconds,Duration,std::greater_equal<tick_type>,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ); } + + milliseconds operator +( const milliseconds& r ) const + { return milliseconds( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + typename std::tr2::detail::__is_more_precise<milliseconds,Duration>::finest_type operator +(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<milliseconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<milliseconds,Duration,std::tr2::detail::add,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ) ); + } + + milliseconds operator -( const milliseconds& r ) const + { return milliseconds( tv - r.tv ); } + + template <class Duration> + typename std::tr2::detail::__is_more_precise<milliseconds,Duration>::finest_type operator -(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<milliseconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<milliseconds,Duration,std::tr2::detail::sub,std::tr2::detail::__is_more_precise<milliseconds,Duration>::value>()( *this, r ) ); + } + + milliseconds operator *( long r ) const + { return milliseconds( tv * r ); } + + microseconds operator /( long r ) const + { return milliseconds( tv / r ); } + + private: + tick_type tv; + + friend class nanoseconds; + friend class microseconds; + friend class seconds; + friend class minutes; + friend class hours; +}; + +class seconds +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + seconds( long long s = 0LL ) : + tv( s ) + { } + + tick_type count() const + { return tv; } + + template <typename RhsDuration> + seconds& operator -=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv -= d.tv * factor / 1000000000LL; + return *this; + } + + template <typename RhsDuration> + seconds& operator +=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv += d.tv * factor / 1000000000LL; + return *this; + } + + seconds& operator *=( long v ) + { + tv *= v; + return *this; + } + + seconds& operator /=( long v ) + { + tv /= v; + return *this; + } + + seconds operator -() const + { return seconds( -tv ); } + + operator nanoseconds() const + { return nanoseconds(tv * 1000000000LL); } + + operator microseconds() const + { return microseconds(tv * 1000000LL); } + + operator milliseconds() const + { return milliseconds(tv * 1000LL); } + + bool operator ==( const seconds& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::equal_to<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + bool operator !=( const seconds& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::not_equal_to<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + bool operator <( const seconds& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::less<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + bool operator <=( const seconds& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::less_equal<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + bool operator >( const seconds& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::greater<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + bool operator >=( const seconds& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return std::tr2::detail::__op_aux<seconds,Duration,std::greater_equal<tick_type>,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ); } + + seconds operator +( const seconds& r ) const + { return seconds( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + typename std::tr2::detail::__is_more_precise<seconds,Duration>::finest_type operator +(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<seconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<seconds,Duration,std::tr2::detail::add,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ) ); + } + + seconds operator -( const seconds& r ) const + { return seconds( tv - r.tv ); } + + template <class Duration> + typename std::tr2::detail::__is_more_precise<seconds,Duration>::finest_type operator -(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<seconds,Duration>::finest_type( + std::tr2::detail::__op_aux2<seconds,Duration,std::tr2::detail::sub,std::tr2::detail::__is_more_precise<seconds,Duration>::value>()( *this, r ) ); + } + + seconds operator *( long r ) const + { return seconds( tv * r ); } + + seconds operator /( long r ) const + { return seconds( tv / r ); } + + private: + tick_type tv; + + friend class nanoseconds; + friend class microseconds; + friend class milliseconds; + friend class minutes; + friend class hours; +}; + +class minutes +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + minutes( long long m = 0LL ) : + tv( m ) + { } + + tick_type count() const + { return tv; } + + template <typename RhsDuration> + minutes& operator -=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv -= d.tv * factor / 60000000000LL; + return *this; + } + + template <typename RhsDuration> + minutes& operator +=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv += d.tv * factor / 60000000000LL; + return *this; + } + + + minutes& operator *=( long v ) + { + tv *= v; + return *this; + } + + minutes& operator /=( long v ) + { + tv /= v; + return *this; + } + + minutes operator-() const + { return minutes( -tv ); } + + operator nanoseconds() const + { return nanoseconds(tv * 60000000000LL); } + + operator microseconds() const + { return microseconds(tv * 60000000LL); } + + operator milliseconds() const + { return milliseconds(tv * 60000LL); } + + operator seconds() const + { return seconds(tv * 60LL); } + + bool operator ==( const minutes& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::equal_to<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + bool operator !=( const minutes& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::not_equal_to<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + bool operator <( const minutes& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::less<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + bool operator <=( const minutes& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::less_equal<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + bool operator >( const minutes& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::greater<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + bool operator >=( const minutes& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return std::tr2::detail::__op_aux<minutes,Duration,std::greater_equal<tick_type>,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ); } + + minutes operator +( const minutes& r ) const + { return minutes( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + typename std::tr2::detail::__is_more_precise<minutes,Duration>::finest_type operator +(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<minutes,Duration>::finest_type( + std::tr2::detail::__op_aux2<minutes,Duration,std::tr2::detail::add,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ) ); + } + + minutes operator -( const minutes& r ) const + { return minutes( tv - r.tv ); } + + template <class Duration> + typename std::tr2::detail::__is_more_precise<minutes,Duration>::finest_type operator -(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<minutes,Duration>::finest_type( + std::tr2::detail::__op_aux2<minutes,Duration,std::tr2::detail::sub,std::tr2::detail::__is_more_precise<minutes,Duration>::value>()( *this, r ) ); + } + + minutes operator *( long r ) const + { return minutes( tv * r ); } + + minutes operator /( long r ) const + { return minutes( tv / r ); } + + private: + tick_type tv; + + friend class nanoseconds; + friend class microseconds; + friend class milliseconds; + friend class seconds; + friend class hours; +}; + +class hours +{ + public: + typedef std::tr2::detail::signed_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + hours( long long h = 0LL ) : + tv( h ) + { } + + tick_type count() const + { return tv; } + + template <typename RhsDuration> + hours& operator -=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv -= d.tv * factor / 3600000000000LL; + return *this; + } + + template <typename RhsDuration> + hours& operator +=( const RhsDuration& d ) + { + static const tick_type factor = RhsDuration::is_subsecond ? nanoseconds::ticks_per_second / RhsDuration::ticks_per_second : nanoseconds::ticks_per_second * RhsDuration::seconds_per_tick; + + tv += d.tv * factor / 3600000000000LL; + return *this; + } + + hours& operator *=( long v ) + { + tv *= v; + return *this; + } + + hours& operator /=( long v ) + { + tv /= v; + return *this; + } + + hours operator -() const + { return hours( -tv ); } + + operator nanoseconds() const + { return nanoseconds(tv * 3600000000000LL); } + + operator microseconds() const + { return microseconds(tv * 3600000000LL); } + + operator milliseconds() const + { return milliseconds(tv * 3600000LL); } + + operator seconds() const + { return seconds(tv * 3600LL); } + + operator minutes() const + { return minutes(tv * 60LL); } + + bool operator ==( const hours& r ) const + { return tv == r.tv; } + + template <class Duration> + bool operator ==( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::equal_to<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + bool operator !=( const hours& r ) const + { return tv != r.tv; } + + template <class Duration> + bool operator !=( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::not_equal_to<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + bool operator <( const hours& r ) const + { return tv < r.tv; } + + template <class Duration> + bool operator <( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::less<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + bool operator <=( const hours& r ) const + { return tv <= r.tv; } + + template <class Duration> + bool operator <=( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::less_equal<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + bool operator >( const hours& r ) const + { return tv > r.tv; } + + template <class Duration> + bool operator >( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::greater<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + bool operator >=( const hours& r ) const + { return tv >= r.tv; } + + template <class Duration> + bool operator >=( const Duration& r ) const + { return std::tr2::detail::__op_aux<hours,Duration,std::greater_equal<tick_type>,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ); } + + hours operator +( const hours& r ) const + { return hours( tv + r.tv ); } + + system_time operator +( const system_time& r ) const; + + template <class Duration> + typename std::tr2::detail::__is_more_precise<hours,Duration>::finest_type operator +(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<hours,Duration>::finest_type( + std::tr2::detail::__op_aux2<hours,Duration,std::tr2::detail::add,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ) ); + } + + hours operator -( const hours& r ) const + { return hours( tv - r.tv ); } + + template <class Duration> + typename std::tr2::detail::__is_more_precise<hours,Duration>::finest_type operator -(const Duration& r) const + { + return typename std::tr2::detail::__is_more_precise<hours,Duration>::finest_type( + std::tr2::detail::__op_aux2<hours,Duration,std::tr2::detail::sub,std::tr2::detail::__is_more_precise<hours,Duration>::value>()( *this, r ) ); + } + + hours operator *( long r ) const + { return hours( tv * r ); } + + hours operator /( long r ) const + { return hours( tv / r ); } + + private: + tick_type tv; + + friend class nanoseconds; + friend class microseconds; + friend class milliseconds; + friend class seconds; + friend class minutes; +}; + +system_time get_system_time(); + +class system_time +{ + private: + struct _adopt_t {}; + + public: + typedef std::tr2::detail::unsigned_tick_type tick_type; + + static const tick_type ticks_per_second; + static const tick_type seconds_per_tick; + static const bool is_subsecond; + + system_time() : + tv( 0ULL ) + { } + explicit system_time( time_t t, nanoseconds ns ) : + tv( t * ticks_per_second + ns.count() ) + { } + explicit system_time( time_t t ) : + tv( t * ticks_per_second ) + { } + + time_t seconds_since_epoch() const + { return static_cast<time_t>( tv / nanoseconds::ticks_per_second ); } + + nanoseconds nanoseconds_since_epoch() const + { return nanoseconds( tv ); } + + bool operator ==(const system_time& rhs) const + { return tv == rhs.tv; } + + bool operator !=(const system_time& rhs) const + { return tv != rhs.tv; } + + bool operator >(const system_time& rhs) const + { return tv > rhs.tv; } + + bool operator >=(const system_time& rhs) const + { return tv >= rhs.tv; } + + bool operator <(const system_time& rhs) const + { return tv < rhs.tv; } + + bool operator <=(const system_time& rhs) const + { return tv <= rhs.tv; } + + nanoseconds operator -(const system_time& rhs) const + { return nanoseconds( tv - rhs.tv ); } + + system_time operator +(const nanoseconds& td) const + { return system_time( tv + td.count(), _adopt_t() ); } + + template <typename Duration> + system_time operator +(const Duration& td) const + { return system_time( tv + static_cast<nanoseconds>( td ).count(), _adopt_t() ); } + + system_time& operator +=(const nanoseconds& td) + { + tv += td.count(); + + return *this; + } + + template <typename Duration> + system_time& operator +=(const Duration& td) + { + tv += static_cast<nanoseconds>( td ).count(); + + return *this; + } + + system_time operator -(const nanoseconds& td) const + { return system_time( tv - td.count() ); } + + template <typename Duration> + system_time operator -(const Duration& td) const + { return system_time( tv - static_cast<nanoseconds>( td ).count() ); } + + system_time& operator -=(const nanoseconds& td) + { + tv -= td.count(); + + return *this; + } + + template <typename Duration> + system_time& operator -=(const Duration& td) + { + tv -= static_cast<nanoseconds>( td ).count(); + + return *this; + } + + private: + system_time( tick_type _v, const _adopt_t& ) : + tv( _v ) + { } + + tick_type tv; + + friend system_time get_system_time(); +}; + +inline nanoseconds operator *( long lhs, const nanoseconds& rhs ) +{ return nanoseconds( rhs.count() * lhs ); } + +inline microseconds operator *( long lhs, const microseconds& rhs ) +{ return microseconds( rhs.count() * lhs ); } + +inline milliseconds operator *( long lhs, const milliseconds& rhs ) +{ return milliseconds( rhs.count() * lhs ); } + +inline seconds operator *( long lhs, const seconds& rhs ) +{ return seconds( rhs.count() * lhs ); } + +inline minutes operator *( long lhs, const minutes& rhs ) +{ return minutes( rhs.count() * lhs ); } + +inline hours operator *( long lhs, const hours& rhs ) +{ return hours( rhs.count() * lhs ); } + +} // namespace tr2 + +} // namespace std + +#endif // __MT_DATE_TIME Modified: branches/wg21-thread/include/mt/mutex =================================================================== --- branches/wg21-thread/include/mt/mutex 2008-02-26 13:06:33 UTC (rev 1816) +++ branches/wg21-thread/include/mt/mutex 2008-02-26 14:39:44 UTC (rev 1817) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <07/09/15 10:03:40 ptr> +// -*- C++ -*- Time-stamp: <08/02/24 23:48:23 ptr> /* - * Copyright (c) 1997-1999, 2002-2007 + * Copyright (c) 1997-1999, 2002-2008 * Petr Ovtchenkov * * Portion Copyright (c) 1999-2001 @@ -9,23 +9,22 @@ * * Licensed under the Academic Free License version 3.0 * + * Derived from original <mt/xmt.h> of 'complement' project + * [http://complement.sourceforge.net] + * to make it close to JTC1/SC22/WG21 working draft + * [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html] */ -#ifndef __XMT_H -#define __XMT_H +#ifndef __MUTEX_H +#define __MUTEX_H #ifndef __config_feature_h #include <config/feature.h> #endif -#include <memory> #include <cstddef> #include <stdexcept> -#if !defined(_STLPORT_VERSION) && !defined(__STATIC_CAST) -# define __STATIC_CAST(t,v) static_cast<t>(v) -#endif - #ifdef WIN32 # include <windows.h> # include <memory> @@ -35,81 +34,17 @@ #endif // WIN32 #ifdef __unix -# if defined( _REENTRANT ) && !defined(_NOTHREADS) -# ifdef _PTHREADS -# include <pthread.h> -# include <semaphore.h> -# include <sched.h> -# else -# include <thread.h> -# include <synch.h> -# endif -# elif !defined(_NOTHREADS) // !_REENTRANT -# define _NOTHREADS -# endif -// # define __DLLEXPORT +# include <pthread.h> +# include <sched.h> #endif // __unix #include <cerrno> +#include <mt/system_error> -#include <mt/time.h> +namespace std { -#ifdef _REENTRANT +namespace tr2 { -# define MT_REENTRANT(point,nm) xmt::scoped_lock nm(point) -# define MT_LOCK(point) point.lock() -# define MT_UNLOCK(point) point.unlock() - -#else // !_REENTRANT - -# define MT_REENTRANT(point,nm) ((void)0) -# define MT_REENTRANT_RS(point,nm) ((void)0) -# define MT_LOCK(point) ((void)0) -# define MT_UNLOCK(point) ((void)0) - -#endif // _REENTRANT - -#include <signal.h> - -extern "C" { - -#ifndef SIG_PF // sys/signal.h - -# ifdef WIN32 -typedef void __cdecl SIG_FUNC_TYP(int); -# else -typedef void SIG_FUNC_TYP(int); -# endif -typedef SIG_FUNC_TYP *SIG_TYP; -# define SIG_PF SIG_TYP - -# ifndef SIG_DFL -# define SIG_DFL (SIG_PF)0 -# endif -# ifndef SIG_ERR -# define SIG_ERR (SIG_PF)-1 -# endif -# ifndef SIG_IGN -# define SIG_IGN (SIG_PF)1 -# endif -# ifndef SIG_HOLD -# define SIG_HOLD (SIG_PF)2 -# endif -#endif // SIG_PF - -typedef void si... [truncated message content] |