summaryrefslogtreecommitdiff
path: root/boost/chrono
diff options
context:
space:
mode:
Diffstat (limited to 'boost/chrono')
-rw-r--r--boost/chrono/chrono_io.hpp15
-rw-r--r--boost/chrono/config.hpp68
-rw-r--r--boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp43
-rw-r--r--boost/chrono/detail/inlined/mac/thread_clock.hpp80
-rw-r--r--boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp17
-rw-r--r--boost/chrono/detail/inlined/posix/thread_clock.hpp2
-rw-r--r--boost/chrono/detail/inlined/win/chrono.hpp91
-rw-r--r--boost/chrono/detail/inlined/win/process_cpu_clocks.hpp53
-rw-r--r--boost/chrono/detail/inlined/win/thread_clock.hpp22
-rw-r--r--boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp10
-rw-r--r--boost/chrono/detail/scan_keyword.hpp4
-rw-r--r--boost/chrono/detail/static_assert.hpp2
-rw-r--r--boost/chrono/duration.hpp43
-rw-r--r--boost/chrono/floor.hpp4
-rw-r--r--boost/chrono/io/duration_get.hpp593
-rw-r--r--boost/chrono/io/duration_io.hpp225
-rw-r--r--boost/chrono/io/duration_put.hpp297
-rw-r--r--boost/chrono/io/duration_style.hpp35
-rw-r--r--boost/chrono/io/duration_units.hpp1003
-rw-r--r--boost/chrono/io/ios_base_state.hpp151
-rw-r--r--boost/chrono/io/time_point_get.hpp330
-rw-r--r--boost/chrono/io/time_point_io.hpp1239
-rw-r--r--boost/chrono/io/time_point_put.hpp261
-rw-r--r--boost/chrono/io/time_point_units.hpp249
-rw-r--r--boost/chrono/io/timezone.hpp30
-rw-r--r--boost/chrono/io/utility/ios_base_state_ptr.hpp436
-rw-r--r--boost/chrono/io/utility/manip_base.hpp101
-rw-r--r--boost/chrono/io/utility/to_string.hpp50
-rw-r--r--boost/chrono/io_v1/chrono_io.hpp76
-rw-r--r--boost/chrono/process_cpu_clocks.hpp16
-rw-r--r--boost/chrono/round.hpp24
-rw-r--r--boost/chrono/system_clocks.hpp2
-rw-r--r--boost/chrono/time_point.hpp11
-rw-r--r--boost/chrono/typeof/boost/chrono/chrono.hpp1
-rw-r--r--boost/chrono/typeof/boost/ratio.hpp2
35 files changed, 5386 insertions, 200 deletions
diff --git a/boost/chrono/chrono_io.hpp b/boost/chrono/chrono_io.hpp
index 29a8d3493e..ebd18a3dab 100644
--- a/boost/chrono/chrono_io.hpp
+++ b/boost/chrono/chrono_io.hpp
@@ -14,6 +14,21 @@
#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
diff --git a/boost/chrono/config.hpp b/boost/chrono/config.hpp
index b7d0c0d198..1045ba3a79 100644
--- a/boost/chrono/config.hpp
+++ b/boost/chrono/config.hpp
@@ -2,6 +2,7 @@
// 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)
@@ -12,6 +13,7 @@
#define BOOST_CHRONO_CONFIG_HPP
#include <boost/config.hpp>
+#include <boost/predef.h>
#if !defined BOOST_CHRONO_VERSION
#define BOOST_CHRONO_VERSION 1
@@ -25,6 +27,13 @@
#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
@@ -57,13 +66,16 @@
# define BOOST_CHRONO_HAS_PROCESS_CLOCKS
# endif
# define BOOST_CHRONO_HAS_CLOCK_STEADY
-# define BOOST_CHRONO_HAS_THREAD_CLOCK
+# 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
@@ -85,10 +97,13 @@
# undef BOOST_CHRONO_HAS_THREAD_CLOCK
# undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY
# endif
-# if defined(__HP_aCC) && defined(__hpux)
+# 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)
@@ -96,21 +111,53 @@
#undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY
#endif
-//#undef BOOST_CHRONO_HAS_PROCESS_CLOCKS
-
// unicode support ------------------------------//
-#if defined(BOOST_NO_UNICODE_LITERALS) || defined(BOOST_NO_CHAR16_T) || defined(BOOST_NO_CHAR32_T)
+#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) || defined(BOOST_NO_CXX11_CHAR16_T) || defined(BOOST_NO_CXX11_CHAR32_T)
//~ #define BOOST_CHRONO_HAS_UNICODE_SUPPORT
#else
#define BOOST_CHRONO_HAS_UNICODE_SUPPORT 1
#endif
-#if ! defined BOOST_NOEXCEPT
-#if defined(BOOST_NO_NOEXCEPT)
-#define BOOST_NOEXCEPT
+#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_NOEXCEPT noexcept
+# 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
@@ -143,7 +190,7 @@
#define BOOST_CHRONO_DECL
#endif
-//#define BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
+
// enable automatic library variant selection ------------------------------//
@@ -166,3 +213,4 @@
#endif // auto-linking disabled
#endif // BOOST_CHRONO_HEADER_ONLY
#endif // BOOST_CHRONO_CONFIG_HPP
+
diff --git a/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp
index 48753bdfc7..6d09e2cb3a 100644
--- a/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp
+++ b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp
@@ -48,7 +48,7 @@ namespace boost
process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT
{
-#if 0
+#if 1
tms tm;
clock_t c = ::times(&tm);
if (c == clock_t(-1)) // error
@@ -71,10 +71,18 @@ namespace boost
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(
- duration(c*(1000000000l/CLOCKS_PER_SEC))
- );
+ return time_point();
#endif
}
@@ -82,7 +90,7 @@ namespace boost
process_real_cpu_clock::time_point process_real_cpu_clock::now(system::error_code & ec)
{
-#if 0
+#if 1
tms tm;
clock_t c = ::times(&tm);
if (c == clock_t(-1)) // error
@@ -129,11 +137,28 @@ namespace boost
ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
return time_point();
}
+ } else
+ {
+ long factor = chrono_detail::tick_factor();
+ if (factor != -1)
+ {
+ if (!BOOST_CHRONO_IS_THROWS(ec))
+ {
+ ec.clear();
+ }
+ return time_point(nanoseconds(c * factor));
+ } else
+ {
+ if (BOOST_CHRONO_IS_THROWS(ec))
+ {
+ boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock"));
+ } else
+ {
+ ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
+ return time_point();
+ }
+ }
}
- return time_point(
- duration(c*(1000000000l/CLOCKS_PER_SEC))
- );
-
#endif
}
diff --git a/boost/chrono/detail/inlined/mac/thread_clock.hpp b/boost/chrono/detail/inlined/mac/thread_clock.hpp
index dad806e4e2..1a4406b83d 100644
--- a/boost/chrono/detail/inlined/mac/thread_clock.hpp
+++ b/boost/chrono/detail/inlined/mac/thread_clock.hpp
@@ -1,6 +1,8 @@
// boost thread_clock.cpp -----------------------------------------------------------//
-// Copyright Vicente J. Botet Escriba 2010
+// 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
@@ -10,6 +12,80 @@
//--------------------------------------------------------------------------------------//
#include <boost/chrono/config.hpp>
-#include <boost/chrono/detail/inlined/posix/thread_clock.hpp>
+#include <boost/chrono/thread_clock.hpp>
#include <cassert>
+# 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_CHRONO_SYSTEM_CATEGORY,
+ "chrono::thread_clock" ));
+ }
+ else
+ {
+ ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY );
+ return time_point();
+ }
+ }
+ if (!BOOST_CHRONO_IS_THROWS(ec))
+ {
+ ec.clear();
+ }
+
+ // 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
+} }
diff --git a/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp
index 5d5c4f4806..0476f590c9 100644
--- a/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp
+++ b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp
@@ -22,7 +22,7 @@
namespace boost { namespace chrono {
namespace chrono_detail
{
- inline long tick_factor() // multiplier to convert ticks
+ inline nanoseconds::rep tick_factor() // multiplier to convert ticks
// to nanoseconds; -1 if unknown
{
static long factor = 0;
@@ -281,12 +281,13 @@ process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT
}
else
{
- if ( chrono_detail::tick_factor() != -1 )
+ nanoseconds::rep factor = chrono_detail::tick_factor();
+ if ( factor != -1 )
{
time_point::rep r(
- 1000*c*chrono_detail::tick_factor(),
- 1000*(tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(),
- 1000*(tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor());
+ c*factor,
+ (tm.tms_utime + tm.tms_cutime)*factor,
+ (tm.tms_stime + tm.tms_cstime)*factor);
return time_point(duration(r));
}
else
@@ -324,9 +325,9 @@ process_cpu_clock::time_point process_cpu_clock::now(
if ( chrono_detail::tick_factor() != -1 )
{
time_point::rep r(
- 1000*c*chrono_detail::tick_factor(),
- 1000*(tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(),
- 1000*(tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor());
+ 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
diff --git a/boost/chrono/detail/inlined/posix/thread_clock.hpp b/boost/chrono/detail/inlined/posix/thread_clock.hpp
index 42a544a0d6..a1012240ec 100644
--- a/boost/chrono/detail/inlined/posix/thread_clock.hpp
+++ b/boost/chrono/detail/inlined/posix/thread_clock.hpp
@@ -14,7 +14,9 @@
#include <boost/chrono/thread_clock.hpp>
#include <cassert>
+#if !defined(__VXWORKS__)
# include <sys/times.h>
+#endif
# include <pthread.h>
# include <unistd.h>
diff --git a/boost/chrono/detail/inlined/win/chrono.hpp b/boost/chrono/detail/inlined/win/chrono.hpp
index 75160dba97..16e8c51426 100644
--- a/boost/chrono/detail/inlined/win/chrono.hpp
+++ b/boost/chrono/detail/inlined/win/chrono.hpp
@@ -12,9 +12,9 @@
#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
#define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
-#include <boost/detail/win/time.hpp>
-#include <boost/detail/win/timers.hpp>
-#include <boost/detail/win/GetLastError.hpp>
+#include <boost/detail/winapi/time.hpp>
+#include <boost/detail/winapi/timers.hpp>
+#include <boost/detail/winapi/GetLastError.hpp>
namespace boost
{
@@ -25,8 +25,8 @@ namespace chrono_detail
BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT
{
- boost::detail::win32::LARGE_INTEGER_ freq;
- if ( !boost::detail::win32::QueryPerformanceFrequency( &freq ) )
+ boost::detail::winapi::LARGE_INTEGER_ freq;
+ if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
return 0.0L;
return double(1000000000.0L / freq.QuadPart);
}
@@ -35,15 +35,23 @@ namespace chrono_detail
steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT
{
- static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
+ double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
- boost::detail::win32::LARGE_INTEGER_ pcount;
- if ( (nanosecs_per_tic <= 0.0L) ||
- (!boost::detail::win32::QueryPerformanceCounter( &pcount )) )
+ boost::detail::winapi::LARGE_INTEGER_ pcount;
+ if ( nanosecs_per_tic <= 0.0L )
{
- BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
+ BOOST_ASSERT(0 && "Boost::Chrono - get_nanosecs_per_tic Internal Error");
return steady_clock::time_point();
}
+ unsigned times=0;
+ while ( ! boost::detail::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)));
@@ -53,16 +61,16 @@ namespace chrono_detail
#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
steady_clock::time_point steady_clock::now( system::error_code & ec )
{
- static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
+ double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
- boost::detail::win32::LARGE_INTEGER_ pcount;
+ boost::detail::winapi::LARGE_INTEGER_ pcount;
if ( (nanosecs_per_tic <= 0.0L)
- || (!boost::detail::win32::QueryPerformanceCounter( &pcount )) )
+ || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) )
{
- boost::detail::win32::DWORD_ cause =
+ boost::detail::winapi::DWORD_ cause =
((nanosecs_per_tic <= 0.0L)
? ERROR_NOT_SUPPORTED
- : boost::detail::win32::GetLastError());
+ : boost::detail::winapi::GetLastError());
if (BOOST_CHRONO_IS_THROWS(ec)) {
boost::throw_exception(
system::system_error(
@@ -89,38 +97,33 @@ namespace chrono_detail
BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now() BOOST_NOEXCEPT
{
- boost::detail::win32::FILETIME_ ft;
- #if defined(UNDER_CE)
- // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
- boost::detail::win32::SYSTEMTIME_ st;
- boost::detail::win32::GetSystemTime( &st );
- boost::detail::win32::SystemTimeToFileTime( &st, &ft );
- #else
- boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails
- #endif
- return system_clock::time_point(system_clock::duration(
- (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime));
+ boost::detail::winapi::FILETIME_ ft;
+ boost::detail::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::detail::win32::FILETIME_ ft;
- #if defined(UNDER_CE)
- // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
- boost::detail::win32::SYSTEMTIME_ st;
- boost::detail::win32::GetSystemTime( &st );
- boost::detail::win32::SystemTimeToFileTime( &st, &ft );
- #else
- boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails
- #endif
+ boost::detail::winapi::FILETIME_ ft;
+ boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
if (!BOOST_CHRONO_IS_THROWS(ec))
{
ec.clear();
}
- return time_point(duration(
- (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime));
+ return system_clock::time_point(
+ system_clock::duration(
+ ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
+ - 116444736000000000LL
+ //- (134775LL*864000000000LL)
+ ));
}
#endif
@@ -128,13 +131,6 @@ namespace chrono_detail
std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT
{
__int64 temp = t.time_since_epoch().count();
-
- # if (!defined( BOOST_MSVC )) || (BOOST_MSVC > 1300) // > VC++ 7.0
- temp -= 116444736000000000LL; // delta from epoch in microseconds
- # else
- temp -= 116444736000000000;
- # endif
-
temp /= 10000000;
return static_cast<std::time_t>( temp );
}
@@ -144,13 +140,6 @@ namespace chrono_detail
{
__int64 temp = t;
temp *= 10000000;
-
- # if (!defined( BOOST_MSVC )) || (BOOST_MSVC > 1300) // > VC++ 7.0
- temp += 116444736000000000LL;
- # else
- temp += 116444736000000000;
- # endif
-
return time_point(duration(temp));
}
diff --git a/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp
index 1b7e67a120..e97bfe590c 100644
--- a/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp
+++ b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp
@@ -2,6 +2,7 @@
// 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
@@ -18,9 +19,11 @@
#include <cassert>
#include <time.h>
-#include <boost/detail/win/GetLastError.hpp>
-#include <boost/detail/win/GetCurrentProcess.hpp>
-#include <boost/detail/win/GetProcessTimes.hpp>
+#include <boost/detail/winapi/GetLastError.hpp>
+#include <boost/detail/winapi/GetCurrentProcess.hpp>
+#if BOOST_PLAT_WINDOWS_DESKTOP
+#include <boost/detail/winapi/GetProcessTimes.hpp>
+#endif
namespace boost
{
@@ -64,14 +67,15 @@ process_real_cpu_clock::time_point process_real_cpu_clock::now(
}
#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::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
return time_point(duration(
@@ -93,10 +97,10 @@ process_user_cpu_clock::time_point process_user_cpu_clock::now(
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
if (!BOOST_CHRONO_IS_THROWS(ec))
@@ -110,7 +114,7 @@ process_user_cpu_clock::time_point process_user_cpu_clock::now(
}
else
{
- boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError();
+ boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
if (BOOST_CHRONO_IS_THROWS(ec))
{
boost::throw_exception(
@@ -133,10 +137,10 @@ process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXC
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
return time_point(duration(
@@ -158,10 +162,10 @@ process_system_cpu_clock::time_point process_system_cpu_clock::now(
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
if (!BOOST_CHRONO_IS_THROWS(ec))
@@ -175,7 +179,7 @@ process_system_cpu_clock::time_point process_system_cpu_clock::now(
}
else
{
- boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError();
+ boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
if (BOOST_CHRONO_IS_THROWS(ec))
{
boost::throw_exception(
@@ -198,10 +202,10 @@ process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count()
@@ -229,10 +233,10 @@ process_cpu_clock::time_point process_cpu_clock::now(
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetProcessTimes(
- boost::detail::win32::GetCurrentProcess(), &creation, &exit,
+ if ( boost::detail::winapi::GetProcessTimes(
+ boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
&system_time, &user_time ) )
{
if (!BOOST_CHRONO_IS_THROWS(ec))
@@ -252,7 +256,7 @@ process_cpu_clock::time_point process_cpu_clock::now(
}
else
{
- boost::detail::win32::DWORD_ cause = boost::detail::win32::GetLastError();
+ boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
if (BOOST_CHRONO_IS_THROWS(ec))
{
boost::throw_exception(
@@ -270,6 +274,7 @@ process_cpu_clock::time_point process_cpu_clock::now(
}
#endif
+#endif
} // namespace chrono
} // namespace boost
diff --git a/boost/chrono/detail/inlined/win/thread_clock.hpp b/boost/chrono/detail/inlined/win/thread_clock.hpp
index 8ca1506ce5..e47c481473 100644
--- a/boost/chrono/detail/inlined/win/thread_clock.hpp
+++ b/boost/chrono/detail/inlined/win/thread_clock.hpp
@@ -15,9 +15,9 @@
#include <boost/chrono/thread_clock.hpp>
#include <cassert>
-#include <boost/detail/win/GetLastError.hpp>
-#include <boost/detail/win/GetCurrentThread.hpp>
-#include <boost/detail/win/GetThreadTimes.hpp>
+#include <boost/detail/winapi/GetLastError.hpp>
+#include <boost/detail/winapi/GetCurrentThread.hpp>
+#include <boost/detail/winapi/GetThreadTimes.hpp>
namespace boost
{
@@ -28,10 +28,10 @@ namespace chrono
thread_clock::time_point thread_clock::now( system::error_code & ec )
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetThreadTimes(
- boost::detail::win32::GetCurrentThread (), &creation, &exit,
+ if ( boost::detail::winapi::GetThreadTimes(
+ boost::detail::winapi::GetCurrentThread (), &creation, &exit,
&system_time, &user_time ) )
{
duration user = duration(
@@ -55,13 +55,13 @@ thread_clock::time_point thread_clock::now( system::error_code & ec )
{
boost::throw_exception(
system::system_error(
- boost::detail::win32::GetLastError(),
+ boost::detail::winapi::GetLastError(),
BOOST_CHRONO_SYSTEM_CATEGORY,
"chrono::thread_clock" ));
}
else
{
- ec.assign( boost::detail::win32::GetLastError(), BOOST_CHRONO_SYSTEM_CATEGORY );
+ ec.assign( boost::detail::winapi::GetLastError(), BOOST_CHRONO_SYSTEM_CATEGORY );
return thread_clock::time_point(duration(0));
}
}
@@ -72,10 +72,10 @@ thread_clock::time_point thread_clock::now() BOOST_NOEXCEPT
{
// note that Windows uses 100 nanosecond ticks for FILETIME
- boost::detail::win32::FILETIME_ creation, exit, user_time, system_time;
+ boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
- if ( boost::detail::win32::GetThreadTimes(
- boost::detail::win32::GetCurrentThread (), &creation, &exit,
+ if ( boost::detail::winapi::GetThreadTimes(
+ boost::detail::winapi::GetCurrentThread (), &creation, &exit,
&system_time, &user_time ) )
{
duration user = duration(
diff --git a/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp
index 491c1d64a0..94936c8baf 100644
--- a/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp
+++ b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp
@@ -19,6 +19,10 @@
#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 {
@@ -41,4 +45,10 @@ 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
diff --git a/boost/chrono/detail/scan_keyword.hpp b/boost/chrono/detail/scan_keyword.hpp
index 7c3ba6e2af..aa4e2e87b9 100644
--- a/boost/chrono/detail/scan_keyword.hpp
+++ b/boost/chrono/detail/scan_keyword.hpp
@@ -19,14 +19,14 @@
#include <boost/chrono/config.hpp>
-#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
+#include <boost/move/unique_ptr.hpp>
#include <ios>
#include <exception>
#include <stdlib.h>
#include <boost/throw_exception.hpp>
namespace boost {
- using interprocess::unique_ptr;
+ using movelib::unique_ptr;
namespace chrono {
namespace chrono_detail {
diff --git a/boost/chrono/detail/static_assert.hpp b/boost/chrono/detail/static_assert.hpp
index 1ad21a56ba..8615194754 100644
--- a/boost/chrono/detail/static_assert.hpp
+++ b/boost/chrono/detail/static_assert.hpp
@@ -11,7 +11,7 @@
#include <boost/chrono/config.hpp>
-#ifndef BOOST_NO_STATIC_ASSERT
+#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>
diff --git a/boost/chrono/duration.hpp b/boost/chrono/duration.hpp
index e32357cc72..814adb0e91 100644
--- a/boost/chrono/duration.hpp
+++ b/boost/chrono/duration.hpp
@@ -51,7 +51,7 @@ time2_demo contained this comment:
#include <boost/detail/workaround.hpp>
#include <boost/integer_traits.hpp>
-#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT)
+#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"
@@ -340,17 +340,17 @@ namespace detail
namespace detail {
template <class T, bool = is_arithmetic<T>::value>
struct chrono_numeric_limits {
- static T lowest() throw() {return (std::numeric_limits<T>::min) ();}
+ 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 T lowest() throw() {return (std::numeric_limits<T>::min) ();}
+ 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 float lowest() throw()
+ static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
{
return -(std::numeric_limits<float>::max) ();
}
@@ -358,7 +358,7 @@ namespace detail {
template <>
struct chrono_numeric_limits<double,true> {
- static double lowest() throw()
+ static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
{
return -(std::numeric_limits<double>::max) ();
}
@@ -366,7 +366,7 @@ namespace detail {
template <>
struct chrono_numeric_limits<long double,true> {
- static long double lowest() throw()
+ static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
{
return -(std::numeric_limits<long double>::max)();
}
@@ -381,12 +381,12 @@ template <class Rep>
struct duration_values
{
static BOOST_CONSTEXPR Rep zero() {return Rep(0);}
- static BOOST_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (std::numeric_limits<Rep>::max)();
}
- static BOOST_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return detail::numeric_limits<Rep>::lowest();
}
@@ -417,7 +417,7 @@ struct common_type<chrono::duration<Rep1, Period1>,
namespace chrono {
template <class Rep, class Period>
- class duration
+ 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,
@@ -433,10 +433,10 @@ namespace chrono {
rep rep_;
public:
- BOOST_CONSTEXPR
+ BOOST_FORCEINLINE BOOST_CONSTEXPR
duration() : rep_(duration_values<rep>::zero()) { }
template <class Rep2>
- BOOST_CONSTEXPR
+ BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR
explicit duration(const Rep2& r
, typename boost::enable_if <
mpl::and_ <
@@ -452,8 +452,7 @@ namespace chrono {
>::type* = 0
) : rep_(r) { }
//~duration() {} //= default;
- BOOST_CONSTEXPR
- duration(const duration& rhs) : rep_(rhs.rep_) {} // = default;
+// BOOST_CONSTEXPR duration(const duration& rhs) : rep_(rhs.rep_) {} // = default;
duration& operator=(const duration& rhs) // = default;
{
if (&rhs != this) rep_= rhs.rep_;
@@ -462,7 +461,7 @@ namespace chrono {
// conversions
template <class Rep2, class Period2>
- BOOST_CONSTEXPR
+ BOOST_FORCEINLINE BOOST_CONSTEXPR
duration(const duration<Rep2, Period2>& d
, typename boost::enable_if <
mpl::or_ <
@@ -484,7 +483,7 @@ namespace chrono {
// arithmetic
BOOST_CONSTEXPR
- duration operator+() const {return *this;}
+ duration operator+() const {return duration(rep_);;}
BOOST_CONSTEXPR
duration operator-() const {return duration(-rep_);}
duration& operator++() {++rep_; return *this;}
@@ -514,11 +513,11 @@ namespace chrono {
{
return duration(duration_values<rep>::zero());
}
- static BOOST_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return duration((duration_values<rep>::min)());
}
- static BOOST_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return duration((duration_values<rep>::max)());
}
@@ -664,7 +663,7 @@ namespace detail
template <class LhsDuration, class RhsDuration>
struct duration_eq
{
- BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs)
+ BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
{
typedef typename common_type<LhsDuration, RhsDuration>::type CD;
return CD(lhs).count() == CD(rhs).count();
@@ -674,7 +673,7 @@ namespace detail
template <class LhsDuration>
struct duration_eq<LhsDuration, LhsDuration>
{
- BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
+ BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
{
return lhs.count() == rhs.count();
}
@@ -683,7 +682,7 @@ namespace detail
template <class LhsDuration, class RhsDuration>
struct duration_lt
{
- BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs)
+ BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
{
typedef typename common_type<LhsDuration, RhsDuration>::type CD;
return CD(lhs).count() < CD(rhs).count();
@@ -693,7 +692,7 @@ namespace detail
template <class LhsDuration>
struct duration_lt<LhsDuration, LhsDuration>
{
- BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
+ BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
{
return lhs.count() < rhs.count();
}
@@ -761,7 +760,7 @@ namespace detail
// Duration >=
template <class Rep1, class Period1, class Rep2, class Period2>
- inline
+ inline BOOST_CONSTEXPR
bool
operator>=(const duration<Rep1, Period1>& lhs,
const duration<Rep2, Period2>& rhs)
diff --git a/boost/chrono/floor.hpp b/boost/chrono/floor.hpp
index e133e49c8a..eb85fa7446 100644
--- a/boost/chrono/floor.hpp
+++ b/boost/chrono/floor.hpp
@@ -24,7 +24,9 @@ namespace boost
template <class To, class Rep, class Period>
To floor(const duration<Rep, Period>& d)
{
- return duration_cast<To>(d);
+ To t = duration_cast<To>(d);
+ if (t>d) --t;
+ return t;
}
diff --git a/boost/chrono/io/duration_get.hpp b/boost/chrono/io/duration_get.hpp
new file mode 100644
index 0000000000..ce3075b7b3
--- /dev/null
+++ b/boost/chrono/io/duration_get.hpp
@@ -0,0 +1,593 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_DURATION_GET_HPP
+#define BOOST_CHRONO_IO_DURATION_GET_HPP
+
+#include <boost/chrono/config.hpp>
+#include <string>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/math/common_factor_rt.hpp>
+#include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp>
+#include <boost/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 = math::gcd<common_type_t>(common_type_t(r), common_type_t(den));
+ r /= t;
+ den /= t;
+ if (den != 1)
+ {
+ // Conversion to Period is integral and not exact
+ err |= std::ios_base::failbit;
+ return false;
+ }
+ return true;
+ }
+ template <typename intermediate_type>
+ typename disable_if<is_integral<intermediate_type> , bool>::type reduce(intermediate_type&, unsigned long long&,
+ std::ios_base::iostate&)
+ {
+ return true;
+ }
+
+ }
+
+ /**
+ * @c duration_get is used to parse a character sequence, extracting
+ * components of a duration into a class duration.
+ * Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
+ * If the sequence being parsed matches the correct format, the
+ * corresponding member of the class duration argument are set to the
+ * value used to produce the sequence;
+ * otherwise either an error is reported or unspecified values are assigned.
+ * In other words, user confirmation is required for reliable parsing of
+ * user-entered durations, but machine-generated formats can be parsed
+ * reliably. This allows parsers to be aggressive about interpreting user
+ * variations on standard formats.
+ *
+ * If the end iterator is reached during parsing of the get() member
+ * function, the member sets std::ios_base::eofbit in err.
+ */
+ template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
+ class duration_get: public std::locale::facet
+ {
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of character string passed to member functions.
+ */
+ typedef std::basic_string<CharT> string_type;
+ /**
+ * Type of iterator used to scan the character buffer.
+ */
+ typedef InputIterator iter_type;
+
+ /**
+ * Construct a @c duration_get facet.
+ * @param refs
+ * @Effects Construct a @c duration_get facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+
+ explicit duration_get(size_t refs = 0) :
+ std::locale::facet(refs)
+ {
+ }
+
+ /**
+ * @param s start input stream iterator
+ * @param end end input stream iterator
+ * @param ios a reference to a ios_base
+ * @param err the ios_base state
+ * @param d the duration
+ * @param pattern begin of the formatting pattern
+ * @param pat_end end of the formatting pattern
+ *
+ * Requires: [pattern,pat_end) shall be a valid range.
+ *
+ * Effects: The function starts by evaluating err = std::ios_base::goodbit.
+ * It then enters a loop, reading zero or more characters from s at
+ * each iteration. Unless otherwise specified below, the loop
+ * terminates when the first of the following conditions holds:
+ * - The expression pattern == pat_end evaluates to true.
+ * - The expression err == std::ios_base::goodbit evaluates to false.
+ * - The expression s == end evaluates to true, in which case the
+ * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
+ * - The next element of pattern is equal to '%', followed by a conversion
+ * specifier character, format.
+ * If the number of elements in the range [pattern,pat_end) is not
+ * sufficient to unambiguously determine whether the conversion
+ * specification is complete and valid, the function evaluates
+ * err = std::ios_base::failbit. Otherwise, the function evaluates
+ * s = get_value(s, end, ios, err, r) when the conversion specification is 'v' and
+ * s = get_value(s, end, ios, err, rt) when the conversion specification is 'u'.
+ * If err == std::ios_base::goodbit holds after
+ * the evaluation of the expression, the function increments pattern to
+ * point just past the end of the conversion specification and continues
+ * looping.
+ * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
+ * which case the function first increments pattern until
+ * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
+ * then advances s until s == end || !isspace(*s, ios.getloc()) is true,
+ * and finally resumes looping.
+ * - The next character read from s matches the element pointed to by
+ * pattern in a case-insensitive comparison, in which case the function
+ * evaluates ++pattern, ++s and continues looping. Otherwise, the function
+ * evaluates err = std::ios_base::failbit.
+ *
+ * Once r and rt are retrieved,
+ * Returns: s
+ */
+ template <typename Rep, typename Period>
+ iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+ duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
+ {
+ if (std::has_facet<duration_units<CharT> >(ios.getloc()))
+ {
+ duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
+ return get(facet, s, end, ios, err, d, pattern, pat_end);
+ }
+ else
+ {
+ duration_units_default<CharT> facet;
+ return get(facet, s, end, ios, err, d, pattern, pat_end);
+ }
+ }
+
+ template <typename Rep, typename Period>
+ iter_type get(duration_units<CharT> const&facet, iter_type s, iter_type end, std::ios_base& ios,
+ std::ios_base::iostate& err, duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
+ {
+
+ typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
+ intermediate_type r;
+ rt_ratio rt;
+ bool value_found = false, unit_found = false;
+
+ const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+ while (pattern != pat_end && err == std::ios_base::goodbit)
+ {
+ if (s == end)
+ {
+ err |= std::ios_base::eofbit;
+ break;
+ }
+ if (ct.narrow(*pattern, 0) == '%')
+ {
+ if (++pattern == pat_end)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ char cmd = ct.narrow(*pattern, 0);
+ switch (cmd)
+ {
+ case 'v':
+ {
+ if (value_found)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ value_found = true;
+ s = get_value(s, end, ios, err, r);
+ if (err & (std::ios_base::badbit | std::ios_base::failbit))
+ {
+ return s;
+ }
+ break;
+ }
+ case 'u':
+ {
+ if (unit_found)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ unit_found = true;
+ s = get_unit(facet, s, end, ios, err, rt);
+ if (err & (std::ios_base::badbit | std::ios_base::failbit))
+ {
+ return s;
+ }
+ break;
+ }
+ default:
+ BOOST_ASSERT(false && "Boost::Chrono internal error.");
+ break;
+ }
+
+ ++pattern;
+ }
+ else if (ct.is(std::ctype_base::space, *pattern))
+ {
+ for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
+ ;
+ for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
+ ;
+ }
+ else if (ct.toupper(*s) == ct.toupper(*pattern))
+ {
+ ++s;
+ ++pattern;
+ }
+ else
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+
+ }
+
+ unsigned long long num = rt.num;
+ unsigned long long den = rt.den;
+
+ // r should be multiplied by (num/den) / Period
+ // Reduce (num/den) / Period to lowest terms
+ unsigned long long gcd_n1_n2 = math::gcd<unsigned long long>(num, Period::num);
+ unsigned long long gcd_d1_d2 = math::gcd<unsigned long long>(den, Period::den);
+ num /= gcd_n1_n2;
+ den /= gcd_d1_d2;
+ unsigned long long n2 = Period::num / gcd_n1_n2;
+ unsigned long long d2 = Period::den / gcd_d1_d2;
+ if (num > (std::numeric_limits<unsigned long long>::max)() / d2 || den
+ > (std::numeric_limits<unsigned long long>::max)() / n2)
+ {
+ // (num/den) / Period overflows
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ num *= d2;
+ den *= n2;
+
+ typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
+
+ // num / den is now factor to multiply by r
+ if (!detail::reduce(r, den, err)) return s;
+
+ if (chrono::detail::gt(r, ( (duration_values<common_type_t>::max)() / num)))
+ {
+ // Conversion to Period overflowed
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ common_type_t t = r * num;
+ t /= den;
+ if (t > duration_values<common_type_t>::zero())
+ {
+ Rep pt = t;
+ if ( (duration_values<Rep>::max)() < pt)
+ {
+ // Conversion to Period overflowed
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ }
+ // Success! Store it.
+ r = Rep(t);
+ d = duration<Rep, Period> (r);
+
+ return s;
+ }
+
+ /**
+ *
+ * @param s start input stream iterator
+ * @param end end input stream iterator
+ * @param ios a reference to a ios_base
+ * @param err the ios_base state
+ * @param d the duration
+ * Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+ * @code
+ * return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
+ * @codeend
+ * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+ */
+ template <typename Rep, typename Period>
+ iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+ duration<Rep, Period> & d) const
+ {
+ if (std::has_facet<duration_units<CharT> >(ios.getloc()))
+ {
+ duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
+ std::basic_string<CharT> str = facet.get_pattern();
+ return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
+ }
+ else
+ {
+ duration_units_default<CharT> facet;
+ std::basic_string<CharT> str = facet.get_pattern();
+ return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
+ }
+ }
+
+ /**
+ *
+ * @param s start input stream iterator
+ * @param end end input stream iterator
+ * @param ios a reference to a ios_base
+ * @param err the ios_base state
+ * @param r a reference to the duration representation.
+ * @Effects As if
+ * @code
+ * return std::use_facet<std::num_get<cahr_type, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
+ * @endcode
+ *
+ * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+ */
+ template <typename Rep>
+ iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const
+ {
+ return std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
+ }
+ 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
diff --git a/boost/chrono/io/duration_io.hpp b/boost/chrono/io/duration_io.hpp
new file mode 100644
index 0000000000..438f7696db
--- /dev/null
+++ b/boost/chrono/io/duration_io.hpp
@@ -0,0 +1,225 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+// This code was adapted by Vicente from Howard Hinnant's experimental work
+// on chrono i/o to Boost
+
+#ifndef BOOST_CHRONO_IO_DURATION_IO_HPP
+#define BOOST_CHRONO_IO_DURATION_IO_HPP
+
+#include <boost/chrono/duration.hpp>
+#include <boost/ratio/ratio_io.hpp>
+#include <boost/chrono/io/duration_style.hpp>
+#include <boost/chrono/io/ios_base_state.hpp>
+#include <boost/chrono/io/duration_put.hpp>
+#include <boost/chrono/io/duration_get.hpp>
+#include <boost/chrono/io/utility/manip_base.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <locale>
+#include <iostream>
+
+namespace boost
+{
+ namespace chrono
+ {
+
+ /**
+ * duration parameterized manipulator.
+ */
+
+ class duration_fmt: public manip<duration_fmt>
+ {
+ duration_style style_;
+ public:
+
+ /**
+ * explicit manipulator constructor from a @c duration_style
+ */
+ explicit duration_fmt(duration_style style)BOOST_NOEXCEPT
+ : style_(style)
+ {}
+
+ /**
+ * Change the duration_style ios state;
+ */
+ void operator()(std::ios_base &ios) const
+
+ {
+ set_duration_style(ios, style_);
+ }
+ };
+
+ /**
+ * duration_style i/o saver.
+ *
+ * See Boost.IO i/o state savers for a motivating compression.
+ */
+ struct duration_style_io_saver
+ {
+
+ //! the type of the state to restore
+ typedef std::ios_base state_type;
+ //! the type of aspect to save
+ typedef duration_style aspect_type;
+
+ /**
+ * Explicit construction from an i/o stream.
+ *
+ * Store a reference to the i/o stream and the value of the associated @c duration_style.
+ */
+ explicit duration_style_io_saver(state_type &s) :
+ s_save_(s)
+ {
+ a_save_ = get_duration_style(s_save_);
+ }
+
+ /**
+ * Construction from an i/o stream and a @c duration_style to restore.
+ *
+ * Stores a reference to the i/o stream and the value @c duration_style to restore given as parameter.
+ */
+ duration_style_io_saver(state_type &s, aspect_type new_value) :
+ s_save_(s), a_save_(new_value)
+ {
+ }
+
+ /**
+ * Destructor.
+ *
+ * Restores the i/o stream with the duration_style to be restored.
+ */
+ ~duration_style_io_saver()
+ {
+ this->restore();
+ }
+
+ /**
+ * Restores the i/o stream with the duration_style to be restored.
+ */
+ void restore()
+ {
+ set_duration_style(s_save_, a_save_);
+ }
+
+ private:
+ duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ;
+
+ state_type& s_save_;
+ aspect_type a_save_;
+ };
+
+ /**
+ * duration stream inserter
+ * @param os the output stream
+ * @param d to value to insert
+ * @return @c os
+ */
+ template <class CharT, class Traits, class Rep, class Period>
+ std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
+ {
+ bool failed = false;
+ BOOST_TRY
+ {
+ std::ios_base::iostate err = std::ios_base::goodbit;
+ BOOST_TRY
+ {
+ typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
+ if (bool(opfx))
+ {
+ if (!std::has_facet<duration_put<CharT> >(os.getloc()))
+ {
+ if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed())
+ {
+ err = std::ios_base::badbit;
+ }
+ }
+ else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), d) .failed())
+ {
+ err = std::ios_base::badbit;
+ }
+ os.width(0);
+ }
+ }
+ BOOST_CATCH(...)
+ {
+ bool flag = false;
+ BOOST_TRY
+ {
+ os.setstate(std::ios_base::failbit);
+ }
+ BOOST_CATCH (std::ios_base::failure )
+ {
+ flag = true;
+ }
+ BOOST_CATCH_END
+ if (flag) throw;
+ }
+ BOOST_CATCH_END
+ if (err) os.setstate(err);
+ return os;
+ }
+ BOOST_CATCH(...)
+ {
+ failed = true;
+ }
+ BOOST_CATCH_END
+ if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
+ return os;
+ }
+
+ /**
+ *
+ * @param is the input stream
+ * @param d the duration
+ * @return @c is
+ */
+ template <class CharT, class Traits, class Rep, class Period>
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
+ {
+ std::ios_base::iostate err = std::ios_base::goodbit;
+
+ BOOST_TRY
+ {
+ typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
+ if (bool(ipfx))
+ {
+ if (!std::has_facet<duration_get<CharT> >(is.getloc()))
+ {
+ duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d);
+ }
+ else
+ {
+ std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is,
+ err, d);
+ }
+ }
+ }
+ BOOST_CATCH (...)
+ {
+ bool flag = false;
+ BOOST_TRY
+ {
+ is.setstate(std::ios_base::failbit);
+ }
+ BOOST_CATCH (std::ios_base::failure )
+ {
+ flag = true;
+ }
+ BOOST_CATCH_END
+ if (flag) { BOOST_RETHROW }
+ }
+ BOOST_CATCH_END
+ if (err) is.setstate(err);
+ return is;
+ }
+
+ } // chrono
+
+}
+
+#endif // header
diff --git a/boost/chrono/io/duration_put.hpp b/boost/chrono/io/duration_put.hpp
new file mode 100644
index 0000000000..81c13cf40e
--- /dev/null
+++ b/boost/chrono/io/duration_put.hpp
@@ -0,0 +1,297 @@
+// (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
+ {
+
+ /**
+ * @tparam ChatT a character type
+ * @tparam OutputIterator a model of @c OutputIterator
+ *
+ * The @c duration_put facet provides facilities for formatted output of duration values.
+ * The member function of @c duration_put take a duration and format it into character string representation.
+ *
+ */
+ template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
+ class duration_put: public std::locale::facet
+ {
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of character string passed to member functions.
+ */
+ typedef std::basic_string<CharT> string_type;
+ /**
+ * Type of iterator used to write in the character buffer.
+ */
+ typedef OutputIterator iter_type;
+
+ /**
+ * Construct a duration_put facet.
+ * @param refs
+ * @Effects Construct a duration_put facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+ explicit duration_put(size_t refs = 0) :
+ std::locale::facet(refs)
+ {
+ }
+
+ /**
+ *
+ * @param s an output stream iterator
+ * @param ios a reference to a ios_base
+ * @param fill the character used as filler
+ * @param d the duration
+ * @param pattern begin of the formatting pattern
+ * @param pat_end end of the formatting pattern
+ *
+ * @Effects Steps through the sequence from @c pattern to @c pat_end,
+ * identifying characters that are part of a pattern sequence. Each character
+ * that is not part of a pattern sequence is written to @c s immediately, and
+ * each pattern sequence, as it is identified, results in a call to
+ * @c put_value or @c put_unit;
+ * thus, pattern elements and other characters are interleaved in the output
+ * in the order in which they appear in the pattern. Pattern sequences are
+ * identified by converting each character @c c to a @c char value as if by
+ * @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
+ * @c ios.getloc(). The first character of each sequence is equal to @c '%',
+ * followed by a pattern specifier character @c spec, which can be @c 'v' for
+ * the duration value or @c 'u' for the duration unit. .
+ * For each valid pattern sequence identified, calls
+ * <c>put_value(s, ios, fill, d)</c> or <c>put_unit(s, ios, fill, d)</c>.
+ *
+ * @Returns An iterator pointing immediately after the last character produced.
+ */
+ template <typename Rep, typename Period>
+ iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const CharT* pattern,
+ const CharT* pat_end) const
+ {
+ if (std::has_facet<duration_units<CharT> >(ios.getloc()))
+ {
+ duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
+ ios.getloc());
+ return put(facet, s, ios, fill, d, pattern, pat_end);
+ }
+ else
+ {
+ duration_units_default<CharT> facet;
+ return put(facet, s, ios, fill, d, pattern, pat_end);
+ }
+ }
+
+ template <typename Rep, typename Period>
+ iter_type put(duration_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
+ duration<Rep, Period> const& d, const CharT* pattern, const CharT* pat_end) const
+ {
+
+ const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+ for (; pattern != pat_end; ++pattern)
+ {
+ if (ct.narrow(*pattern, 0) == '%')
+ {
+ if (++pattern == pat_end)
+ {
+ *s++ = pattern[-1];
+ break;
+ }
+ char fmt = ct.narrow(*pattern, 0);
+ switch (fmt)
+ {
+ case 'v':
+ {
+ s = put_value(s, ios, fill, d);
+ break;
+ }
+ case 'u':
+ {
+ s = put_unit(units_facet, s, ios, fill, d);
+ break;
+ }
+ default:
+ BOOST_ASSERT(false && "Boost::Chrono internal error.");
+ break;
+ }
+ }
+ else
+ *s++ = *pattern;
+ }
+ return s;
+ }
+
+ /**
+ *
+ * @param s an output stream iterator
+ * @param ios a reference to a ios_base
+ * @param fill the character used as filler
+ * @param d the duration
+ * @Effects imbue in @c ios the @c duration_units_default facet if not already present.
+ * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+ * @code
+ * return put(s, ios, d, str.data(), str.data() + str.size());
+ * @endcode
+ * @Returns An iterator pointing immediately after the last character produced.
+ */
+ template <typename Rep, typename Period>
+ iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
+ {
+ if (std::has_facet<duration_units<CharT> >(ios.getloc()))
+ {
+ duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
+ ios.getloc());
+ std::basic_string<CharT> str = facet.get_pattern();
+ return put(facet, s, ios, fill, d, str.data(), str.data() + str.size());
+ }
+ else
+ {
+ duration_units_default<CharT> facet;
+ std::basic_string<CharT> str = facet.get_pattern();
+ return put(facet, s, ios, fill, d, str.data(), str.data() + str.size());
+ }
+ }
+
+ /**
+ *
+ * @param s an output stream iterator
+ * @param ios a reference to a ios_base
+ * @param fill the character used as filler
+ * @param d the duration
+ * @Effects As if s=std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())).
+ * @Returns s, iterator pointing immediately after the last character produced.
+ */
+ template <typename Rep, typename Period>
+ iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
+ {
+ return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
+ static_cast<long int> (d.count()));
+ }
+
+ 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
+ {
+ *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
diff --git a/boost/chrono/io/duration_style.hpp b/boost/chrono/io/duration_style.hpp
new file mode 100644
index 0000000000..65b76a902c
--- /dev/null
+++ b/boost/chrono/io/duration_style.hpp
@@ -0,0 +1,35 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+// This code was adapted by Vicente from Howard Hinnant's experimental work
+// on chrono i/o to Boost
+
+#ifndef BOOST_CHRONO_IO_DURATION_STYLE_HPP
+#define BOOST_CHRONO_IO_DURATION_STYLE_HPP
+
+#include <boost/detail/scoped_enum_emulation.hpp>
+
+namespace boost
+{
+ namespace chrono
+ {
+ /**
+ * Scoped enumeration emulation stating whether the duration I/O style is long or short.
+ * prefix means duration::rep with whatever stream/locale settings are set for it followed by a long name representing the unit
+ * symbol means duration::rep with whatever stream/locale settings are set for it followed by a SI unit abbreviation
+ */
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(duration_style)
+ {
+ prefix, symbol
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(duration_style)
+
+
+ } // chrono
+
+}
+
+#endif // header
diff --git a/boost/chrono/io/duration_units.hpp b/boost/chrono/io/duration_units.hpp
new file mode 100644
index 0000000000..84faa819a9
--- /dev/null
+++ b/boost/chrono/io/duration_units.hpp
@@ -0,0 +1,1003 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_DURATION_UNITS_HPP
+#define BOOST_CHRONO_IO_DURATION_UNITS_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/ratio/ratio_io.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/io/duration_style.hpp>
+#include <boost/chrono/io/ios_base_state.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <ios>
+#include <locale>
+#include <algorithm>
+
+namespace boost
+{
+ namespace chrono
+ {
+ class rt_ratio
+ {
+ public:
+ template <typename Period>
+ rt_ratio(Period const&) :
+ num(Period::type::num), den(Period::type::den)
+ {
+ }
+
+ rt_ratio(intmax_t n = 0, intmax_t d = 0) :
+ num(n), den(d)
+ {
+ }
+
+ intmax_t num;
+ intmax_t den;
+ };
+
+ /**
+ * @c duration_units facet gives useful information about the duration units,
+ * as the number of plural forms, the plural form associated to a duration,
+ * the text associated to a plural form and a duration's period,
+ */
+ template <typename CharT = char>
+ class duration_units: public std::locale::facet
+ {
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of character string passed to member functions.
+ */
+ typedef std::basic_string<CharT> string_type;
+
+ /**
+ * Unique identifier for this type of facet.
+ */
+ static std::locale::id id;
+
+ /**
+ * Construct a @c duration_units facet.
+ * @param refs
+ * @Effects Construct a @c duration_units facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+ explicit duration_units(size_t refs = 0) :
+ std::locale::facet(refs)
+ {
+ }
+
+ /**
+ * @return pointer to the start of valid [N/D] units.
+ */
+ virtual const string_type* get_n_d_valid_units_start() const =0;
+ /**
+ * @effect calls the do_...
+ * @return pointer to the end of valid [N/D] units.
+ */
+ virtual const string_type* get_n_d_valid_units_end() const=0;
+
+ /**
+ * @return pointer to the start of valid units, symbol or prefix with its different plural forms.
+ */
+ virtual const string_type* get_valid_units_start() const=0;
+ /**
+ * @return pointer to the end of valid units.
+ */
+ virtual const string_type* get_valid_units_end() const=0;
+
+ /**
+ * @param k the found pointer to the [N/D] unit.
+ * @return true if @c k matches a valid unit.
+ */
+ virtual bool match_n_d_valid_unit(const string_type* k) const = 0;
+ /**
+ * @param k the found pointer to the unit.
+ * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
+ * @return true if @c k matches a valid unit.
+ */
+ virtual bool match_valid_unit(const string_type* k, rt_ratio& rt) const = 0;
+
+ /**
+ * @effect calls the do_...
+ * @return the pattern to be used by default.
+ */
+ virtual string_type get_pattern() const=0;
+
+ /**
+ * @effect calls the do_...
+ * @return the unit associated to this duration.
+ */
+ template <typename Rep, typename Period>
+ string_type get_unit(duration_style style, duration<Rep, Period> const& d) const
+ {
+ return do_get_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
+ }
+ /**
+ * @effect calls the do_...
+ * @return the [N/D] suffix unit associated to this duration.
+ */
+ template <typename Rep, typename Period>
+ string_type get_n_d_unit(duration_style style, duration<Rep, Period> const& d) const
+ {
+ return do_get_n_d_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
+ }
+
+ /**
+ * @effect calls the do_...
+ * @return true if the unit associated to the given Period is named, false otherwise.
+ */
+ template <typename Period>
+ bool is_named_unit() const
+ {
+ return do_is_named_unit(rt_ratio(Period()));
+ }
+
+
+ protected:
+
+ /**
+ * @Effects Destroys the facet
+ */
+ virtual ~duration_units()
+ {
+ }
+ /**
+ * @return the [N/D] suffix unit associated to this duration.
+ */
+ virtual string_type do_get_n_d_unit(duration_style style, rt_ratio rt, intmax_t v) const = 0;
+ /**
+ * @return the unit associated to this duration.
+ */
+ virtual string_type do_get_unit(duration_style style,rt_ratio rt, intmax_t v) const = 0;
+ /**
+ * @return true if the unit associated to the given Period is named, false otherwise.
+ */
+ virtual bool do_is_named_unit(rt_ratio rt) const =0;
+
+ };
+
+ template <typename CharT>
+ std::locale::id duration_units<CharT>::id;
+
+ namespace detail
+ {
+ template<typename CharT>
+ struct duration_units_default_holder
+ {
+ typedef std::basic_string<CharT> string_type;
+ static string_type* n_d_valid_units_;
+ static string_type* valid_units_;
+ static bool initialized_;
+ };
+ template <typename CharT>
+ typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::n_d_valid_units_=0;
+ template <typename CharT>
+ typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::valid_units_=0;
+ template<typename CharT>
+ bool duration_units_default_holder<CharT>::initialized_ = false;
+ }
+
+ /**
+ * This class is used to define the strings for the default English
+ */
+ template <typename CharT = char>
+ class duration_units_default: public duration_units<CharT>
+ {
+ protected:
+ static const std::size_t pfs_ = 2;
+
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of character string passed to member functions.
+ */
+ typedef std::basic_string<CharT> string_type;
+
+ /**
+ * Construct a @c duration_units_default facet.
+ * @param refs
+ * @Effects Construct a @c duration_units_default facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+ explicit duration_units_default(size_t refs = 0) :
+ duration_units<CharT> (refs)
+ {
+ }
+
+ /**
+ * Destroys the facet.
+ */
+ ~duration_units_default()
+ {
+ }
+
+ public:
+
+ /**
+ * @param k the found pointer to the [N/D] unit.
+ * @return true if @c k matches a valid unit.
+ */
+ bool match_n_d_valid_unit(const string_type* k) const
+ {
+ std::size_t index = (k - get_n_d_valid_units_start()) / (pfs_ + 1);
+ switch (index)
+ {
+ case 0:
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ /**
+ * @param k the found pointer to the unit.
+ * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
+ * @return true if @c k matches a valid unit.
+ */
+ bool match_valid_unit(const string_type* k, rt_ratio& rt) const
+ {
+ std::size_t index = (k - get_valid_units_start()) / (pfs_ + 1);
+ switch (index)
+ {
+ case 0:
+ rt = rt_ratio(atto());
+ break;
+ case 1:
+ rt = rt_ratio(femto());
+ break;
+ case 2:
+ rt = rt_ratio(pico());
+ break;
+ case 3:
+ rt = rt_ratio(nano());
+ break;
+ case 4:
+ rt = rt_ratio(micro());
+ break;
+ case 5:
+ rt = rt_ratio(milli());
+ break;
+ case 6:
+ rt = rt_ratio(centi());
+ break;
+ case 7:
+ rt = rt_ratio(deci());
+ break;
+ case 8:
+ rt = rt_ratio(deca());
+ break;
+ case 9:
+ rt = rt_ratio(hecto());
+ break;
+ case 10:
+ rt = rt_ratio(kilo());
+ break;
+ case 11:
+ rt = rt_ratio(mega());
+ break;
+ case 12:
+ rt = rt_ratio(giga());
+ break;
+ case 13:
+ rt = rt_ratio(tera());
+ break;
+ case 14:
+ rt = rt_ratio(peta());
+ break;
+ case 15:
+ rt = rt_ratio(exa());
+ break;
+ case 16:
+ rt = rt_ratio(ratio<1> ());
+ break;
+ case 17:
+ rt = rt_ratio(ratio<60> ());
+ break;
+ case 18:
+ rt = rt_ratio(ratio<3600> ());
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return pointer to the start of valid [N/D] units.
+ */
+ virtual const string_type* get_n_d_valid_units_start()const
+ {
+ return detail::duration_units_default_holder<CharT>::n_d_valid_units_;
+ }
+ /**
+ * @return pointer to the end of valid [N/D] units.
+ */
+ virtual const string_type* get_n_d_valid_units_end()const
+ {
+ return detail::duration_units_default_holder<CharT>::n_d_valid_units_ + (pfs_ + 1);
+ }
+
+ /**
+ * @return pointer to the start of valid units.
+ */
+ virtual const string_type* get_valid_units_start() const
+ {
+ return detail::duration_units_default_holder<CharT>::valid_units_;
+ }
+ /**
+ * @return pointer to the end of valid units.
+ */
+ virtual const string_type* get_valid_units_end() const
+ {
+ return detail::duration_units_default_holder<CharT>::valid_units_ + 19 * (pfs_ + 1);
+ }
+
+ string_type get_pattern() const
+ {
+ static const CharT t[] =
+ { '%', 'v', ' ', '%', 'u' };
+ static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
+
+ return pattern;
+ }
+
+ protected:
+ /**
+ *
+ * This facet names the units associated to the following periods:
+ * atto,femto,pico,nano,micro,milli,centi,deci,ratio<1>,deca,hecto,kilo,mega,giga,tera,peta,exa,ratio<60> and ratio<3600>.
+ * @return true if the unit associated to the given Period is named, false otherwise.
+ */
+ bool do_is_named_unit(rt_ratio rt) const
+ {
+ if (rt.num==1) {
+ switch (rt.den)
+ {
+ case BOOST_RATIO_INTMAX_C(1):
+ case BOOST_RATIO_INTMAX_C(10):
+ case BOOST_RATIO_INTMAX_C(100):
+ case BOOST_RATIO_INTMAX_C(1000):
+ case BOOST_RATIO_INTMAX_C(1000000):
+ case BOOST_RATIO_INTMAX_C(1000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000000000):
+ return true;
+ default:
+ return false;
+ }
+ } else if (rt.den==1) {
+ switch (rt.num)
+ {
+ case BOOST_RATIO_INTMAX_C(10):
+ case BOOST_RATIO_INTMAX_C(60):
+ case BOOST_RATIO_INTMAX_C(100):
+ case BOOST_RATIO_INTMAX_C(1000):
+ case BOOST_RATIO_INTMAX_C(3600):
+ case BOOST_RATIO_INTMAX_C(1000000):
+ case BOOST_RATIO_INTMAX_C(1000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000000):
+ case BOOST_RATIO_INTMAX_C(1000000000000000000):
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+
+ }
+
+ /**
+ * In English the suffix used after [N/D] is the one associated to the period ratio<1>.
+ * @return the [N/D] suffix unit associated to this duration.
+ */
+ string_type do_get_n_d_unit(duration_style style, rt_ratio, intmax_t v) const
+ {
+ return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
+ }
+
+ /**
+ * @return the unit associated to this duration if it is named, "" otherwise.
+ */
+ string_type do_get_unit(duration_style style, rt_ratio rt, intmax_t v) const
+ {
+ if (rt.num==1) {
+ switch (rt.den)
+ {
+ case BOOST_RATIO_INTMAX_C(1):
+ return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(10):
+ return do_get_unit(style, deci(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(100):
+ return do_get_unit(style, centi(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000):
+ return do_get_unit(style, milli(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000):
+ return do_get_unit(style, micro(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000):
+ return do_get_unit(style, nano(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000):
+ return do_get_unit(style, pico(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000000):
+ return do_get_unit(style, femto(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000000000):
+ return do_get_unit(style, atto(), do_get_plural_form(v));
+ default:
+ ;
+ }
+ } else if (rt.den==1) {
+ switch (rt.num)
+ {
+ case BOOST_RATIO_INTMAX_C(10):
+ return do_get_unit(style, deca(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(60):
+ return do_get_unit(style, ratio<60>(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(100):
+ return do_get_unit(style, hecto(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000):
+ return do_get_unit(style, kilo(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(3600):
+ return do_get_unit(style, ratio<3600>(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000):
+ return do_get_unit(style, mega(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000):
+ return do_get_unit(style, giga(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000):
+ return do_get_unit(style, tera(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000000):
+ return do_get_unit(style, peta(), do_get_plural_form(v));
+ case BOOST_RATIO_INTMAX_C(1000000000000000000):
+ return do_get_unit(style, exa(), do_get_plural_form(v));
+ default:
+ ;
+ }
+ }
+ BOOST_ASSERT(false&&"ratio parameter can not be translated");
+ //throw "exception";
+ return string_type();
+ }
+
+ protected:
+ /**
+ * @return the number of associated plural forms this facet manages.
+ */
+ virtual std::size_t do_get_plural_forms() const
+ {
+ return static_get_plural_forms();
+ }
+ static std::size_t static_get_plural_forms()
+ {
+ return pfs_;
+ }
+ /**
+ * Gets the associated plural form.
+ * @param value the duration representation
+ * @return the plural form associated to the @c value parameter. In English there are 2 plural forms
+ * 0 singular (-1 or 1)
+ * 1 plural for all others
+ */
+ virtual std::size_t do_get_plural_form(int_least64_t value) const
+ {
+ return static_get_plural_form(value);
+ }
+ static std::size_t static_get_plural_form(int_least64_t value)
+ {
+ return (value == -1 || value == 1) ? 0 : 1;
+ }
+
+ /**
+ * @param style the duration style.
+ * @param period the period associated to the duration seconds.
+ * @param pf the requested plural form.
+ * @return if style is symbol returns "s", otherwise if pf is 0 return "second", if pf is 1 "seconds"
+ */
+ virtual string_type do_get_unit(duration_style style, ratio<1> u, std::size_t pf) const
+ {
+ return static_get_unit(style,u,pf);
+ }
+ static string_type static_get_unit(duration_style style, ratio<1> , std::size_t pf)
+ {
+ static const CharT t[] =
+ { 's' };
+ static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
+ static const CharT u[] =
+ { 's', 'e', 'c', 'o', 'n', 'd' };
+ static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
+ static const CharT v[] =
+ { 's', 'e', 'c', 'o', 'n', 'd', 's' };
+ static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
+
+ if (style == duration_style::symbol)
+ {
+ return symbol;
+ }
+ if (pf == 0)
+ {
+ return singular;
+ }
+ if (pf == 1)
+ {
+ return plural;
+ }
+ BOOST_ASSERT(false&&"style/pf parameters not valid");
+ //throw "exception";
+ return string_type();
+ }
+
+ /**
+ * @param style the duration style.
+ * @param period the period associated to the duration minutes.
+ * @param pf the requested plural form.
+ * @return if style is symbol returns "min", otherwise if pf is 0 return "minute", if pf is 1 "minutes"
+ */
+ virtual string_type do_get_unit(duration_style style, ratio<60> u, std::size_t pf) const
+ {
+ return static_get_unit(style,u,pf);
+ }
+ static string_type static_get_unit(duration_style style, ratio<60> , std::size_t pf)
+ {
+ static const CharT t[] =
+ { 'm', 'i', 'n' };
+ static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
+
+ static const CharT u[] =
+ { 'm', 'i', 'n', 'u', 't', 'e' };
+ static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
+ static const CharT v[] =
+ { 'm', 'i', 'n', 'u', 't', 'e', 's' };
+ static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
+
+ if (style == duration_style::symbol) return symbol;
+ if (pf == 0) return singular;
+ if (pf == 1) return plural;
+ BOOST_ASSERT(false&&"style/pf parameters not valid");
+ //throw "exception";
+ return string_type();
+
+ }
+
+ /**
+ * @param style the duration style.
+ * @param period the period associated to the duration hours.
+ * @param pf the requested plural form.
+ * @return if style is symbol returns "h", otherwise if pf is 0 return "hour", if pf is 1 "hours"
+ */
+ virtual string_type do_get_unit(duration_style style, ratio<3600> u, std::size_t pf) const
+ {
+ return static_get_unit(style,u,pf);
+ }
+ static string_type static_get_unit(duration_style style, ratio<3600> , std::size_t pf)
+ {
+ static const CharT t[] =
+ { 'h' };
+ static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
+ static const CharT u[] =
+ { 'h', 'o', 'u', 'r' };
+ static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
+ static const CharT v[] =
+ { 'h', 'o', 'u', 'r', 's' };
+ static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
+
+ if (style == duration_style::symbol) return symbol;
+ if (pf == 0) return singular;
+ if (pf == 1) return plural;
+ BOOST_ASSERT(false&&"style/pf parameters not valid");
+ //throw "exception";
+ return string_type();
+
+ }
+ /**
+ * @param style the duration style.
+ * @param u the period tag atto.
+ * @param pf the requested plural form.
+ * @return the concatenation of the prefix associated to @c period + the one associated to seconds.
+ */
+ virtual string_type do_get_unit(duration_style style, atto u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, atto u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ /**
+ * @param style the duration style.
+ * @param u the period tag femto.
+ * @param pf the requested plural form.
+ * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
+ */
+ virtual string_type do_get_unit(duration_style style, femto u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, femto u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ /**
+ * @param style the duration style.
+ * @param u the period tag femto.
+ * @param pf the requested plural form.
+ * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
+ */
+ virtual string_type do_get_unit(duration_style style, pico u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, pico u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, nano u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, nano u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, micro u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, micro u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, milli u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, milli u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, centi u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, centi u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, deci u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, deci u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, deca u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, deca u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, hecto u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, hecto u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, kilo u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, kilo u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, mega u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, mega u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, giga u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, giga u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, tera u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, tera u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, peta u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, peta u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+ virtual string_type do_get_unit(duration_style style, exa u, std::size_t pf) const
+ {
+ return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
+ }
+ static string_type static_get_unit(duration_style style, exa u, std::size_t pf)
+ {
+ return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
+ }
+
+ protected:
+
+ /**
+ * @param style the duration style.
+ * @param u the period tag atto.
+ * @return depending on the value of @c style return the ratio_string symbol or prefix.
+ */
+ virtual string_type do_get_ratio_prefix(duration_style style, atto u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, atto)
+ {
+ if (style == duration_style::symbol) return ratio_string<atto, CharT>::symbol();
+ return ratio_string<atto, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, femto u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, femto)
+ {
+ if (style == duration_style::symbol) return ratio_string<femto, CharT>::symbol();
+ return ratio_string<femto, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, pico u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, pico)
+ {
+ if (style == duration_style::symbol) return ratio_string<pico, CharT>::symbol();
+ return ratio_string<pico, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, nano u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, nano)
+ {
+ if (style == duration_style::symbol) return ratio_string<nano, CharT>::symbol();
+ return ratio_string<nano, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, micro u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, micro)
+ {
+ if (style == duration_style::symbol) return ratio_string<micro, CharT>::symbol();
+ return ratio_string<micro, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, milli u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, milli)
+ {
+ if (style == duration_style::symbol) return ratio_string<milli, CharT>::symbol();
+ return ratio_string<milli, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, centi u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, centi)
+ {
+ if (style == duration_style::symbol) return ratio_string<centi, CharT>::symbol();
+ return ratio_string<centi, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, deci u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, deci)
+ {
+ if (style == duration_style::symbol) return ratio_string<deci, CharT>::symbol();
+ return ratio_string<deci, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, deca u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, deca)
+ {
+ if (style == duration_style::symbol) return ratio_string<deca, CharT>::symbol();
+ return ratio_string<deca, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, hecto u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, hecto)
+ {
+ if (style == duration_style::symbol) return ratio_string<hecto, CharT>::symbol();
+ return ratio_string<hecto, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, kilo u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, kilo)
+ {
+ if (style == duration_style::symbol) return ratio_string<kilo, CharT>::symbol();
+ return ratio_string<kilo, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, mega u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, mega)
+ {
+ if (style == duration_style::symbol) return ratio_string<mega, CharT>::symbol();
+ return ratio_string<mega, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, giga u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, giga)
+ {
+ if (style == duration_style::symbol) return ratio_string<giga, CharT>::symbol();
+ return ratio_string<giga, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, tera u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, tera)
+ {
+ if (style == duration_style::symbol) return ratio_string<tera, CharT>::symbol();
+ return ratio_string<tera, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, peta u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, peta)
+ {
+ if (style == duration_style::symbol) return ratio_string<peta, CharT>::symbol();
+ return ratio_string<peta, CharT>::prefix();
+ }
+ virtual string_type do_get_ratio_prefix(duration_style style, exa u) const
+ {
+ return static_get_ratio_prefix(style, u);
+ }
+ static string_type static_get_ratio_prefix(duration_style style, exa)
+ {
+ if (style == duration_style::symbol) return ratio_string<exa, CharT>::symbol();
+ return ratio_string<exa, CharT>::prefix();
+ }
+
+ protected:
+ template <typename Period>
+ string_type* fill_units(string_type* it, Period) const
+ {
+ std::size_t pfs = do_get_plural_forms();
+ for (std::size_t pf = 0; pf < pfs; ++pf)
+ {
+ *it++ = do_get_unit(duration_style::prefix, Period(), pf);
+ }
+ *it++ = do_get_unit(duration_style::symbol, Period(), 0);
+ return it;
+ }
+ public:
+ template <typename Period>
+ static string_type* static_fill_units(string_type* it, Period)
+ {
+ std::size_t pfs = static_get_plural_forms();
+ for (std::size_t pf = 0; pf < pfs; ++pf)
+ {
+ *it++ = static_get_unit(duration_style::prefix, Period(), pf);
+ }
+ *it++ = static_get_unit(duration_style::symbol, Period(), 0);
+ return it;
+ }
+ static string_type* static_init_valid_units(string_type* it)
+ {
+ it = static_fill_units(it, atto());
+ it = static_fill_units(it, femto());
+ it = static_fill_units(it, pico());
+ it = static_fill_units(it, nano());
+ it = static_fill_units(it, micro());
+ it = static_fill_units(it, milli());
+ it = static_fill_units(it, centi());
+ it = static_fill_units(it, deci());
+ it = static_fill_units(it, deca());
+ it = static_fill_units(it, hecto());
+ it = static_fill_units(it, kilo());
+ it = static_fill_units(it, mega());
+ it = static_fill_units(it, giga());
+ it = static_fill_units(it, tera());
+ it = static_fill_units(it, peta());
+ it = static_fill_units(it, exa());
+ it = static_fill_units(it, ratio<1> ());
+ it = static_fill_units(it, ratio<60> ());
+ it = static_fill_units(it, ratio<3600> ());
+ return it;
+ }
+ };
+
+ namespace detail
+ {
+
+ template<typename CharT>
+ struct duration_units_default_initializer_t
+ {
+ duration_units_default_initializer_t()
+ {
+ if (!duration_units_default_holder<CharT>::initialized_)
+ {
+ typedef typename duration_units_default_holder<CharT>::string_type string_type;
+ duration_units_default_holder<CharT>::n_d_valid_units_ = new string_type[3];
+ duration_units_default_holder<CharT>::valid_units_ = new string_type[19 * 3];
+
+ string_type* it = duration_units_default_holder<CharT>::n_d_valid_units_;
+ it = duration_units_default<CharT>::static_fill_units(it, ratio<1> ());
+ it = duration_units_default<CharT>::static_init_valid_units(duration_units_default_holder<CharT>::valid_units_);
+
+ duration_units_default_holder<CharT>::initialized_ = true;
+ }
+ }
+ ~duration_units_default_initializer_t()
+ {
+ if (duration_units_default_holder<CharT>::initialized_)
+ {
+ delete[] duration_units_default_holder<CharT>::n_d_valid_units_;
+ duration_units_default_holder<CharT>::n_d_valid_units_ = 0;
+ delete[] duration_units_default_holder<CharT>::valid_units_;
+ duration_units_default_holder<CharT>::valid_units_ = 0;
+ duration_units_default_holder<CharT>::initialized_ = false;
+ }
+ }
+ };
+ namespace /**/
+ {
+ duration_units_default_initializer_t<char> duration_units_default_initializer;
+ duration_units_default_initializer_t<wchar_t> wduration_units_default_initializer;
+ } // namespace
+ }
+ } // chrono
+
+} // boost
+
+#endif // header
diff --git a/boost/chrono/io/ios_base_state.hpp b/boost/chrono/io/ios_base_state.hpp
new file mode 100644
index 0000000000..6e320a5678
--- /dev/null
+++ b/boost/chrono/io/ios_base_state.hpp
@@ -0,0 +1,151 @@
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+// This code was adapted by Vicente from Howard Hinnant's experimental work
+// on chrono i/o to Boost
+
+#ifndef BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
+#define BOOST_CHRONO_IO_IOS_BASE_STATE_HPP
+
+#include <boost/chrono/config.hpp>
+#include <locale>
+#include <boost/chrono/io/duration_style.hpp>
+#include <boost/chrono/io/timezone.hpp>
+#include <boost/chrono/io/utility/ios_base_state_ptr.hpp>
+
+namespace boost
+{
+ namespace chrono
+ {
+
+ class fmt_masks : public ios_flags<fmt_masks>
+ {
+ typedef ios_flags<fmt_masks> base_type;
+ fmt_masks& operator=(fmt_masks const& rhs) ;
+
+ public:
+ fmt_masks(std::ios_base& ios): base_type(ios) {}
+ enum type
+ {
+ uses_symbol = 1 << 0,
+ uses_local = 1 << 1
+ };
+
+ inline duration_style get_duration_style()
+ {
+ return (flags() & uses_symbol) ? duration_style::symbol : duration_style::prefix;
+ }
+ inline void set_duration_style(duration_style style)
+ {
+ if (style == duration_style::symbol)
+ setf(uses_symbol);
+ else
+ unsetf(uses_symbol);
+ }
+
+ inline timezone get_timezone()
+ {
+ return (flags() & uses_local) ? timezone::local : timezone::utc;
+ }
+ inline void set_timezone(timezone tz)
+ {
+ if (tz == timezone::local)
+ setf(uses_local);
+ else
+ unsetf(uses_local);
+ }
+ };
+ namespace detail
+ {
+ namespace /**/ {
+ xalloc_key_initializer<fmt_masks > fmt_masks_xalloc_key_initializer;
+ } // namespace
+ } // namespace detail
+
+ inline duration_style get_duration_style(std::ios_base & ios)
+ {
+ return fmt_masks(ios).get_duration_style();
+ }
+ inline void set_duration_style(std::ios_base& ios, duration_style style)
+ {
+ fmt_masks(ios).set_duration_style(style);
+ }
+ inline std::ios_base& symbol_format(std::ios_base& ios)
+ {
+ fmt_masks(ios).setf(fmt_masks::uses_symbol);
+ return ios;
+ }
+ inline std::ios_base& name_format(std::ios_base& ios)
+ {
+ fmt_masks(ios).unsetf(fmt_masks::uses_symbol);
+ return ios;
+ }
+
+ inline timezone get_timezone(std::ios_base & ios)
+ {
+ return fmt_masks(ios).get_timezone();
+ }
+ inline void set_timezone(std::ios_base& ios, timezone tz)
+ {
+ fmt_masks(ios).set_timezone(tz);
+ }
+ inline std::ios_base& local_timezone(std::ios_base& ios)
+ {
+ fmt_masks(ios).setf(fmt_masks::uses_local);
+ return ios;
+ }
+
+ inline std::ios_base& utc_timezone(std::ios_base& ios)
+ {
+ fmt_masks(ios).unsetf(fmt_masks::uses_local);
+ return ios;
+ }
+
+ namespace detail
+ {
+
+ template<typename CharT>
+ struct ios_base_data_aux
+ {
+ std::basic_string<CharT> time_fmt;
+ std::basic_string<CharT> duration_fmt;
+ public:
+
+ ios_base_data_aux() :
+ time_fmt(""),
+ duration_fmt("")
+ {
+ }
+ };
+ template<typename CharT>
+ struct ios_base_data {};
+ namespace /**/ {
+ xalloc_key_initializer<detail::ios_base_data<char> > ios_base_data_aux_xalloc_key_initializer;
+ xalloc_key_initializer<detail::ios_base_data<wchar_t> > wios_base_data_aux_xalloc_key_initializer;
+#if BOOST_CHRONO_HAS_UNICODE_SUPPORT
+ xalloc_key_initializer<detail::ios_base_data<char16_t> > u16ios_base_data_aux_xalloc_key_initializer;
+ xalloc_key_initializer<detail::ios_base_data<char32_t> > u32ios_base_data_aux_xalloc_key_initializer;
+#endif
+ } // namespace
+ } // namespace detail
+
+ template<typename CharT>
+ inline std::basic_string<CharT> get_time_fmt(std::ios_base & ios)
+ {
+ ios_state_not_null_ptr<detail::ios_base_data<CharT>, detail::ios_base_data_aux<CharT> > ptr(ios);
+ return ptr->time_fmt;
+ }
+ template<typename CharT>
+ inline void set_time_fmt(std::ios_base& ios, std::basic_string<
+ CharT> const& fmt)
+ {
+ ios_state_not_null_ptr<detail::ios_base_data<CharT>, detail::ios_base_data_aux<CharT> > ptr(ios);
+ ptr->time_fmt = fmt;
+ }
+
+ } // chrono
+} // boost
+
+#endif // header
diff --git a/boost/chrono/io/time_point_get.hpp b/boost/chrono/io/time_point_get.hpp
new file mode 100644
index 0000000000..5e4acd39cc
--- /dev/null
+++ b/boost/chrono/io/time_point_get.hpp
@@ -0,0 +1,330 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_TIME_POINT_GET_HPP
+#define BOOST_CHRONO_IO_TIME_POINT_GET_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/chrono/io/time_point_units.hpp>
+#include <boost/chrono/io/duration_get.hpp>
+#include <boost/assert.hpp>
+#include <locale>
+#include <string>
+
+/**
+ * Duration formatting facet for input.
+ */
+namespace boost
+{
+ namespace chrono
+ {
+
+ template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
+ class time_point_get: public std::locale::facet
+ {
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of iterator used to scan the character buffer.
+ */
+ typedef InputIterator iter_type;
+
+ /**
+ * Construct a @c time_point_get facet.
+ * @param refs
+ * @Effects Construct a @c time_point_get facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+
+ explicit time_point_get(size_t refs = 0) :
+ std::locale::facet(refs)
+ {
+ }
+
+ /**
+ * @param s start input stream iterator
+ * @param end end input stream iterator
+ * @param ios a reference to a ios_base
+ * @param err the ios_base state
+ * @param d the duration
+ * @param pattern begin of the formatting pattern
+ * @param pat_end end of the formatting pattern
+ *
+ * Requires: [pattern,pat_end) shall be a valid range.
+ *
+ * Effects: The function starts by evaluating err = std::ios_base::goodbit.
+ * It then enters a loop, reading zero or more characters from s at
+ * each iteration. Unless otherwise specified below, the loop
+ * terminates when the first of the following conditions holds:
+ * - The expression pattern == pat_end evaluates to true.
+ * - The expression err == std::ios_base::goodbit evaluates to false.
+ * - The expression s == end evaluates to true, in which case the
+ * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
+ * - The next element of pattern is equal to '%', followed by a conversion
+ * specifier character, the functions @c get_duration or @c get_epoch are called depending on
+ * whether the format is @c 'd' or @c 'e'.
+ * If the number of elements in the range [pattern,pat_end) is not
+ * sufficient to unambiguously determine whether the conversion
+ * specification is complete and valid, the function evaluates
+ * err = std::ios_base::failbit. Otherwise, the function evaluates
+ * s = do_get(s, end, ios, err, d). If err == std::ios_base::goodbit holds after
+ * the evaluation of the expression, the function increments pattern to
+ * point just past the end of the conversion specification and continues
+ * looping.
+ * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
+ * which case the function first increments pattern until
+ * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
+ * then advances s until s == end || !isspace(*s, ios.getloc()) is true,
+ * and finally resumes looping.
+ * - The next character read from s matches the element pointed to by
+ * pattern in a case-insensitive comparison, in which case the function
+ * evaluates ++pattern, ++s and continues looping. Otherwise, the function
+ * evaluates err = std::ios_base::failbit.
+ *
+ * Returns: s
+ */
+
+ template <class Clock, class Duration>
+ iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
+ time_point<Clock, Duration> &tp, const char_type *pattern, const char_type *pat_end) const
+ {
+ if (std::has_facet<time_point_units<CharT> >(is.getloc()))
+ {
+ time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
+ return get(facet, i, e, is, err, tp, pattern, pat_end);
+ }
+ else
+ {
+ time_point_units_default<CharT> facet;
+ return get(facet, i, e, is, err, tp, pattern, pat_end);
+ }
+ }
+
+ template <class Clock, class Duration>
+ iter_type get(time_point_units<CharT> const &facet, iter_type s, iter_type end, std::ios_base& ios,
+ std::ios_base::iostate& err, time_point<Clock, Duration> &tp, const char_type *pattern,
+ const char_type *pat_end) const
+ {
+
+ Duration d;
+ bool duration_found = false, epoch_found = false;
+
+ const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+ err = std::ios_base::goodbit;
+ while (pattern != pat_end && err == std::ios_base::goodbit)
+ {
+ if (s == end)
+ {
+ err |= std::ios_base::eofbit;
+ break;
+ }
+ if (ct.narrow(*pattern, 0) == '%')
+ {
+ if (++pattern == pat_end)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ char cmd = ct.narrow(*pattern, 0);
+ switch (cmd)
+ {
+ case 'd':
+ {
+ if (duration_found)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ duration_found = true;
+ s = get_duration(s, end, ios, err, d);
+ if (err & (std::ios_base::badbit | std::ios_base::failbit))
+ {
+ return s;
+ }
+ break;
+ }
+ case 'e':
+ {
+ if (epoch_found)
+ {
+ err |= std::ios_base::failbit;
+ return s;
+ }
+ epoch_found = true;
+ s = get_epoch<Clock> (facet, s, end, ios, err);
+ if (err & (std::ios_base::badbit | std::ios_base::failbit))
+ {
+ return s;
+ }
+ break;
+ }
+ default:
+ BOOST_ASSERT(false && "Boost::Chrono internal error.");
+ break;
+ }
+
+ ++pattern;
+ }
+ else if (ct.is(std::ctype_base::space, *pattern))
+ {
+ for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
+ ;
+ for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
+ ;
+ }
+ else if (ct.toupper(*s) == ct.toupper(*pattern))
+ {
+ ++s;
+ ++pattern;
+ }
+ else
+ {
+ err |= std::ios_base::failbit;
+ }
+ }
+
+ // Success! Store it.
+ tp = time_point<Clock, Duration> (d);
+ return s;
+ }
+
+ /**
+ *
+ * @param s an input stream iterator
+ * @param ios a reference to a ios_base
+ * @param d the duration
+ * Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+ * @code
+ * return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
+ * @codeend
+ * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+ */
+ template <class Clock, class Duration>
+ iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
+ time_point<Clock, Duration> &tp) const
+ {
+ if (std::has_facet<time_point_units<CharT> >(is.getloc()))
+ {
+ time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
+ std::basic_string<CharT> str = facet.get_pattern();
+ return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
+ }
+ else
+ {
+ time_point_units_default<CharT> facet;
+ std::basic_string<CharT> str = facet.get_pattern();
+ return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size());
+ }
+ }
+
+ /**
+ * As if
+ * @code
+ * return facet.get(s, end, ios, err, d);
+ * @endcode
+ * where @c facet is either the @c duration_get facet associated to the @c ios or an instance of the default @c duration_get facet.
+ *
+ * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid duration.
+ */
+ template <typename Rep, typename Period>
+ iter_type get_duration(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
+ duration<Rep, Period>& d) const
+ {
+ if (std::has_facet<duration_get<CharT> >(is.getloc()))
+ {
+ duration_get<CharT> const &facet = std::use_facet<duration_get<CharT> >(is.getloc());
+ return get_duration(facet, i, e, is, err, d);
+ }
+ else
+ {
+ duration_get<CharT> facet;
+ return get_duration(facet, i, e, is, err, d);
+ }
+ }
+
+ template <typename Rep, typename Period>
+ iter_type get_duration(duration_get<CharT> const& facet, iter_type s, iter_type end, std::ios_base& ios,
+ std::ios_base::iostate& err, duration<Rep, Period>& d) const
+ {
+ return facet.get(s, end, ios, err, d);
+ }
+
+ /**
+ *
+ * @Effects Let @c facet be the @c time_point_units facet associated to @c is or a new instance of the default @c time_point_units_default facet.
+ * Let @c epoch be the epoch string associated to the Clock using this facet.
+ * Scans @c i to match @c epoch or @c e is reached.
+ *
+ * If not match before the @c e is reached @c std::ios_base::failbit is set in @c err.
+ * If @c e is reached @c std::ios_base::failbit is set in @c err.
+ *
+ * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid epoch.
+ */
+ template <class Clock>
+ iter_type get_epoch(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err) const
+ {
+ if (std::has_facet<time_point_units<CharT> >(is.getloc()))
+ {
+ time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(is.getloc());
+ return get_epoch(facet, i, e, is, err);
+ }
+ else
+ {
+ time_point_units_default<CharT> facet;
+ return get_epoch(facet, i, e, is, err);
+ }
+ }
+
+ template <class Clock>
+ iter_type get_epoch(time_point_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base&,
+ std::ios_base::iostate& err) const
+ {
+ const std::basic_string<CharT> epoch = facet.template get_epoch<Clock> ();
+ std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, &epoch, &epoch + 1,
+ //~ std::use_facet<std::ctype<CharT> >(ios.getloc()),
+ err) - &epoch;
+ if (k == 1)
+ {
+ err |= std::ios_base::failbit;
+ return i;
+ }
+ return i;
+ }
+
+ /**
+ * Unique identifier for this type of facet.
+ */
+ static std::locale::id id;
+
+ /**
+ * @Effects Destroy the facet
+ */
+ ~time_point_get()
+ {
+ }
+ };
+
+ /**
+ * Unique identifier for this type of facet.
+ */
+ template <class CharT, class InputIterator>
+ std::locale::id time_point_get<CharT, InputIterator>::id;
+
+ } // chrono
+}
+// boost
+
+#endif // header
diff --git a/boost/chrono/io/time_point_io.hpp b/boost/chrono/io/time_point_io.hpp
new file mode 100644
index 0000000000..629479cde9
--- /dev/null
+++ b/boost/chrono/io/time_point_io.hpp
@@ -0,0 +1,1239 @@
+// (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).
+
+//===-------------------------- locale ------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// This code was adapted by Vicente from Howard Hinnant's experimental work
+// on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get()
+
+#ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
+#define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
+
+#include <boost/chrono/io/time_point_put.hpp>
+#include <boost/chrono/io/time_point_get.hpp>
+#include <boost/chrono/io/duration_io.hpp>
+#include <boost/chrono/io/ios_base_state.hpp>
+#include <boost/chrono/io/utility/manip_base.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/clock_string.hpp>
+#include <boost/chrono/round.hpp>
+#include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <cstring>
+#include <locale>
+#include <ctime>
+
+#define BOOST_CHRONO_INTERNAL_TIMEGM \
+ ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
+ || (defined(sun) || defined(__sun)) \
+ || (defined __IBMCPP__) \
+ || defined __ANDROID__ \
+ || defined __QNXNTO__ \
+ || (defined(_AIX) && defined __GNUC__)
+
+#define BOOST_CHRONO_INTERNAL_GMTIME \
+ (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
+ || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
+ || (defined __IBMCPP__) \
+ || defined __ANDROID__ \
+ || (defined(_AIX) && defined __GNUC__)
+
+#define BOOST_CHRONO_USES_INTERNAL_TIME_GET
+
+namespace boost
+{
+ namespace chrono
+ {
+ typedef double fractional_seconds;
+ namespace detail
+ {
+
+
+ template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
+ struct time_get
+ {
+ std::time_get<CharT> const &that_;
+ time_get(std::time_get<CharT> const& that) : that_(that) {}
+
+ typedef std::time_get<CharT> facet;
+ typedef typename facet::iter_type iter_type;
+ typedef typename facet::char_type char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ static int
+ get_up_to_n_digits(
+ InputIterator& b, InputIterator e,
+ std::ios_base::iostate& err,
+ const std::ctype<CharT>& ct,
+ int n)
+ {
+ // Precondition: n >= 1
+ if (b == e)
+ {
+ err |= std::ios_base::eofbit | std::ios_base::failbit;
+ return 0;
+ }
+ // get first digit
+ CharT c = *b;
+ if (!ct.is(std::ctype_base::digit, c))
+ {
+ err |= std::ios_base::failbit;
+ return 0;
+ }
+ int r = ct.narrow(c, 0) - '0';
+ for (++b, --n; b != e && n > 0; ++b, --n)
+ {
+ // get next digit
+ c = *b;
+ if (!ct.is(std::ctype_base::digit, c))
+ return r;
+ r = r * 10 + ct.narrow(c, 0) - '0';
+ }
+ if (b == e)
+ err |= std::ios_base::eofbit;
+ return r;
+ }
+
+
+ void get_day(
+ int& d,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2);
+ if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31)
+ d = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void get_month(
+ int& m,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2) - 1;
+ if (!(err & std::ios_base::failbit) && t <= 11)
+ m = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+
+ void get_year4(int& y,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 4);
+ if (!(err & std::ios_base::failbit))
+ y = t - 1900;
+ }
+
+ void
+ get_hour(int& h,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2);
+ if (!(err & std::ios_base::failbit) && t <= 23)
+ h = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void
+ get_minute(int& m,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2);
+ if (!(err & std::ios_base::failbit) && t <= 59)
+ m = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void get_second(int& s,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2);
+ if (!(err & std::ios_base::failbit) && t <= 60)
+ s = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void get_white_space(iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ for (; b != e && ct.is(std::ctype_base::space, *b); ++b)
+ ;
+ if (b == e)
+ err |= std::ios_base::eofbit;
+ }
+
+ void get_12_hour(int& h,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 2);
+ if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
+ h = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void get_percent(iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ if (b == e)
+ {
+ err |= std::ios_base::eofbit | std::ios_base::failbit;
+ return;
+ }
+ if (ct.narrow(*b, 0) != '%')
+ err |= std::ios_base::failbit;
+ else if(++b == e)
+ err |= std::ios_base::eofbit;
+ }
+
+ void get_day_year_num(int& d,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 3);
+ if (!(err & std::ios_base::failbit) && t <= 365)
+ d = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+
+ void
+ get_weekday(int& w,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ int t = get_up_to_n_digits(b, e, err, ct, 1);
+ if (!(err & std::ios_base::failbit) && t <= 6)
+ w = t;
+ else
+ err |= std::ios_base::failbit;
+ }
+#if 0
+
+ void
+ get_am_pm(int& h,
+ iter_type& b, iter_type e,
+ std::ios_base::iostate& err,
+ const std::ctype<char_type>& ct) const
+ {
+ const string_type* ap = am_pm();
+ if (ap[0].size() + ap[1].size() == 0)
+ {
+ err |= ios_base::failbit;
+ return;
+ }
+ ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap;
+ if (i == 0 && h == 12)
+ h = 0;
+ else if (i == 1 && h < 12)
+ h += 12;
+ }
+
+#endif
+
+ InputIterator get(
+ iter_type b, iter_type e,
+ std::ios_base& iob,
+ std::ios_base::iostate& err,
+ std::tm* tm,
+ char fmt, char) const
+ {
+ err = std::ios_base::goodbit;
+ const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
+
+ switch (fmt)
+ {
+ case 'a':
+ case 'A':
+ {
+ std::tm tm2;
+ std::memset(&tm2, 0, sizeof(std::tm));
+ that_.get_weekday(b, e, iob, err, &tm2);
+ //tm->tm_wday = tm2.tm_wday;
+ }
+ break;
+ case 'b':
+ case 'B':
+ case 'h':
+ {
+ std::tm tm2;
+ std::memset(&tm2, 0, sizeof(std::tm));
+ that_.get_monthname(b, e, iob, err, &tm2);
+ //tm->tm_mon = tm2.tm_mon;
+ }
+ break;
+// case 'c':
+// {
+// const string_type& fm = c();
+// b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
+// }
+// break;
+ case 'd':
+ case 'e':
+ get_day(tm->tm_mday, b, e, err, ct);
+ break;
+ case 'D':
+ {
+ const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
+ b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
+ }
+ break;
+ case 'F':
+ {
+ const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
+ b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
+ }
+ break;
+ case 'H':
+ get_hour(tm->tm_hour, b, e, err, ct);
+ break;
+ case 'I':
+ get_12_hour(tm->tm_hour, b, e, err, ct);
+ break;
+ case 'j':
+ get_day_year_num(tm->tm_yday, b, e, err, ct);
+ break;
+ case 'm':
+ get_month(tm->tm_mon, b, e, err, ct);
+ break;
+ case 'M':
+ get_minute(tm->tm_min, b, e, err, ct);
+ break;
+ case 'n':
+ case 't':
+ get_white_space(b, e, err, ct);
+ break;
+// case 'p':
+// get_am_pm(tm->tm_hour, b, e, err, ct);
+// break;
+ case 'r':
+ {
+ const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
+ b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
+ }
+ break;
+ case 'R':
+ {
+ const char_type fm[] = {'%', 'H', ':', '%', 'M'};
+ b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
+ }
+ break;
+ case 'S':
+ get_second(tm->tm_sec, b, e, err, ct);
+ break;
+ case 'T':
+ {
+ const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
+ b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
+ }
+ break;
+ case 'w':
+ {
+ get_weekday(tm->tm_wday, b, e, err, ct);
+ }
+ break;
+ case 'x':
+ return that_.get_date(b, e, iob, err, tm);
+// case 'X':
+// return that_.get_time(b, e, iob, err, tm);
+// {
+// const string_type& fm = X();
+// b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
+// }
+// break;
+// case 'y':
+// get_year(tm->tm_year, b, e, err, ct);
+ break;
+ case 'Y':
+ get_year4(tm->tm_year, b, e, err, ct);
+ break;
+ case '%':
+ get_percent(b, e, err, ct);
+ break;
+ default:
+ err |= std::ios_base::failbit;
+ }
+ return b;
+ }
+
+
+ InputIterator get(
+ iter_type b, iter_type e,
+ std::ios_base& iob,
+ std::ios_base::iostate& err, std::tm* tm,
+ const char_type* fmtb, const char_type* fmte) const
+ {
+ const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
+ err = std::ios_base::goodbit;
+ while (fmtb != fmte && err == std::ios_base::goodbit)
+ {
+ if (b == e)
+ {
+ err = std::ios_base::failbit;
+ break;
+ }
+ if (ct.narrow(*fmtb, 0) == '%')
+ {
+ if (++fmtb == fmte)
+ {
+ err = std::ios_base::failbit;
+ break;
+ }
+ char cmd = ct.narrow(*fmtb, 0);
+ char opt = '\0';
+ if (cmd == 'E' || cmd == '0')
+ {
+ if (++fmtb == fmte)
+ {
+ err = std::ios_base::failbit;
+ break;
+ }
+ opt = cmd;
+ cmd = ct.narrow(*fmtb, 0);
+ }
+ b = get(b, e, iob, err, tm, cmd, opt);
+ ++fmtb;
+ }
+ else if (ct.is(std::ctype_base::space, *fmtb))
+ {
+ for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb)
+ ;
+ for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b)
+ ;
+ }
+ else if (ct.toupper(*b) == ct.toupper(*fmtb))
+ {
+ ++b;
+ ++fmtb;
+ }
+ else
+ err = std::ios_base::failbit;
+ }
+ if (b == e)
+ err |= std::ios_base::eofbit;
+ return b;
+ }
+
+ };
+
+
+ template <class CharT>
+ class time_manip: public manip<time_manip<CharT> >
+ {
+ std::basic_string<CharT> fmt_;
+ timezone tz_;
+ public:
+
+ time_manip(timezone tz, std::basic_string<CharT> fmt)
+ // todo move semantics
+ :
+ fmt_(fmt), tz_(tz)
+ {
+ }
+
+ /**
+ * Change the timezone and time format ios state;
+ */
+ void operator()(std::ios_base &ios) const
+ {
+ set_time_fmt<CharT> (ios, fmt_);
+ set_timezone(ios, tz_);
+ }
+ };
+
+ class time_man: public manip<time_man>
+ {
+ timezone tz_;
+ public:
+
+ time_man(timezone tz)
+ // todo move semantics
+ :
+ tz_(tz)
+ {
+ }
+
+ /**
+ * Change the timezone and time format ios state;
+ */
+ void operator()(std::ios_base &ios) const
+ {
+ //set_time_fmt<typename out_stream::char_type>(ios, "");
+ set_timezone(ios, tz_);
+ }
+ };
+
+ }
+
+ template <class CharT>
+ inline detail::time_manip<CharT> time_fmt(timezone tz, const CharT* fmt)
+ {
+ return detail::time_manip<CharT>(tz, fmt);
+ }
+
+ template <class CharT>
+ inline detail::time_manip<CharT> time_fmt(timezone tz, std::basic_string<CharT> fmt)
+ {
+ // todo move semantics
+ return detail::time_manip<CharT>(tz, fmt);
+ }
+
+ inline detail::time_man time_fmt(timezone f)
+ {
+ return detail::time_man(f);
+ }
+
+ /**
+ * time_fmt_io_saver i/o saver.
+ *
+ * See Boost.IO i/o state savers for a motivating compression.
+ */
+ template <typename CharT = char, typename Traits = std::char_traits<CharT> >
+ struct time_fmt_io_saver
+ {
+
+ //! the type of the state to restore
+ typedef std::basic_ostream<CharT, Traits> state_type;
+ //! the type of aspect to save
+ typedef std::basic_string<CharT, Traits> aspect_type;
+
+ /**
+ * Explicit construction from an i/o stream.
+ *
+ * Store a reference to the i/o stream and the value of the associated @c time format .
+ */
+ explicit time_fmt_io_saver(state_type &s) :
+ s_save_(s), a_save_(get_time_fmt(s_save_))
+ {
+ }
+
+ /**
+ * Construction from an i/o stream and a @c time format to restore.
+ *
+ * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
+ */
+ time_fmt_io_saver(state_type &s, aspect_type new_value) :
+ s_save_(s), a_save_(new_value)
+ {
+ }
+
+ /**
+ * Destructor.
+ *
+ * Restores the i/o stream with the format to be restored.
+ */
+ ~time_fmt_io_saver()
+ {
+ this->restore();
+ }
+
+ /**
+ * Restores the i/o stream with the time format to be restored.
+ */
+ void restore()
+ {
+ set_time_fmt(a_save_, a_save_);
+ }
+ private:
+ state_type& s_save_;
+ aspect_type a_save_;
+ };
+
+ /**
+ * timezone_io_saver i/o saver.
+ *
+ * See Boost.IO i/o state savers for a motivating compression.
+ */
+ struct timezone_io_saver
+ {
+
+ //! the type of the state to restore
+ typedef std::ios_base state_type;
+ //! the type of aspect to save
+ typedef timezone aspect_type;
+
+ /**
+ * Explicit construction from an i/o stream.
+ *
+ * Store a reference to the i/o stream and the value of the associated @c timezone.
+ */
+ explicit timezone_io_saver(state_type &s) :
+ s_save_(s), a_save_(get_timezone(s_save_))
+ {
+ }
+
+ /**
+ * Construction from an i/o stream and a @c timezone to restore.
+ *
+ * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
+ */
+ timezone_io_saver(state_type &s, aspect_type new_value) :
+ s_save_(s), a_save_(new_value)
+ {
+ }
+
+ /**
+ * Destructor.
+ *
+ * Restores the i/o stream with the format to be restored.
+ */
+ ~timezone_io_saver()
+ {
+ this->restore();
+ }
+
+ /**
+ * Restores the i/o stream with the timezone to be restored.
+ */
+ void restore()
+ {
+ set_timezone(s_save_, a_save_);
+ }
+ private:
+ timezone_io_saver& operator=(timezone_io_saver const& rhs) ;
+
+ state_type& s_save_;
+ aspect_type a_save_;
+ };
+
+ /**
+ *
+ * @param os
+ * @param tp
+ * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry
+ * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put<CharT>
+ * facet associated to @c os or a new created instance of the default @c time_point_put<CharT> facet.
+ * @return @c os.
+ */
+ 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)
+ {
+
+ 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<time_point_put<CharT> >(os.getloc()))
+ {
+ if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
+ {
+ err = std::ios_base::badbit;
+ }
+ }
+ else
+ {
+ if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, os.fill(), tp).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 Clock, class Duration>
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock, Duration>& tp)
+ {
+ 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<time_point_get<CharT> >(is.getloc()))
+ {
+ time_point_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, tp);
+ }
+ else
+ {
+ std::use_facet<time_point_get<CharT> >(is.getloc()).get(is, std::istreambuf_iterator<CharT, Traits>(), is,
+ err, tp);
+ }
+ }
+ }
+ 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) throw;
+ }
+ BOOST_CATCH_END
+ if (err) is.setstate(err);
+ return is;
+ }
+
+
+ namespace detail
+ {
+
+//#if BOOST_CHRONO_INTERNAL_TIMEGM
+
+ inline int32_t is_leap(int32_t year)
+ {
+ if(year % 400 == 0)
+ return 1;
+ if(year % 100 == 0)
+ return 0;
+ if(year % 4 == 0)
+ return 1;
+ return 0;
+ }
+ inline int32_t days_from_0(int32_t year)
+ {
+ year--;
+ return 365 * year + (year / 400) - (year/100) + (year / 4);
+ }
+ inline int32_t days_from_1970(int32_t year)
+ {
+ static const int days_from_0_to_1970 = days_from_0(1970);
+ return days_from_0(year) - days_from_0_to_1970;
+ }
+ inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
+ {
+ static const int32_t days[2][12] =
+ {
+ { 0,31,59,90,120,151,181,212,243,273,304,334},
+ { 0,31,60,91,121,152,182,213,244,274,305,335}
+ };
+
+ return days[is_leap(year)][month-1] + day - 1;
+ }
+
+ inline time_t internal_timegm(std::tm const *t)
+ {
+ int year = t->tm_year + 1900;
+ int month = t->tm_mon;
+ if(month > 11)
+ {
+ year += month/12;
+ month %= 12;
+ }
+ else if(month < 0)
+ {
+ int years_diff = (-month + 11)/12;
+ year -= years_diff;
+ month+=12 * years_diff;
+ }
+ month++;
+ int day = t->tm_mday;
+ int day_of_year = days_from_1jan(year,month,day);
+ int days_since_epoch = days_from_1970(year) + day_of_year ;
+
+ time_t seconds_in_day = 3600 * 24;
+ time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
+
+ return result;
+ }
+//#endif
+
+ /**
+ * from_ymd could be made more efficient by using a table
+ * day_count_table indexed by the y%400.
+ * This table could contain the day_count
+ * by*365 + by/4 - by/100 + by/400
+ *
+ * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] +
+ * days_in_year_before[is_leap_table[by%400]][m-1] + d;
+ */
+ inline unsigned days_before_years(int32_t y)
+ {
+ return y * 365 + y / 4 - y / 100 + y / 400;
+ }
+
+ // Returns year/month/day triple in civil calendar
+ // Preconditions: z is number of days since 1970-01-01 and is in the range:
+ // [numeric_limits<Int>::min(), numeric_limits<Int>::max()-719468].
+ template <class Int>
+ //constexpr
+ void
+ inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT
+ {
+ BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
+ "This algorithm has not been ported to a 16 bit unsigned integer");
+ BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
+ "This algorithm has not been ported to a 16 bit signed integer");
+ z += 719468;
+ const Int era = (z >= 0 ? z : z - 146096) / 146097;
+ const unsigned doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
+ const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
+ y = static_cast<Int>(yoe) + era * 400;
+ const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
+ const unsigned mp = (5*doy + 2)/153; // [0, 11]
+ d = doy - (153*mp+2)/5 + 1; // [1, 31]
+ m = mp + (mp < 10 ? 3 : -9); // [1, 12]
+ y += (m <= 2);
+ --m;
+ }
+ inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
+ {
+ if (t==0) return 0;
+ if (tm==0) return 0;
+
+#if 0
+ static const unsigned char
+ day_of_year_month[2][366] =
+ {
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 },
+
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
+
+ } };
+
+ static const int32_t days_in_year_before[2][13] =
+ {
+ { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
+ { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
+ };
+#endif
+
+ const time_t seconds_in_day = 3600 * 24;
+ int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
+ int32_t hms = static_cast<int32_t>(*t - seconds_in_day*days_since_epoch);
+ if (hms < 0) {
+ days_since_epoch-=1;
+ hms = seconds_in_day+hms;
+ }
+
+#if 0
+ int32_t x = days_since_epoch;
+ int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) * 400
+ / 146097);
+ const int32_t ym1 = y - 1;
+ int32_t doy = x - days_before_years(y);
+ const int32_t doy1 = x - days_before_years(ym1);
+ const int32_t N = std::numeric_limits<int>::digits - 1;
+ const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal
+ const int32_t mask0 = ~mask1;
+ doy = (doy & mask0) | (doy1 & mask1);
+ y = (y & mask0) | (ym1 & mask1);
+ //y -= 32767 + 2;
+ y += 70;
+ tm->tm_year=y;
+ const int32_t leap = is_leap(y);
+ tm->tm_mon = day_of_year_month[leap][doy]-1;
+ tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
+#else
+ int32_t y;
+ unsigned m, d;
+ civil_from_days(days_since_epoch, y, m, d);
+ tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
+#endif
+
+ tm->tm_hour = hms / 3600;
+ const int ms = hms % 3600;
+ tm->tm_min = ms / 60;
+ tm->tm_sec = ms % 60;
+
+ tm->tm_isdst = -1;
+ (void)mktime(tm);
+ return tm;
+ }
+
+ } // detail
+#ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
+
+#if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
+
+ template <class CharT, class Traits, class Duration>
+ std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<system_clock, Duration>& tp)
+ {
+ typename std::basic_ostream<CharT, Traits>::sentry ok(os);
+ if (bool(ok))
+ {
+ bool failed = false;
+ BOOST_TRY
+ {
+ const CharT* pb = 0; //nullptr;
+ const CharT* pe = pb;
+ std::basic_string<CharT> fmt = get_time_fmt<CharT> (os);
+ pb = fmt.data();
+ pe = pb + fmt.size();
+
+ timezone tz = get_timezone(os);
+ std::locale loc = os.getloc();
+ time_t t = system_clock::to_time_t(time_point_cast<system_clock::duration>(tp));
+ std::tm tm;
+ std::memset(&tm, 0, sizeof(std::tm));
+ if (tz == timezone::local)
+ {
+#if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
+ std::tm *tmp = 0;
+ if ((tmp=localtime(&t)) == 0)
+ failed = true;
+ else
+ tm =*tmp;
+#else
+ if (localtime_r(&t, &tm) == 0) failed = true;
+#endif
+ }
+ else
+ {
+#if BOOST_CHRONO_INTERNAL_GMTIME
+ if (detail::internal_gmtime(&t, &tm) == 0) failed = true;
+
+#elif defined BOOST_WINDOWS && ! defined(__CYGWIN__)
+ std::tm *tmp = 0;
+ if((tmp = gmtime(&t)) == 0)
+ failed = true;
+ else
+ tm = *tmp;
+#else
+ if (gmtime_r(&t, &tm) == 0) failed = true;
+ tm.tm_isdst = -1;
+ (void)mktime(&tm);
+
+#endif
+
+ }
+ if (!failed)
+ {
+ const std::time_put<CharT>& tpf = std::use_facet<std::time_put<CharT> >(loc);
+ if (pb == pe)
+ {
+ CharT pattern[] =
+ { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
+ pb = pattern;
+ pe = pb + sizeof (pattern) / sizeof(CharT);
+ failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
+ if (!failed)
+ {
+ duration<fractional_seconds> d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec);
+ if (d.count() < 10) os << CharT('0');
+ //if (! os.good()) {
+ // throw "exception";
+ //}
+ std::ios::fmtflags flgs = os.flags();
+ os.setf(std::ios::fixed, std::ios::floatfield);
+ //if (! os.good()) {
+ //throw "exception";
+ //}
+ os.precision(9);
+ os << d.count();
+ //if (! os.good()) {
+ //throw "exception";
+ //}
+ os.flags(flgs);
+ if (tz == timezone::local)
+ {
+ CharT sub_pattern[] =
+ { ' ', '%', 'z' };
+ pb = sub_pattern;
+ pe = pb + +sizeof (sub_pattern) / sizeof(CharT);
+ failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
+ }
+ else
+ {
+ CharT sub_pattern[] =
+ { ' ', '+', '0', '0', '0', '0', 0 };
+ os << sub_pattern;
+ }
+ }
+ }
+ else
+ {
+ failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
+ }
+ }
+ }
+ BOOST_CATCH (...)
+ {
+ failed = true;
+ }
+ BOOST_CATCH_END
+ if (failed)
+ {
+ os.setstate(std::ios_base::failbit | std::ios_base::badbit);
+ }
+ }
+ return os;
+ }
+#endif
+
+ namespace detail
+ {
+
+ template <class CharT, class InputIterator>
+ minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype<CharT>& ct)
+ {
+ int min = 0;
+ if (b != e)
+ {
+ char cn = ct.narrow(*b, 0);
+ if (cn != '+' && cn != '-')
+ {
+ err |= std::ios_base::failbit;
+ return minutes(0);
+ }
+ int sn = cn == '-' ? -1 : 1;
+ int hr = 0;
+ for (int i = 0; i < 2; ++i)
+ {
+ if (++b == e)
+ {
+ err |= std::ios_base::eofbit | std::ios_base::failbit;
+ return minutes(0);
+ }
+ cn = ct.narrow(*b, 0);
+ if (! ('0' <= cn && cn <= '9'))
+ {
+ err |= std::ios_base::failbit;
+ return minutes(0);
+ }
+ hr = hr * 10 + cn - '0';
+ }
+ for (int i = 0; i < 2; ++i)
+ {
+ if (++b == e)
+ {
+ err |= std::ios_base::eofbit | std::ios_base::failbit;
+ return minutes(0);
+ }
+ cn = ct.narrow(*b, 0);
+ if (! ('0' <= cn && cn <= '9'))
+ {
+ err |= std::ios_base::failbit;
+ return minutes(0);
+ }
+ min = min * 10 + cn - '0';
+ }
+ if (++b == e) {
+ err |= std::ios_base::eofbit;
+ }
+ min += hr * 60;
+ min *= sn;
+ }
+ else
+ {
+ err |= std::ios_base::eofbit | std::ios_base::failbit;
+ }
+ return minutes(min);
+ }
+
+ } // detail
+
+#if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
+
+ template <class CharT, class Traits, class Duration>
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, time_point<system_clock, Duration>& tp)
+ {
+ typename std::basic_istream<CharT, Traits>::sentry ok(is);
+ if (bool(ok))
+ {
+ std::ios_base::iostate err = std::ios_base::goodbit;
+ BOOST_TRY
+ {
+ const CharT* pb = 0; //nullptr;
+ const CharT* pe = pb;
+ std::basic_string<CharT> fmt = get_time_fmt<CharT> (is);
+ pb = fmt.data();
+ pe = pb + fmt.size();
+
+ timezone tz = get_timezone(is);
+ std::locale loc = is.getloc();
+ const std::time_get<CharT>& tg = std::use_facet<std::time_get<CharT> >(loc);
+ const std::ctype<CharT>& ct = std::use_facet<std::ctype<CharT> >(loc);
+ tm tm; // {0}
+ std::memset(&tm, 0, sizeof(std::tm));
+
+ typedef std::istreambuf_iterator<CharT, Traits> It;
+ if (pb == pe)
+ {
+ CharT pattern[] =
+ { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
+ pb = pattern;
+ pe = pb + sizeof (pattern) / sizeof(CharT);
+
+#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
+ const detail::time_get<CharT>& dtg(tg);
+ dtg.get(is, 0, is, err, &tm, pb, pe);
+#else
+ tg.get(is, 0, is, err, &tm, pb, pe);
+#endif
+ if (err & std::ios_base::failbit) goto exit;
+ fractional_seconds sec;
+ CharT c = CharT();
+ std::ios::fmtflags flgs = is.flags();
+ is.setf(std::ios::fixed, std::ios::floatfield);
+ is.precision(9);
+ is >> sec;
+ is.flags(flgs);
+ if (is.fail())
+ {
+ err |= std::ios_base::failbit;
+ goto exit;
+ }
+ It i(is);
+ It eof;
+ c = *i;
+ if (++i == eof || c != ' ')
+ {
+ err |= std::ios_base::failbit;
+ goto exit;
+ }
+ minutes min = detail::extract_z(i, eof, err, ct);
+
+ if (err & std::ios_base::failbit) goto exit;
+ time_t t;
+
+#if BOOST_CHRONO_INTERNAL_TIMEGM
+ t = detail::internal_timegm(&tm);
+#else
+ t = timegm(&tm);
+#endif
+ tp = time_point_cast<Duration>(
+ system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
+ );
+ }
+ else
+ {
+ const CharT z[2] =
+ { '%', 'z' };
+ const CharT* fz = std::search(pb, pe, z, z + 2);
+#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
+ const detail::time_get<CharT>& dtg(tg);
+ dtg.get(is, 0, is, err, &tm, pb, fz);
+#else
+ tg.get(is, 0, is, err, &tm, pb, fz);
+#endif
+ minutes minu(0);
+ if (fz != pe)
+ {
+ if (err != std::ios_base::goodbit)
+ {
+ err |= std::ios_base::failbit;
+ goto exit;
+ }
+ It i(is);
+ It eof;
+ minu = detail::extract_z(i, eof, err, ct);
+ if (err & std::ios_base::failbit) goto exit;
+ if (fz + 2 != pe)
+ {
+ if (err != std::ios_base::goodbit)
+ {
+ err |= std::ios_base::failbit;
+ goto exit;
+ }
+#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
+ const detail::time_get<CharT>& dtg(tg);
+ dtg.get(is, 0, is, err, &tm, fz + 2, pe);
+#else
+ tg.get(is, 0, is, err, &tm, fz + 2, pe);
+#endif
+ if (err & std::ios_base::failbit) goto exit;
+ }
+ }
+ tm.tm_isdst = -1;
+ time_t t;
+ if (tz == timezone::utc || fz != pe)
+ {
+#if BOOST_CHRONO_INTERNAL_TIMEGM
+ t = detail::internal_timegm(&tm);
+#else
+ t = timegm(&tm);
+#endif
+ }
+ else
+ {
+ t = mktime(&tm);
+ }
+ tp = time_point_cast<Duration>(
+ system_clock::from_time_t(t) - minu
+ );
+ }
+ }
+ BOOST_CATCH (...)
+ {
+ err |= std::ios_base::badbit | std::ios_base::failbit;
+ }
+ BOOST_CATCH_END
+ exit: is.setstate(err);
+ }
+ return is;
+ }
+
+#endif
+#endif //UTC
+ } // chrono
+
+}
+
+#endif // header
diff --git a/boost/chrono/io/time_point_put.hpp b/boost/chrono/io/time_point_put.hpp
new file mode 100644
index 0000000000..9c8c7cadd0
--- /dev/null
+++ b/boost/chrono/io/time_point_put.hpp
@@ -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
diff --git a/boost/chrono/io/time_point_units.hpp b/boost/chrono/io/time_point_units.hpp
new file mode 100644
index 0000000000..378c112603
--- /dev/null
+++ b/boost/chrono/io/time_point_units.hpp
@@ -0,0 +1,249 @@
+// (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 <iostream>
+#include <ios>
+#include <locale>
+#include <algorithm>
+
+namespace boost
+{
+ namespace chrono
+ {
+
+ /**
+ * @c time_point_units facet gives useful information about the time_point pattern,
+ * the text associated to a time_point's epoch,
+ */
+ template <typename CharT=char>
+ class time_point_units: public std::locale::facet
+ {
+ public:
+ /**
+ * Type of character the facet is instantiated on.
+ */
+ typedef CharT char_type;
+ /**
+ * Type of character string used by member functions.
+ */
+ typedef std::basic_string<char_type> string_type;
+
+ /**
+ * Unique identifier for this type of facet.
+ */
+ static std::locale::id id;
+
+ /**
+ * Construct a @c time_point_units facet.
+ * @param refs
+ * @Effects Construct a @c time_point_units facet.
+ * If the @c refs argument is @c 0 then destruction of the object is
+ * delegated to the @c locale, or locales, containing it. This allows
+ * the user to ignore lifetime management issues. On the other had,
+ * if @c refs is @c 1 then the object must be explicitly deleted;
+ * the @c locale will not do so. In this case, the object can be
+ * maintained across the lifetime of multiple locales.
+ */
+ explicit time_point_units(size_t refs = 0) :
+ std::locale::facet(refs)
+ {
+ }
+
+ /**
+ * @return the pattern to be used by default.
+ */
+ virtual string_type get_pattern() const =0;
+
+ /**
+ * @return the epoch associated to the clock @c Clock calling @c do_get_epoch(Clock())
+ */
+ template <typename Clock>
+ string_type get_epoch() const
+ {
+ return do_get_epoch(Clock());
+ }
+
+ protected:
+ /**
+ * Destroy the facet.
+ */
+ virtual ~time_point_units() {}
+
+
+ /**
+ *
+ * @param c a dummy instance of @c system_clock.
+ * @return The epoch string associated to the @c system_clock.
+ */
+ virtual string_type do_get_epoch(system_clock) const=0;
+
+ /**
+ *
+ * @param c a dummy instance of @c steady_clock.
+ * @return The epoch string associated to the @c steady_clock.
+ */
+ virtual string_type do_get_epoch(steady_clock) const=0;
+
+#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
+ /**
+ *
+ * @param c a dummy instance of @c process_real_cpu_clock.
+ * @return The epoch string associated to the @c process_real_cpu_clock.
+ */
+ virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
+#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
diff --git a/boost/chrono/io/timezone.hpp b/boost/chrono/io/timezone.hpp
new file mode 100644
index 0000000000..67975da96f
--- /dev/null
+++ b/boost/chrono/io/timezone.hpp
@@ -0,0 +1,30 @@
+// (C) Copyright Howard Hinnant
+// (C) Copyright 2010-2011 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+//
+// This code was adapted by Vicente from Howard Hinnant's experimental work
+// on chrono i/o to Boost
+
+#ifndef BOOST_CHRONO_IO_TIMEZONE_HPP
+#define BOOST_CHRONO_IO_TIMEZONE_HPP
+#include <boost/detail/scoped_enum_emulation.hpp>
+
+namespace boost
+{
+ namespace chrono
+ {
+ /**
+ * Scoped enumeration emulation stating whether the time_point for system_clock I/O is UTC or local.
+ */
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(timezone)
+ {
+ utc, local
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(timezone)
+
+ } // chrono
+} // boost
+
+#endif // header
diff --git a/boost/chrono/io/utility/ios_base_state_ptr.hpp b/boost/chrono/io/utility/ios_base_state_ptr.hpp
new file mode 100644
index 0000000000..f7dfdddca0
--- /dev/null
+++ b/boost/chrono/io/utility/ios_base_state_ptr.hpp
@@ -0,0 +1,436 @@
+// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
+
+// Copyright 2011 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
+#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
+
+#include <ios>
+#include <boost/assert.hpp>
+
+/**
+ *
+
+
+ */
+namespace boost
+{
+ namespace chrono
+ {
+ namespace detail
+ {
+
+ /**
+ * xalloc key holder.
+ */
+ template <typename T>
+ struct xalloc_key_holder
+ {
+ static int value; //< the xalloc value associated to T.
+ static bool initialized; //< whether the value has been initialized or not.
+ };
+
+ template <typename T>
+ int xalloc_key_holder<T>::value = 0;
+
+ template <typename T>
+ bool xalloc_key_holder<T>::initialized = false;
+
+ }
+
+ /**
+ * xalloc key initialiazer.
+ *
+ * Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
+ */
+ template <typename T>
+ struct xalloc_key_initializer
+ {
+ xalloc_key_initializer()
+ {
+ if (!detail::xalloc_key_holder<T>::initialized)
+ {
+ detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
+ detail::xalloc_key_holder<T>::initialized = true;
+ }
+ }
+ };
+ /**
+ * @c ios_state_ptr is a smart pointer to a ios_base specific state.
+ */
+ template <typename Final, typename T>
+ class ios_state_ptr
+ {
+ ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
+
+ public:
+ /**
+ * The pointee type
+ */
+ typedef T element_type;
+ /**
+ * Explicit constructor.
+ * @param ios the ios
+ * @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
+ */
+ explicit ios_state_ptr(std::ios_base& ios) :
+ ios_(ios)
+ {
+
+ }
+ /**
+ * Nothing to do as xalloc index can not be removed.
+ */
+ ~ios_state_ptr()
+ {
+ }
+
+ /**
+ * @Effects Allocates the index if not already done.
+ * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
+ * Retrieves the associated ios pointer
+ * @return the retrieved pointer statically casted to const.
+ */
+ T const* get() const BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void* &pw = ios_.pword(index());
+ if (pw == 0)
+ {
+ return 0;
+ }
+ return static_cast<const T*> (pw);
+ }
+ /**
+ * @Effects Allocates the index if not already done.
+ * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
+ * Retrieves the associated ios pointer
+ * @return the retrieved pointer.
+ */
+ T * get() BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void* &pw = ios_.pword(index());
+ if (pw == 0)
+ {
+ return 0;
+ }
+ return static_cast<T*> (pw);
+ }
+ /**
+ * @Effects as if @c return get();
+ * @return the retrieved pointer.
+ */
+ T * operator->()BOOST_NOEXCEPT
+ {
+ return get();
+ }
+ /**
+ * @Effects as if @c return get();
+ * @return the retrieved pointer.
+ */
+ T const * operator->() const BOOST_NOEXCEPT
+ {
+ return get();
+ }
+
+ /**
+ * @Effects as if @c return *get();
+ * @return a reference to the retrieved state.
+ * @Remark The behavior is undefined if @c get()==0.
+ */
+ T & operator*() BOOST_NOEXCEPT
+ {
+ return *get();
+ }
+ /**
+ * @Effects as if @c return *get();
+ * @return a reference to the retrieved state.
+ * @Remark The behavior is undefined if @c get()==0.
+ */
+ T const & operator *() const BOOST_NOEXCEPT
+ {
+ return *get();
+ }
+
+ /**
+ * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
+ * @return the stored state pointer.
+ */
+ T * release() BOOST_NOEXCEPT
+ {
+ T const* f = get();
+ reset();
+ return f;
+ }
+
+ /**
+ *
+ * @param new_ptr the new pointer.
+ * @Effects deletes the current state and replace it with the new one.
+ */
+ void reset(T* new_ptr = 0)BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void*& pw = ios_.pword(index());
+ delete static_cast<T*> (pw);
+ pw = new_ptr;
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef T* (ios_state_ptr::*bool_type)();
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return (get()!=0)?&ios_state_ptr::release:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return (get()==0)?&ios_state_ptr::release:0;
+ }
+#else
+ /**
+ * Explicit conversion to bool.
+ */
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return get()!=0;
+ }
+#endif
+
+ std::ios_base& getios()BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ std::ios_base& getios() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * Implicit conversion to the ios_base
+ */
+ operator std::ios_base&() BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * Implicit conversion to the ios_base const
+ */
+ operator std::ios_base&() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ private:
+ static inline bool is_registerd(std::ios_base& ios)
+ {
+ long iw = ios.iword(index());
+ return (iw == 1);
+ }
+ static inline void set_registered(std::ios_base& ios)
+ {
+ long& iw = ios.iword(index());
+ iw = 1;
+ }
+ static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
+ {
+ switch (evt)
+ {
+ case std::ios_base::erase_event:
+ {
+ void*& pw = ios.pword(index);
+ if (pw != 0)
+ {
+ T* ptr = static_cast<T*> (pw);
+ delete ptr;
+ pw = 0;
+ }
+ break;
+ }
+ case std::ios_base::copyfmt_event:
+ {
+ void*& pw = ios.pword(index);
+ if (pw != 0)
+ {
+ pw = new T(*static_cast<T*> (pw));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ static inline int index()
+ {
+ return detail::xalloc_key_holder<Final>::value;
+ }
+
+ static inline void register_once(int indx, std::ios_base& ios)
+ {
+ // needs a mask registered
+ if (!is_registerd(ios))
+ {
+ set_registered(ios);
+ ios.register_callback(callback, indx);
+ }
+ }
+
+
+ protected:
+ std::ios_base& ios_;
+ //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
+
+ };
+ //template <typename Final, typename T>
+ //detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
+
+
+ /**
+ * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
+ * @tparm T
+ * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
+ */
+ template <typename Final, typename T>
+ class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
+ {
+ typedef ios_state_ptr<Final, T> base_type;
+ public:
+ explicit ios_state_not_null_ptr(std::ios_base& ios) :
+ base_type(ios)
+ {
+ if (this->get() == 0)
+ {
+ this->base_type::reset(new T());
+ }
+ }
+ ~ios_state_not_null_ptr()
+ {
+ }
+
+ void reset(T* new_value) BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(new_value!=0);
+ this->base_type::reset(new_value);
+ }
+
+ };
+
+ /**
+ * This class is useful to associate some flags to an std::ios_base.
+ */
+ template <typename Final>
+ class ios_flags
+ {
+ public:
+ /**
+ *
+ * @param ios the associated std::ios_base.
+ * @Postcondition <c>flags()==0</c>
+ */
+ explicit ios_flags(std::ios_base& ios) :
+ ios_(ios)
+ {
+ }
+ ~ios_flags()
+ {
+ }
+ /**
+ * @Returns The format control information.
+ */
+ long flags() const BOOST_NOEXCEPT
+ {
+ return value();
+ }
+
+ /**
+ * @param v the new bit mask.
+ * @Postcondition <c>v == flags()</c>.
+ * @Returns The previous value of @c flags().
+ */
+ long flags(long v)BOOST_NOEXCEPT
+ {
+ long tmp = flags();
+ ref() = v;
+ return tmp;
+ }
+
+ /**
+ * @param v the new value
+ * @Effects: Sets @c v in @c flags().
+ * @Returns: The previous value of @c flags().
+ */
+ long setf(long v)
+ {
+ long tmp = value();
+ ref() |= v;
+ return tmp;
+ }
+
+ /**
+ * @param mask the bit mask to clear.
+ * @Effects: Clears @c mask in @c flags().
+ */
+ void unsetf(long mask)
+ {
+ ref() &= ~mask;
+ }
+
+ /**
+ *
+ * @param v
+ * @param mask
+ * @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
+ * @Returns: The previous value of flags().
+ */
+ long setf(long v, long mask)
+ {
+ long tmp = value();
+ unsetf(mask);
+ ref() |= v & mask;
+ return tmp;
+ }
+
+ /**
+ * implicit conversion to the @c ios_base
+ */
+ operator std::ios_base&()BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * implicit conversion to the @c ios_base const
+ */
+ operator std::ios_base const&() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ private:
+ long value() const BOOST_NOEXCEPT
+ {
+ return ios_.iword(index());
+ }
+ long& ref()BOOST_NOEXCEPT
+ {
+ return ios_.iword(index());
+ }
+ static inline int index()
+ {
+ return detail::xalloc_key_holder<Final>::value;
+ }
+ ios_flags& operator=(ios_flags const& rhs) ;
+
+ std::ios_base& ios_;
+ //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
+
+ };
+ //template <typename Final>
+ //detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
+
+ } // namespace chrono
+} // namespace boost
+
+#endif // header
diff --git a/boost/chrono/io/utility/manip_base.hpp b/boost/chrono/io/utility/manip_base.hpp
new file mode 100644
index 0000000000..f4a5f562c4
--- /dev/null
+++ b/boost/chrono/io/utility/manip_base.hpp
@@ -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
diff --git a/boost/chrono/io/utility/to_string.hpp b/boost/chrono/io/utility/to_string.hpp
new file mode 100644
index 0000000000..4717ba6ad3
--- /dev/null
+++ b/boost/chrono/io/utility/to_string.hpp
@@ -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
diff --git a/boost/chrono/io_v1/chrono_io.hpp b/boost/chrono/io_v1/chrono_io.hpp
index 6ca1ca2d69..1a7e832b5b 100644
--- a/boost/chrono/io_v1/chrono_io.hpp
+++ b/boost/chrono/io_v1/chrono_io.hpp
@@ -265,59 +265,59 @@ 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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
typedef duration_punct<CharT> Facet;
std::locale loc = is.getloc();
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
if (!std::has_facet<Facet>(loc)) {
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.imbue(std::locale(loc, new Facet));
}
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is >> r;
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
if (is.good())
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
if (i != e && *i == ' ') // mandatory ' ' after value
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
++i;
if (i != e)
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(is.failbit);
return is;
}
i = in_iterator(is);
if (*i != ']')
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(is.failbit);
return is;
}
@@ -328,27 +328,27 @@ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
f.template plural<ratio<1> >(),
f.template short_name<ratio<1> >()
};
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(err);
switch ((k - units) / 3)
{
case 0:
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
break;
default:
is.setstate(err);
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
return is;
}
}
else
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
// parse SI name, short or long
const std::basic_string<CharT> units[] =
{
@@ -410,12 +410,12 @@ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
f.template plural<ratio<3600> >(),
f.template short_name<ratio<3600> >()
};
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
switch ((k - units) / 3)
{
case 0:
@@ -495,12 +495,12 @@ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
den = 1;
break;
default:
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(err|is.failbit);
return is;
}
}
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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
@@ -513,7 +513,7 @@ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
// (num/den) / Period overflows
is.setstate(err|is.failbit);
return is;
@@ -523,68 +523,68 @@ operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //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;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(err|is.failbit);
return is;
}
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
common_type_t t = r * num;
t /= den;
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
- if (t > 0)
+ if (t > duration_values<common_type_t>::zero())
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
Rep pt = t;
if ( (duration_values<Rep>::max)() < pt)
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
// Conversion to Period overflowed
is.setstate(err|is.failbit);
return is;
}
}
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
// Success! Store it.
r = Rep(t);
d = duration<Rep, Period>(r);
is.setstate(err);
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
return is;
}
else {
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
is.setstate(is.failbit | is.eofbit);
return is;
}
}
else
{
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //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;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
return is;
}
}
else {
- std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
+ //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
//is.setstate(is.failbit);
return is;
}
diff --git a/boost/chrono/process_cpu_clocks.hpp b/boost/chrono/process_cpu_clocks.hpp
index 486950da40..248837506e 100644
--- a/boost/chrono/process_cpu_clocks.hpp
+++ b/boost/chrono/process_cpu_clocks.hpp
@@ -1,6 +1,7 @@
// 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
@@ -43,6 +44,7 @@ namespace boost { namespace chrono {
#endif
};
+#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
class BOOST_CHRONO_DECL process_user_cpu_clock {
public:
typedef nanoseconds duration;
@@ -70,6 +72,7 @@ namespace boost { namespace chrono {
static BOOST_CHRONO_INLINE time_point now(system::error_code & ec );
#endif
};
+#endif
template <typename Rep>
struct process_times
@@ -83,12 +86,15 @@ namespace boost { namespace chrono {
: 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)
@@ -107,10 +113,12 @@ namespace boost { namespace chrono {
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 &&
@@ -180,7 +188,7 @@ namespace boost { namespace chrono {
}
template <class CharT, class Traits>
- void read(std::basic_istream<CharT, Traits>& is) const
+ void read(std::basic_istream<CharT, Traits>& is)
{
typedef std::istreambuf_iterator<CharT, Traits> in_iterator;
in_iterator i(is);
@@ -292,6 +300,7 @@ namespace chrono
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:
@@ -308,6 +317,7 @@ namespace chrono
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>&
@@ -321,7 +331,7 @@ namespace chrono
template <class CharT, class Traits, typename Rep>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
- process_times<Rep> const& rhs)
+ process_times<Rep>& rhs)
{
rhs.read(is);
return is;
@@ -372,6 +382,7 @@ namespace chrono
}
};
+#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
template<class CharT>
struct clock_string<process_user_cpu_clock, CharT>
{
@@ -436,6 +447,7 @@ namespace chrono
return str;
}
};
+#endif
} // namespace chrono
} // namespace boost
diff --git a/boost/chrono/round.hpp b/boost/chrono/round.hpp
index 3d0619e681..09741fcf09 100644
--- a/boost/chrono/round.hpp
+++ b/boost/chrono/round.hpp
@@ -26,18 +26,22 @@ namespace boost
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;
- ++t1;
-#if 0
- // Avoid the user of BOOST_AUTO to make the library portable to Sun, PGI, ..
- BOOST_AUTO(diff0, d - t0);
- BOOST_AUTO(diff1, t1 - d);
-#else
- typedef typename common_type<To, duration<Rep, Period> >::type result_type;
- result_type diff0 = d - t0;
- result_type diff1 = t1 - d;
-#endif
+ if (t0>d) {
+ --t1;
+ diff0 = t0 - d;
+ diff1 = d - t1;
+ } else {
+ ++t1;
+ diff0 = d - t0;
+ diff1 = t1 - d;
+ }
+
if (diff0 == diff1)
{
if (t0.count() & 1)
diff --git a/boost/chrono/system_clocks.hpp b/boost/chrono/system_clocks.hpp
index df8b79e207..5ba6a3b0e9 100644
--- a/boost/chrono/system_clocks.hpp
+++ b/boost/chrono/system_clocks.hpp
@@ -67,7 +67,7 @@ TODO:
#include <ctime>
# if defined( BOOST_CHRONO_POSIX_API )
-# if ! defined(CLOCK_REALTIME)
+# if ! defined(CLOCK_REALTIME) && ! defined (__hpux__)
# error <time.h> does not supply CLOCK_REALTIME
# endif
# endif
diff --git a/boost/chrono/time_point.hpp b/boost/chrono/time_point.hpp
index 9aad25e66c..6449fac6e1 100644
--- a/boost/chrono/time_point.hpp
+++ b/boost/chrono/time_point.hpp
@@ -168,16 +168,17 @@ namespace chrono {
duration d_;
public:
- BOOST_CONSTEXPR
+ BOOST_FORCEINLINE BOOST_CONSTEXPR
time_point() : d_(duration::zero())
{}
- BOOST_CONSTEXPR explicit time_point(const duration& d)
+ BOOST_FORCEINLINE BOOST_CONSTEXPR
+ explicit time_point(const duration& d)
: d_(d)
{}
// conversions
template <class Duration2>
- BOOST_CONSTEXPR
+ BOOST_FORCEINLINE BOOST_CONSTEXPR
time_point(const time_point<clock, Duration2>& t
, typename boost::enable_if
<
@@ -217,12 +218,12 @@ namespace chrono {
// special values
- static BOOST_CONSTEXPR time_point
+ static BOOST_CHRONO_LIB_CONSTEXPR time_point
min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return time_point((duration::min)());
}
- static BOOST_CONSTEXPR time_point
+ static BOOST_CHRONO_LIB_CONSTEXPR time_point
max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return time_point((duration::max)());
diff --git a/boost/chrono/typeof/boost/chrono/chrono.hpp b/boost/chrono/typeof/boost/chrono/chrono.hpp
index 88dad54ed0..0b0d274800 100644
--- a/boost/chrono/typeof/boost/chrono/chrono.hpp
+++ b/boost/chrono/typeof/boost/chrono/chrono.hpp
@@ -15,7 +15,6 @@
#define BOOST_CHRONO_TYPEOF_CHRONO_HPP
#include <boost/chrono/chrono.hpp>
-#define BOOST_TYPEOF_SILENT
#include <boost/typeof/typeof.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
diff --git a/boost/chrono/typeof/boost/ratio.hpp b/boost/chrono/typeof/boost/ratio.hpp
index 4438a4f9dc..d61ce2440c 100644
--- a/boost/chrono/typeof/boost/ratio.hpp
+++ b/boost/chrono/typeof/boost/ratio.hpp
@@ -15,8 +15,6 @@
#define BOOST_CHRONO_TYPEOF_RATIO_HPP
#include <boost/ratio/ratio.hpp>
-#define BOOST_TYPEOF_SILENT
-
#include <boost/typeof/typeof.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()