first commit
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
// 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>
|
||||
|
||||
//#if BOOST_CHRONO_VERSION == 2
|
||||
//#include <boost/chrono/io/time_point_io.hpp>
|
||||
//#include <boost/chrono/io/duration_io.hpp>
|
||||
//#elif BOOST_CHRONO_VERSION == 1
|
||||
//#include <boost/chrono/io_v1/chrono_io.hpp>
|
||||
//#endif
|
||||
|
||||
#if defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
|
||||
#include <boost/chrono/io/time_point_io.hpp>
|
||||
#include <boost/chrono/io/duration_io.hpp>
|
||||
#else
|
||||
#include <boost/chrono/io_v1/chrono_io.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/chrono/io/utility/to_string.hpp>
|
||||
|
||||
#endif // BOOST_CHRONO_CHRONO_IO_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
|
||||
@@ -0,0 +1,218 @@
|
||||
// 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_VERSION
|
||||
#define BOOST_CHRONO_VERSION 1
|
||||
#else
|
||||
#if BOOST_CHRONO_VERSION!=1 && BOOST_CHRONO_VERSION!=2
|
||||
#error "BOOST_CHRONO_VERSION must be 1 or 2"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_USE_WINDOWS_H)
|
||||
#define BOOST_USE_WINDOWS_H
|
||||
#endif
|
||||
|
||||
#if ! defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT \
|
||||
&& ! defined BOOST_CHRONO_DONT_PROVIDE_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
|
||||
|
||||
# define BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
|
||||
|
||||
#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_MONOTONIC)
|
||||
# define BOOST_CHRONO_HAS_CLOCK_STEADY
|
||||
# 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
|
||||
# if defined(__HP_aCC) && defined(__hpux)
|
||||
# undef BOOST_CHRONO_HAS_THREAD_CLOCK
|
||||
# undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY
|
||||
# endif
|
||||
# if defined(__VXWORKS__)
|
||||
# undef BOOST_CHRONO_HAS_PROCESS_CLOCKS
|
||||
# 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
|
||||
|
||||
//#undef BOOST_CHRONO_HAS_PROCESS_CLOCKS
|
||||
|
||||
// unicode support ------------------------------//
|
||||
|
||||
#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) || defined(BOOST_NO_CXX11_CHAR16_T) || defined(BOOST_NO_CXX11_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_CXX11_NOEXCEPT)
|
||||
#define BOOST_NOEXCEPT
|
||||
#else
|
||||
#define BOOST_NOEXCEPT noexcept
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_NO_CXX11_NUMERIC_LIMITS )
|
||||
#define BOOST_CHRONO_LIB_CONSTEXPR
|
||||
#else
|
||||
#define BOOST_CHRONO_LIB_CONSTEXPR BOOST_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_NO_CXX11_NUMERIC_LIMITS )
|
||||
# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW throw()
|
||||
#else
|
||||
#ifdef BOOST_NO_CXX11_NOEXCEPT
|
||||
# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW throw()
|
||||
#else
|
||||
# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW noexcept
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING \
|
||||
&& defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
|
||||
#error "BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING && BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING defined"
|
||||
#endif
|
||||
|
||||
#if defined BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 \
|
||||
&& defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
|
||||
#error "BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 && BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 defined"
|
||||
#endif
|
||||
|
||||
#if ! defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING \
|
||||
&& ! defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
|
||||
#define BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING
|
||||
#endif
|
||||
|
||||
#if (BOOST_CHRONO_VERSION == 2)
|
||||
#if ! defined BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 \
|
||||
&& ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
|
||||
#define BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
|
||||
#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
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
// 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 <= 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
|
||||
{
|
||||
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(
|
||||
nanoseconds(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(
|
||||
nanoseconds(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(
|
||||
nanoseconds((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(
|
||||
nanoseconds((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(
|
||||
nanoseconds((tm.tms_stime + tm.tms_cstime)*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_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(
|
||||
nanoseconds((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
|
||||
|
||||
} }
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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 <pthread.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
|
||||
} }
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,152 @@
|
||||
// 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();
|
||||
}
|
||||
|
||||
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)
|
||||
-116444736000000000LL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#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();
|
||||
|
||||
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;
|
||||
|
||||
return time_point(duration(temp));
|
||||
}
|
||||
|
||||
} // namespace chrono
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,276 @@
|
||||
// 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");
|
||||
}
|
||||
typedef ratio_divide<giga, ratio<CLOCKS_PER_SEC> >::type R;
|
||||
return time_point(
|
||||
duration(static_cast<rep>(c)*R::num/R::den)
|
||||
);
|
||||
}
|
||||
|
||||
#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();
|
||||
}
|
||||
typedef ratio_divide<giga, ratio<CLOCKS_PER_SEC> >::type R;
|
||||
return time_point(
|
||||
duration(static_cast<rep>(c)*R::num/R::den)
|
||||
);
|
||||
}
|
||||
#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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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
|
||||
#elif defined __SUNPRO_CC
|
||||
#pragma disable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#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
|
||||
|
||||
#if defined __SUNPRO_CC
|
||||
#pragma enable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP
|
||||
@@ -0,0 +1,163 @@
|
||||
// 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>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
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_exception(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
|
||||
@@ -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_CXX11_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
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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
|
||||
|
||||
#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
|
||||
|
||||
#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
|
||||
#endif
|
||||
@@ -0,0 +1,794 @@
|
||||
// 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_CXX11_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
|
||||
|
||||
#ifndef BOOST_CHRONO_HEADER_ONLY
|
||||
// this must occur after all of the includes and before any code appears:
|
||||
#include <boost/config/abi_prefix.hpp> // must be the last #include
|
||||
#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 BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct chrono_numeric_limits<T,true> {
|
||||
static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chrono_numeric_limits<float,true> {
|
||||
static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
|
||||
{
|
||||
return -(std::numeric_limits<float>::max) ();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chrono_numeric_limits<double,true> {
|
||||
static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
|
||||
{
|
||||
return -(std::numeric_limits<double>::max) ();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chrono_numeric_limits<long double,true> {
|
||||
static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_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_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
return (std::numeric_limits<Rep>::max)();
|
||||
}
|
||||
|
||||
static BOOST_CHRONO_LIB_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 BOOST_SYMBOL_VISIBLE 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_SYMBOL_VISIBLE inline 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 duration(rep_);;}
|
||||
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_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
return duration((duration_values<rep>::min)());
|
||||
}
|
||||
static BOOST_CHRONO_LIB_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
|
||||
{
|
||||
BOOST_CONSTEXPR 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>
|
||||
{
|
||||
BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
|
||||
{
|
||||
return lhs.count() == rhs.count();
|
||||
}
|
||||
};
|
||||
|
||||
template <class LhsDuration, class RhsDuration>
|
||||
struct duration_lt
|
||||
{
|
||||
BOOST_CONSTEXPR 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>
|
||||
{
|
||||
BOOST_CONSTEXPR 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 BOOST_CONSTEXPR
|
||||
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
|
||||
|
||||
#ifndef BOOST_CHRONO_HEADER_ONLY
|
||||
// the suffix header occurs after all of our code:
|
||||
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CHRONO_DURATION_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
|
||||
@@ -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
|
||||
@@ -0,0 +1,542 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_DURATION_GET_HPP
|
||||
#define BOOST_CHRONO_IO_DURATION_GET_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <string>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/utility/enable_if.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/chrono/detail/no_warning/signed_unsigned_cmp.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <locale>
|
||||
|
||||
/**
|
||||
* Duration formatting facet for input.
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
namespace 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @c duration_get is used to parse a character sequence, extracting
|
||||
* components of a duration into a class duration.
|
||||
* Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
|
||||
* If the sequence being parsed matches the correct format, the
|
||||
* corresponding member of the class duration argument are set to the
|
||||
* value used to produce the sequence;
|
||||
* otherwise either an error is reported or unspecified values are assigned.
|
||||
* In other words, user confirmation is required for reliable parsing of
|
||||
* user-entered durations, but machine-generated formats can be parsed
|
||||
* reliably. This allows parsers to be aggressive about interpreting user
|
||||
* variations on standard formats.
|
||||
*
|
||||
* If the end iterator is reached during parsing of the get() member
|
||||
* function, the member sets std::ios_base::eofbit in err.
|
||||
*/
|
||||
template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
|
||||
class duration_get: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string passed to member functions.
|
||||
*/
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
/**
|
||||
* Type of iterator used to scan the character buffer.
|
||||
*/
|
||||
typedef InputIterator iter_type;
|
||||
|
||||
/**
|
||||
* Construct a @c duration_get facet.
|
||||
* @param refs
|
||||
* @Effects Construct a @c duration_get facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
|
||||
explicit duration_get(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s start input stream iterator
|
||||
* @param end end input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param err the ios_base state
|
||||
* @param d the duration
|
||||
* @param pattern begin of the formatting pattern
|
||||
* @param pat_end end of the formatting pattern
|
||||
*
|
||||
* Requires: [pattern,pat_end) shall be a valid range.
|
||||
*
|
||||
* Effects: The function starts by evaluating err = std::ios_base::goodbit.
|
||||
* It then enters a loop, reading zero or more characters from s at
|
||||
* each iteration. Unless otherwise specified below, the loop
|
||||
* terminates when the first of the following conditions holds:
|
||||
* - The expression pattern == pat_end evaluates to true.
|
||||
* - The expression err == std::ios_base::goodbit evaluates to false.
|
||||
* - The expression s == end evaluates to true, in which case the
|
||||
* function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
|
||||
* - The next element of pattern is equal to '%', followed by a conversion
|
||||
* specifier character, format.
|
||||
* If the number of elements in the range [pattern,pat_end) is not
|
||||
* sufficient to unambiguously determine whether the conversion
|
||||
* specification is complete and valid, the function evaluates
|
||||
* err = std::ios_base::failbit. Otherwise, the function evaluates
|
||||
* s = get_value(s, end, ios, err, r) when the conversion specification is 'v' and
|
||||
* s = get_value(s, end, ios, err, rt) when the conversion specification is 'u'.
|
||||
* If err == std::ios_base::goodbit holds after
|
||||
* the evaluation of the expression, the function increments pattern to
|
||||
* point just past the end of the conversion specification and continues
|
||||
* looping.
|
||||
* - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
|
||||
* which case the function first increments pattern until
|
||||
* pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
|
||||
* then advances s until s == end || !isspace(*s, ios.getloc()) is true,
|
||||
* and finally resumes looping.
|
||||
* - The next character read from s matches the element pointed to by
|
||||
* pattern in a case-insensitive comparison, in which case the function
|
||||
* evaluates ++pattern, ++s and continues looping. Otherwise, the function
|
||||
* evaluates err = std::ios_base::failbit.
|
||||
*
|
||||
* Once r and rt are retrieved,
|
||||
* Returns: s
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
|
||||
duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
|
||||
return get(facet, s, end, ios, err, d, pattern, pat_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
return get(facet, s, end, ios, err, d, pattern, pat_end);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
iter_type get(duration_units<CharT> const&facet, iter_type s, iter_type end, std::ios_base& ios,
|
||||
std::ios_base::iostate& err, duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
|
||||
{
|
||||
|
||||
typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
|
||||
intermediate_type r;
|
||||
rt_ratio rt;
|
||||
bool value_found = false, unit_found = false;
|
||||
|
||||
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
|
||||
while (pattern != pat_end && err == std::ios_base::goodbit)
|
||||
{
|
||||
if (s == end)
|
||||
{
|
||||
err |= std::ios_base::eofbit;
|
||||
break;
|
||||
}
|
||||
if (ct.narrow(*pattern, 0) == '%')
|
||||
{
|
||||
if (++pattern == pat_end)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
char cmd = ct.narrow(*pattern, 0);
|
||||
switch (cmd)
|
||||
{
|
||||
case 'v':
|
||||
{
|
||||
if (value_found)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
value_found = true;
|
||||
s = get_value(s, end, ios, err, r);
|
||||
if (err & (std::ios_base::badbit | std::ios_base::failbit))
|
||||
{
|
||||
return s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
if (unit_found)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
unit_found = true;
|
||||
s = get_unit(facet, s, end, ios, err, rt);
|
||||
if (err & (std::ios_base::badbit | std::ios_base::failbit))
|
||||
{
|
||||
return s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_ASSERT(false && "Boost::Chrono internal error.");
|
||||
break;
|
||||
}
|
||||
|
||||
++pattern;
|
||||
}
|
||||
else if (ct.is(std::ctype_base::space, *pattern))
|
||||
{
|
||||
for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
|
||||
;
|
||||
for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
|
||||
;
|
||||
}
|
||||
else if (ct.toupper(*s) == ct.toupper(*pattern))
|
||||
{
|
||||
++s;
|
||||
++pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned long long num = rt.num;
|
||||
unsigned long long den = rt.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)
|
||||
{
|
||||
// (num/den) / Period overflows
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
num *= d2;
|
||||
den *= n2;
|
||||
|
||||
typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
|
||||
|
||||
// num / den is now factor to multiply by r
|
||||
if (!detail::reduce(r, den, err)) return s;
|
||||
|
||||
if (chrono::detail::gt(r, ( (duration_values<common_type_t>::max)() / num)))
|
||||
{
|
||||
// Conversion to Period overflowed
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
common_type_t t = r * num;
|
||||
t /= den;
|
||||
if (t > 0)
|
||||
{
|
||||
Rep pt = t;
|
||||
if ( (duration_values<Rep>::max)() < pt)
|
||||
{
|
||||
// Conversion to Period overflowed
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
// Success! Store it.
|
||||
r = Rep(t);
|
||||
d = duration<Rep, Period> (r);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s start input stream iterator
|
||||
* @param end end input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param err the ios_base state
|
||||
* @param d the duration
|
||||
* Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
|
||||
* @code
|
||||
* return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
|
||||
* @codeend
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
|
||||
duration<Rep, Period> & d) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s start input stream iterator
|
||||
* @param end end input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param err the ios_base state
|
||||
* @param r a reference to the duration representation.
|
||||
* @Effects As if
|
||||
* @code
|
||||
* return std::use_facet<std::num_get<cahr_type, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
|
||||
* @endcode
|
||||
*
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
|
||||
*/
|
||||
template <typename Rep>
|
||||
iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const
|
||||
{
|
||||
return std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s start input stream iterator
|
||||
* @param e end input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param err the ios_base state
|
||||
* @param rt a reference to the duration run-time ratio.
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
|
||||
*/
|
||||
iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, rt_ratio &rt) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(is.getloc()))
|
||||
{
|
||||
return get_unit(std::use_facet<duration_units<CharT> >(is.getloc()), i, e, is, err, rt);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
return get_unit(facet, i, e, is, err, rt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
iter_type get_unit(duration_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base& is,
|
||||
std::ios_base::iostate& err, rt_ratio &rt) const
|
||||
{
|
||||
|
||||
if (*i == '[')
|
||||
{
|
||||
// parse [N/D]s or [N/D]second or [N/D]seconds format
|
||||
++i;
|
||||
i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.num);
|
||||
if ( (err & std::ios_base::failbit) != 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
if (i == e)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
CharT x = *i++;
|
||||
if (x != '/')
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.den);
|
||||
if ( (err & std::ios_base::failbit) != 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
if (i == e)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
if (*i != ']')
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
if (i == e)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
// parse s or second or seconds
|
||||
return do_get_n_d_valid_unit(facet, i, e, is, err);
|
||||
}
|
||||
else
|
||||
{
|
||||
return do_get_valid_unit(facet, i, e, is, err, rt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* @Effects Destroy the facet
|
||||
*/
|
||||
~duration_get()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Extracts the run-time ratio associated to the duration when it is given in prefix form.
|
||||
*
|
||||
* This is an extension point of this facet so that we can take in account other periods that can have a useful
|
||||
* translation in other contexts, as e.g. days and weeks.
|
||||
*
|
||||
* @param facet the duration_units facet
|
||||
* @param s start input stream iterator.
|
||||
* @param e end input stream iterator.
|
||||
* @param ios a reference to a ios_base.
|
||||
* @param err the ios_base state.
|
||||
* @return @c s
|
||||
*/
|
||||
iter_type do_get_n_d_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
|
||||
std::ios_base&, std::ios_base::iostate& err) const
|
||||
{
|
||||
// parse SI name, short or long
|
||||
|
||||
const string_type* units = facet.get_n_d_valid_units_start();
|
||||
const string_type* units_end = facet.get_n_d_valid_units_end();
|
||||
|
||||
const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
|
||||
//~ std::use_facet<std::ctype<CharT> >(loc),
|
||||
err);
|
||||
if (!facet.match_n_d_valid_unit(k))
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the run-time ratio associated to the duration when it is given in prefix form.
|
||||
*
|
||||
* This is an extension point of this facet so that we can take in account other periods that can have a useful
|
||||
* translation in other contexts, as e.g. days and weeks.
|
||||
*
|
||||
* @param facet the duration_units facet
|
||||
* @param s start input stream iterator.
|
||||
* @param e end input stream iterator.
|
||||
* @param ios a reference to a ios_base.
|
||||
* @param err the ios_base state.
|
||||
* @param rt a reference to the duration run-time ratio.
|
||||
* @Effects
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name.
|
||||
*/
|
||||
iter_type do_get_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
|
||||
std::ios_base&, std::ios_base::iostate& err, rt_ratio &rt) const
|
||||
{
|
||||
// parse SI name, short or long
|
||||
|
||||
const string_type* units = facet.get_valid_units_start();
|
||||
const string_type* units_end = facet.get_valid_units_end();
|
||||
|
||||
err = std::ios_base::goodbit;
|
||||
const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
|
||||
//~ std::use_facet<std::ctype<CharT> >(loc),
|
||||
err);
|
||||
|
||||
if (!facet.match_valid_unit(k, rt))
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
}
|
||||
return i;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
template <class CharT, class InputIterator>
|
||||
std::locale::id duration_get<CharT, InputIterator>::id;
|
||||
|
||||
} // chrono
|
||||
}
|
||||
// boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,225 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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 to Boost
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_DURATION_IO_HPP
|
||||
#define BOOST_CHRONO_IO_DURATION_IO_HPP
|
||||
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/ratio/ratio_io.hpp>
|
||||
#include <boost/chrono/io/duration_style.hpp>
|
||||
#include <boost/chrono/io/ios_base_state.hpp>
|
||||
#include <boost/chrono/io/duration_put.hpp>
|
||||
#include <boost/chrono/io/duration_get.hpp>
|
||||
#include <boost/chrono/io/utility/manip_base.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <locale>
|
||||
#include <iostream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
/**
|
||||
* duration parameterized manipulator.
|
||||
*/
|
||||
|
||||
class duration_fmt: public manip<duration_fmt>
|
||||
{
|
||||
duration_style style_;
|
||||
public:
|
||||
|
||||
/**
|
||||
* explicit manipulator constructor from a @c duration_style
|
||||
*/
|
||||
explicit duration_fmt(duration_style style)BOOST_NOEXCEPT
|
||||
: style_(style)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Change the duration_style ios state;
|
||||
*/
|
||||
void operator()(std::ios_base &ios) const
|
||||
|
||||
{
|
||||
set_duration_style(ios, style_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* duration_style i/o saver.
|
||||
*
|
||||
* See Boost.IO i/o state savers for a motivating compression.
|
||||
*/
|
||||
struct duration_style_io_saver
|
||||
{
|
||||
|
||||
//! the type of the state to restore
|
||||
typedef std::ios_base state_type;
|
||||
//! the type of aspect to save
|
||||
typedef duration_style aspect_type;
|
||||
|
||||
/**
|
||||
* Explicit construction from an i/o stream.
|
||||
*
|
||||
* Store a reference to the i/o stream and the value of the associated @c duration_style.
|
||||
*/
|
||||
explicit duration_style_io_saver(state_type &s) :
|
||||
s_save_(s)
|
||||
{
|
||||
a_save_ = get_duration_style(s_save_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction from an i/o stream and a @c duration_style to restore.
|
||||
*
|
||||
* Stores a reference to the i/o stream and the value @c duration_style to restore given as parameter.
|
||||
*/
|
||||
duration_style_io_saver(state_type &s, aspect_type new_value) :
|
||||
s_save_(s), a_save_(new_value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* Restores the i/o stream with the duration_style to be restored.
|
||||
*/
|
||||
~duration_style_io_saver()
|
||||
{
|
||||
this->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the i/o stream with the duration_style to be restored.
|
||||
*/
|
||||
void restore()
|
||||
{
|
||||
set_duration_style(s_save_, a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ;
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
/**
|
||||
* duration stream inserter
|
||||
* @param os the output stream
|
||||
* @param d to value to insert
|
||||
* @return @c 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)
|
||||
{
|
||||
bool failed = false;
|
||||
BOOST_TRY
|
||||
{
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
BOOST_TRY
|
||||
{
|
||||
typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
|
||||
if (bool(opfx))
|
||||
{
|
||||
if (!std::has_facet<duration_put<CharT> >(os.getloc()))
|
||||
{
|
||||
if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed())
|
||||
{
|
||||
err = std::ios_base::badbit;
|
||||
}
|
||||
}
|
||||
else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), d) .failed())
|
||||
{
|
||||
err = std::ios_base::badbit;
|
||||
}
|
||||
os.width(0);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
bool flag = false;
|
||||
BOOST_TRY
|
||||
{
|
||||
os.setstate(std::ios_base::failbit);
|
||||
}
|
||||
BOOST_CATCH (std::ios_base::failure )
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if (flag) throw;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if (err) os.setstate(err);
|
||||
return os;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param is the input stream
|
||||
* @param d the duration
|
||||
* @return @c is
|
||||
*/
|
||||
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::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
||||
BOOST_TRY
|
||||
{
|
||||
typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
|
||||
if (bool(ipfx))
|
||||
{
|
||||
if (!std::has_facet<duration_get<CharT> >(is.getloc()))
|
||||
{
|
||||
duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is,
|
||||
err, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_CATCH (...)
|
||||
{
|
||||
bool flag = false;
|
||||
BOOST_TRY
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
BOOST_CATCH (std::ios_base::failure )
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if (flag) { BOOST_RETHROW }
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if (err) is.setstate(err);
|
||||
return is;
|
||||
}
|
||||
|
||||
} // chrono
|
||||
|
||||
}
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,264 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
/**
|
||||
* Duration formatting facet for output.
|
||||
*/
|
||||
#ifndef BOOST_CHRONO_IO_DURATION_PUT_HPP
|
||||
#define BOOST_CHRONO_IO_DURATION_PUT_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <boost/chrono/io/duration_units.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <locale>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
/**
|
||||
* @tparam ChatT a character type
|
||||
* @tparam OutputIterator a model of @c OutputIterator
|
||||
*
|
||||
* The @c duration_put facet provides facilities for formatted output of duration values.
|
||||
* The member function of @c duration_put take a duration and format it into character string representation.
|
||||
*
|
||||
*/
|
||||
template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
|
||||
class duration_put: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string passed to member functions.
|
||||
*/
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
/**
|
||||
* Type of iterator used to write in the character buffer.
|
||||
*/
|
||||
typedef OutputIterator iter_type;
|
||||
|
||||
/**
|
||||
* Construct a duration_put facet.
|
||||
* @param refs
|
||||
* @Effects Construct a duration_put facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
explicit duration_put(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param d the duration
|
||||
* @param pattern begin of the formatting pattern
|
||||
* @param pat_end end of the formatting pattern
|
||||
*
|
||||
* @Effects Steps through the sequence from @c pattern to @c pat_end,
|
||||
* identifying characters that are part of a pattern sequence. Each character
|
||||
* that is not part of a pattern sequence is written to @c s immediately, and
|
||||
* each pattern sequence, as it is identified, results in a call to
|
||||
* @c put_value or @c put_unit;
|
||||
* thus, pattern elements and other characters are interleaved in the output
|
||||
* in the order in which they appear in the pattern. Pattern sequences are
|
||||
* identified by converting each character @c c to a @c char value as if by
|
||||
* @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
|
||||
* @c ios.getloc(). The first character of each sequence is equal to @c '%',
|
||||
* followed by a pattern specifier character @c spec, which can be @c 'v' for
|
||||
* the duration value or @c 'u' for the duration unit. .
|
||||
* For each valid pattern sequence identified, calls
|
||||
* <c>put_value(s, ios, fill, d)</c> or <c>put_unit(s, ios, fill, d)</c>.
|
||||
*
|
||||
* @Returns An iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const CharT* pattern,
|
||||
const CharT* pat_end) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
|
||||
ios.getloc());
|
||||
return put(facet, s, ios, fill, d, pattern, pat_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
return put(facet, s, ios, fill, d, pattern, pat_end);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put(duration_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
|
||||
duration<Rep, Period> const& d, const CharT* pattern, const CharT* pat_end) const
|
||||
{
|
||||
|
||||
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
|
||||
for (; pattern != pat_end; ++pattern)
|
||||
{
|
||||
if (ct.narrow(*pattern, 0) == '%')
|
||||
{
|
||||
if (++pattern == pat_end)
|
||||
{
|
||||
*s++ = pattern[-1];
|
||||
break;
|
||||
}
|
||||
char fmt = ct.narrow(*pattern, 0);
|
||||
switch (fmt)
|
||||
{
|
||||
case 'v':
|
||||
{
|
||||
s = put_value(s, ios, fill, d);
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
s = put_unit(units_facet, s, ios, fill, d);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_ASSERT(false && "Boost::Chrono internal error.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
*s++ = *pattern;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param d the duration
|
||||
* @Effects imbue in @c ios the @c duration_units_default facet if not already present.
|
||||
* Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
|
||||
* @code
|
||||
* return put(s, ios, d, str.data(), str.data() + str.size());
|
||||
* @endcode
|
||||
* @Returns An iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
|
||||
ios.getloc());
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return put(facet, s, ios, fill, d, str.data(), str.data() + str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return put(facet, s, ios, fill, d, str.data(), str.data() + str.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param d the duration
|
||||
* @Effects As if s=std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())).
|
||||
* @Returns s, iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
|
||||
{
|
||||
return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
|
||||
static_cast<long int> (d.count()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param d the duration
|
||||
* @Effects Let facet be the duration_units<CharT> facet associated to ios. If the associated unit is named,
|
||||
* as if
|
||||
* @code
|
||||
string_type str = facet.get_unit(get_duration_style(ios), d);
|
||||
s=std::copy(str.begin(), str.end(), s);
|
||||
* @endcode
|
||||
* Otherwise, format the unit as "[Period::num/Period::den]" followed by the unit associated to [N/D] obtained using facet.get_n_d_unit(get_duration_style(ios), d)
|
||||
* @Returns s, iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put_unit(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
|
||||
{
|
||||
if (std::has_facet<duration_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
|
||||
ios.getloc());
|
||||
return put_unit(facet, s, ios, fill, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_units_default<CharT> facet;
|
||||
return put_unit(facet, s, ios, fill, d);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
|
||||
duration<Rep, Period> const& d) const
|
||||
{
|
||||
if (facet.template is_named_unit<Period>()) {
|
||||
string_type str = facet.get_unit(get_duration_style(ios), d);
|
||||
s=std::copy(str.begin(), str.end(), s);
|
||||
} else {
|
||||
*s++ = CharT('[');
|
||||
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
|
||||
*s++ = CharT('/');
|
||||
std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
|
||||
*s++ = CharT(']');
|
||||
string_type str = facet.get_n_d_unit(get_duration_style(ios), d);
|
||||
s=std::copy(str.begin(), str.end(), s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* @Effects Destroy the facet
|
||||
*/
|
||||
~duration_put()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class CharT, class OutputIterator>
|
||||
std::locale::id duration_put<CharT, OutputIterator>::id;
|
||||
|
||||
} // chrono
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,35 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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 to Boost
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_DURATION_STYLE_HPP
|
||||
#define BOOST_CHRONO_IO_DURATION_STYLE_HPP
|
||||
|
||||
#include <boost/detail/scoped_enum_emulation.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
/**
|
||||
* Scoped enumeration emulation stating whether the duration I/O style is long or short.
|
||||
* prefix means duration::rep with whatever stream/locale settings are set for it followed by a long name representing the unit
|
||||
* symbol means duration::rep with whatever stream/locale settings are set for it followed by a SI unit abbreviation
|
||||
*/
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(duration_style)
|
||||
{
|
||||
prefix, symbol
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(duration_style)
|
||||
|
||||
|
||||
} // chrono
|
||||
|
||||
}
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,992 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_DURATION_UNITS_HPP
|
||||
#define BOOST_CHRONO_IO_DURATION_UNITS_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <boost/ratio/ratio_io.hpp>
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/chrono/io/duration_style.hpp>
|
||||
#include <boost/chrono/io/ios_base_state.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
class rt_ratio
|
||||
{
|
||||
public:
|
||||
template <typename Period>
|
||||
rt_ratio(Period const&) :
|
||||
num(Period::type::num), den(Period::type::den)
|
||||
{
|
||||
}
|
||||
|
||||
rt_ratio(intmax_t n = 0, intmax_t d = 0) :
|
||||
num(n), den(d)
|
||||
{
|
||||
}
|
||||
|
||||
intmax_t num;
|
||||
intmax_t den;
|
||||
};
|
||||
|
||||
/**
|
||||
* @c duration_units facet gives useful information about the duration units,
|
||||
* as the number of plural forms, the plural form associated to a duration,
|
||||
* the text associated to a plural form and a duration's period,
|
||||
*/
|
||||
template <typename CharT = char>
|
||||
class duration_units: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string passed to member functions.
|
||||
*/
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* Construct a @c duration_units facet.
|
||||
* @param refs
|
||||
* @Effects Construct a @c duration_units facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
explicit duration_units(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the start of valid [N/D] units.
|
||||
*/
|
||||
virtual const string_type* get_n_d_valid_units_start() const =0;
|
||||
/**
|
||||
* @effect calls the do_...
|
||||
* @return pointer to the end of valid [N/D] units.
|
||||
*/
|
||||
virtual const string_type* get_n_d_valid_units_end() const=0;
|
||||
|
||||
/**
|
||||
* @return pointer to the start of valid units, symbol or prefix with its different plural forms.
|
||||
*/
|
||||
virtual const string_type* get_valid_units_start() const=0;
|
||||
/**
|
||||
* @return pointer to the end of valid units.
|
||||
*/
|
||||
virtual const string_type* get_valid_units_end() const=0;
|
||||
|
||||
/**
|
||||
* @param k the found pointer to the [N/D] unit.
|
||||
* @return true if @c k matches a valid unit.
|
||||
*/
|
||||
virtual bool match_n_d_valid_unit(const string_type* k) const = 0;
|
||||
/**
|
||||
* @param k the found pointer to the unit.
|
||||
* @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
|
||||
* @return true if @c k matches a valid unit.
|
||||
*/
|
||||
virtual bool match_valid_unit(const string_type* k, rt_ratio& rt) const = 0;
|
||||
|
||||
/**
|
||||
* @effect calls the do_...
|
||||
* @return the pattern to be used by default.
|
||||
*/
|
||||
virtual string_type get_pattern() const=0;
|
||||
|
||||
/**
|
||||
* @effect calls the do_...
|
||||
* @return the unit associated to this duration.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
string_type get_unit(duration_style style, duration<Rep, Period> const& d) const
|
||||
{
|
||||
return do_get_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
|
||||
}
|
||||
/**
|
||||
* @effect calls the do_...
|
||||
* @return the [N/D] suffix unit associated to this duration.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
string_type get_n_d_unit(duration_style style, duration<Rep, Period> const& d) const
|
||||
{
|
||||
return do_get_n_d_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @effect calls the do_...
|
||||
* @return true if the unit associated to the given Period is named, false otherwise.
|
||||
*/
|
||||
template <typename Period>
|
||||
bool is_named_unit() const
|
||||
{
|
||||
return do_is_named_unit(rt_ratio(Period()));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @Effects Destroys the facet
|
||||
*/
|
||||
virtual ~duration_units()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @return the [N/D] suffix unit associated to this duration.
|
||||
*/
|
||||
virtual string_type do_get_n_d_unit(duration_style style, rt_ratio rt, intmax_t v) const = 0;
|
||||
/**
|
||||
* @return the unit associated to this duration.
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style,rt_ratio rt, intmax_t v) const = 0;
|
||||
/**
|
||||
* @return true if the unit associated to the given Period is named, false otherwise.
|
||||
*/
|
||||
virtual bool do_is_named_unit(rt_ratio rt) const =0;
|
||||
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
std::locale::id duration_units<CharT>::id;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
struct duration_units_default_holder
|
||||
{
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
static string_type* n_d_valid_units_;
|
||||
static string_type* valid_units_;
|
||||
static bool initialized_;
|
||||
};
|
||||
template <typename CharT>
|
||||
typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::n_d_valid_units_=0;
|
||||
template <typename CharT>
|
||||
typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::valid_units_=0;
|
||||
template<typename CharT>
|
||||
bool duration_units_default_holder<CharT>::initialized_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to define the strings for the default English
|
||||
*/
|
||||
template <typename CharT = char>
|
||||
class duration_units_default: public duration_units<CharT>
|
||||
{
|
||||
protected:
|
||||
static const std::size_t pfs_ = 2;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string passed to member functions.
|
||||
*/
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
|
||||
/**
|
||||
* Construct a @c duration_units_default facet.
|
||||
* @param refs
|
||||
* @Effects Construct a @c duration_units_default facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
explicit duration_units_default(size_t refs = 0) :
|
||||
duration_units<CharT> (refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the facet.
|
||||
*/
|
||||
~duration_units_default()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @param k the found pointer to the [N/D] unit.
|
||||
* @return true if @c k matches a valid unit.
|
||||
*/
|
||||
bool match_n_d_valid_unit(const string_type* k) const
|
||||
{
|
||||
std::size_t index = (k - get_n_d_valid_units_start()) / (pfs_ + 1);
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @param k the found pointer to the unit.
|
||||
* @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
|
||||
* @return true if @c k matches a valid unit.
|
||||
*/
|
||||
bool match_valid_unit(const string_type* k, rt_ratio& rt) const
|
||||
{
|
||||
std::size_t index = (k - get_valid_units_start()) / (pfs_ + 1);
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
rt = rt_ratio(atto());
|
||||
break;
|
||||
case 1:
|
||||
rt = rt_ratio(femto());
|
||||
break;
|
||||
case 2:
|
||||
rt = rt_ratio(pico());
|
||||
break;
|
||||
case 3:
|
||||
rt = rt_ratio(nano());
|
||||
break;
|
||||
case 4:
|
||||
rt = rt_ratio(micro());
|
||||
break;
|
||||
case 5:
|
||||
rt = rt_ratio(milli());
|
||||
break;
|
||||
case 6:
|
||||
rt = rt_ratio(centi());
|
||||
break;
|
||||
case 7:
|
||||
rt = rt_ratio(deci());
|
||||
break;
|
||||
case 8:
|
||||
rt = rt_ratio(deca());
|
||||
break;
|
||||
case 9:
|
||||
rt = rt_ratio(hecto());
|
||||
break;
|
||||
case 10:
|
||||
rt = rt_ratio(kilo());
|
||||
break;
|
||||
case 11:
|
||||
rt = rt_ratio(mega());
|
||||
break;
|
||||
case 12:
|
||||
rt = rt_ratio(giga());
|
||||
break;
|
||||
case 13:
|
||||
rt = rt_ratio(tera());
|
||||
break;
|
||||
case 14:
|
||||
rt = rt_ratio(peta());
|
||||
break;
|
||||
case 15:
|
||||
rt = rt_ratio(exa());
|
||||
break;
|
||||
case 16:
|
||||
rt = rt_ratio(ratio<1> ());
|
||||
break;
|
||||
case 17:
|
||||
rt = rt_ratio(ratio<60> ());
|
||||
break;
|
||||
case 18:
|
||||
rt = rt_ratio(ratio<3600> ());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the start of valid [N/D] units.
|
||||
*/
|
||||
virtual const string_type* get_n_d_valid_units_start()const
|
||||
{
|
||||
return detail::duration_units_default_holder<CharT>::n_d_valid_units_;
|
||||
}
|
||||
/**
|
||||
* @return pointer to the end of valid [N/D] units.
|
||||
*/
|
||||
virtual const string_type* get_n_d_valid_units_end()const
|
||||
{
|
||||
return detail::duration_units_default_holder<CharT>::n_d_valid_units_ + (pfs_ + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the start of valid units.
|
||||
*/
|
||||
virtual string_type* get_valid_units_start() const
|
||||
{
|
||||
return detail::duration_units_default_holder<CharT>::valid_units_;
|
||||
}
|
||||
/**
|
||||
* @return pointer to the end of valid units.
|
||||
*/
|
||||
virtual string_type* get_valid_units_end() const
|
||||
{
|
||||
return detail::duration_units_default_holder<CharT>::valid_units_ + 19 * (pfs_ + 1);
|
||||
}
|
||||
|
||||
string_type get_pattern() const
|
||||
{
|
||||
static const CharT t[] =
|
||||
{ '%', 'v', ' ', '%', 'u' };
|
||||
static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
*
|
||||
* This facet names the units associated to the following periods:
|
||||
* atto,femto,pico,nano,micro,milli,centi,deci,ratio<1>,deca,hecto,kilo,mega,giga,tera,peta,exa,ratio<60> and ratio<3600>.
|
||||
* @return true if the unit associated to the given Period is named, false otherwise.
|
||||
*/
|
||||
bool do_is_named_unit(rt_ratio rt) const
|
||||
{
|
||||
if (rt.num==1) {
|
||||
switch (rt.den)
|
||||
{
|
||||
case BOOST_RATIO_INTMAX_C(1):
|
||||
case BOOST_RATIO_INTMAX_C(10):
|
||||
case BOOST_RATIO_INTMAX_C(100):
|
||||
case BOOST_RATIO_INTMAX_C(1000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000000):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else if (rt.den==1) {
|
||||
switch (rt.num)
|
||||
{
|
||||
case BOOST_RATIO_INTMAX_C(10):
|
||||
case BOOST_RATIO_INTMAX_C(60):
|
||||
case BOOST_RATIO_INTMAX_C(100):
|
||||
case BOOST_RATIO_INTMAX_C(1000):
|
||||
case BOOST_RATIO_INTMAX_C(3600):
|
||||
case BOOST_RATIO_INTMAX_C(1000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000):
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000000):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* In English the suffix used after [N/D] is the one associated to the period ratio<1>.
|
||||
* @return the [N/D] suffix unit associated to this duration.
|
||||
*/
|
||||
string_type do_get_n_d_unit(duration_style style, rt_ratio, intmax_t v) const
|
||||
{
|
||||
return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unit associated to this duration if it is named, "" otherwise.
|
||||
*/
|
||||
string_type do_get_unit(duration_style style, rt_ratio rt, intmax_t v) const
|
||||
{
|
||||
if (rt.num==1) {
|
||||
switch (rt.den)
|
||||
{
|
||||
case BOOST_RATIO_INTMAX_C(1):
|
||||
return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(10):
|
||||
return do_get_unit(style, deci(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(100):
|
||||
return do_get_unit(style, centi(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000):
|
||||
return do_get_unit(style, milli(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000):
|
||||
return do_get_unit(style, micro(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000):
|
||||
return do_get_unit(style, nano(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000):
|
||||
return do_get_unit(style, pico(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000):
|
||||
return do_get_unit(style, femto(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000000):
|
||||
return do_get_unit(style, atto(), do_get_plural_form(v));
|
||||
default:
|
||||
;
|
||||
}
|
||||
} else if (rt.den==1) {
|
||||
switch (rt.num)
|
||||
{
|
||||
case BOOST_RATIO_INTMAX_C(10):
|
||||
return do_get_unit(style, deca(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(60):
|
||||
return do_get_unit(style, ratio<60>(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(100):
|
||||
return do_get_unit(style, hecto(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000):
|
||||
return do_get_unit(style, kilo(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(3600):
|
||||
return do_get_unit(style, ratio<3600>(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000):
|
||||
return do_get_unit(style, mega(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000):
|
||||
return do_get_unit(style, giga(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000):
|
||||
return do_get_unit(style, tera(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000):
|
||||
return do_get_unit(style, peta(), do_get_plural_form(v));
|
||||
case BOOST_RATIO_INTMAX_C(1000000000000000000):
|
||||
return do_get_unit(style, exa(), do_get_plural_form(v));
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(false&&"ratio parameter can not be translated");
|
||||
//throw "exception";
|
||||
return string_type();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @return the number of associated plural forms this facet manages.
|
||||
*/
|
||||
virtual std::size_t do_get_plural_forms() const
|
||||
{
|
||||
return static_get_plural_forms();
|
||||
}
|
||||
static std::size_t static_get_plural_forms()
|
||||
{
|
||||
return pfs_;
|
||||
}
|
||||
/**
|
||||
* Gets the associated plural form.
|
||||
* @param value the duration representation
|
||||
* @return the plural form associated to the @c value parameter. In English there are 2 plural forms
|
||||
* 0 singular (-1 or 1)
|
||||
* 1 plural for all others
|
||||
*/
|
||||
virtual std::size_t do_get_plural_form(int_least64_t value) const
|
||||
{
|
||||
return static_get_plural_form(value);
|
||||
}
|
||||
static std::size_t static_get_plural_form(int_least64_t value)
|
||||
{
|
||||
return (value == -1 || value == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param period the period associated to the duration seconds.
|
||||
* @param pf the requested plural form.
|
||||
* @return if style is symbol returns "s", otherwise if pf is 0 return "second", if pf is 1 "seconds"
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, ratio<1> u, std::size_t pf) const
|
||||
{
|
||||
return static_get_unit(style,u,pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, ratio<1> , std::size_t pf)
|
||||
{
|
||||
static const CharT t[] =
|
||||
{ 's' };
|
||||
static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
|
||||
static const CharT u[] =
|
||||
{ 's', 'e', 'c', 'o', 'n', 'd' };
|
||||
static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
|
||||
static const CharT v[] =
|
||||
{ 's', 'e', 'c', 'o', 'n', 'd', 's' };
|
||||
static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
|
||||
|
||||
if (style == duration_style::symbol)
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
if (pf == 0)
|
||||
{
|
||||
return singular;
|
||||
}
|
||||
if (pf == 1)
|
||||
{
|
||||
return plural;
|
||||
}
|
||||
BOOST_ASSERT(false&&"style/pf parameters not valid");
|
||||
//throw "exception";
|
||||
return string_type();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param period the period associated to the duration minutes.
|
||||
* @param pf the requested plural form.
|
||||
* @return if style is symbol returns "min", otherwise if pf is 0 return "minute", if pf is 1 "minutes"
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, ratio<60> u, std::size_t pf) const
|
||||
{
|
||||
return static_get_unit(style,u,pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, ratio<60> , std::size_t pf)
|
||||
{
|
||||
static const CharT t[] =
|
||||
{ 'm', 'i', 'n' };
|
||||
static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
|
||||
|
||||
static const CharT u[] =
|
||||
{ 'm', 'i', 'n', 'u', 't', 'e' };
|
||||
static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
|
||||
static const CharT v[] =
|
||||
{ 'm', 'i', 'n', 'u', 't', 'e', 's' };
|
||||
static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
|
||||
|
||||
if (style == duration_style::symbol) return symbol;
|
||||
if (pf == 0) return singular;
|
||||
if (pf == 1) return plural;
|
||||
BOOST_ASSERT(false&&"style/pf parameters not valid");
|
||||
//throw "exception";
|
||||
return string_type();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param period the period associated to the duration hours.
|
||||
* @param pf the requested plural form.
|
||||
* @return if style is symbol returns "h", otherwise if pf is 0 return "hour", if pf is 1 "hours"
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, ratio<3600> u, std::size_t pf) const
|
||||
{
|
||||
return static_get_unit(style,u,pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, ratio<3600> , std::size_t pf)
|
||||
{
|
||||
static const CharT t[] =
|
||||
{ 'h' };
|
||||
static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
|
||||
static const CharT u[] =
|
||||
{ 'h', 'o', 'u', 'r' };
|
||||
static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
|
||||
static const CharT v[] =
|
||||
{ 'h', 'o', 'u', 'r', 's' };
|
||||
static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
|
||||
|
||||
if (style == duration_style::symbol) return symbol;
|
||||
if (pf == 0) return singular;
|
||||
if (pf == 1) return plural;
|
||||
BOOST_ASSERT(false&&"style/pf parameters not valid");
|
||||
//throw "exception";
|
||||
return string_type();
|
||||
|
||||
}
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param u the period tag atto.
|
||||
* @param pf the requested plural form.
|
||||
* @return the concatenation of the prefix associated to @c period + the one associated to seconds.
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, atto u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, atto u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param u the period tag femto.
|
||||
* @param pf the requested plural form.
|
||||
* @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, femto u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, femto u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param u the period tag femto.
|
||||
* @param pf the requested plural form.
|
||||
* @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
|
||||
*/
|
||||
virtual string_type do_get_unit(duration_style style, pico u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, pico u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, nano u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, nano u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, micro u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, micro u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, milli u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, milli u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, centi u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, centi u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, deci u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, deci u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, deca u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, deca u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, hecto u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, hecto u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, kilo u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, kilo u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, mega u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, mega u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, giga u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, giga u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, tera u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, tera u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, peta u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, peta u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
virtual string_type do_get_unit(duration_style style, exa u, std::size_t pf) const
|
||||
{
|
||||
return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
static string_type static_get_unit(duration_style style, exa u, std::size_t pf)
|
||||
{
|
||||
return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @param style the duration style.
|
||||
* @param u the period tag atto.
|
||||
* @return depending on the value of @c style return the ratio_string symbol or prefix.
|
||||
*/
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, atto u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, atto)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<atto, CharT>::symbol();
|
||||
return ratio_string<atto, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, femto u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, femto)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<femto, CharT>::symbol();
|
||||
return ratio_string<femto, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, pico u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, pico)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<pico, CharT>::symbol();
|
||||
return ratio_string<pico, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, nano u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, nano)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<nano, CharT>::symbol();
|
||||
return ratio_string<nano, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, micro u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, micro)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<micro, CharT>::symbol();
|
||||
return ratio_string<micro, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, milli u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, milli)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<milli, CharT>::symbol();
|
||||
return ratio_string<milli, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, centi u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, centi)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<centi, CharT>::symbol();
|
||||
return ratio_string<centi, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, deci u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, deci)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<deci, CharT>::symbol();
|
||||
return ratio_string<deci, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, deca u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, deca)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<deca, CharT>::symbol();
|
||||
return ratio_string<deca, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, hecto u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, hecto)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<hecto, CharT>::symbol();
|
||||
return ratio_string<hecto, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, kilo u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, kilo)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<kilo, CharT>::symbol();
|
||||
return ratio_string<kilo, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, mega u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, mega)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<mega, CharT>::symbol();
|
||||
return ratio_string<mega, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, giga u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, giga)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<giga, CharT>::symbol();
|
||||
return ratio_string<giga, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, tera u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, tera)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<tera, CharT>::symbol();
|
||||
return ratio_string<tera, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, peta u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, peta)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<peta, CharT>::symbol();
|
||||
return ratio_string<peta, CharT>::prefix();
|
||||
}
|
||||
virtual string_type do_get_ratio_prefix(duration_style style, exa u) const
|
||||
{
|
||||
return static_get_ratio_prefix(style, u);
|
||||
}
|
||||
static string_type static_get_ratio_prefix(duration_style style, exa)
|
||||
{
|
||||
if (style == duration_style::symbol) return ratio_string<exa, CharT>::symbol();
|
||||
return ratio_string<exa, CharT>::prefix();
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename Period>
|
||||
string_type* fill_units(string_type* it, Period) const
|
||||
{
|
||||
std::size_t pfs = do_get_plural_forms();
|
||||
for (std::size_t pf = 0; pf < pfs; ++pf)
|
||||
{
|
||||
*it++ = do_get_unit(duration_style::prefix, Period(), pf);
|
||||
}
|
||||
*it++ = do_get_unit(duration_style::symbol, Period(), 0);
|
||||
return it;
|
||||
}
|
||||
public:
|
||||
template <typename Period>
|
||||
static string_type* static_fill_units(string_type* it, Period)
|
||||
{
|
||||
std::size_t pfs = static_get_plural_forms();
|
||||
for (std::size_t pf = 0; pf < pfs; ++pf)
|
||||
{
|
||||
*it++ = static_get_unit(duration_style::prefix, Period(), pf);
|
||||
}
|
||||
*it++ = static_get_unit(duration_style::symbol, Period(), 0);
|
||||
return it;
|
||||
}
|
||||
static string_type* static_init_valid_units(string_type* it)
|
||||
{
|
||||
it = static_fill_units(it, atto());
|
||||
it = static_fill_units(it, femto());
|
||||
it = static_fill_units(it, pico());
|
||||
it = static_fill_units(it, nano());
|
||||
it = static_fill_units(it, micro());
|
||||
it = static_fill_units(it, milli());
|
||||
it = static_fill_units(it, centi());
|
||||
it = static_fill_units(it, deci());
|
||||
it = static_fill_units(it, deca());
|
||||
it = static_fill_units(it, hecto());
|
||||
it = static_fill_units(it, kilo());
|
||||
it = static_fill_units(it, mega());
|
||||
it = static_fill_units(it, giga());
|
||||
it = static_fill_units(it, tera());
|
||||
it = static_fill_units(it, peta());
|
||||
it = static_fill_units(it, exa());
|
||||
it = static_fill_units(it, ratio<1> ());
|
||||
it = static_fill_units(it, ratio<60> ());
|
||||
it = static_fill_units(it, ratio<3600> ());
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename CharT>
|
||||
struct duration_units_default_initializer_t
|
||||
{
|
||||
duration_units_default_initializer_t()
|
||||
{
|
||||
if (!duration_units_default_holder<CharT>::initialized_)
|
||||
{
|
||||
typedef typename duration_units_default_holder<CharT>::string_type string_type;
|
||||
duration_units_default_holder<CharT>::n_d_valid_units_ = new string_type[3];
|
||||
duration_units_default_holder<CharT>::valid_units_ = new string_type[19 * 3];
|
||||
|
||||
string_type* it = duration_units_default_holder<CharT>::n_d_valid_units_;
|
||||
it = duration_units_default<CharT>::static_fill_units(it, ratio<1> ());
|
||||
it = duration_units_default<CharT>::static_init_valid_units(duration_units_default_holder<CharT>::valid_units_);
|
||||
|
||||
duration_units_default_holder<CharT>::initialized_ = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
namespace /**/
|
||||
{
|
||||
duration_units_default_initializer_t<char> duration_units_default_initializer;
|
||||
duration_units_default_initializer_t<wchar_t> wduration_units_default_initializer;
|
||||
} // namespace
|
||||
}
|
||||
} // chrono
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,151 @@
|
||||
// (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 to Boost
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
|
||||
#define BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <locale>
|
||||
#include <boost/chrono/io/duration_style.hpp>
|
||||
#include <boost/chrono/io/timezone.hpp>
|
||||
#include <boost/chrono/io/utility/ios_base_state_ptr.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
class fmt_masks : public ios_flags<fmt_masks>
|
||||
{
|
||||
typedef ios_flags<fmt_masks> base_type;
|
||||
fmt_masks& operator=(fmt_masks const& rhs) ;
|
||||
|
||||
public:
|
||||
fmt_masks(std::ios_base& ios): base_type(ios) {}
|
||||
enum type
|
||||
{
|
||||
uses_symbol = 1 << 0,
|
||||
uses_local = 1 << 1
|
||||
};
|
||||
|
||||
inline duration_style get_duration_style()
|
||||
{
|
||||
return (flags() & uses_symbol) ? duration_style::symbol : duration_style::prefix;
|
||||
}
|
||||
inline void set_duration_style(duration_style style)
|
||||
{
|
||||
if (style == duration_style::symbol)
|
||||
setf(uses_symbol);
|
||||
else
|
||||
unsetf(uses_symbol);
|
||||
}
|
||||
|
||||
inline timezone get_timezone()
|
||||
{
|
||||
return (flags() & uses_local) ? timezone::local : timezone::utc;
|
||||
}
|
||||
inline void set_timezone(timezone tz)
|
||||
{
|
||||
if (tz == timezone::local)
|
||||
setf(uses_local);
|
||||
else
|
||||
unsetf(uses_local);
|
||||
}
|
||||
};
|
||||
namespace detail
|
||||
{
|
||||
namespace /**/ {
|
||||
xalloc_key_initializer<fmt_masks > fmt_masks_xalloc_key_initializer;
|
||||
} // namespace
|
||||
} // namespace detail
|
||||
|
||||
inline duration_style get_duration_style(std::ios_base & ios)
|
||||
{
|
||||
return fmt_masks(ios).get_duration_style();
|
||||
}
|
||||
inline void set_duration_style(std::ios_base& ios, duration_style style)
|
||||
{
|
||||
fmt_masks(ios).set_duration_style(style);
|
||||
}
|
||||
inline std::ios_base& symbol_format(std::ios_base& ios)
|
||||
{
|
||||
fmt_masks(ios).setf(fmt_masks::uses_symbol);
|
||||
return ios;
|
||||
}
|
||||
inline std::ios_base& name_format(std::ios_base& ios)
|
||||
{
|
||||
fmt_masks(ios).unsetf(fmt_masks::uses_symbol);
|
||||
return ios;
|
||||
}
|
||||
|
||||
inline timezone get_timezone(std::ios_base & ios)
|
||||
{
|
||||
return fmt_masks(ios).get_timezone();
|
||||
}
|
||||
inline void set_timezone(std::ios_base& ios, timezone tz)
|
||||
{
|
||||
fmt_masks(ios).set_timezone(tz);
|
||||
}
|
||||
inline std::ios_base& local_timezone(std::ios_base& ios)
|
||||
{
|
||||
fmt_masks(ios).setf(fmt_masks::uses_local);
|
||||
return ios;
|
||||
}
|
||||
|
||||
inline std::ios_base& utc_timezone(std::ios_base& ios)
|
||||
{
|
||||
fmt_masks(ios).unsetf(fmt_masks::uses_local);
|
||||
return ios;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename CharT>
|
||||
struct ios_base_data_aux
|
||||
{
|
||||
std::basic_string<CharT> time_fmt;
|
||||
std::basic_string<CharT> duration_fmt;
|
||||
public:
|
||||
|
||||
ios_base_data_aux() :
|
||||
time_fmt(""),
|
||||
duration_fmt("")
|
||||
{
|
||||
}
|
||||
};
|
||||
template<typename CharT>
|
||||
struct ios_base_data {};
|
||||
namespace /**/ {
|
||||
xalloc_key_initializer<detail::ios_base_data<char> > ios_base_data_aux_xalloc_key_initializer;
|
||||
xalloc_key_initializer<detail::ios_base_data<wchar_t> > wios_base_data_aux_xalloc_key_initializer;
|
||||
#if BOOST_CHRONO_HAS_UNICODE_SUPPORT
|
||||
xalloc_key_initializer<detail::ios_base_data<char16_t> > u16ios_base_data_aux_xalloc_key_initializer;
|
||||
xalloc_key_initializer<detail::ios_base_data<char32_t> > u32ios_base_data_aux_xalloc_key_initializer;
|
||||
#endif
|
||||
} // namespace
|
||||
} // namespace detail
|
||||
|
||||
template<typename CharT>
|
||||
inline std::basic_string<CharT> get_time_fmt(std::ios_base & ios)
|
||||
{
|
||||
ios_state_not_null_ptr<detail::ios_base_data<CharT>, detail::ios_base_data_aux<CharT> > ptr(ios);
|
||||
return ptr->time_fmt;
|
||||
}
|
||||
template<typename CharT>
|
||||
inline void set_time_fmt(std::ios_base& ios, std::basic_string<
|
||||
CharT> const& fmt)
|
||||
{
|
||||
ios_state_not_null_ptr<detail::ios_base_data<CharT>, detail::ios_base_data_aux<CharT> > ptr(ios);
|
||||
ptr->time_fmt = fmt;
|
||||
}
|
||||
|
||||
} // chrono
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,330 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_TIME_POINT_GET_HPP
|
||||
#define BOOST_CHRONO_IO_TIME_POINT_GET_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <boost/chrono/detail/scan_keyword.hpp>
|
||||
#include <boost/chrono/io/time_point_units.hpp>
|
||||
#include <boost/chrono/io/duration_get.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Duration formatting facet for input.
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
|
||||
class time_point_get: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of iterator used to scan the character buffer.
|
||||
*/
|
||||
typedef InputIterator iter_type;
|
||||
|
||||
/**
|
||||
* Construct a @c time_point_get facet.
|
||||
* @param refs
|
||||
* @Effects Construct a @c time_point_get facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
|
||||
explicit time_point_get(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s start input stream iterator
|
||||
* @param end end input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param err the ios_base state
|
||||
* @param d the duration
|
||||
* @param pattern begin of the formatting pattern
|
||||
* @param pat_end end of the formatting pattern
|
||||
*
|
||||
* Requires: [pattern,pat_end) shall be a valid range.
|
||||
*
|
||||
* Effects: The function starts by evaluating err = std::ios_base::goodbit.
|
||||
* It then enters a loop, reading zero or more characters from s at
|
||||
* each iteration. Unless otherwise specified below, the loop
|
||||
* terminates when the first of the following conditions holds:
|
||||
* - The expression pattern == pat_end evaluates to true.
|
||||
* - The expression err == std::ios_base::goodbit evaluates to false.
|
||||
* - The expression s == end evaluates to true, in which case the
|
||||
* function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
|
||||
* - The next element of pattern is equal to '%', followed by a conversion
|
||||
* specifier character, the functions @c get_duration or @c get_epoch are called depending on
|
||||
* whether the format is @c 'd' or @c 'e'.
|
||||
* If the number of elements in the range [pattern,pat_end) is not
|
||||
* sufficient to unambiguously determine whether the conversion
|
||||
* specification is complete and valid, the function evaluates
|
||||
* err = std::ios_base::failbit. Otherwise, the function evaluates
|
||||
* s = do_get(s, end, ios, err, d). If err == std::ios_base::goodbit holds after
|
||||
* the evaluation of the expression, the function increments pattern to
|
||||
* point just past the end of the conversion specification and continues
|
||||
* looping.
|
||||
* - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
|
||||
* which case the function first increments pattern until
|
||||
* pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
|
||||
* then advances s until s == end || !isspace(*s, ios.getloc()) is true,
|
||||
* and finally resumes looping.
|
||||
* - The next character read from s matches the element pointed to by
|
||||
* pattern in a case-insensitive comparison, in which case the function
|
||||
* evaluates ++pattern, ++s and continues looping. Otherwise, the function
|
||||
* evaluates err = std::ios_base::failbit.
|
||||
*
|
||||
* Returns: s
|
||||
*/
|
||||
|
||||
template <class Clock, class Duration>
|
||||
iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
|
||||
time_point<Clock, Duration> &tp, const char_type *pattern, const char_type *pat_end) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
|
||||
return get(facet, i, e, is, err, tp, pattern, pat_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
return get(facet, i, e, is, err, tp, pattern, pat_end);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
iter_type get(time_point_units<CharT> const &facet, iter_type s, iter_type end, std::ios_base& ios,
|
||||
std::ios_base::iostate& err, time_point<Clock, Duration> &tp, const char_type *pattern,
|
||||
const char_type *pat_end) const
|
||||
{
|
||||
|
||||
Duration d;
|
||||
bool duration_found = false, epoch_found = false;
|
||||
|
||||
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
|
||||
err = std::ios_base::goodbit;
|
||||
while (pattern != pat_end && err == std::ios_base::goodbit)
|
||||
{
|
||||
if (s == end)
|
||||
{
|
||||
err |= std::ios_base::eofbit;
|
||||
break;
|
||||
}
|
||||
if (ct.narrow(*pattern, 0) == '%')
|
||||
{
|
||||
if (++pattern == pat_end)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
char cmd = ct.narrow(*pattern, 0);
|
||||
switch (cmd)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
if (duration_found)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
duration_found = true;
|
||||
s = get_duration(s, end, ios, err, d);
|
||||
if (err & (std::ios_base::badbit | std::ios_base::failbit))
|
||||
{
|
||||
return s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'e':
|
||||
{
|
||||
if (epoch_found)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return s;
|
||||
}
|
||||
epoch_found = true;
|
||||
s = get_epoch<Clock> (facet, s, end, ios, err);
|
||||
if (err & (std::ios_base::badbit | std::ios_base::failbit))
|
||||
{
|
||||
return s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_ASSERT(false && "Boost::Chrono internal error.");
|
||||
break;
|
||||
}
|
||||
|
||||
++pattern;
|
||||
}
|
||||
else if (ct.is(std::ctype_base::space, *pattern))
|
||||
{
|
||||
for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
|
||||
;
|
||||
for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
|
||||
;
|
||||
}
|
||||
else if (ct.toupper(*s) == ct.toupper(*pattern))
|
||||
{
|
||||
++s;
|
||||
++pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
}
|
||||
}
|
||||
|
||||
// Success! Store it.
|
||||
tp = time_point<Clock, Duration> (d);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s an input stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param d the duration
|
||||
* Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
|
||||
* @code
|
||||
* return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
|
||||
* @codeend
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
|
||||
*/
|
||||
template <class Clock, class Duration>
|
||||
iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
|
||||
time_point<Clock, Duration> &tp) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* As if
|
||||
* @code
|
||||
* return facet.get(s, end, ios, err, d);
|
||||
* @endcode
|
||||
* where @c facet is either the @c duration_get facet associated to the @c ios or an instance of the default @c duration_get facet.
|
||||
*
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid duration.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type get_duration(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
|
||||
duration<Rep, Period>& d) const
|
||||
{
|
||||
if (std::has_facet<duration_get<CharT> >(is.getloc()))
|
||||
{
|
||||
duration_get<CharT> const &facet = std::use_facet<duration_get<CharT> >(is.getloc());
|
||||
return get_duration(facet, i, e, is, err, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_get<CharT> facet;
|
||||
return get_duration(facet, i, e, is, err, d);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
iter_type get_duration(duration_get<CharT> const& facet, iter_type s, iter_type end, std::ios_base& ios,
|
||||
std::ios_base::iostate& err, duration<Rep, Period>& d) const
|
||||
{
|
||||
return facet.get(s, end, ios, err, d);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Effects Let @c facet be the @c time_point_units facet associated to @c is or a new instance of the default @c time_point_units_default facet.
|
||||
* Let @c epoch be the epoch string associated to the Clock using this facet.
|
||||
* Scans @c i to match @c epoch or @c e is reached.
|
||||
*
|
||||
* If not match before the @c e is reached @c std::ios_base::failbit is set in @c err.
|
||||
* If @c e is reached @c std::ios_base::failbit is set in @c err.
|
||||
*
|
||||
* @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid epoch.
|
||||
*/
|
||||
template <class Clock>
|
||||
iter_type get_epoch(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(is.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
|
||||
return get_epoch(facet, i, e, is, err);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
return get_epoch(facet, i, e, is, err);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Clock>
|
||||
iter_type get_epoch(time_point_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base&,
|
||||
std::ios_base::iostate& err) const
|
||||
{
|
||||
const std::basic_string<CharT> epoch = facet.template get_epoch<Clock> ();
|
||||
std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, &epoch, &epoch + 1,
|
||||
//~ std::use_facet<std::ctype<CharT> >(ios.getloc()),
|
||||
err) - &epoch;
|
||||
if (k == 1)
|
||||
{
|
||||
err |= std::ios_base::failbit;
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* @Effects Destroy the facet
|
||||
*/
|
||||
~time_point_get()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
template <class CharT, class InputIterator>
|
||||
std::locale::id time_point_get<CharT, InputIterator>::id;
|
||||
|
||||
} // chrono
|
||||
}
|
||||
// boost
|
||||
|
||||
#endif // header
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
/**
|
||||
* Duration formatting facet for output.
|
||||
*/
|
||||
#ifndef BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
|
||||
#define BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <boost/chrono/io/time_point_units.hpp>
|
||||
#include <boost/chrono/io/duration_put.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <locale>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
/**
|
||||
* @tparam ChatT a character type
|
||||
* @tparam OutputIterator a model of @c OutputIterator
|
||||
*
|
||||
* The @c time_point_put facet provides facilities for formatted output of @c time_point values.
|
||||
* The member function of @c time_point_put take a @c time_point and format it into character string representation.
|
||||
*
|
||||
*/
|
||||
template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
|
||||
class time_point_put: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string passed to member functions.
|
||||
*/
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
/**
|
||||
* Type of iterator used to write in the character buffer.
|
||||
*/
|
||||
typedef OutputIterator iter_type;
|
||||
|
||||
/**
|
||||
* Construct a time_point_put facet.
|
||||
* @param refs
|
||||
* @Effects Construct a time_point_put facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
explicit time_point_put(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param tp the @c time_point
|
||||
* @param pattern begin of the formatting pattern
|
||||
* @param pat_end end of the formatting pattern
|
||||
*
|
||||
* @Effects Steps through the sequence from @c pattern to @c pat_end,
|
||||
* identifying characters that are part of a pattern sequence. Each character
|
||||
* that is not part of a pattern sequence is written to @c s immediately, and
|
||||
* each pattern sequence, as it is identified, results in a call to
|
||||
* @c put_duration or @c put_epoch;
|
||||
* thus, pattern elements and other characters are interleaved in the output
|
||||
* in the order in which they appear in the pattern. Pattern sequences are
|
||||
* identified by converting each character @c c to a @c char value as if by
|
||||
* @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
|
||||
* @c ios.getloc(). The first character of each sequence is equal to @c '%',
|
||||
* followed by a pattern specifier character @c spec, which can be @c 'd' for
|
||||
* the duration value or @c 'e' for the epoch.
|
||||
* For each valid pattern sequence identified, calls
|
||||
* <c>put_duration(s, ios, fill, tp.time_since_epoch())</c> or <c>put_epoch(s, ios)</c>.
|
||||
*
|
||||
* @Returns An iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
|
||||
template <class Clock, class Duration>
|
||||
iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp, const CharT* pattern,
|
||||
const CharT* pat_end) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet =
|
||||
std::use_facet<time_point_units<CharT> >(ios.getloc());
|
||||
return put(facet, i, ios, fill, tp, pattern, pat_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
return put(facet, i, ios, fill, tp, pattern, pat_end);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
iter_type put(time_point_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
|
||||
time_point<Clock, Duration> const& tp, const CharT* pattern, const CharT* pat_end) const
|
||||
{
|
||||
|
||||
const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
|
||||
for (; pattern != pat_end; ++pattern)
|
||||
{
|
||||
if (ct.narrow(*pattern, 0) == '%')
|
||||
{
|
||||
if (++pattern == pat_end)
|
||||
{
|
||||
*s++ = pattern[-1];
|
||||
break;
|
||||
}
|
||||
char fmt = ct.narrow(*pattern, 0);
|
||||
switch (fmt)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
s = put_duration(s, ios, fill, tp.time_since_epoch());
|
||||
break;
|
||||
}
|
||||
case 'e':
|
||||
{
|
||||
s = put_epoch<Clock> (units_facet, s, ios);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_ASSERT(false && "Boost::Chrono internal error.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
*s++ = *pattern;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param tp the @c time_point
|
||||
* @param pattern begin of the formatting pattern
|
||||
* @param pat_end end of the formatting pattern
|
||||
*
|
||||
* @Effects Stores the time_point pattern from the @c time_point_unit facet in let say @c str. Last as if
|
||||
* @code
|
||||
* return put(s, ios, dill, tp, str.data(), str.data() + str.size());
|
||||
* @endcode
|
||||
* @Returns An iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <class Clock, class Duration>
|
||||
iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet =
|
||||
std::use_facet<time_point_units<CharT> >(ios.getloc());
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
std::basic_string<CharT> str = facet.get_pattern();
|
||||
return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @param fill the character used as filler
|
||||
* @param d the @c duration
|
||||
* @Effects As if <c>facet.put(s, ios, fill, d)</c> where facet is the @c duration_put<CharT> facet associated
|
||||
* to the @c ios or a new instance of @c duration_put<CharT>.
|
||||
* @Returns An iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
template <typename Rep, typename Period>
|
||||
iter_type put_duration(iter_type i, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
|
||||
{
|
||||
if (std::has_facet<duration_put<CharT> >(ios.getloc()))
|
||||
{
|
||||
duration_put<CharT> const &facet = std::use_facet<duration_put<CharT> >(ios.getloc());
|
||||
return facet.put(i, ios, fill, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration_put<CharT> facet;
|
||||
return facet.put(i, ios, fill, d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param i an output stream iterator
|
||||
* @param ios a reference to a ios_base
|
||||
* @Effects As if
|
||||
* @code
|
||||
* string_type str = facet.template get_epoch<Clock>();
|
||||
* s=std::copy(str.begin(), str.end(), s);
|
||||
* @endcode
|
||||
* where facet is the @c time_point_units<CharT> facet associated
|
||||
* to the @c ios or a new instance of @c time_point_units_default<CharT>.
|
||||
* @Returns s, iterator pointing immediately after the last character produced.
|
||||
*/
|
||||
|
||||
template <typename Clock>
|
||||
iter_type put_epoch(iter_type i, std::ios_base& os) const
|
||||
{
|
||||
if (std::has_facet<time_point_units<CharT> >(os.getloc()))
|
||||
{
|
||||
time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(os.getloc());
|
||||
return put_epoch<Clock> (facet, i, os);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_point_units_default<CharT> facet;
|
||||
return put_epoch<Clock> (facet, i, os);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Clock>
|
||||
iter_type put_epoch(time_point_units<CharT> const& facet, iter_type s, std::ios_base&) const
|
||||
{
|
||||
string_type str = facet.template get_epoch<Clock>();
|
||||
s= std::copy(str.begin(), str.end(), s);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* @Effects Destroy the facet
|
||||
*/
|
||||
~time_point_put()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class CharT, class OutputIterator>
|
||||
std::locale::id time_point_put<CharT, OutputIterator>::id;
|
||||
|
||||
} // chrono
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,244 @@
|
||||
// (C) Copyright Howard Hinnant
|
||||
// (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).
|
||||
//
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
|
||||
#define BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <boost/chrono/process_cpu_clocks.hpp>
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/thread_clock.hpp>
|
||||
#include <boost/chrono/io/ios_base_state.hpp>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <ios>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
/**
|
||||
* @c time_point_units facet gives useful information about the time_point pattern,
|
||||
* the text associated to a time_point's epoch,
|
||||
*/
|
||||
template <typename CharT=char>
|
||||
class time_point_units: public std::locale::facet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string used by member functions.
|
||||
*/
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
/**
|
||||
* Unique identifier for this type of facet.
|
||||
*/
|
||||
static std::locale::id id;
|
||||
|
||||
/**
|
||||
* Construct a @c time_point_units facet.
|
||||
* @param refs
|
||||
* @Effects Construct a @c time_point_units facet.
|
||||
* If the @c refs argument is @c 0 then destruction of the object is
|
||||
* delegated to the @c locale, or locales, containing it. This allows
|
||||
* the user to ignore lifetime management issues. On the other had,
|
||||
* if @c refs is @c 1 then the object must be explicitly deleted;
|
||||
* the @c locale will not do so. In this case, the object can be
|
||||
* maintained across the lifetime of multiple locales.
|
||||
*/
|
||||
explicit time_point_units(size_t refs = 0) :
|
||||
std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pattern to be used by default.
|
||||
*/
|
||||
virtual string_type get_pattern() const =0;
|
||||
|
||||
/**
|
||||
* @return the epoch associated to the clock @c Clock calling @c do_get_epoch(Clock())
|
||||
*/
|
||||
template <typename Clock>
|
||||
string_type get_epoch() const
|
||||
{
|
||||
return do_get_epoch(Clock());
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Destroy the facet.
|
||||
*/
|
||||
virtual ~time_point_units() {}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c system_clock.
|
||||
* @return The epoch string associated to the @c system_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(system_clock) const=0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c steady_clock.
|
||||
* @return The epoch string associated to the @c steady_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(steady_clock) const=0;
|
||||
|
||||
#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c process_real_cpu_clock.
|
||||
* @return The epoch string associated to the @c process_real_cpu_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c process_user_cpu_clock.
|
||||
* @return The epoch string associated to the @c process_user_cpu_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(process_user_cpu_clock) const=0;
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c process_system_cpu_clock.
|
||||
* @return The epoch string associated to the @c process_system_cpu_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(process_system_cpu_clock) const=0;
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c process_cpu_clock.
|
||||
* @return The epoch string associated to the @c process_cpu_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(process_cpu_clock) const=0;
|
||||
#endif
|
||||
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
|
||||
/**
|
||||
*
|
||||
* @param c a dummy instance of @c thread_clock.
|
||||
* @return The epoch string associated to the @c thread_clock.
|
||||
*/
|
||||
virtual string_type do_get_epoch(thread_clock) const=0;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
std::locale::id time_point_units<CharT>::id;
|
||||
|
||||
|
||||
// This class is used to define the strings for the default English
|
||||
template <typename CharT=char>
|
||||
class time_point_units_default: public time_point_units<CharT>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Type of character the facet is instantiated on.
|
||||
*/
|
||||
typedef CharT char_type;
|
||||
/**
|
||||
* Type of character string returned by member functions.
|
||||
*/
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
explicit time_point_units_default(size_t refs = 0) :
|
||||
time_point_units<CharT> (refs)
|
||||
{
|
||||
}
|
||||
~time_point_units_default() {}
|
||||
|
||||
/**
|
||||
* @return the default pattern "%d%e".
|
||||
*/
|
||||
string_type get_pattern() const
|
||||
{
|
||||
static const CharT t[] =
|
||||
{ '%', 'd', '%', 'e' };
|
||||
static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @param c a dummy instance of @c system_clock.
|
||||
* @return The epoch string returned by @c clock_string<system_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(system_clock ) const
|
||||
{
|
||||
return clock_string<system_clock,CharT>::since();
|
||||
}
|
||||
/**
|
||||
* @param c a dummy instance of @c steady_clock.
|
||||
* @return The epoch string returned by @c clock_string<steady_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(steady_clock ) const
|
||||
{
|
||||
return clock_string<steady_clock,CharT>::since();
|
||||
}
|
||||
|
||||
#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
|
||||
/**
|
||||
* @param c a dummy instance of @c process_real_cpu_clock.
|
||||
* @return The epoch string returned by @c clock_string<process_real_cpu_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(process_real_cpu_clock ) const
|
||||
{
|
||||
return clock_string<process_real_cpu_clock,CharT>::since();
|
||||
}
|
||||
/**
|
||||
* @param c a dummy instance of @c process_user_cpu_clock.
|
||||
* @return The epoch string returned by @c clock_string<process_user_cpu_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(process_user_cpu_clock ) const
|
||||
{
|
||||
return clock_string<process_user_cpu_clock,CharT>::since();
|
||||
}
|
||||
/**
|
||||
* @param c a dummy instance of @c process_system_cpu_clock.
|
||||
* @return The epoch string returned by @c clock_string<process_system_cpu_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(process_system_cpu_clock ) const
|
||||
{
|
||||
return clock_string<process_system_cpu_clock,CharT>::since();
|
||||
}
|
||||
/**
|
||||
* @param c a dummy instance of @c process_cpu_clock.
|
||||
* @return The epoch string returned by @c clock_string<process_cpu_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(process_cpu_clock ) const
|
||||
{
|
||||
return clock_string<process_cpu_clock,CharT>::since();
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
|
||||
/**
|
||||
* @param c a dummy instance of @c thread_clock.
|
||||
* @return The epoch string returned by @c clock_string<thread_clock,CharT>::since().
|
||||
*/
|
||||
string_type do_get_epoch(thread_clock ) const
|
||||
{
|
||||
return clock_string<thread_clock,CharT>::since();
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // chrono
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,30 @@
|
||||
// (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 to Boost
|
||||
|
||||
#ifndef BOOST_CHRONO_IO_TIMEZONE_HPP
|
||||
#define BOOST_CHRONO_IO_TIMEZONE_HPP
|
||||
#include <boost/detail/scoped_enum_emulation.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
/**
|
||||
* Scoped enumeration emulation stating whether the time_point for system_clock I/O is UTC or local.
|
||||
*/
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(timezone)
|
||||
{
|
||||
utc, local
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(timezone)
|
||||
|
||||
} // chrono
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,435 @@
|
||||
// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
|
||||
|
||||
// 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_UTILITY_IOS_BASE_STATE_PTR_HPP
|
||||
#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
|
||||
|
||||
#include <ios>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/**
|
||||
* xalloc key holder.
|
||||
*/
|
||||
template <typename T>
|
||||
struct xalloc_key_holder
|
||||
{
|
||||
static int value; //< the xalloc value associated to T.
|
||||
static bool initialized; //< whether the value has been initialized or not.
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
int xalloc_key_holder<T>::value = 0;
|
||||
|
||||
template <typename T>
|
||||
bool xalloc_key_holder<T>::initialized = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* xalloc key initialiazer.
|
||||
*
|
||||
* Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
|
||||
*/
|
||||
template <typename T>
|
||||
struct xalloc_key_initializer
|
||||
{
|
||||
xalloc_key_initializer()
|
||||
{
|
||||
if (!detail::xalloc_key_holder<T>::initialized)
|
||||
{
|
||||
detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
|
||||
detail::xalloc_key_holder<T>::initialized = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @c ios_state_ptr is a smart pointer to a ios_base specific state.
|
||||
*/
|
||||
template <typename Final, typename T>
|
||||
class ios_state_ptr
|
||||
{
|
||||
ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
|
||||
|
||||
public:
|
||||
/**
|
||||
* The pointee type
|
||||
*/
|
||||
typedef T element_type;
|
||||
/**
|
||||
* Explicit constructor.
|
||||
* @param ios the ios
|
||||
* @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
|
||||
*/
|
||||
explicit ios_state_ptr(std::ios_base& ios) :
|
||||
ios_(ios)
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Nothing to do as xalloc index can not be removed.
|
||||
*/
|
||||
~ios_state_ptr()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Effects Allocates the index if not already done.
|
||||
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
|
||||
* Retrieves the associated ios pointer
|
||||
* @return the retrieved pointer statically casted to const.
|
||||
*/
|
||||
T const* get() const BOOST_NOEXCEPT
|
||||
{
|
||||
register_once(index(), ios_);
|
||||
void* &pw = ios_.pword(index());
|
||||
if (pw == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return static_cast<const T*> (pw);
|
||||
}
|
||||
/**
|
||||
* @Effects Allocates the index if not already done.
|
||||
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
|
||||
* Retrieves the associated ios pointer
|
||||
* @return the retrieved pointer.
|
||||
*/
|
||||
T * get() BOOST_NOEXCEPT
|
||||
{
|
||||
register_once(index(), ios_);
|
||||
void* &pw = ios_.pword(index());
|
||||
if (pw == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return static_cast<T*> (pw);
|
||||
}
|
||||
/**
|
||||
* @Effects as if @c return get();
|
||||
* @return the retrieved pointer.
|
||||
*/
|
||||
T * operator->()BOOST_NOEXCEPT
|
||||
{
|
||||
return get();
|
||||
}
|
||||
/**
|
||||
* @Effects as if @c return get();
|
||||
* @return the retrieved pointer.
|
||||
*/
|
||||
T const * operator->() const BOOST_NOEXCEPT
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Effects as if @c return *get();
|
||||
* @return a reference to the retrieved state.
|
||||
* @Remark The behavior is undefined if @c get()==0.
|
||||
*/
|
||||
T & operator*() BOOST_NOEXCEPT
|
||||
{
|
||||
return *get();
|
||||
}
|
||||
/**
|
||||
* @Effects as if @c return *get();
|
||||
* @return a reference to the retrieved state.
|
||||
* @Remark The behavior is undefined if @c get()==0.
|
||||
*/
|
||||
T const & operator *() const BOOST_NOEXCEPT
|
||||
{
|
||||
return *get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
|
||||
* @return the stored state pointer.
|
||||
*/
|
||||
T * release() BOOST_NOEXCEPT
|
||||
{
|
||||
T const* f = get();
|
||||
reset();
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param new_ptr the new pointer.
|
||||
* @Effects deletes the current state and replace it with the new one.
|
||||
*/
|
||||
void reset(T* new_ptr = 0)BOOST_NOEXCEPT
|
||||
{
|
||||
register_once(index(), ios_);
|
||||
void*& pw = ios_.pword(index());
|
||||
delete static_cast<T*> (pw);
|
||||
pw = new_ptr;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef T* (ios_state_ptr::*bool_type)();
|
||||
operator bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return (get()!=0)?&ios_state_ptr::release:0;
|
||||
}
|
||||
bool operator!() const BOOST_NOEXCEPT
|
||||
{
|
||||
return (get()==0)?&ios_state_ptr::release:0;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Explicit conversion to bool.
|
||||
*/
|
||||
explicit operator bool() const BOOST_NOEXCEPT
|
||||
{
|
||||
return get()!=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::ios_base& getios()BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
std::ios_base& getios() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
/**
|
||||
* Implicit conversion to the ios_base
|
||||
*/
|
||||
operator std::ios_base&() BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
/**
|
||||
* Implicit conversion to the ios_base const
|
||||
*/
|
||||
operator std::ios_base&() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
private:
|
||||
static inline bool is_registerd(std::ios_base& ios)
|
||||
{
|
||||
long iw = ios.iword(index());
|
||||
return (iw == 1);
|
||||
}
|
||||
static inline void set_registered(std::ios_base& ios)
|
||||
{
|
||||
long& iw = ios.iword(index());
|
||||
iw = 1;
|
||||
}
|
||||
static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
|
||||
{
|
||||
switch (evt)
|
||||
{
|
||||
case std::ios_base::erase_event:
|
||||
{
|
||||
void*& pw = ios.pword(index);
|
||||
if (pw != 0)
|
||||
{
|
||||
T* ptr = static_cast<T*> (pw);
|
||||
delete ptr;
|
||||
pw = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case std::ios_base::copyfmt_event:
|
||||
{
|
||||
void*& pw = ios.pword(index);
|
||||
if (pw != 0)
|
||||
{
|
||||
pw = new T(*static_cast<T*> (pw));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int index()
|
||||
{
|
||||
return detail::xalloc_key_holder<Final>::value;
|
||||
}
|
||||
|
||||
static inline void register_once(int indx, std::ios_base& ios)
|
||||
{
|
||||
// needs a mask registered
|
||||
if (!is_registerd(ios))
|
||||
{
|
||||
set_registered(ios);
|
||||
ios.register_callback(callback, indx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::ios_base& ios_;
|
||||
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
|
||||
|
||||
};
|
||||
//template <typename Final, typename T>
|
||||
//detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
|
||||
|
||||
|
||||
/**
|
||||
* @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
|
||||
* @tparm T
|
||||
* @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
|
||||
*/
|
||||
template <typename Final, typename T>
|
||||
class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
|
||||
{
|
||||
typedef ios_state_ptr<Final, T> base_type;
|
||||
public:
|
||||
explicit ios_state_not_null_ptr(std::ios_base& ios) :
|
||||
base_type(ios)
|
||||
{
|
||||
if (this->get() == 0)
|
||||
{
|
||||
this->base_type::reset(new T());
|
||||
}
|
||||
}
|
||||
~ios_state_not_null_ptr()
|
||||
{
|
||||
}
|
||||
|
||||
void reset(T* new_value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(new_value!=0);
|
||||
this->base_type::reset(new_value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is useful to associate some flags to an std::ios_base.
|
||||
*/
|
||||
template <typename Final>
|
||||
class ios_flags
|
||||
{
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* @param ios the associated std::ios_base.
|
||||
* @Postcondition <c>flags()==0</c>
|
||||
*/
|
||||
explicit ios_flags(std::ios_base& ios) :
|
||||
ios_(ios)
|
||||
{
|
||||
}
|
||||
~ios_flags()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @Returns The format control information.
|
||||
*/
|
||||
long flags() const BOOST_NOEXCEPT
|
||||
{
|
||||
return value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v the new bit mask.
|
||||
* @Postcondition <c>v == flags()</c>.
|
||||
* @Returns The previous value of @c flags().
|
||||
*/
|
||||
long flags(long v)BOOST_NOEXCEPT
|
||||
{
|
||||
long tmp = flags();
|
||||
ref() = v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v the new value
|
||||
* @Effects: Sets @c v in @c flags().
|
||||
* @Returns: The previous value of @c flags().
|
||||
*/
|
||||
long setf(long v)
|
||||
{
|
||||
long tmp = value();
|
||||
ref() |= v;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mask the bit mask to clear.
|
||||
* @Effects: Clears @c mask in @c flags().
|
||||
*/
|
||||
void unsetf(long mask)
|
||||
{
|
||||
ref() &= ~mask;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param v
|
||||
* @param mask
|
||||
* @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
|
||||
* @Returns: The previous value of flags().
|
||||
*/
|
||||
long setf(long v, long mask)
|
||||
{
|
||||
long tmp = value();
|
||||
unsetf(mask);
|
||||
ref() |= v & mask;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* implicit conversion to the @c ios_base
|
||||
*/
|
||||
operator std::ios_base&()BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
/**
|
||||
* implicit conversion to the @c ios_base const
|
||||
*/
|
||||
operator std::ios_base const&() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_;
|
||||
}
|
||||
private:
|
||||
long value() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_.iword(index());
|
||||
}
|
||||
long& ref()BOOST_NOEXCEPT
|
||||
{
|
||||
return ios_.iword(index());
|
||||
}
|
||||
static inline int index()
|
||||
{
|
||||
return detail::xalloc_key_holder<Final>::value;
|
||||
}
|
||||
ios_flags& operator=(ios_flags const& rhs) ;
|
||||
|
||||
std::ios_base& ios_;
|
||||
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
|
||||
|
||||
};
|
||||
//template <typename Final>
|
||||
//detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
|
||||
|
||||
} // namespace chrono
|
||||
} // namespace boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,101 @@
|
||||
// boost/chrono/utility/manip_base.hpp ------------------------------------------------------------//
|
||||
|
||||
// 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_UTILITY_MANIP_BASE_PTR_HPP
|
||||
#define BOOST_CHRONO_UTILITY_MANIP_BASE_PTR_HPP
|
||||
|
||||
#include <ios>
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
/**
|
||||
* manip is a manipulator mixin class following the CRTP.
|
||||
* @tparam Final the derived from manip and final type
|
||||
*
|
||||
* @Example
|
||||
* @code
|
||||
|
||||
class mendl: public manip<mendl>
|
||||
{
|
||||
public:
|
||||
explicit mendl(size_t how_many) :
|
||||
count(how_many) {}
|
||||
template <typename out_stream>
|
||||
void operator()(out_stream &out) const
|
||||
{
|
||||
for (size_t line = 0; line < count; ++line)
|
||||
{
|
||||
out.put(out.widen('\n'));
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
private:
|
||||
size_t count;
|
||||
};
|
||||
|
||||
* @codeend
|
||||
*/
|
||||
template <typename Final>
|
||||
class manip
|
||||
{
|
||||
public:
|
||||
/**
|
||||
*
|
||||
* @param ios the io stream or ios_base.
|
||||
* @Effects calls to the manipulator final functor.
|
||||
*/
|
||||
//template <typename out_stream>
|
||||
void operator()(std::ios_base &ios) const
|
||||
{
|
||||
(*static_cast<const Final *> (this))(ios);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @c manip stream inserter
|
||||
* @param out the io stream or ios_base.
|
||||
* @param op the manipulator instance.
|
||||
* @Effects if @c out is good calls to the manipulator functor @op.
|
||||
* @return @c out
|
||||
*/
|
||||
template <typename out_stream, typename manip_type>
|
||||
out_stream &operator<<(out_stream &out, const manip<manip_type> &op)
|
||||
{
|
||||
if (out.good())
|
||||
op(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @c manip stream extractor
|
||||
* @param in the io stream or ios_base.
|
||||
* @param op the manipulator instance.
|
||||
* @Effects if @c in is good calls to the manipulator functor @op.
|
||||
* @return @c in
|
||||
*/
|
||||
template <typename in_stream, typename manip_type>
|
||||
in_stream &operator>>(in_stream &in, const manip<manip_type> &op)
|
||||
{
|
||||
if (in.good())
|
||||
op(in);
|
||||
return in;
|
||||
}
|
||||
|
||||
} // namespace chrono
|
||||
} // namespace boost
|
||||
|
||||
#endif // header
|
||||
@@ -0,0 +1,50 @@
|
||||
// boost/chrono/utility/to_string.hpp
|
||||
//
|
||||
// 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).
|
||||
|
||||
#ifndef BOOST_CHRONO_UTILITY_TO_STRING_HPP
|
||||
#define BOOST_CHRONO_UTILITY_TO_STRING_HPP
|
||||
|
||||
#include <boost/chrono/config.hpp>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
template <typename CharT, typename T>
|
||||
std::basic_string<CharT> to_basic_string(T const&v) {
|
||||
std::basic_stringstream<CharT> sstr;
|
||||
sstr << v;
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(T const&v) {
|
||||
return to_basic_string<char>(v);
|
||||
}
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
template <typename T>
|
||||
std::wstring to_wstring(T const&v) {
|
||||
return to_basic_string<wchar_t>(v);
|
||||
}
|
||||
#endif
|
||||
#if BOOST_CHRONO_HAS_UNICODE_SUPPORT
|
||||
template <typename T>
|
||||
std::basic_string<char16_t> to_u16string(T const&v) {
|
||||
return to_basic_string<char16_t>(v);
|
||||
}
|
||||
template <typename T>
|
||||
std::basic_string<char32_t> to_u32string(T const&v) {
|
||||
return to_basic_string<char32_t>(v);
|
||||
}
|
||||
#endif
|
||||
} // chrono
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // header
|
||||
@@ -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
|
||||
@@ -0,0 +1,510 @@
|
||||
// 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>
|
||||
#include <boost/chrono/detail/system.hpp>
|
||||
#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
|
||||
@@ -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
|
||||
@@ -0,0 +1,233 @@
|
||||
// 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.
|
||||
* 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>
|
||||
#include <boost/chrono/detail/system.hpp>
|
||||
#include <boost/chrono/clock_string.hpp>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
# if defined( BOOST_CHRONO_POSIX_API )
|
||||
# if ! defined(CLOCK_REALTIME)
|
||||
# error <time.h> does not supply CLOCK_REALTIME
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#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
|
||||
|
||||
// this must occur after all of the includes and before any code appears:
|
||||
#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
|
||||
// the suffix header occurs after all of our code:
|
||||
#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
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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>
|
||||
#include <boost/chrono/detail/system.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 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', 'a', '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', 'h', '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
|
||||
@@ -0,0 +1,379 @@
|
||||
// duration.hpp --------------------------------------------------------------//
|
||||
|
||||
// Copyright 2008 Howard Hinnant
|
||||
// Copyright 2008 Beman Dawes
|
||||
// Copyright 2009-2012 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>
|
||||
|
||||
#ifndef BOOST_CHRONO_HEADER_ONLY
|
||||
// this must occur after all of the includes and before any code appears:
|
||||
#include <boost/config/abi_prefix.hpp> // must be the last #include
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// 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_CHRONO_LIB_CONSTEXPR time_point
|
||||
min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
return time_point((duration::min)());
|
||||
}
|
||||
static BOOST_CHRONO_LIB_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
|
||||
|
||||
#ifndef BOOST_CHRONO_HEADER_ONLY
|
||||
// the suffix header occurs after all of our code:
|
||||
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CHRONO_TIME_POINT_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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user