1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-10 00:06:32 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 2010.
// 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/stm for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CHRONO_HPP
#define BOOST_CHRONO_HPP
//-----------------------------------------------------------------------------
#include <boost/chrono/include.hpp>
//-----------------------------------------------------------------------------
#endif // BOOST_CHRONO_HPP

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,216 @@
// boost/chrono/config.hpp -------------------------------------------------//
// Copyright Beman Dawes 2003, 2006, 2008
// Copyright 2009-2011 Vicente J. Botet Escriba
// Copyright (c) Microsoft Corporation 2014
// 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>
#include <boost/predef.h>
#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
# if BOOST_PLAT_WINDOWS_DESKTOP
# define BOOST_CHRONO_HAS_THREAD_CLOCK
# endif
# 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_HAS_THREAD_CLOCK
# 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(__GNUC__)) && 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
// 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
#ifndef BOOST_CHRONO_LIB_CONSTEXPR
#if defined( BOOST_NO_CXX11_NUMERIC_LIMITS )
#define BOOST_CHRONO_LIB_CONSTEXPR
#elif defined(_LIBCPP_VERSION) && !defined(_LIBCPP_CONSTEXPR)
#define BOOST_CHRONO_LIB_CONSTEXPR
#else
#define BOOST_CHRONO_LIB_CONSTEXPR BOOST_CONSTEXPR
#endif
#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

View File

@@ -0,0 +1,46 @@
// 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>
#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING
#include <boost/system/system_error.hpp>
#endif
#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

View File

@@ -0,0 +1,242 @@
// 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
#include <boost/assert.hpp>
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()
{
kern_return_t err;
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)
{
kern_return_t err;
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::system::system_category(),
"chrono::steady_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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
{
kern_return_t err;
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)
{
kern_return_t err;
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::system::system_category(),
"chrono::steady_clock" ));
}
else
{
ec.assign( err, ::boost::system::system_category() );
return time_point();
}
}
if (!::boost::chrono::is_throws(ec))
{
ec.clear();
}
return time_point(duration(fp(ec)));
}
#endif
} // namespace chrono
} // namespace boost

View File

@@ -0,0 +1,356 @@
// 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
{
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 1
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");
} 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();
#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 1
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::system::system_category(), "chrono::process_real_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_real_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_real_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_real_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::system_category());
return time_point();
}
}
}
#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::system::system_category(), "chrono::process_user_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_user_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_system_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_system_cpu_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_clock"));
} else
{
ec.assign(errno, ::boost::system::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::system::system_category(), "chrono::process_clock"));
} else
{
ec.assign(errno, ::boost::system::system_category());
return time_point();
}
}
}
}
#endif
}
}

View File

@@ -0,0 +1,92 @@
// boost thread_clock.cpp -----------------------------------------------------------//
// Copyright Beman Dawes 1994, 2006, 2008
// Copyright Vicente J. Botet Escriba 2009-2011
// Copyright Christopher Brown 2013
// 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 <boost/assert.hpp>
# include <pthread.h>
# include <mach/thread_act.h>
namespace boost { namespace chrono {
thread_clock::time_point thread_clock::now( ) BOOST_NOEXCEPT
{
// get the thread port (borrowing pthread's reference)
mach_port_t port = pthread_mach_thread_np(pthread_self());
// get the thread info
thread_basic_info_data_t info;
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
if ( thread_info(port, THREAD_BASIC_INFO, (thread_info_t)&info, &count) != KERN_SUCCESS )
{
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
return time_point();
}
// convert to nanoseconds
duration user = duration(
static_cast<thread_clock::rep>( info.user_time.seconds ) * 1000000000
+ static_cast<thread_clock::rep>(info.user_time.microseconds ) * 1000);
duration system = duration(
static_cast<thread_clock::rep>( info.system_time.seconds ) * 1000000000
+ static_cast<thread_clock::rep>( info.system_time.microseconds ) * 1000);
return time_point( user + system );
}
#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
thread_clock::time_point thread_clock::now( system::error_code & ec )
{
// get the thread port (borrowing pthread's reference)
mach_port_t port = pthread_mach_thread_np(pthread_self());
// get the thread info
thread_basic_info_data_t info;
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
if ( thread_info(port, THREAD_BASIC_INFO, (thread_info_t)&info, &count) != KERN_SUCCESS )
{
if (::boost::chrono::is_throws(ec))
{
boost::throw_exception(
system::system_error(
EINVAL,
::boost::system::system_category(),
"chrono::thread_clock" ));
}
else
{
ec.assign( errno, ::boost::system::system_category() );
return time_point();
}
}
if (!::boost::chrono::is_throws(ec))
{
ec.clear();
}
// convert to nanoseconds
duration user = duration(
static_cast<thread_clock::rep>( info.user_time.seconds ) * 1000000000
+ static_cast<thread_clock::rep>(info.user_time.microseconds ) * 1000);
duration system = duration(
static_cast<thread_clock::rep>( info.system_time.seconds ) * 1000000000
+ static_cast<thread_clock::rep>( info.system_time.microseconds ) * 1000);
return time_point( user + system );
}
#endif
} }

View File

@@ -0,0 +1,141 @@
// 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
#include <boost/assert.hpp>
#include <boost/predef/os.h>
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::system::system_category(),
"chrono::system_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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 BOOST_OS_CYGWIN
// lack of thread safety in high resolution timer initialization
// can lead to a timespec of zero without an error; was reported
// to the cygwin mailing list and can be removed once fixed
do
{
#endif
if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
{
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
}
#if BOOST_OS_CYGWIN
} while (ts.tv_sec == 0 && ts.tv_nsec == 0);
#endif
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 BOOST_OS_CYGWIN
// lack of thread safety in high resolution timer initialization
// can lead to a timespec of zero without an error; was reported
// to the cygwin mailing list and can be removed once fixed
do
{
#endif
if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
{
if (::boost::chrono::is_throws(ec))
{
boost::throw_exception(
system::system_error(
errno,
::boost::system::system_category(),
"chrono::steady_clock" ));
}
else
{
ec.assign( errno, ::boost::system::system_category() );
return time_point();
}
}
#if BOOST_OS_CYGWIN
} while (ts.tv_sec == 0 && ts.tv_nsec == 0);
#endif
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

View File

@@ -0,0 +1,354 @@
// 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 nanoseconds::rep tick_factor() // multiplier to convert ticks
// to nanoseconds; -1 if unknown
{
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::system::system_category(),
"chrono::process_real_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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::system::system_category(),
"chrono::process_real_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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::system::system_category(),
"chrono::process_user_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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::system::system_category(),
"chrono::process_user_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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::system::system_category(),
"chrono::process_system_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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::system::system_category(),
"chrono::process_system_cpu_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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
{
nanoseconds::rep 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::system::system_category(),
"chrono::process_clock" ));
}
else
{
ec.assign( errno, ::boost::system::system_category() );
return time_point();
}
}
else
{
if ( chrono_detail::tick_factor() != -1 )
{
time_point::rep r(
c*chrono_detail::tick_factor(),
(tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(),
(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::system::system_category(),
"chrono::process_clock" ));
}
else
{
ec.assign( errno, ::boost::system::system_category() );
return time_point();
}
}
}
}
#endif
} }

View File

@@ -0,0 +1,92 @@
// 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 <boost/assert.hpp>
#if !defined(__VXWORKS__)
# include <sys/times.h>
#endif
# 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::system::system_category(),
"chrono::thread_clock" ));
}
else
{
ec.assign( errno, ::boost::system::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
} }

View File

@@ -0,0 +1,46 @@
// 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>
#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING
#include <boost/system/system_error.hpp>
#endif
//----------------------------------------------------------------------------//
// 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

View File

@@ -0,0 +1,46 @@
// 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>
#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING
#include <boost/system/system_error.hpp>
#endif
#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

View File

@@ -0,0 +1,151 @@
// 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/winapi/time.hpp>
#include <boost/winapi/timers.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/winapi/error_codes.hpp>
#include <boost/assert.hpp>
namespace boost
{
namespace chrono
{
namespace chrono_detail
{
BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT
{
boost::winapi::LARGE_INTEGER_ freq;
if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
return 0.0L;
return double(1000000000.0L / freq.QuadPart);
}
}
steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT
{
double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
boost::winapi::LARGE_INTEGER_ pcount;
if ( nanosecs_per_tic <= 0.0L )
{
BOOST_ASSERT(0 && "Boost::Chrono - get_nanosecs_per_tic Internal Error");
return steady_clock::time_point();
}
unsigned times=0;
while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
{
if ( ++times > 3 )
{
BOOST_ASSERT(0 && "Boost::Chrono - QueryPerformanceCounter 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 )
{
double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
boost::winapi::LARGE_INTEGER_ pcount;
if ( (nanosecs_per_tic <= 0.0L)
|| (!boost::winapi::QueryPerformanceCounter( &pcount )) )
{
boost::winapi::DWORD_ cause =
((nanosecs_per_tic <= 0.0L)
? boost::winapi::ERROR_NOT_SUPPORTED_
: boost::winapi::GetLastError());
if (::boost::chrono::is_throws(ec)) {
boost::throw_exception(
system::system_error(
cause,
::boost::system::system_category(),
"chrono::steady_clock" ));
}
else
{
ec.assign( cause, ::boost::system::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::winapi::FILETIME_ ft;
boost::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
return system_clock::time_point(
system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
- 116444736000000000LL
//- (134775LL*864000000000LL)
)
);
}
#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now( system::error_code & ec )
{
boost::winapi::FILETIME_ ft;
boost::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
if (!::boost::chrono::is_throws(ec))
{
ec.clear();
}
return system_clock::time_point(
system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
- 116444736000000000LL
//- (134775LL*864000000000LL)
));
}
#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

View File

@@ -0,0 +1,281 @@
// boost process_timer.cpp -----------------------------------------------------------//
// Copyright Beman Dawes 1994, 2006, 2008
// Copyright 2009-2010 Vicente J. Botet Escriba
// Copyright (c) Microsoft Corporation 2014
// 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/process_cpu_clocks.hpp>
#include <cassert>
#include <time.h>
#include <boost/assert.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/winapi/get_current_process.hpp>
#if BOOST_PLAT_WINDOWS_DESKTOP
#include <boost/winapi/get_process_times.hpp>
#endif
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::system::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
#if BOOST_PLAT_WINDOWS_DESKTOP
process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT
{
// note that Windows uses 100 nanosecond ticks for FILETIME
boost::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::DWORD_ cause = boost::winapi::GetLastError();
if (::boost::chrono::is_throws(ec))
{
boost::throw_exception(
system::system_error(
cause,
::boost::system::system_category(),
"chrono::process_user_cpu_clock" ));
}
else
{
ec.assign( cause, ::boost::system::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::DWORD_ cause = boost::winapi::GetLastError();
if (::boost::chrono::is_throws(ec))
{
boost::throw_exception(
system::system_error(
cause,
::boost::system::system_category(),
"chrono::process_system_cpu_clock" ));
}
else
{
ec.assign( cause, ::boost::system::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetProcessTimes(
boost::winapi::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::winapi::DWORD_ cause = boost::winapi::GetLastError();
if (::boost::chrono::is_throws(ec))
{
boost::throw_exception(
system::system_error(
cause,
::boost::system::system_category(),
"chrono::process_cpu_clock" ));
}
else
{
ec.assign( cause, ::boost::system::system_category() );
return time_point();
}
}
}
#endif
#endif
} // namespace chrono
} // namespace boost
#endif

View File

@@ -0,0 +1,103 @@
// 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/assert.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/winapi/get_current_thread.hpp>
#include <boost/winapi/get_thread_times.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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetThreadTimes(
boost::winapi::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::winapi::GetLastError(),
::boost::system::system_category(),
"chrono::thread_clock" ));
}
else
{
ec.assign( boost::winapi::GetLastError(), ::boost::system::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::winapi::FILETIME_ creation, exit, user_time, system_time;
if ( boost::winapi::GetThreadTimes(
boost::winapi::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

View File

@@ -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

View File

@@ -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

View File

@@ -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/move/unique_ptr.hpp>
#include <ios>
#include <exception>
#include <stdlib.h>
#include <boost/throw_exception.hpp>
namespace boost {
using movelib::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

View File

@@ -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

View File

@@ -0,0 +1,20 @@
// 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/system/error_code.hpp>
namespace boost {
namespace chrono {
inline bool is_throws(system::error_code & ec) { return (&ec==&boost::throws()); }
}
}
#endif
#endif

View File

@@ -0,0 +1,798 @@
// 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:
#if defined BOOST_CHRONO_DURATION_DEFAULTS_TO_ZERO
BOOST_FORCEINLINE BOOST_CONSTEXPR
duration() : rep_(duration_values<rep>::zero()) { }
#elif defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
BOOST_CONSTEXPR duration() {}
#else
BOOST_CONSTEXPR duration() = default;
#endif
template <class Rep2>
BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE 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) { }
#if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
duration& operator=(const duration& rhs)
{
if (&rhs != this) rep_= rhs.rep_;
return *this;
}
#else
duration& operator=(const duration& rhs) = default;
#endif
// conversions
template <class Rep2, class Period2>
BOOST_FORCEINLINE 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 common_duration;
return common_duration(common_duration(lhs).count()+common_duration(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 common_duration;
return common_duration(common_duration(lhs).count()-common_duration(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 common_rep;
typedef duration<common_rep, Period> common_duration;
return common_duration(common_duration(d).count()*static_cast<common_rep>(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 common_rep;
typedef duration<common_rep, Period> common_duration;
return common_duration(common_duration(d).count()/static_cast<common_rep>(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 common_duration;
return common_duration(lhs).count() / common_duration(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 common_rep;
typedef duration<common_rep, Period> common_duration;
return static_cast<common_rep>(s)/common_duration(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 common_rep;
typedef duration<common_rep, Period> common_duration;
return common_duration(common_duration(d).count()%static_cast<common_rep>(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 common_duration;
return common_duration(common_duration(lhs).count()%common_duration(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) const
{
typedef typename common_type<LhsDuration, RhsDuration>::type common_duration;
return common_duration(lhs).count() == common_duration(rhs).count();
}
};
template <class LhsDuration>
struct duration_eq<LhsDuration, LhsDuration>
{
BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
{
return lhs.count() == rhs.count();
}
};
template <class LhsDuration, class RhsDuration>
struct duration_lt
{
BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
{
typedef typename common_type<LhsDuration, RhsDuration>::type common_duration;
return common_duration(lhs).count() < common_duration(rhs).count();
}
};
template <class LhsDuration>
struct duration_lt<LhsDuration, LhsDuration>
{
BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
{
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

View File

@@ -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_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)
{
To t = duration_cast<To>(d);
if (t>d) --t;
return t;
}
} // namespace chrono
} // namespace boost
#endif

View File

@@ -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

View File

@@ -0,0 +1,591 @@
// (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/integer/common_factor_rt.hpp>
#include <boost/chrono/detail/scan_keyword.hpp>
#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp>
#include <boost/chrono/process_cpu_clocks.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 <class Rep>
struct duration_io_intermediate<process_times<Rep>, false>
{
typedef process_times<typename duration_io_intermediate<Rep>::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 = integer::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 = integer::gcd<unsigned long long>(num, Period::num);
unsigned long long gcd_d1_d2 = integer::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 > duration_values<common_type_t>::zero())
{
if ( (duration_values<Rep>::max)() < Rep(t))
{
// Conversion to Period overflowed
err |= std::ios_base::failbit;
return s;
}
}
// Success! Store it.
d = duration<Rep, Period> (Rep(t));
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);
}
template <typename Rep>
iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, process_times<Rep>& r) const
{
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != '{') { // mandatory '{'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.real);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != ';') { // mandatory ';'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.user);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != ';') { // mandatory ';'
err |= std::ios_base::failbit;
return s;
}
++s;
s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.system);
if (s == end) {
err |= std::ios_base::eofbit;
return s;
} else if (*s != '}') { // mandatory '}'
err |= std::ios_base::failbit;
return s;
}
return s;
}
/**
*
* @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 i 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 (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return i;
}
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 i 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 (err & (std::ios_base::badbit | std::ios_base::failbit))
{
return i;
}
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

View File

@@ -0,0 +1,295 @@
// (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/core/no_exceptions_support.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <locale>
#include <iosfwd>
#include <sstream>
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))
{
}
/**
* 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 new_value @c duration_style to set.
*/
duration_style_io_saver(state_type &s, aspect_type new_value) :
s_save_(s), a_save_(get_duration_style(s))
{
set_duration_style(s, 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_;
};
template <class Rep>
struct duration_put_enabled
: integral_constant<bool,
is_integral<Rep>::value || is_floating_point<Rep>::value
>
{};
/**
* 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>
typename boost::enable_if_c< ! duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT, Traits> ostr;
ostr << d.count();
duration<int, Period> dd(0);
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(), dd, ostr.str().c_str()) .failed())
{
err = std::ios_base::badbit;
}
}
else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), dd, ostr.str().c_str()) .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;
}
template <class CharT, class Traits, class Rep, class Period>
typename boost::enable_if_c< duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
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

View File

@@ -0,0 +1,317 @@
// (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/chrono/process_cpu_clocks.hpp>
#include <boost/assert.hpp>
#include <locale>
namespace boost
{
namespace chrono
{
namespace detail
{
template <class T>
struct propagate {
typedef T type;
};
template <>
struct propagate<boost::int_least32_t> {
typedef boost::int_least64_t type;
};
}
/**
* @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 char_type* val = 0) 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, val);
}
else
{
duration_units_default<CharT> facet;
return put(facet, s, ios, fill, d, pattern, pat_end, val);
}
}
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 char_type* val = 0) 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, val);
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 char_type* val = 0) 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(), val);
}
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(), val);
}
}
/**
*
* @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 char_type* val = 0) const
{
if (val)
{
while (*val) {
*s = *val;
s++; val++;
}
return s;
}
return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
static_cast<typename detail::propagate<Rep>::type> (d.count()));
}
template <typename Rep, typename Period>
iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<process_times<Rep>, Period> const& d, const char_type* = 0) const
{
*s++ = CharT('{');
s = put_value(s, ios, fill, process_real_cpu_clock::duration(d.count().real));
*s++ = CharT(';');
s = put_value(s, ios, fill, process_user_cpu_clock::duration(d.count().user));
*s++ = CharT(';');
s = put_value(s, ios, fill, process_system_cpu_clock::duration(d.count().system));
*s++ = CharT('}');
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 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;
}
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<process_times<Rep>, Period> const& d) const
{
duration<Rep,Period> real(d.count().real);
if (facet.template is_named_unit<Period>()) {
string_type str = facet.get_unit(get_duration_style(ios), real);
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), real);
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

View File

@@ -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/core/scoped_enum.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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
// (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

View File

@@ -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<Clock>(facet, i, e, is, err);
}
else
{
time_point_units_default<CharT> facet;
return get_epoch<Clock>(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

View File

@@ -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

View File

@@ -0,0 +1,260 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2011 Vicente J. Botet Escriba
// Copyright (c) Microsoft Corporation 2014
// 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 <iosfwd>
#include <ios>
#include <locale>
#include <algorithm>
namespace boost
{
namespace chrono
{
/**
* customization point to the epoch associated to the clock @c Clock
* The default calls @c f.do_get_epoch(Clock()). The user can overload this function.
* @return the string epoch associated to the @c Clock
*/
template <typename CharT, typename Clock, typename TPUFacet>
std::basic_string<CharT> get_epoch_custom(Clock, TPUFacet& f)
{
return f.do_get_epoch(Clock());
}
/**
* @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 get_epoch_custom<CharT>(Clock(), *this);
}
protected:
/**
* Destroy the facet.
*/
virtual ~time_point_units() {}
public:
/**
*
* @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;
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
/**
*
* @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
#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();
}
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
/**
* @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
#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

View File

@@ -0,0 +1,31 @@
// (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/core/scoped_enum.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

View File

@@ -0,0 +1,437 @@
// 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
{
void*& pw = ios_.pword(index());
T* ptr = static_cast<T*> (pw);
pw = 0;
return ptr;
}
/**
*
* @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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,635 @@
// 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/integer/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 = integer::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 = integer::gcd<unsigned long long>(num, Period::num);
unsigned long long gcd_d1_d2 = integer::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 > duration_values<common_type_t>::zero())
{
//std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
if ( (duration_values<Rep>::max)() < Rep(t))
{
//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.
d = duration<Rep, Period>(Rep(t));
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

View File

@@ -0,0 +1,525 @@
// boost/chrono/process_cpu_clocks.hpp -----------------------------------------------------------//
// Copyright 2009-2011 Vicente J. Botet Escriba
// Copyright (c) Microsoft Corporation 2014
// 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 <iosfwd>
#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
};
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
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
};
#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){}
#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
template <typename Rep2>
explicit process_times(
Rep2 r)
: real(r)
, user(r)
, system(r){}
#endif
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
#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
operator rep() const
{
return real;
}
#endif
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)
{
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<Rep1, Period1>, duration<Rep2, Period2>
>()(duration<Rep1, Period1>(lhs.count().real), duration<Rep2, Period2>(rhs.count().real));
}
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 boost::chrono::detail::duration_lt<
duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, duration<Rep2, Period2>(rhs.count().real));
}
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>
>()(duration<Rep1, Period1>(lhs.count().real), duration<Rep2, Period2>(rhs.count().real));
}
typedef process_times<nanoseconds::rep> process_cpu_clock_times;
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
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
};
#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>& 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;
}
};
#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
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', '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;
}
};
#endif
} // 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() BOOST_NOEXCEPT_OR_NOTHROW
{
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

View File

@@ -0,0 +1,59 @@
// 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)
{
typedef typename common_type<To, duration<Rep, Period> >::type result_type;
result_type diff0;
result_type diff1;
To t0 = duration_cast<To>(d);
To t1 = t0;
if (t0>d) {
--t1;
diff0 = t0 - d;
diff1 = d - t1;
} else {
++t1;
diff0 = d - t0;
diff1 = t1 - d;
}
if (diff0 == diff1)
{
if (t0.count() & 1)
return t1;
return t0;
}
else if (diff0 < diff1)
return t0;
return t1;
}
} // namespace chrono
} // namespace boost
#endif

View File

@@ -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) && ! defined (__hpux__)
# 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 system_clock;
#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
class 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

View File

@@ -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

View File

@@ -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>
#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_FORCEINLINE BOOST_CONSTEXPR
time_point() : d_(duration::zero())
{}
BOOST_FORCEINLINE BOOST_CONSTEXPR
explicit time_point(const duration& d)
: d_(d)
{}
// conversions
template <class Duration2>
BOOST_FORCEINLINE 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

View File

@@ -0,0 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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>
#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

View File

@@ -0,0 +1,24 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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>
#include <boost/typeof/typeof.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::ratio, (boost::intmax_t)(boost::intmax_t))
#endif