diff options
Diffstat (limited to 'boost/chrono')
33 files changed, 5150 insertions, 0 deletions
diff --git a/boost/chrono/ceil.hpp b/boost/chrono/ceil.hpp new file mode 100644 index 0000000000..7fbf9ddc29 --- /dev/null +++ b/boost/chrono/ceil.hpp @@ -0,0 +1,36 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_CHRONO_CEIL_HPP +#define BOOST_CHRONO_CEIL_HPP + +#include <boost/chrono/duration.hpp> + +namespace boost +{ + namespace chrono + { + + /** + * rounds up + */ + template <class To, class Rep, class Period> + To ceil(const duration<Rep, Period>& d) + { + To t = duration_cast<To>(d); + if (t < d) + ++t; + return t; + } + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/chrono.hpp b/boost/chrono/chrono.hpp new file mode 100644 index 0000000000..ebc29d8d47 --- /dev/null +++ b/boost/chrono/chrono.hpp @@ -0,0 +1,15 @@ +// chrono.hpp --------------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_CHRONO_HPP +#define BOOST_CHRONO_CHRONO_HPP + +#include <boost/chrono/duration.hpp> +#include <boost/chrono/time_point.hpp> +#include <boost/chrono/system_clocks.hpp> + +#endif // BOOST_CHRONO_CHRONO_HPP diff --git a/boost/chrono/chrono_io.hpp b/boost/chrono/chrono_io.hpp new file mode 100644 index 0000000000..29a8d3493e --- /dev/null +++ b/boost/chrono/chrono_io.hpp @@ -0,0 +1,19 @@ + +// chrono_io +// +// (C) Copyright Howard Hinnant +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// This code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_CHRONO_IO_HPP +#define BOOST_CHRONO_CHRONO_IO_HPP + +#include <boost/chrono/config.hpp> +#include <boost/chrono/io_v1/chrono_io.hpp> + +#endif // BOOST_CHRONO_CHRONO_IO_HPP diff --git a/boost/chrono/clock_string.hpp b/boost/chrono/clock_string.hpp new file mode 100644 index 0000000000..af025f27e0 --- /dev/null +++ b/boost/chrono/clock_string.hpp @@ -0,0 +1,25 @@ +// +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// + +#ifndef BOOST_CHRONO_CLOCK_STRING_HPP +#define BOOST_CHRONO_CLOCK_STRING_HPP + +#include <string> + +namespace boost +{ + namespace chrono + { + + template<class Clock, class CharT> + struct clock_string; + + } // chrono + +} // boost + +#endif // BOOST_CHRONO_CLOCK_STRING_HPP diff --git a/boost/chrono/config.hpp b/boost/chrono/config.hpp new file mode 100644 index 0000000000..a852b103a7 --- /dev/null +++ b/boost/chrono/config.hpp @@ -0,0 +1,161 @@ +// boost/chrono/config.hpp -------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006, 2008 +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_CHRONO_CONFIG_HPP +#define BOOST_CHRONO_CONFIG_HPP + +#include <boost/config.hpp> + +#if defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_USE_WINDOWS_H) +#define BOOST_USE_WINDOWS_H +#endif + +// BOOST_CHRONO_POSIX_API, BOOST_CHRONO_MAC_API, or BOOST_CHRONO_WINDOWS_API +// can be defined by the user to specify which API should be used + +#if defined(BOOST_CHRONO_WINDOWS_API) +# warning Boost.Chrono will use the Windows API +#elif defined(BOOST_CHRONO_MAC_API) +# warning Boost.Chrono will use the Mac API +#elif defined(BOOST_CHRONO_POSIX_API) +# warning Boost.Chrono will use the POSIX API +#endif + +# if defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_POSIX_API ) +# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_POSIX_API are defined +# elif defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_MAC_API ) +# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_MAC_API are defined +# elif defined( BOOST_CHRONO_MAC_API ) && defined( BOOST_CHRONO_POSIX_API ) +# error both BOOST_CHRONO_MAC_API and BOOST_CHRONO_POSIX_API are defined +# elif !defined( BOOST_CHRONO_WINDOWS_API ) && !defined( BOOST_CHRONO_MAC_API ) && !defined( BOOST_CHRONO_POSIX_API ) +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +# define BOOST_CHRONO_WINDOWS_API +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# define BOOST_CHRONO_MAC_API +# else +# define BOOST_CHRONO_POSIX_API +# endif +# endif + +# if defined( BOOST_CHRONO_WINDOWS_API ) +# ifndef UNDER_CE +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# endif +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif + +# if defined( BOOST_CHRONO_MAC_API ) +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif + +# if defined( BOOST_CHRONO_POSIX_API ) +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# include <time.h> //to check for CLOCK_REALTIME and CLOCK_MONOTONIC and _POSIX_THREAD_CPUTIME +# if defined(CLOCK_REALTIME) +# if defined(CLOCK_MONOTONIC) +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# endif +# else +# error <time.h> does not supply CLOCK_REALTIME +# endif +# if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif +# if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif +# if defined(sun) || defined(__sun) +# undef BOOST_CHRONO_HAS_THREAD_CLOCK +# undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY +# endif +# endif + +#if defined(BOOST_CHRONO_THREAD_DISABLED) && defined(BOOST_CHRONO_HAS_THREAD_CLOCK) +#undef BOOST_CHRONO_HAS_THREAD_CLOCK +#undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY +#endif + + +// unicode support ------------------------------// + +#if defined(BOOST_NO_UNICODE_LITERALS) || defined(BOOST_NO_CHAR16_T) || defined(BOOST_NO_CHAR32_T) +//~ #define BOOST_CHRONO_HAS_UNICODE_SUPPORT +#else +#define BOOST_CHRONO_HAS_UNICODE_SUPPORT 1 +#endif + +#if ! defined BOOST_NOEXCEPT +#if defined(BOOST_NO_NOEXCEPT) +#define BOOST_NOEXCEPT +#else +#define BOOST_NOEXCEPT noexcept +#endif +#endif + +#ifdef BOOST_CHRONO_HEADER_ONLY +#define BOOST_CHRONO_INLINE inline +#define BOOST_CHRONO_STATIC inline +#define BOOST_CHRONO_DECL + +#else +#define BOOST_CHRONO_INLINE +#define BOOST_CHRONO_STATIC static + +// enable dynamic linking on Windows ---------------------------------------// + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_CHRONO_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_CHRONO_SOURCE +# define BOOST_CHRONO_DECL BOOST_SYMBOL_EXPORT +#else +# define BOOST_CHRONO_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_CHRONO_SOURCE +#endif // DYN_LINK +// +// if BOOST_CHRONO_DECL isn't defined yet define it now: +#ifndef BOOST_CHRONO_DECL +#define BOOST_CHRONO_DECL +#endif + + +//#define BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CHRONO_NO_LIB) +// +// Set the name of our library; this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_chrono +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled +#endif // BOOST_CHRONO_HEADER_ONLY +#endif // BOOST_CHRONO_CONFIG_HPP + diff --git a/boost/chrono/detail/inlined/chrono.hpp b/boost/chrono/detail/inlined/chrono.hpp new file mode 100644 index 0000000000..027884365e --- /dev/null +++ b/boost/chrono/detail/inlined/chrono.hpp @@ -0,0 +1,44 @@ +// chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_INLINED_CHRONO_HPP +#define BOOST_CHRONO_DETAIL_INLINED_CHRONO_HPP + +#include <boost/version.hpp> +#include <boost/chrono/chrono.hpp> +#include <boost/system/system_error.hpp> +#include <boost/throw_exception.hpp> +#include <boost/chrono/detail/system.hpp> + +//----------------------------------------------------------------------------// +// // +// Platform-specific Implementations // +// // +//----------------------------------------------------------------------------// + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include <boost/chrono/detail/inlined/win/chrono.hpp> + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include <boost/chrono/detail/inlined/mac/chrono.hpp> + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include <boost/chrono/detail/inlined/posix/chrono.hpp> + +#endif // POSIX + +#endif diff --git a/boost/chrono/detail/inlined/mac/chrono.hpp b/boost/chrono/detail/inlined/mac/chrono.hpp new file mode 100644 index 0000000000..bf20ae924b --- /dev/null +++ b/boost/chrono/detail/inlined/mac/chrono.hpp @@ -0,0 +1,241 @@ +// mac/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// + +#include <sys/time.h> //for gettimeofday and timeval +#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t + +namespace boost +{ +namespace chrono +{ + +// system_clock + +// gettimeofday is the most precise "system time" available on this platform. +// It returns the number of microseconds since New Years 1970 in a struct called timeval +// which has a field for seconds and a field for microseconds. +// Fill in the timeval and then convert that to the time_point +system_clock::time_point +system_clock::now() BOOST_NOEXCEPT +{ + timeval tv; + gettimeofday(&tv, 0); + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +system_clock::time_point +system_clock::now(system::error_code & ec) +{ + timeval tv; + gettimeofday(&tv, 0); + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +} +#endif +// Take advantage of the fact that on this platform time_t is nothing but +// an integral count of seconds since New Years 1970 (same epoch as timeval). +// Just get the duration out of the time_point and truncate it to seconds. +time_t +system_clock::to_time_t(const time_point& t) BOOST_NOEXCEPT +{ + return time_t(duration_cast<seconds>(t.time_since_epoch()).count()); +} + +// Just turn the time_t into a count of seconds and construct a time_point with it. +system_clock::time_point +system_clock::from_time_t(time_t t) BOOST_NOEXCEPT +{ + return system_clock::time_point(seconds(t)); +} + +namespace chrono_detail +{ + +// steady_clock + +// Note, in this implementation steady_clock and high_resolution_clock +// are the same clock. They are both based on mach_absolute_time(). +// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of +// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom +// are run time constants supplied by the OS. This clock has no relationship +// to the Gregorian calendar. It's main use is as a high resolution timer. + +// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize +// for that case as an optimization. +BOOST_CHRONO_STATIC +steady_clock::rep +steady_simplified() +{ + return mach_absolute_time(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +steady_clock::rep +steady_simplified_ec(system::error_code & ec) +{ + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return mach_absolute_time(); +} +#endif + +BOOST_CHRONO_STATIC +double +compute_steady_factor(kern_return_t& err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) { + return 0; + } + return static_cast<double>(MachInfo.numer) / MachInfo.denom; +} + +BOOST_CHRONO_STATIC +steady_clock::rep +steady_full() +{ + static kern_return_t err; + static const double factor = chrono_detail::compute_steady_factor(err); + if (err != 0) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return static_cast<steady_clock::rep>(mach_absolute_time() * factor); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +steady_clock::rep +steady_full_ec(system::error_code & ec) +{ + static kern_return_t err; + static const double factor = chrono_detail::compute_steady_factor(err); + if (err != 0) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + err, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return steady_clock::rep(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return static_cast<steady_clock::rep>(mach_absolute_time() * factor); +} +#endif + +typedef steady_clock::rep (*FP)(); +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +typedef steady_clock::rep (*FP_ec)(system::error_code &); +#endif + +BOOST_CHRONO_STATIC +FP +init_steady_clock(kern_return_t & err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) + { + return 0; + } + + if (MachInfo.numer == MachInfo.denom) + { + return &chrono_detail::steady_simplified; + } + return &chrono_detail::steady_full; +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +FP_ec +init_steady_clock_ec(kern_return_t & err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) + { + return 0; + } + + if (MachInfo.numer == MachInfo.denom) + { + return &chrono_detail::steady_simplified_ec; + } + return &chrono_detail::steady_full_ec; +} +#endif +} + +steady_clock::time_point +steady_clock::now() BOOST_NOEXCEPT +{ + static kern_return_t err; + static chrono_detail::FP fp = chrono_detail::init_steady_clock(err); + if ( err != 0 ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return time_point(duration(fp())); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +steady_clock::time_point +steady_clock::now(system::error_code & ec) +{ + static kern_return_t err; + static chrono_detail::FP_ec fp = chrono_detail::init_steady_clock_ec(err); + if ( err != 0 ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + err, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( err, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration(fp(ec))); +} +#endif +} // namespace chrono +} // namespace boost diff --git a/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp new file mode 100644 index 0000000000..48753bdfc7 --- /dev/null +++ b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp @@ -0,0 +1,331 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include <boost/chrono/config.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/assert.hpp> + +#include <sys/time.h> //for gettimeofday and timeval +#include <sys/times.h> //for times +# include <unistd.h> + +namespace boost +{ + namespace chrono + { + namespace chrono_detail + { + + inline long tick_factor() // multiplier to convert ticks + // to nanoseconds; -1 if unknown + { + static long factor = 0; + if (!factor) + { + if ((factor = ::sysconf(_SC_CLK_TCK)) <= 0) + factor = -1; + else + { + BOOST_ASSERT(factor <= 1000000000l); // doesn't handle large ticks + factor = 1000000000l / factor; // compute factor + if (!factor) + factor = -1; + } + } + return factor; + } + } + + + process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT + { +#if 0 + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds(c * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +#else + clock_t c = ::clock(); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return time_point( + duration(c*(1000000000l/CLOCKS_PER_SEC)) + ); +#endif + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_real_cpu_clock::time_point process_real_cpu_clock::now(system::error_code & ec) + { + +#if 0 + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds(c * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } +#else + clock_t c = ::clock(); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + return time_point( + duration(c*(1000000000l/CLOCKS_PER_SEC)) + ); + +#endif + + } +#endif + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_user_cpu_clock::time_point process_user_cpu_clock::now(system::error_code & ec) + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + } +#endif + + process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) + * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) + * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_system_cpu_clock::time_point process_system_cpu_clock::now(system::error_code & ec) + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + } +#endif + + process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + time_point::rep + r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime + + tm.tms_cstime) * factor); + return time_point(duration(r)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_cpu_clock::time_point process_cpu_clock::now(system::error_code & ec) + { + + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + time_point::rep + r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime + + tm.tms_cstime) * factor); + return time_point(duration(r)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + + } +#endif + + } +} diff --git a/boost/chrono/detail/inlined/mac/thread_clock.hpp b/boost/chrono/detail/inlined/mac/thread_clock.hpp new file mode 100644 index 0000000000..dad806e4e2 --- /dev/null +++ b/boost/chrono/detail/inlined/mac/thread_clock.hpp @@ -0,0 +1,15 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright Vicente J. Botet Escriba 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include <boost/chrono/config.hpp> +#include <boost/chrono/detail/inlined/posix/thread_clock.hpp> +#include <cassert> + diff --git a/boost/chrono/detail/inlined/posix/chrono.hpp b/boost/chrono/detail/inlined/posix/chrono.hpp new file mode 100644 index 0000000000..e35a7ce267 --- /dev/null +++ b/boost/chrono/detail/inlined/posix/chrono.hpp @@ -0,0 +1,120 @@ +// posix/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// + +#include <time.h> // for clock_gettime + +namespace boost +{ +namespace chrono +{ + + system_clock::time_point system_clock::now() BOOST_NOEXCEPT + { + timespec ts; + if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + return time_point(duration( + static_cast<system_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + system_clock::time_point system_clock::now(system::error_code & ec) + { + timespec ts; + if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::system_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast<system_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } +#endif + + std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT + { + return static_cast<std::time_t>( t.time_since_epoch().count() / 1000000000 ); + } + + system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT + { + return time_point(duration(static_cast<system_clock::rep>(t) * 1000000000)); + } + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + + steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT + { + timespec ts; + if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + return time_point(duration( + static_cast<steady_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + steady_clock::time_point steady_clock::now(system::error_code & ec) + { + timespec ts; + if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast<steady_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } +#endif +#endif + +} // namespace chrono +} // namespace boost + + diff --git a/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp new file mode 100644 index 0000000000..d76d9356cf --- /dev/null +++ b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp @@ -0,0 +1,352 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include <boost/chrono/config.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/assert.hpp> + +#include <sys/times.h> +#include <unistd.h> +#include <time.h> // for clock_gettime + + +namespace boost { namespace chrono { +namespace chrono_detail +{ + inline long tick_factor() // multiplier to convert ticks + // to nanoseconds; -1 if unknown + { + static long factor = 0; + if ( !factor ) + { + if ( (factor = ::sysconf( _SC_CLK_TCK )) <= 0 ) + factor = -1; + else + { + BOOST_ASSERT( factor <= 1000000l ); // doesn't handle large ticks + factor = 1000000l / factor; // compute factor + if ( !factor ) factor = -1; + } + } + return factor; + } +} + +process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + microseconds(c*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_real_cpu_clock::time_point process_real_cpu_clock::now( + system::error_code & ec) +{ + + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + microseconds(c*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + microseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_user_cpu_clock::time_point process_user_cpu_clock::now( + system::error_code & ec) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + microseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + microseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_system_cpu_clock::time_point process_system_cpu_clock::now( + system::error_code & ec) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + microseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + time_point::rep r( + 1000*c*chrono_detail::tick_factor(), + 1000*(tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(), + 1000*(tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()); + return time_point(duration(r)); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_cpu_clock::time_point process_cpu_clock::now( + system::error_code & ec ) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + time_point::rep r( + 1000*c*chrono_detail::tick_factor(), + 1000*(tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(), + 1000*(tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()); + return time_point(duration(r)); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } + +} +#endif + +} } diff --git a/boost/chrono/detail/inlined/posix/thread_clock.hpp b/boost/chrono/detail/inlined/posix/thread_clock.hpp new file mode 100644 index 0000000000..5ad41f84e3 --- /dev/null +++ b/boost/chrono/detail/inlined/posix/thread_clock.hpp @@ -0,0 +1,88 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009-2011 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include <boost/chrono/config.hpp> +#include <boost/chrono/thread_clock.hpp> +#include <cassert> + +# include <sys/times.h> +# include <unistd.h> + +namespace boost { namespace chrono { + + thread_clock::time_point thread_clock::now( ) BOOST_NOEXCEPT + { + struct timespec ts; +#if defined CLOCK_THREAD_CPUTIME_ID + // get the timespec associated to the thread clock + if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) +#else + // get the current thread + pthread_t pth=pthread_self(); + // get the clock_id associated to the current thread + clockid_t clock_id; + pthread_getcpuclockid(pth, &clock_id); + // get the timespec associated to the thread clock + if ( ::clock_gettime( clock_id, &ts ) ) +#endif + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + // transform to nanoseconds + return time_point(duration( + static_cast<thread_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + thread_clock::time_point thread_clock::now( system::error_code & ec ) + { + struct timespec ts; +#if defined CLOCK_THREAD_CPUTIME_ID + // get the timespec associated to the thread clock + if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) +#else + // get the current thread + pthread_t pth=pthread_self(); + // get the clock_id associated to the current thread + clockid_t clock_id; + pthread_getcpuclockid(pth, &clock_id); + // get the timespec associated to the thread clock + if ( ::clock_gettime( clock_id, &ts ) ) +#endif + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::thread_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + // transform to nanoseconds + return time_point(duration( + static_cast<thread_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + + } +#endif +} } diff --git a/boost/chrono/detail/inlined/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/process_cpu_clocks.hpp new file mode 100644 index 0000000000..d37f6754cb --- /dev/null +++ b/boost/chrono/detail/inlined/process_cpu_clocks.hpp @@ -0,0 +1,45 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_PROCESS_CPU_CLOCKS_HPP +#define BOOST_CHRONO_DETAIL_INLINED_PROCESS_CPU_CLOCKS_HPP + + +#include <boost/chrono/config.hpp> +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + +#include <boost/version.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/throw_exception.hpp> +#include <boost/system/system_error.hpp> + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include <boost/chrono/detail/inlined/win/process_cpu_clocks.hpp> + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include <boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp> + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include <boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp> + +#endif // POSIX + +#endif + +#endif diff --git a/boost/chrono/detail/inlined/thread_clock.hpp b/boost/chrono/detail/inlined/thread_clock.hpp new file mode 100644 index 0000000000..16d19ef488 --- /dev/null +++ b/boost/chrono/detail/inlined/thread_clock.hpp @@ -0,0 +1,44 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_THREAD_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_THREAD_CLOCK_HPP + +#include <boost/chrono/config.hpp> +#include <boost/version.hpp> +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) +#include <boost/chrono/thread_clock.hpp> +#include <boost/throw_exception.hpp> +#include <boost/system/system_error.hpp> +#include <boost/throw_exception.hpp> +#include <boost/chrono/detail/system.hpp> + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include <boost/chrono/detail/inlined/win/thread_clock.hpp> + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include <boost/chrono/detail/inlined/mac/thread_clock.hpp> + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include <boost/chrono/detail/inlined/posix/thread_clock.hpp> + +#endif // POSIX + +#endif +#endif diff --git a/boost/chrono/detail/inlined/win/chrono.hpp b/boost/chrono/detail/inlined/win/chrono.hpp new file mode 100644 index 0000000000..d953fe4bb4 --- /dev/null +++ b/boost/chrono/detail/inlined/win/chrono.hpp @@ -0,0 +1,159 @@ +// win/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP + +#include <boost/detail/win/time.hpp> +#include <boost/detail/win/timers.hpp> +#include <boost/detail/win/GetLastError.hpp> + +namespace boost +{ +namespace chrono +{ +namespace chrono_detail +{ + + BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT + { + boost::detail::win32::LARGE_INTEGER_ freq; + if ( !boost::detail::win32::QueryPerformanceFrequency( &freq ) ) + return 0.0L; + return double(1000000000.0L / freq.QuadPart); + } + +} + + steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT + { + static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); + + boost::detail::win32::LARGE_INTEGER_ pcount; + if ( (nanosecs_per_tic <= 0.0L) || + (!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + return steady_clock::time_point(steady_clock::duration( + static_cast<steady_clock::rep>((nanosecs_per_tic) * pcount.QuadPart))); + } + + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + steady_clock::time_point steady_clock::now( system::error_code & ec ) + { + static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); + + boost::detail::win32::LARGE_INTEGER_ pcount; + if ( (nanosecs_per_tic <= 0.0L) + || (!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) + { + boost::detail::win32::DWORD_ cause = + ((nanosecs_per_tic <= 0.0L) + ? ERROR_NOT_SUPPORTED + : boost::detail::win32::GetLastError()); + if (BOOST_CHRONO_IS_THROWS(ec)) { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return steady_clock::time_point(duration(0)); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast<steady_clock::rep>(nanosecs_per_tic * pcount.QuadPart))); + } +#endif + + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::now() BOOST_NOEXCEPT + { + boost::detail::win32::FILETIME_ ft; + #if defined(UNDER_CE) + // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps. + boost::detail::win32::SYSTEMTIME_ st; + boost::detail::win32::GetSystemTime( &st ); + boost::detail::win32::SystemTimeToFileTime( &st, &ft ); + #else + boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails + #endif + return system_clock::time_point(system_clock::duration( + (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::now( system::error_code & ec ) + { + boost::detail::win32::FILETIME_ ft; + #if defined(UNDER_CE) + // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps. + boost::detail::win32::SYSTEMTIME_ st; + boost::detail::win32::GetSystemTime( &st ); + boost::detail::win32::SystemTimeToFileTime( &st, &ft ); + #else + boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails + #endif + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)); + } +#endif + + BOOST_CHRONO_INLINE + std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT + { + __int64 temp = t.time_since_epoch().count(); + + # if (!defined( BOOST_MSVC )) || (BOOST_MSVC > 1300) // > VC++ 7.0 + temp -= 116444736000000000LL; // delta from epoch in microseconds + # else + temp -= 116444736000000000; + # endif + + temp /= 10000000; + return static_cast<std::time_t>( temp ); + } + + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT + { + __int64 temp = t; + temp *= 10000000; + + # if (!defined( BOOST_MSVC )) || (BOOST_MSVC > 1300) // > VC++ 7.0 + temp += 116444736000000000LL; + # else + temp += 116444736000000000; + # endif + + return time_point(duration(temp)); + } + +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp new file mode 100644 index 0000000000..6453aa600a --- /dev/null +++ b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp @@ -0,0 +1,274 @@ +// boost process_timer.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP + +#include <boost/chrono/config.hpp> +//#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <cassert> +#include <time.h> + +#include <boost/detail/win/GetLastError.hpp> +#include <boost/detail/win/GetCurrentProcess.hpp> +#include <boost/detail/win/GetProcessTimes.hpp> + +namespace boost +{ +namespace chrono +{ + +process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT +{ + clock_t c = ::clock(); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return time_point( + duration(c*(1000000000l/CLOCKS_PER_SEC)) + ); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_real_cpu_clock::time_point process_real_cpu_clock::now( + system::error_code & ec) +{ + clock_t c = ::clock(); + if ( c == clock_t(-1) ) // error + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + duration(c*(1000000000l/CLOCKS_PER_SEC)) + ); +} +#endif + +process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + return time_point(duration( + ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 + )); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_user_cpu_clock::time_point process_user_cpu_clock::now( + system::error_code & ec) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 + )); + } + else + { + boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif + +process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + return time_point(duration( + ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 + )); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_system_cpu_clock::time_point process_system_cpu_clock::now( + system::error_code & ec) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 + )); + } + else + { + boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif + +process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count() + , + ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime + ) * 100, + ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime + ) * 100 + ); + return time_point(duration(r)); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_cpu_clock::time_point process_cpu_clock::now( + system::error_code & ec ) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetProcessTimes( + boost::detail::win32::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count() + , + ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime + ) * 100, + ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime + ) * 100 + ); + return time_point(duration(r)); + } + else + { + boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/inlined/win/thread_clock.hpp b/boost/chrono/detail/inlined/win/thread_clock.hpp new file mode 100644 index 0000000000..8ca1506ce5 --- /dev/null +++ b/boost/chrono/detail/inlined/win/thread_clock.hpp @@ -0,0 +1,102 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_THREAD_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_THREAD_CLOCK_HPP + +#include <boost/chrono/config.hpp> +#include <boost/chrono/thread_clock.hpp> +#include <cassert> + +#include <boost/detail/win/GetLastError.hpp> +#include <boost/detail/win/GetCurrentThread.hpp> +#include <boost/detail/win/GetThreadTimes.hpp> + +namespace boost +{ +namespace chrono +{ + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +thread_clock::time_point thread_clock::now( system::error_code & ec ) +{ + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetThreadTimes( + boost::detail::win32::GetCurrentThread (), &creation, &exit, + &system_time, &user_time ) ) + { + duration user = duration( + ((static_cast<duration::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 ); + + duration system = duration( + ((static_cast<duration::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 ); + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(system+user); + + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + boost::detail::win32::GetLastError(), + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::thread_clock" )); + } + else + { + ec.assign( boost::detail::win32::GetLastError(), BOOST_CHRONO_SYSTEM_CATEGORY ); + return thread_clock::time_point(duration(0)); + } + } +} +#endif + +thread_clock::time_point thread_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::win32::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::win32::GetThreadTimes( + boost::detail::win32::GetCurrentThread (), &creation, &exit, + &system_time, &user_time ) ) + { + duration user = duration( + ((static_cast<duration::rep>(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 ); + + duration system = duration( + ((static_cast<duration::rep>(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 ); + + return time_point(system+user); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/is_evenly_divisible_by.hpp b/boost/chrono/detail/is_evenly_divisible_by.hpp new file mode 100644 index 0000000000..960a208a75 --- /dev/null +++ b/boost/chrono/detail/is_evenly_divisible_by.hpp @@ -0,0 +1,31 @@ +// is_evenly_divisible_by.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP +#define BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP + +#include <boost/chrono/config.hpp> + +#include <boost/mpl/logical.hpp> +#include <boost/ratio/detail/overflow_helpers.hpp> + +namespace boost { +namespace chrono { +namespace chrono_detail { + +// template <class R1, class R2> +// struct is_evenly_divisible_by : public boost::mpl::bool_ < ratio_divide<R1, R2>::type::den == 1 > +// {}; + template <class R1, class R2> + struct is_evenly_divisible_by : public boost::ratio_detail::is_evenly_divisible_by<R1, R2> + {}; + +} // namespace chrono_detail +} // namespace detail +} // namespace chrono + +#endif // BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP diff --git a/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp new file mode 100644 index 0000000000..78a0ce13e7 --- /dev/null +++ b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp @@ -0,0 +1,44 @@ +// is_evenly_divisible_by.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP +#define BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +//../../../boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp:37: warning: comparison between signed and unsigned integer expressions +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost { +namespace chrono { +namespace detail { + + template <class T, class U> + bool lt(T t, U u) + { + return t < u; + } + + template <class T, class U> + bool gt(T t, U u) + { + return t > u; + } + +} // namespace detail +} // namespace detail +} // namespace chrono + +#endif // BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP diff --git a/boost/chrono/detail/scan_keyword.hpp b/boost/chrono/detail/scan_keyword.hpp new file mode 100644 index 0000000000..13ad0ca8c8 --- /dev/null +++ b/boost/chrono/detail/scan_keyword.hpp @@ -0,0 +1,162 @@ +// scan_keyword.hpp --------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP +#define BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP + +#include <boost/chrono/config.hpp> + +#include <boost/interprocess/smart_ptr/unique_ptr.hpp> +#include <ios> +#include <exception> +#include <stdlib.h> + +namespace boost { + using interprocess::unique_ptr; + +namespace chrono { +namespace chrono_detail { + +inline void free_aux(void* ptr) { free(ptr); } + +// scan_keyword +// Scans [b, e) until a match is found in the basic_strings range +// [kb, ke) or until it can be shown that there is no match in [kb, ke). +// b will be incremented (visibly), consuming CharT until a match is found +// or proved to not exist. A keyword may be "", in which will match anything. +// If one keyword is a prefix of another, and the next CharT in the input +// might match another keyword, the algorithm will attempt to find the longest +// matching keyword. If the longer matching keyword ends up not matching, then +// no keyword match is found. If no keyword match is found, ke is returned +// and failbit is set in err. +// Else an iterator pointing to the matching keyword is found. If more than +// one keyword matches, an iterator to the first matching keyword is returned. +// If on exit b == e, eofbit is set in err. +// Examples: +// Keywords: "a", "abb" +// If the input is "a", the first keyword matches and eofbit is set. +// If the input is "abc", no match is found and "ab" are consumed. + +template <class InputIterator, class ForwardIterator> +ForwardIterator +scan_keyword(InputIterator& b, InputIterator e, + ForwardIterator kb, ForwardIterator ke, + std::ios_base::iostate& err + ) +{ + typedef typename std::iterator_traits<InputIterator>::value_type CharT; + size_t nkw = std::distance(kb, ke); + const unsigned char doesnt_match = '\0'; + const unsigned char might_match = '\1'; + const unsigned char does_match = '\2'; + unsigned char statbuf[100]; + unsigned char* status = statbuf; + // Change free by free_aux to avoid + // Error: Could not find a match for boost::interprocess::unique_ptr<unsigned char, void(*)(void*)>::unique_ptr(int, extern "C" void(void*)) + unique_ptr<unsigned char, void(*)(void*)> stat_hold(0, free_aux); + if (nkw > sizeof(statbuf)) + { + status = (unsigned char*)malloc(nkw); + if (status == 0) + throw std::bad_alloc(); + stat_hold.reset(status); + } + size_t n_might_match = nkw; // At this point, any keyword might match + size_t n_does_match = 0; // but none of them definitely do + // Initialize all statuses to might_match, except for "" keywords are does_match + unsigned char* st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (!ky->empty()) + *st = might_match; + else + { + *st = does_match; + --n_might_match; + ++n_does_match; + } + } + // While there might be a match, test keywords against the next CharT + for (size_t indx = 0; b != e && n_might_match > 0; ++indx) + { + // Peek at the next CharT but don't consume it + CharT c = *b; + bool consume = false; + // For each keyword which might match, see if the indx character is c + // If a match if found, consume c + // If a match is found, and that is the last character in the keyword, + // then that keyword matches. + // If the keyword doesn't match this character, then change the keyword + // to doesn't match + st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (*st == might_match) + { + CharT kc = (*ky)[indx]; + if (c == kc) + { + consume = true; + if (ky->size() == indx+1) + { + *st = does_match; + --n_might_match; + ++n_does_match; + } + } + else + { + *st = doesnt_match; + --n_might_match; + } + } + } + // consume if we matched a character + if (consume) + { + ++b; + // If we consumed a character and there might be a matched keyword that + // was marked matched on a previous iteration, then such keywords + // which are now marked as not matching. + if (n_might_match + n_does_match > 1) + { + st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (*st == does_match && ky->size() != indx+1) + { + *st = doesnt_match; + --n_does_match; + } + } + } + } + } + // We've exited the loop because we hit eof and/or we have no more "might matches". + if (b == e) + err |= std::ios_base::eofbit; + // Return the first matching result + for (st = status; kb != ke; ++kb, ++st) + if (*st == does_match) + break; + if (kb == ke) + err |= std::ios_base::failbit; + return kb; +} +} +} +} +#endif // BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP diff --git a/boost/chrono/detail/static_assert.hpp b/boost/chrono/detail/static_assert.hpp new file mode 100644 index 0000000000..1ad21a56ba --- /dev/null +++ b/boost/chrono/detail/static_assert.hpp @@ -0,0 +1,30 @@ +// static_assert.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + + +#ifndef BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP +#define BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP + +#include <boost/chrono/config.hpp> + +#ifndef BOOST_NO_STATIC_ASSERT +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) +#elif defined(BOOST_CHRONO_USES_STATIC_ASSERT) +#include <boost/static_assert.hpp> +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) +#elif defined(BOOST_CHRONO_USES_MPL_ASSERT) +#include <boost/mpl/assert.hpp> +#include <boost/mpl/bool.hpp> +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) \ + BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) +#else +//~ #elif defined(BOOST_CHRONO_USES_ARRAY_ASSERT) +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_JOIN(boost_chrono_test_,__LINE__)[(CND)?1:-1] +//~ #define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) +#endif + +#endif // BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP diff --git a/boost/chrono/detail/system.hpp b/boost/chrono/detail/system.hpp new file mode 100644 index 0000000000..f8a40f12a8 --- /dev/null +++ b/boost/chrono/detail/system.hpp @@ -0,0 +1,26 @@ +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_SYSTEM_HPP +#define BOOST_CHRONO_DETAIL_SYSTEM_HPP + +#include <boost/version.hpp> +#include <boost/system/error_code.hpp> + +#if ((BOOST_VERSION / 100000) < 2) && ((BOOST_VERSION / 100 % 1000) < 44) +#define BOOST_CHRONO_SYSTEM_CATEGORY boost::system::system_category +#else +#define BOOST_CHRONO_SYSTEM_CATEGORY boost::system::system_category() +#endif + +#ifdef BOOST_SYSTEM_NO_DEPRECATED +#define BOOST_CHRONO_THROWS boost::throws() +#define BOOST_CHRONO_IS_THROWS(EC) (&EC==&boost::throws()) +#else +#define BOOST_CHRONO_THROWS boost::system::throws +#define BOOST_CHRONO_IS_THROWS(EC) (&EC==&boost::system::throws) +#endif + +#endif diff --git a/boost/chrono/duration.hpp b/boost/chrono/duration.hpp new file mode 100644 index 0000000000..323474014d --- /dev/null +++ b/boost/chrono/duration.hpp @@ -0,0 +1,786 @@ +// duration.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + + +#ifndef BOOST_CHRONO_DURATION_HPP +#define BOOST_CHRONO_DURATION_HPP + +#include <boost/chrono/config.hpp> +#include <boost/chrono/detail/static_assert.hpp> + +#include <climits> +#include <limits> + + +#include <boost/mpl/logical.hpp> +#include <boost/ratio/ratio.hpp> +#include <boost/type_traits/common_type.hpp> +#include <boost/type_traits/is_arithmetic.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/type_traits/is_unsigned.hpp> +#include <boost/chrono/detail/is_evenly_divisible_by.hpp> + +#include <boost/cstdint.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/integer_traits.hpp> + +#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT) +#define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" +#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" +#define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" +#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION "Second template parameter of time_point must be a boost::chrono::duration" +#endif + + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + template <class Rep, class Period = ratio<1> > + class duration; + + namespace detail + { + template <class T> + struct is_duration + : boost::false_type {}; + + template <class Rep, class Period> + struct is_duration<duration<Rep, Period> > + : boost::true_type {}; + + template <class Duration, class Rep, bool = is_duration<Rep>::value> + struct duration_divide_result + { + }; + + template <class Duration, class Rep2, + bool = ( + ((boost::is_convertible<typename Duration::rep, + typename common_type<typename Duration::rep, Rep2>::type>::value)) + && ((boost::is_convertible<Rep2, + typename common_type<typename Duration::rep, Rep2>::type>::value)) + ) + > + struct duration_divide_imp + { + }; + + template <class Rep1, class Period, class Rep2> + struct duration_divide_imp<duration<Rep1, Period>, Rep2, true> + { + typedef duration<typename common_type<Rep1, Rep2>::type, Period> type; + }; + + template <class Rep1, class Period, class Rep2> + struct duration_divide_result<duration<Rep1, Period>, Rep2, false> + : duration_divide_imp<duration<Rep1, Period>, Rep2> + { + }; + +/// + template <class Rep, class Duration, bool = is_duration<Rep>::value> + struct duration_divide_result2 + { + }; + + template <class Rep, class Duration, + bool = ( + ((boost::is_convertible<typename Duration::rep, + typename common_type<typename Duration::rep, Rep>::type>::value)) + && ((boost::is_convertible<Rep, + typename common_type<typename Duration::rep, Rep>::type>::value)) + ) + > + struct duration_divide_imp2 + { + }; + + template <class Rep1, class Rep2, class Period > + struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true> + { + //typedef typename common_type<Rep1, Rep2>::type type; + typedef double type; + }; + + template <class Rep1, class Rep2, class Period > + struct duration_divide_result2<Rep1, duration<Rep2, Period>, false> + : duration_divide_imp2<Rep1, duration<Rep2, Period> > + { + }; + +/// + template <class Duration, class Rep, bool = is_duration<Rep>::value> + struct duration_modulo_result + { + }; + + template <class Duration, class Rep2, + bool = ( + //boost::is_convertible<typename Duration::rep, + //typename common_type<typename Duration::rep, Rep2>::type>::value + //&& + boost::is_convertible<Rep2, + typename common_type<typename Duration::rep, Rep2>::type>::value + ) + > + struct duration_modulo_imp + { + }; + + template <class Rep1, class Period, class Rep2> + struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true> + { + typedef duration<typename common_type<Rep1, Rep2>::type, Period> type; + }; + + template <class Rep1, class Period, class Rep2> + struct duration_modulo_result<duration<Rep1, Period>, Rep2, false> + : duration_modulo_imp<duration<Rep1, Period>, Rep2> + { + }; + +} // namespace detail +} // namespace chrono + + +// common_type trait specializations + +template <class Rep1, class Period1, class Rep2, class Period2> +struct common_type<chrono::duration<Rep1, Period1>, + chrono::duration<Rep2, Period2> >; + + +namespace chrono { + + // customization traits + template <class Rep> struct treat_as_floating_point; + template <class Rep> struct duration_values; + + // convenience typedefs + typedef duration<boost::int_least64_t, nano> nanoseconds; // at least 64 bits needed + typedef duration<boost::int_least64_t, micro> microseconds; // at least 55 bits needed + typedef duration<boost::int_least64_t, milli> milliseconds; // at least 45 bits needed + typedef duration<boost::int_least64_t> seconds; // at least 35 bits needed + typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed + typedef duration<boost::int_least32_t, ratio<3600> > hours; // at least 23 bits needed + +//----------------------------------------------------------------------------// +// duration helpers // +//----------------------------------------------------------------------------// + +namespace detail +{ + + // duration_cast + + // duration_cast is the heart of this whole prototype. It can convert any + // duration to any other. It is also (implicitly) used in converting + // time_points. The conversion is always exact if possible. And it is + // always as efficient as hand written code. If different representations + // are involved, care is taken to never require implicit conversions. + // Instead static_cast is used explicitly for every required conversion. + // If there are a mixture of integral and floating point representations, + // the use of common_type ensures that the most logical "intermediate" + // representation is used. + template <class FromDuration, class ToDuration, + class Period, + bool PeriodNumEq1, + bool PeriodDenEq1> + struct duration_cast_aux; + + // When the two periods are the same, all that is left to do is static_cast from + // the source representation to the target representation (which may be a no-op). + // This conversion is always exact as long as the static_cast from the source + // representation to the destination representation is exact. + template <class FromDuration, class ToDuration, class Period> + struct duration_cast_aux<FromDuration, ToDuration, Period, true, true> + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + return ToDuration(static_cast<typename ToDuration::rep>(fd.count())); + } + }; + + // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is + // divide by the denominator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template <class FromDuration, class ToDuration, class Period> + struct duration_cast_aux<FromDuration, ToDuration, Period, true, false> + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) / static_cast<C>(Period::den))); + } + }; + + // When the denominator of FromPeriod / ToPeriod is 1, then all we need to do is + // multiply by the numerator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is always exact as long as the static_cast's involved are exact. + template <class FromDuration, class ToDuration, class Period> + struct duration_cast_aux<FromDuration, ToDuration, Period, false, true> + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) * static_cast<C>(Period::num))); + } + }; + + // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to + // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The + // common_type of the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template <class FromDuration, class ToDuration, class Period> + struct duration_cast_aux<FromDuration, ToDuration, Period, false, false> + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) * static_cast<C>(Period::num) + / static_cast<C>(Period::den))); + } + }; + + template <class FromDuration, class ToDuration> + struct duration_cast { + typedef typename ratio_divide<typename FromDuration::period, + typename ToDuration::period>::type Period; + typedef duration_cast_aux< + FromDuration, + ToDuration, + Period, + Period::num == 1, + Period::den == 1 + > Aux; + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + return Aux()(fd); + } + }; + +} // namespace detail + +//----------------------------------------------------------------------------// +// // +// 20.9.2 Time-related traits [time.traits] // +// // +//----------------------------------------------------------------------------// +//----------------------------------------------------------------------------// +// 20.9.2.1 treat_as_floating_point [time.traits.is_fp] // +// Probably should have been treat_as_floating_point. Editor notifed. // +//----------------------------------------------------------------------------// + + // Support bidirectional (non-exact) conversions for floating point rep types + // (or user defined rep types which specialize treat_as_floating_point). + template <class Rep> + struct treat_as_floating_point : boost::is_floating_point<Rep> {}; + +//----------------------------------------------------------------------------// +// 20.9.2.2 duration_values [time.traits.duration_values] // +//----------------------------------------------------------------------------// + +namespace detail { + template <class T, bool = is_arithmetic<T>::value> + struct chrono_numeric_limits { + static T lowest() throw() {return (std::numeric_limits<T>::min) ();} + }; + + template <class T> + struct chrono_numeric_limits<T,true> { + static T lowest() throw() {return (std::numeric_limits<T>::min) ();} + }; + + template <> + struct chrono_numeric_limits<float,true> { + static float lowest() throw() + { + return -(std::numeric_limits<float>::max) (); + } + }; + + template <> + struct chrono_numeric_limits<double,true> { + static double lowest() throw() + { + return -(std::numeric_limits<double>::max) (); + } + }; + + template <> + struct chrono_numeric_limits<long double,true> { + static long double lowest() throw() + { + return -(std::numeric_limits<long double>::max)(); + } + }; + + template <class T> + struct numeric_limits : chrono_numeric_limits<typename remove_cv<T>::type> + {}; + +} +template <class Rep> +struct duration_values +{ + static BOOST_CONSTEXPR Rep zero() {return Rep(0);} + static BOOST_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (std::numeric_limits<Rep>::max)(); + } + + static BOOST_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return detail::numeric_limits<Rep>::lowest(); + } +}; + +} // namespace chrono + +//----------------------------------------------------------------------------// +// 20.9.2.3 Specializations of common_type [time.traits.specializations] // +//----------------------------------------------------------------------------// + +template <class Rep1, class Period1, class Rep2, class Period2> +struct common_type<chrono::duration<Rep1, Period1>, + chrono::duration<Rep2, Period2> > +{ + typedef chrono::duration<typename common_type<Rep1, Rep2>::type, + typename boost::ratio_gcd<Period1, Period2>::type> type; +}; + + +//----------------------------------------------------------------------------// +// // +// 20.9.3 Class template duration [time.duration] // +// // +//----------------------------------------------------------------------------// + + +namespace chrono { + + template <class Rep, class Period> + class duration + { + //BOOST_CHRONO_STATIC_ASSERT(boost::is_integral<Rep>::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ()); + BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration<Rep>::value, + BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); + BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<typename Period::type>::value, + BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); + BOOST_CHRONO_STATIC_ASSERT(Period::num>0, + BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); + public: + typedef Rep rep; + typedef Period period; + private: + rep rep_; + public: + + BOOST_CONSTEXPR + duration() : rep_(duration_values<rep>::zero()) { } + template <class Rep2> + BOOST_CONSTEXPR + explicit duration(const Rep2& r + , typename boost::enable_if < + mpl::and_ < + boost::is_convertible<Rep2, rep>, + mpl::or_ < + treat_as_floating_point<rep>, + mpl::and_ < + mpl::not_ < treat_as_floating_point<rep> >, + mpl::not_ < treat_as_floating_point<Rep2> > + > + > + > + >::type* = 0 + ) : rep_(r) { } + ~duration() {} //= default; + BOOST_CONSTEXPR + duration(const duration& rhs) : rep_(rhs.rep_) {} // = default; + duration& operator=(const duration& rhs) // = default; + { + if (&rhs != this) rep_= rhs.rep_; + return *this; + } + + // conversions + template <class Rep2, class Period2> + BOOST_CONSTEXPR + duration(const duration<Rep2, Period2>& d + , typename boost::enable_if < + mpl::or_ < + treat_as_floating_point<rep>, + mpl::and_ < + chrono_detail::is_evenly_divisible_by<Period2, period>, + mpl::not_ < treat_as_floating_point<Rep2> > + > + > + >::type* = 0 + ) + : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {} + + // observer + + BOOST_CONSTEXPR + rep count() const {return rep_;} + + // arithmetic + + BOOST_CONSTEXPR + duration operator+() const {return *this;} + BOOST_CONSTEXPR + duration operator-() const {return duration(-rep_);} + duration& operator++() {++rep_; return *this;} + duration operator++(int) {return duration(rep_++);} + duration& operator--() {--rep_; return *this;} + duration operator--(int) {return duration(rep_--);} + + duration& operator+=(const duration& d) + { + rep_ += d.count(); return *this; + } + duration& operator-=(const duration& d) + { + rep_ -= d.count(); return *this; + } + + duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} + duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} + duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;} + duration& operator%=(const duration& rhs) + { + rep_ %= rhs.count(); return *this; + } + // 20.9.3.4 duration special values [time.duration.special] + + static BOOST_CONSTEXPR duration zero() + { + return duration(duration_values<rep>::zero()); + } + static BOOST_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return duration((duration_values<rep>::min)()); + } + static BOOST_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return duration((duration_values<rep>::max)()); + } + }; + +//----------------------------------------------------------------------------// +// 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] // +//----------------------------------------------------------------------------// + + // Duration + + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator+(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + typedef typename common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + return CD(CD(lhs).count()+CD(rhs).count()); + } + + // Duration - + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator-(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + typedef typename common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + return CD(CD(lhs).count()-CD(rhs).count()); + } + + // Duration * + + template <class Rep1, class Period, class Rep2> + inline BOOST_CONSTEXPR + typename boost::enable_if < + mpl::and_ < + boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, + boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> + >, + duration<typename common_type<Rep1, Rep2>::type, Period> + >::type + operator*(const duration<Rep1, Period>& d, const Rep2& s) + { + typedef typename common_type<Rep1, Rep2>::type CR; + typedef duration<CR, Period> CD; + return CD(CD(d).count()*static_cast<CR>(s)); + } + + template <class Rep1, class Period, class Rep2> + inline BOOST_CONSTEXPR + typename boost::enable_if < + mpl::and_ < + boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, + boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> + >, + duration<typename common_type<Rep1, Rep2>::type, Period> + >::type + operator*(const Rep1& s, const duration<Rep2, Period>& d) + { + return d * s; + } + + // Duration / + + template <class Rep1, class Period, class Rep2> + inline BOOST_CONSTEXPR + typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, + typename boost::chrono::detail::duration_divide_result< + duration<Rep1, Period>, Rep2>::type + >::type + operator/(const duration<Rep1, Period>& d, const Rep2& s) + { + typedef typename common_type<Rep1, Rep2>::type CR; + typedef duration<CR, Period> CD; + + return CD(CD(d).count()/static_cast<CR>(s)); + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + typename common_type<Rep1, Rep2>::type + operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + typedef typename common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + return CD(lhs).count() / CD(rhs).count(); + } + + #ifdef BOOST_CHRONO_EXTENSIONS + template <class Rep1, class Rep2, class Period> + inline BOOST_CONSTEXPR + typename boost::disable_if <boost::chrono::detail::is_duration<Rep1>, + typename boost::chrono::detail::duration_divide_result2< + Rep1, duration<Rep2, Period> >::type + >::type + operator/(const Rep1& s, const duration<Rep2, Period>& d) + { + typedef typename common_type<Rep1, Rep2>::type CR; + typedef duration<CR, Period> CD; + + return static_cast<CR>(s)/CD(d).count(); + } + #endif + // Duration % + + template <class Rep1, class Period, class Rep2> + inline BOOST_CONSTEXPR + typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, + typename boost::chrono::detail::duration_modulo_result< + duration<Rep1, Period>, Rep2>::type + >::type + operator%(const duration<Rep1, Period>& d, const Rep2& s) + { + typedef typename common_type<Rep1, Rep2>::type CR; + typedef duration<CR, Period> CD; + + return CD(CD(d).count()%static_cast<CR>(s)); + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator%(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) { + typedef typename common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + + return CD(CD(lhs).count()%CD(rhs).count()); + } + + +//----------------------------------------------------------------------------// +// 20.9.3.6 duration comparisons [time.duration.comparisons] // +//----------------------------------------------------------------------------// + +namespace detail +{ + template <class LhsDuration, class RhsDuration> + struct duration_eq + { + bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) + { + typedef typename common_type<LhsDuration, RhsDuration>::type CD; + return CD(lhs).count() == CD(rhs).count(); + } + }; + + template <class LhsDuration> + struct duration_eq<LhsDuration, LhsDuration> + { + bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) + { + return lhs.count() == rhs.count(); + } + }; + + template <class LhsDuration, class RhsDuration> + struct duration_lt + { + bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) + { + typedef typename common_type<LhsDuration, RhsDuration>::type CD; + return CD(lhs).count() < CD(rhs).count(); + } + }; + + template <class LhsDuration> + struct duration_lt<LhsDuration, LhsDuration> + { + bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) + { + return lhs.count() < rhs.count(); + } + }; + +} // namespace detail + + // Duration == + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator==(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return boost::chrono::detail::duration_eq< + duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); + } + + // Duration != + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator!=(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return !(lhs == rhs); + } + + // Duration < + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator< (const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return boost::chrono::detail::duration_lt< + duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); + } + + // Duration > + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator> (const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return rhs < lhs; + } + + // Duration <= + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator<=(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return !(rhs < lhs); + } + + // Duration >= + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator>=(const duration<Rep1, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return !(lhs < rhs); + } + +//----------------------------------------------------------------------------// +// 20.9.3.7 duration_cast [time.duration.cast] // +//----------------------------------------------------------------------------// + + // Compile-time select the most efficient algorithm for the conversion... + template <class ToDuration, class Rep, class Period> + inline BOOST_CONSTEXPR + typename boost::enable_if < + boost::chrono::detail::is_duration<ToDuration>, ToDuration>::type + duration_cast(const duration<Rep, Period>& fd) + { + return boost::chrono::detail::duration_cast< + duration<Rep, Period>, ToDuration>()(fd); + } + +} // namespace chrono +} // namespace boost + +#endif // BOOST_CHRONO_DURATION_HPP diff --git a/boost/chrono/floor.hpp b/boost/chrono/floor.hpp new file mode 100644 index 0000000000..e133e49c8a --- /dev/null +++ b/boost/chrono/floor.hpp @@ -0,0 +1,34 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_CHRONO_FLOOR_HPP +#define BOOST_CHRONO_FLOOR_HPP + +#include <boost/chrono/duration.hpp> + +namespace boost +{ + namespace chrono + { + + /** + * rounds down + */ + template <class To, class Rep, class Period> + To floor(const duration<Rep, Period>& d) + { + return duration_cast<To>(d); + } + + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/include.hpp b/boost/chrono/include.hpp new file mode 100644 index 0000000000..b58f76bef8 --- /dev/null +++ b/boost/chrono/include.hpp @@ -0,0 +1,23 @@ + +// include +// +// (C) Copyright 2011 Vicente J. Botet Escriba +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// This code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_INCLUDE_HPP +#define BOOST_CHRONO_INCLUDE_HPP + +#include <boost/chrono/chrono.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/chrono/thread_clock.hpp> +#include <boost/chrono/ceil.hpp> +#include <boost/chrono/floor.hpp> +#include <boost/chrono/round.hpp> + +#endif // BOOST_CHRONO_INCLUDE_HPP diff --git a/boost/chrono/io_v1/chrono_io.hpp b/boost/chrono/io_v1/chrono_io.hpp new file mode 100644 index 0000000000..6ca1ca2d69 --- /dev/null +++ b/boost/chrono/io_v1/chrono_io.hpp @@ -0,0 +1,637 @@ + +// chrono_io +// +// (C) Copyright Howard Hinnant +// (C) Copyright 2010 Vicente J. Botet Escriba +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// This code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_IO_V1_CHRONO_IO_HPP +#define BOOST_CHRONO_IO_V1_CHRONO_IO_HPP + +#include <boost/chrono/chrono.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/chrono/thread_clock.hpp> +#include <boost/chrono/clock_string.hpp> +#include <boost/ratio/ratio_io.hpp> +#include <locale> +#include <boost/type_traits/is_scalar.hpp> +#include <boost/type_traits/is_signed.hpp> +#include <boost/mpl/if.hpp> +#include <boost/math/common_factor_rt.hpp> +#include <boost/chrono/detail/scan_keyword.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp> + +namespace boost +{ + +namespace chrono +{ + +template <class CharT> +class duration_punct + : public std::locale::facet +{ +public: + typedef std::basic_string<CharT> string_type; + enum {use_long, use_short}; + +private: + bool use_short_; + string_type long_seconds_; + string_type long_minutes_; + string_type long_hours_; + string_type short_seconds_; + string_type short_minutes_; + string_type short_hours_; + + template <class Period> + string_type short_name(Period) const + {return ::boost::ratio_string<Period, CharT>::short_name() + short_seconds_;} + + string_type short_name(ratio<1>) const {return short_seconds_;} + string_type short_name(ratio<60>) const {return short_minutes_;} + string_type short_name(ratio<3600>) const {return short_hours_;} + + template <class Period> + string_type long_name(Period) const + {return ::boost::ratio_string<Period, CharT>::long_name() + long_seconds_;} + + string_type long_name(ratio<1>) const {return long_seconds_;} + string_type long_name(ratio<60>) const {return long_minutes_;} + string_type long_name(ratio<3600>) const {return long_hours_;} + + void init_C(); +public: + static std::locale::id id; + + explicit duration_punct(int use = use_long) + : use_short_(use==use_short) {init_C();} + + duration_punct(int use, + const string_type& long_seconds, const string_type& long_minutes, + const string_type& long_hours, const string_type& short_seconds, + const string_type& short_minutes, const string_type& short_hours); + + duration_punct(int use, const duration_punct& d); + + template <class Period> + string_type short_name() const + {return short_name(typename Period::type());} + + template <class Period> + string_type long_name() const + {return long_name(typename Period::type());} + + template <class Period> + string_type plural() const + {return long_name(typename Period::type());} + + template <class Period> + string_type singular() const + { + return string_type(long_name(typename Period::type()), 0, long_name(typename Period::type()).size()-1); + } + + template <class Period> + string_type name() const + { + if (use_short_) return short_name<Period>(); + else { + return long_name<Period>(); + } + } + template <class Period, class D> + string_type name(D v) const + { + if (use_short_) return short_name<Period>(); + else + { + if (v==-1 || v==1) + return singular<Period>(); + else + return plural<Period>(); + } + } + + bool is_short_name() const {return use_short_;} + bool is_long_name() const {return !use_short_;} +}; + +template <class CharT> +std::locale::id +duration_punct<CharT>::id; + +template <class CharT> +void +duration_punct<CharT>::init_C() +{ + short_seconds_ = CharT('s'); + short_minutes_ = CharT('m'); + short_hours_ = CharT('h'); + const CharT s[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'}; + const CharT m[] = {'m', 'i', 'n', 'u', 't', 'e', 's'}; + const CharT h[] = {'h', 'o', 'u', 'r', 's'}; + long_seconds_.assign(s, s + sizeof(s)/sizeof(s[0])); + long_minutes_.assign(m, m + sizeof(m)/sizeof(m[0])); + long_hours_.assign(h, h + sizeof(h)/sizeof(h[0])); +} + +template <class CharT> +duration_punct<CharT>::duration_punct(int use, + const string_type& long_seconds, const string_type& long_minutes, + const string_type& long_hours, const string_type& short_seconds, + const string_type& short_minutes, const string_type& short_hours) + : use_short_(use==use_short), + long_seconds_(long_seconds), + long_minutes_(long_minutes), + long_hours_(long_hours), + short_seconds_(short_seconds), + short_minutes_(short_minutes), + short_hours_(short_hours) +{} + +template <class CharT> +duration_punct<CharT>::duration_punct(int use, const duration_punct& d) + : use_short_(use==use_short), + long_seconds_(d.long_seconds_), + long_minutes_(d.long_minutes_), + long_hours_(d.long_hours_), + short_seconds_(d.short_seconds_), + short_minutes_(d.short_minutes_), + short_hours_(d.short_hours_) +{} + +template <class CharT, class Traits> +std::basic_ostream<CharT, Traits>& +duration_short(std::basic_ostream<CharT, Traits>& os) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (std::has_facet<Facet>(loc)) + { + const Facet& f = std::use_facet<Facet>(loc); + if (f.is_long_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_short, f))); + } + else + os.imbue(std::locale(loc, new Facet(Facet::use_short))); + return os; +} + +template <class CharT, class Traits> +std::basic_ostream<CharT, Traits>& +duration_long(std::basic_ostream<CharT, Traits>& os) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (std::has_facet<Facet>(loc)) + { + const Facet& f = std::use_facet<Facet>(loc); + if (f.is_short_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_long, f))); + } + return os; +} + +template <class CharT, class Traits, class Rep, class Period> +std::basic_ostream<CharT, Traits>& +operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (!std::has_facet<Facet>(loc)) + os.imbue(std::locale(loc, new Facet)); + const Facet& f = std::use_facet<Facet>(os.getloc()); + return os << d.count() << ' ' << f.template name<Period>(d.count()); +} + +namespace chrono_detail { +template <class Rep, bool = is_scalar<Rep>::value> +struct duration_io_intermediate +{ + typedef Rep type; +}; + +template <class Rep> +struct duration_io_intermediate<Rep, true> +{ + typedef typename mpl::if_c + < + is_floating_point<Rep>::value, + long double, + typename mpl::if_c + < + is_signed<Rep>::value, + long long, + unsigned long long + >::type + >::type type; +}; + +template <typename intermediate_type> +typename enable_if<is_integral<intermediate_type>, bool>::type +reduce(intermediate_type& r, unsigned long long& den, std::ios_base::iostate& err) +{ + typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t; + + // Reduce r * num / den + common_type_t t = math::gcd<common_type_t>(common_type_t(r), common_type_t(den)); + r /= t; + den /= t; + if (den != 1) + { + // Conversion to Period is integral and not exact + err |= std::ios_base::failbit; + return false; + } + return true; +} +template <typename intermediate_type> +typename disable_if<is_integral<intermediate_type>, bool>::type +reduce(intermediate_type& , unsigned long long& , std::ios_base::iostate& ) +{ + return true; +} + +} + +template <class CharT, class Traits, class Rep, class Period> +std::basic_istream<CharT, Traits>& +operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d) +{ + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + typedef duration_punct<CharT> Facet; + std::locale loc = is.getloc(); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (!std::has_facet<Facet>(loc)) { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.imbue(std::locale(loc, new Facet)); + } + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + loc = is.getloc(); + const Facet& f = std::use_facet<Facet>(loc); + typedef typename chrono_detail::duration_io_intermediate<Rep>::type intermediate_type; + intermediate_type r; + std::ios_base::iostate err = std::ios_base::goodbit; + // read value into r + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is >> r; + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (is.good()) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // now determine unit + typedef std::istreambuf_iterator<CharT, Traits> in_iterator; + in_iterator i(is); + in_iterator e; + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i != e && *i == ' ') // mandatory ' ' after value + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + ++i; + if (i != e) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // unit is num / den (yet to be determined) + unsigned long long num = 0; + unsigned long long den = 0; + if (*i == '[') + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse [N/D]s or [N/D]seconds format + ++i; + CharT x; + is >> num >> x >> den; + if (!is.good() || (x != '/')) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + i = in_iterator(is); + if (*i != ']') + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + ++i; + const std::basic_string<CharT> units[] = + { + f.template singular<ratio<1> >(), + f.template plural<ratio<1> >(), + f.template short_name<ratio<1> >() + }; + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet<std::ctype<CharT> >(loc), + err); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err); + switch ((k - units) / 3) + { + case 0: + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + break; + default: + is.setstate(err); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse SI name, short or long + const std::basic_string<CharT> units[] = + { + f.template singular<atto>(), + f.template plural<atto>(), + f.template short_name<atto>(), + f.template singular<femto>(), + f.template plural<femto>(), + f.template short_name<femto>(), + f.template singular<pico>(), + f.template plural<pico>(), + f.template short_name<pico>(), + f.template singular<nano>(), + f.template plural<nano>(), + f.template short_name<nano>(), + f.template singular<micro>(), + f.template plural<micro>(), + f.template short_name<micro>(), + f.template singular<milli>(), + f.template plural<milli>(), + f.template short_name<milli>(), + f.template singular<centi>(), + f.template plural<centi>(), + f.template short_name<centi>(), + f.template singular<deci>(), + f.template plural<deci>(), + f.template short_name<deci>(), + f.template singular<deca>(), + f.template plural<deca>(), + f.template short_name<deca>(), + f.template singular<hecto>(), + f.template plural<hecto>(), + f.template short_name<hecto>(), + f.template singular<kilo>(), + f.template plural<kilo>(), + f.template short_name<kilo>(), + f.template singular<mega>(), + f.template plural<mega>(), + f.template short_name<mega>(), + f.template singular<giga>(), + f.template plural<giga>(), + f.template short_name<giga>(), + f.template singular<tera>(), + f.template plural<tera>(), + f.template short_name<tera>(), + f.template singular<peta>(), + f.template plural<peta>(), + f.template short_name<peta>(), + f.template singular<exa>(), + f.template plural<exa>(), + f.template short_name<exa>(), + f.template singular<ratio<1> >(), + f.template plural<ratio<1> >(), + f.template short_name<ratio<1> >(), + f.template singular<ratio<60> >(), + f.template plural<ratio<60> >(), + f.template short_name<ratio<60> >(), + f.template singular<ratio<3600> >(), + f.template plural<ratio<3600> >(), + f.template short_name<ratio<3600> >() + }; + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet<std::ctype<CharT> >(loc), + err); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + switch ((k - units) / 3) + { + case 0: + num = 1ULL; + den = 1000000000000000000ULL; + break; + case 1: + num = 1ULL; + den = 1000000000000000ULL; + break; + case 2: + num = 1ULL; + den = 1000000000000ULL; + break; + case 3: + num = 1ULL; + den = 1000000000ULL; + break; + case 4: + num = 1ULL; + den = 1000000ULL; + break; + case 5: + num = 1ULL; + den = 1000ULL; + break; + case 6: + num = 1ULL; + den = 100ULL; + break; + case 7: + num = 1ULL; + den = 10ULL; + break; + case 8: + num = 10ULL; + den = 1ULL; + break; + case 9: + num = 100ULL; + den = 1ULL; + break; + case 10: + num = 1000ULL; + den = 1ULL; + break; + case 11: + num = 1000000ULL; + den = 1ULL; + break; + case 12: + num = 1000000000ULL; + den = 1ULL; + break; + case 13: + num = 1000000000000ULL; + den = 1ULL; + break; + case 14: + num = 1000000000000000ULL; + den = 1ULL; + break; + case 15: + num = 1000000000000000000ULL; + den = 1ULL; + break; + case 16: + num = 1; + den = 1; + break; + case 17: + num = 60; + den = 1; + break; + case 18: + num = 3600; + den = 1; + break; + default: + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + } + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // unit is num/den + // r should be multiplied by (num/den) / Period + // Reduce (num/den) / Period to lowest terms + unsigned long long gcd_n1_n2 = math::gcd<unsigned long long>(num, Period::num); + unsigned long long gcd_d1_d2 = math::gcd<unsigned long long>(den, Period::den); + num /= gcd_n1_n2; + den /= gcd_d1_d2; + unsigned long long n2 = Period::num / gcd_n1_n2; + unsigned long long d2 = Period::den / gcd_d1_d2; + if (num > (std::numeric_limits<unsigned long long>::max)() / d2 || + den > (std::numeric_limits<unsigned long long>::max)() / n2) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // (num/den) / Period overflows + is.setstate(err|is.failbit); + return is; + } + num *= d2; + den *= n2; + + typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t; + + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // num / den is now factor to multiply by r + if (!chrono_detail::reduce(r, den, err)) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + + //if (r > ((duration_values<common_type_t>::max)() / num)) + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (chrono::detail::gt(r,((duration_values<common_type_t>::max)() / num))) + { + // Conversion to Period overflowed + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + common_type_t t = r * num; + t /= den; + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + + if (t > 0) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + Rep pt = t; + if ( (duration_values<Rep>::max)() < pt) + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Conversion to Period overflowed + is.setstate(err|is.failbit); + return is; + } + } + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Success! Store it. + r = Rep(t); + d = duration<Rep, Period>(r); + is.setstate(err); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + else { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit | is.eofbit); + return is; + } + } + else + { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i == e) + is.setstate(is.failbit|is.eofbit); + else + is.setstate(is.failbit); + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else { + std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + //is.setstate(is.failbit); + return is; + } +} + + +template <class CharT, class Traits, class Clock, class Duration> +std::basic_ostream<CharT, Traits>& +operator<<(std::basic_ostream<CharT, Traits>& os, + const time_point<Clock, Duration>& tp) +{ + return os << tp.time_since_epoch() << clock_string<Clock, CharT>::since(); +} + +template <class CharT, class Traits, class Clock, class Duration> +std::basic_istream<CharT, Traits>& +operator>>(std::basic_istream<CharT, Traits>& is, + time_point<Clock, Duration>& tp) +{ + Duration d; + is >> d; + if (is.good()) + { + const std::basic_string<CharT> units=clock_string<Clock, CharT>::since(); + std::ios_base::iostate err = std::ios_base::goodbit; + typedef std::istreambuf_iterator<CharT, Traits> in_iterator; + in_iterator i(is); + in_iterator e; + std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, + &units, &units + 1, + //~ std::use_facet<std::ctype<CharT> >(is.getloc()), + err) - &units; + is.setstate(err); + if (k == 1) + { + is.setstate(err | is.failbit); + // failed to read epoch string + return is; + } + tp = time_point<Clock, Duration>(d); + } + else + is.setstate(is.failbit); + return is; +} +} // chrono + +} + +#endif // BOOST_CHRONO_CHRONO_IO_HPP diff --git a/boost/chrono/process_cpu_clocks.hpp b/boost/chrono/process_cpu_clocks.hpp new file mode 100644 index 0000000000..12ec2e39bf --- /dev/null +++ b/boost/chrono/process_cpu_clocks.hpp @@ -0,0 +1,514 @@ +// boost/chrono/process_cpu_clocks.hpp -----------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +#ifndef BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP +#define BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP + +#include <boost/chrono/config.hpp> + + +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + +#include <boost/chrono/duration.hpp> +#include <boost/chrono/time_point.hpp> +#include <boost/operators.hpp> +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +#include <boost/system/error_code.hpp> +#include <boost/chrono/detail/system.hpp> +#endif +#include <iostream> +#include <boost/type_traits/common_type.hpp> +#include <boost/chrono/clock_string.hpp> + + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_prefix.hpp> // must be the last #include +#endif + +namespace boost { namespace chrono { + + class BOOST_CHRONO_DECL process_real_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<process_real_cpu_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + + class BOOST_CHRONO_DECL process_user_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<process_user_cpu_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + + class BOOST_CHRONO_DECL process_system_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<process_system_cpu_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + + template <typename Rep> + struct process_times + : arithmetic<process_times<Rep>, + multiplicative<process_times<Rep>, Rep, + less_than_comparable<process_times<Rep> > > > + { + //typedef process_real_cpu_clock::rep rep; + typedef Rep rep; + process_times() + : real(0) + , user(0) + , system(0){} + template <typename Rep2> + explicit process_times( + Rep2 r) + : real(r) + , user(r) + , system(r){} + template <typename Rep2> + explicit process_times( + process_times<Rep2> const& rhs) + : real(rhs.real) + , user(rhs.user) + , system(rhs.system){} + process_times( + rep r, + rep u, + rep s) + : real(r) + , user(u) + , system(s){} + + rep real; // real (i.e wall clock) time + rep user; // user cpu time + rep system; // system cpu time + + operator rep() const + { + return real; + } + template <typename Rep2> + bool operator==(process_times<Rep2> const& rhs) { + return (real==rhs.real && + user==rhs.user && + system==rhs.system); + } + + process_times& operator+=( + process_times const& rhs) + { + real+=rhs.real; + user+=rhs.user; + system+=rhs.system; + return *this; + } + process_times& operator-=( + process_times const& rhs) + { + real-=rhs.real; + user-=rhs.user; + system-=rhs.system; + return *this; + } + process_times& operator*=( + process_times const& rhs) + { + real*=rhs.real; + user*=rhs.user; + system*=rhs.system; + return *this; + } + process_times& operator*=(rep const& rhs) + { + real*=rhs; + user*=rhs; + system*=rhs; + return *this; + } + process_times& operator/=(process_times const& rhs) + { + real/=rhs.real; + user/=rhs.user; + system/=rhs.system; + return *this; + } + process_times& operator/=(rep const& rhs) + { + real/=rhs; + user/=rhs; + system/=rhs; + return *this; + } + bool operator<(process_times const & rhs) const + { + if (real < rhs.real) return true; + if (real > rhs.real) return false; + if (user < rhs.user) return true; + if (user > rhs.user) return false; + if (system < rhs.system) return true; + else return false; + } + + template <class CharT, class Traits> + void print(std::basic_ostream<CharT, Traits>& os) const + { + os << "{"<< real <<";"<< user <<";"<< system << "}"; + } + + template <class CharT, class Traits> + void read(std::basic_istream<CharT, Traits>& is) const + { + typedef std::istreambuf_iterator<CharT, Traits> in_iterator; + in_iterator i(is); + in_iterator e; + if (i == e || *i != '{') // mandatory '{' + { + is.setstate(is.failbit | is.eofbit); + return; + } + CharT x,y,z; + is >> real >> x >> user >> y >> system >> z; + if (!is.good() || (x != ';')|| (y != ';')|| (z != '}')) + { + is.setstate(is.failbit); + } + } + }; +} +template <class Rep1, class Rep2> +struct common_type< + chrono::process_times<Rep1>, + chrono::process_times<Rep2> +> +{ + typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type; +}; + +template <class Rep1, class Rep2> +struct common_type< + chrono::process_times<Rep1>, + Rep2 +> +{ + typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type; +}; + +template <class Rep1, class Rep2> +struct common_type< + Rep1, + chrono::process_times<Rep2> +> +{ + typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type; +}; + + +namespace chrono +{ + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator==(const duration<process_times<Rep1>, Period1>& lhs, + const duration<process_times<Rep2>, Period2>& rhs) + { + return boost::chrono::detail::duration_eq< + duration<process_times<Rep1>, Period1>, duration<process_times<Rep2>, Period2> >()(lhs, rhs); + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator==(const duration<process_times<Rep1>, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return boost::chrono::detail::duration_eq< + duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs); + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator==(const duration<Rep1, Period1>& lhs, + const duration<process_times<Rep2>, Period2>& rhs) + { + return rhs == lhs; + } + + + // Duration < + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator< (const duration<process_times<Rep1>, Period1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return boost::chrono::detail::duration_lt< + duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs); + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator< (const duration<Rep1, Period1>& lhs, + const duration<process_times<Rep2>, Period2>& rhs) + { + return rhs < lhs; + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + bool + operator< (const duration<process_times<Rep1>, Period1>& lhs, + const duration<process_times<Rep2>, Period2>& rhs) + { + return boost::chrono::detail::duration_lt< + duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); + } + + + typedef process_times<nanoseconds::rep> process_cpu_clock_times; + class BOOST_CHRONO_DECL process_cpu_clock + { + public: + + typedef process_cpu_clock_times times; + typedef boost::chrono::duration<times, nano> duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<process_cpu_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + + template <class CharT, class Traits, typename Rep> + std::basic_ostream<CharT, Traits>& + operator<<(std::basic_ostream<CharT, Traits>& os, + process_times<Rep> const& rhs) + { + rhs.print(os); + return os; + } + + template <class CharT, class Traits, typename Rep> + std::basic_istream<CharT, Traits>& + operator>>(std::basic_istream<CharT, Traits>& is, + process_times<Rep> const& rhs) + { + rhs.read(is); + return is; + } + + template <typename Rep> + struct duration_values<process_times<Rep> > + { + typedef process_times<Rep> Res; + public: + static Res zero() + { + return Res(); + } + static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits<Rep>::max)(), + (std::numeric_limits<Rep>::max)(), + (std::numeric_limits<Rep>::max)()); + } + static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits<Rep>::min)(), + (std::numeric_limits<Rep>::min)(), + (std::numeric_limits<Rep>::min)()); + } + }; + + template<class CharT> + struct clock_string<process_real_cpu_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'r', 'e', 'a', 'l', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + + template<class CharT> + struct clock_string<process_user_cpu_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'u', 's', 'e', 'r', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + + template<class CharT> + struct clock_string<process_system_cpu_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 's', 'y', 's', 't', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + + template<class CharT> + struct clock_string<process_cpu_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + +} // namespace chrono +} // namespace boost + +namespace std { + + template <typename Rep> + struct numeric_limits<boost::chrono::process_times<Rep> > + { + typedef boost::chrono::process_times<Rep> Res; + + public: + static const bool is_specialized = true; + static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits<Rep>::min)(), + (std::numeric_limits<Rep>::min)(), + (std::numeric_limits<Rep>::min)()); + } + static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits<Rep>::max)(), + (std::numeric_limits<Rep>::max)(), + (std::numeric_limits<Rep>::max)()); + } + static Res lowest() throw() + { + return (min)(); + } + static const int digits = std::numeric_limits<Rep>::digits+ + std::numeric_limits<Rep>::digits+ + std::numeric_limits<Rep>::digits; + static const int digits10 = std::numeric_limits<Rep>::digits10+ + std::numeric_limits<Rep>::digits10+ + std::numeric_limits<Rep>::digits10; + static const bool is_signed = Rep::is_signed; + static const bool is_integer = Rep::is_integer; + static const bool is_exact = Rep::is_exact; + static const int radix = 0; + //~ static Res epsilon() throw() { return 0; } + //~ static Res round_error() throw() { return 0; } + //~ static const int min_exponent = 0; + //~ static const int min_exponent10 = 0; + //~ static const int max_exponent = 0; + //~ static const int max_exponent10 = 0; + //~ static const bool has_infinity = false; + //~ static const bool has_quiet_NaN = false; + //~ static const bool has_signaling_NaN = false; + //~ static const float_denorm_style has_denorm = denorm_absent; + //~ static const bool has_denorm_loss = false; + //~ static Res infinity() throw() { return 0; } + //~ static Res quiet_NaN() throw() { return 0; } + //~ static Res signaling_NaN() throw() { return 0; } + //~ static Res denorm_min() throw() { return 0; } + //~ static const bool is_iec559 = false; + //~ static const bool is_bounded = true; + //~ static const bool is_modulo = false; + //~ static const bool traps = false; + //~ static const bool tinyness_before = false; + //~ static const float_round_style round_style = round_toward_zero; + + }; +} + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#else +#include <boost/chrono/detail/inlined/process_cpu_clocks.hpp> +#endif +#endif + +#endif // BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP diff --git a/boost/chrono/round.hpp b/boost/chrono/round.hpp new file mode 100644 index 0000000000..3d0619e681 --- /dev/null +++ b/boost/chrono/round.hpp @@ -0,0 +1,55 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_CHRONO_ROUND_HPP +#define BOOST_CHRONO_ROUND_HPP + +#include <boost/chrono/duration.hpp> +#include <boost/chrono/duration.hpp> +//#include <boost/chrono/typeof/boost/chrono/chrono.hpp> + +namespace boost +{ + namespace chrono + { + + /** + * rounds to nearest, to even on tie + */ + template <class To, class Rep, class Period> + To round(const duration<Rep, Period>& d) + { + To t0 = duration_cast<To>(d); + To t1 = t0; + ++t1; +#if 0 + // Avoid the user of BOOST_AUTO to make the library portable to Sun, PGI, .. + BOOST_AUTO(diff0, d - t0); + BOOST_AUTO(diff1, t1 - d); +#else + typedef typename common_type<To, duration<Rep, Period> >::type result_type; + result_type diff0 = d - t0; + result_type diff1 = t1 - d; +#endif + if (diff0 == diff1) + { + if (t0.count() & 1) + return t1; + return t0; + } + else if (diff0 < diff1) + return t0; + return t1; + } + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/system_clocks.hpp b/boost/chrono/system_clocks.hpp new file mode 100644 index 0000000000..bb62610c72 --- /dev/null +++ b/boost/chrono/system_clocks.hpp @@ -0,0 +1,229 @@ +// boost/chrono/system_clocks.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + +/* + +TODO: + + * Fully implement error handling, with test cases. + * Use boost::throw_exception. (Currently not used because of an issue with Intel 11.0.) + * Consider issues raised by Michael Marcin: + + > In the past I've seen QueryPerformanceCounter give incorrect results, + > especially with SpeedStep processors on laptops. This was many years ago and + > might have been fixed by service packs and drivers. + > + > Typically you check the results of QPC against GetTickCount to see if the + > results are reasonable. + > http://support.microsoft.com/kb/274323 + > + > I've also heard of problems with QueryPerformanceCounter in multi-processor + > systems. + > + > I know some people SetThreadAffinityMask to 1 for the current thread call + > their QueryPerformance* functions then restore SetThreadAffinityMask. This + > seems horrible to me because it forces your program to jump to another + > physical processor if it isn't already on cpu0 but they claim it worked well + > in practice because they called the timing functions infrequently. + > + > In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for + > high resolution timers to avoid these issues. + +*/ + +#ifndef BOOST_CHRONO_SYSTEM_CLOCKS_HPP +#define BOOST_CHRONO_SYSTEM_CLOCKS_HPP + +#include <boost/chrono/config.hpp> +#include <boost/chrono/duration.hpp> +#include <boost/chrono/time_point.hpp> +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +#include <boost/chrono/detail/system.hpp> +#include <boost/system/error_code.hpp> +#endif +#include <boost/chrono/clock_string.hpp> + +#include <ctime> + +#ifdef BOOST_CHRONO_WINDOWS_API +// The system_clock tick is 100 nanoseconds +# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::duration<boost::int_least64_t, ratio<BOOST_RATIO_INTMAX_C(1), BOOST_RATIO_INTMAX_C(10000000)> > +#else +# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::nanoseconds +#endif + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_prefix.hpp> // must be the last #include +#endif + + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + // Clocks + class BOOST_CHRONO_DECL system_clock; +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + class BOOST_CHRONO_DECL steady_clock; +#endif + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + typedef steady_clock high_resolution_clock; // as permitted by [time.clock.hires] +#else + typedef system_clock high_resolution_clock; // as permitted by [time.clock.hires] +#endif + +//----------------------------------------------------------------------------// +// // +// 20.9.5 Clocks [time.clock] // +// // +//----------------------------------------------------------------------------// + +// If you're porting, clocks are the system-specific (non-portable) part. +// You'll need to know how to get the current time and implement that under now(). +// You'll need to know what units (tick period) and representation makes the most +// sense for your clock and set those accordingly. +// If you know how to map this clock to time_t (perhaps your clock is std::time, which +// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t(). + +//----------------------------------------------------------------------------// +// 20.9.5.1 Class system_clock [time.clock.system] // +//----------------------------------------------------------------------------// + + class BOOST_CHRONO_DECL system_clock + { + public: + typedef BOOST_SYSTEM_CLOCK_DURATION duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<system_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = false; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); +#endif + + static BOOST_CHRONO_INLINE std::time_t to_time_t(const time_point& t) BOOST_NOEXCEPT; + static BOOST_CHRONO_INLINE time_point from_time_t(std::time_t t) BOOST_NOEXCEPT; + }; + +//----------------------------------------------------------------------------// +// 20.9.5.2 Class steady_clock [time.clock.steady] // +//----------------------------------------------------------------------------// + +// As permitted by [time.clock.steady] +// The class steady_clock is conditionally supported. + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + class BOOST_CHRONO_DECL steady_clock + { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<steady_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); +#endif + }; +#endif +//----------------------------------------------------------------------------// +// 20.9.5.3 Class high_resolution_clock [time.clock.hires] // +//----------------------------------------------------------------------------// + +// As permitted, steady_clock or system_clock is a typedef for high_resolution_clock. +// See synopsis. + + + template<class CharT> + struct clock_string<system_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT u[] = + { 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + static const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'J', 'a', 'n', ' ', '1', ',', ' ', '1', '9', '7', '0' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + }; + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + + template<class CharT> + struct clock_string<steady_clock, CharT> + { + static std::basic_string<CharT> name() + { + static const CharT + u[] = + { 's', 't', 'e', 'a', 'd', 'y', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string<CharT> str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't' }; + const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + +#endif + +} // namespace chrono +} // namespace boost + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#else +#include <boost/chrono/detail/inlined/chrono.hpp> +#endif + +#endif // BOOST_CHRONO_SYSTEM_CLOCKS_HPP diff --git a/boost/chrono/thread_clock.hpp b/boost/chrono/thread_clock.hpp new file mode 100644 index 0000000000..7022c61dc1 --- /dev/null +++ b/boost/chrono/thread_clock.hpp @@ -0,0 +1,78 @@ +// boost/chrono/thread_clock.hpp -----------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +#include <boost/chrono/config.hpp> + +#ifndef BOOST_CHRONO_THREAD_CLOCK_HPP +#define BOOST_CHRONO_THREAD_CLOCK_HPP + +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) + +#include <boost/chrono/config.hpp> +#include <boost/chrono/duration.hpp> +#include <boost/chrono/time_point.hpp> +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +#include <boost/system/error_code.hpp> +#include <boost/chrono/detail/system.hpp> +#endif +#include <boost/chrono/clock_string.hpp> + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_prefix.hpp> // must be the last #include +#endif + +namespace boost { namespace chrono { + +class BOOST_CHRONO_DECL thread_clock { +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<thread_clock> time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = BOOST_CHRONO_THREAD_CLOCK_IS_STEADY; + + static BOOST_CHRONO_INLINE time_point now( ) BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now( system::error_code & ec ); +#endif +}; + +template <class CharT> +struct clock_string<thread_clock, CharT> +{ + static std::basic_string<CharT> name() + { + static const CharT u[] = + { 't', 'h', 'r', 'e', 'd', '_', + 'c', 'l','o', 'c', 'k'}; + static const std::basic_string<CharT> str(u, u + sizeof(u)/sizeof(u[0])); + return str; + } + static std::basic_string<CharT> since() + { + const CharT u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 't', 'r', 'e', 'a', 'd', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p'}; + const std::basic_string<CharT> str(u, u + sizeof(u)/sizeof(u[0])); + return str; + } +}; + +} // namespace chrono +} // namespace boost + + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#else +#include <boost/chrono/detail/inlined/thread_clock.hpp> +#endif + +#endif + +#endif // BOOST_CHRONO_THREAD_CLOCK_HPP diff --git a/boost/chrono/time_point.hpp b/boost/chrono/time_point.hpp new file mode 100644 index 0000000000..bef49cb405 --- /dev/null +++ b/boost/chrono/time_point.hpp @@ -0,0 +1,371 @@ +// duration.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + + +#ifndef BOOST_CHRONO_TIME_POINT_HPP +#define BOOST_CHRONO_TIME_POINT_HPP + +#include <boost/chrono/duration.hpp> +#include <iostream> +#include <boost/chrono/detail/system.hpp> + + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + template <class Clock, class Duration = typename Clock::duration> + class time_point; + + +} // namespace chrono + + +// common_type trait specializations + +template <class Clock, class Duration1, class Duration2> + struct common_type<chrono::time_point<Clock, Duration1>, + chrono::time_point<Clock, Duration2> >; + + +//----------------------------------------------------------------------------// +// 20.9.2.3 Specializations of common_type [time.traits.specializations] // +//----------------------------------------------------------------------------// + + +template <class Clock, class Duration1, class Duration2> +struct common_type<chrono::time_point<Clock, Duration1>, + chrono::time_point<Clock, Duration2> > +{ + typedef chrono::time_point<Clock, + typename common_type<Duration1, Duration2>::type> type; +}; + + + +namespace chrono { + + // time_point arithmetic + template <class Clock, class Duration1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<Duration1, duration<Rep2, Period2> >::type> + operator+( + const time_point<Clock, Duration1>& lhs, + const duration<Rep2, Period2>& rhs); + template <class Rep1, class Period1, class Clock, class Duration2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<duration<Rep1, Period1>, Duration2>::type> + operator+( + const duration<Rep1, Period1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<Duration1, duration<Rep2, Period2> >::type> + operator-( + const time_point<Clock, Duration1>& lhs, + const duration<Rep2, Period2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + typename common_type<Duration1, Duration2>::type + operator-( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, + Duration2>& rhs); + + // time_point comparisons + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator==( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator!=( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator< ( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator<=( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator> ( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool operator>=( + const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs); + + // time_point_cast + template <class ToDuration, class Clock, class Duration> + inline BOOST_CONSTEXPR + time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t); + +//----------------------------------------------------------------------------// +// // +// 20.9.4 Class template time_point [time.point] // +// // +//----------------------------------------------------------------------------// + + template <class Clock, class Duration> + class time_point + { + BOOST_CHRONO_STATIC_ASSERT(boost::chrono::detail::is_duration<Duration>::value, + BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION, (Duration)); + public: + typedef Clock clock; + typedef Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; + typedef Duration difference_type; + + private: + duration d_; + + public: + BOOST_CONSTEXPR + time_point() : d_(duration::zero()) + {} + BOOST_CONSTEXPR explicit time_point(const duration& d) + : d_(d) + {} + + // conversions + template <class Duration2> + BOOST_CONSTEXPR + time_point(const time_point<clock, Duration2>& t + , typename boost::enable_if + < + boost::is_convertible<Duration2, duration> + >::type* = 0 + ) + : d_(t.time_since_epoch()) + { + } + // observer + + BOOST_CONSTEXPR + duration time_since_epoch() const + { + return d_; + } + + // arithmetic + +#ifdef BOOST_CHRONO_EXTENSIONS + BOOST_CONSTEXPR + time_point operator+() const {return *this;} + BOOST_CONSTEXPR + time_point operator-() const {return time_point(-d_);} + time_point& operator++() {++d_; return *this;} + time_point operator++(int) {return time_point(d_++);} + time_point& operator--() {--d_; return *this;} + time_point operator--(int) {return time_point(d_--);} + + time_point& operator+=(const rep& r) {d_ += duration(r); return *this;} + time_point& operator-=(const rep& r) {d_ -= duration(r); return *this;} + +#endif + + time_point& operator+=(const duration& d) {d_ += d; return *this;} + time_point& operator-=(const duration& d) {d_ -= d; return *this;} + + // special values + + static BOOST_CONSTEXPR time_point + min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return time_point((duration::min)()); + } + static BOOST_CONSTEXPR time_point + max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return time_point((duration::max)()); + } + }; + +//----------------------------------------------------------------------------// +// 20.9.4.5 time_point non-member arithmetic [time.point.nonmember] // +//----------------------------------------------------------------------------// + + // time_point operator+(time_point x, duration y); + + template <class Clock, class Duration1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<Duration1, duration<Rep2, Period2> >::type> + operator+(const time_point<Clock, Duration1>& lhs, + const duration<Rep2, Period2>& rhs) + { + typedef typename common_type<Duration1, duration<Rep2, Period2> >::type CDuration; + typedef time_point< + Clock, + CDuration + > TimeResult; + return TimeResult(lhs.time_since_epoch() + CDuration(rhs)); + } + + // time_point operator+(duration x, time_point y); + + template <class Rep1, class Period1, class Clock, class Duration2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<duration<Rep1, Period1>, Duration2>::type> + operator+(const duration<Rep1, Period1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return rhs + lhs; + } + + // time_point operator-(time_point x, duration y); + + template <class Clock, class Duration1, class Rep2, class Period2> + inline BOOST_CONSTEXPR + time_point<Clock, + typename common_type<Duration1, duration<Rep2, Period2> >::type> + operator-(const time_point<Clock, Duration1>& lhs, + const duration<Rep2, Period2>& rhs) + { + return lhs + (-rhs); + } + + // duration operator-(time_point x, time_point y); + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + typename common_type<Duration1, Duration2>::type + operator-(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return lhs.time_since_epoch() - rhs.time_since_epoch(); + } + +//----------------------------------------------------------------------------// +// 20.9.4.6 time_point comparisons [time.point.comparisons] // +//----------------------------------------------------------------------------// + + // time_point == + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator==(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return lhs.time_since_epoch() == rhs.time_since_epoch(); + } + + // time_point != + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator!=(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return !(lhs == rhs); + } + + // time_point < + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator<(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return lhs.time_since_epoch() < rhs.time_since_epoch(); + } + + // time_point > + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator>(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return rhs < lhs; + } + + // time_point <= + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator<=(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return !(rhs < lhs); + } + + // time_point >= + + template <class Clock, class Duration1, class Duration2> + inline BOOST_CONSTEXPR + bool + operator>=(const time_point<Clock, Duration1>& lhs, + const time_point<Clock, Duration2>& rhs) + { + return !(lhs < rhs); + } + +//----------------------------------------------------------------------------// +// 20.9.4.7 time_point_cast [time.point.cast] // +//----------------------------------------------------------------------------// + + template <class ToDuration, class Clock, class Duration> + inline BOOST_CONSTEXPR + time_point<Clock, ToDuration> + time_point_cast(const time_point<Clock, Duration>& t) + { + return time_point<Clock, ToDuration>( + duration_cast<ToDuration>(t.time_since_epoch())); + } + +} // namespace chrono +} // namespace boost + +#endif // BOOST_CHRONO_TIME_POINT_HPP diff --git a/boost/chrono/typeof/boost/chrono/chrono.hpp b/boost/chrono/typeof/boost/chrono/chrono.hpp new file mode 100644 index 0000000000..88dad54ed0 --- /dev/null +++ b/boost/chrono/typeof/boost/chrono/chrono.hpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Vicente J. Botet Escriba 20010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Based on the unique_threader/unique_joiner design from of Kevlin Henney (n1883) +// +// See http://www.boost.org/libs/chrono for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CHRONO_TYPEOF_CHRONO_HPP +#define BOOST_CHRONO_TYPEOF_CHRONO_HPP + +#include <boost/chrono/chrono.hpp> +#define BOOST_TYPEOF_SILENT +#include <boost/typeof/typeof.hpp> + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::chrono::duration, (typename)(typename)) +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::chrono::time_point, (typename)(typename)) +#if 0 +BOOST_TYPEOF_REGISTER_TYPE(boost::chrono::system_clock) +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY +BOOST_TYPEOF_REGISTER_TYPE(boost::chrono::steady_clock) +#endif +BOOST_TYPEOF_REGISTER_TYPE(boost::chrono::high_resolution_clock) + +#endif +#endif diff --git a/boost/chrono/typeof/boost/ratio.hpp b/boost/chrono/typeof/boost/ratio.hpp new file mode 100644 index 0000000000..4438a4f9dc --- /dev/null +++ b/boost/chrono/typeof/boost/ratio.hpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Vicente J. Botet Escriba 20010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Based on the unique_threader/unique_joiner design from of Kevlin Henney (n1883) +// +// See http://www.boost.org/libs/chrono for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CHRONO_TYPEOF_RATIO_HPP +#define BOOST_CHRONO_TYPEOF_RATIO_HPP + +#include <boost/ratio/ratio.hpp> +#define BOOST_TYPEOF_SILENT + +#include <boost/typeof/typeof.hpp> + +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::ratio, (boost::intmax_t)(boost::intmax_t)) + +#endif |