diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj b/src/beast/Builds/VisualStudio2012/beast.vcxproj
index e8a152c30..07698e5e0 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -88,7 +88,11 @@
+
+
+
+
@@ -402,12 +406,24 @@
+
+ true
+ true
+ true
+ true
+
true
true
true
true
+
+ true
+ true
+ true
+ true
+
true
true
diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index 0b081079a..723f102f8 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -1227,6 +1227,18 @@
beast\crypto
+
+ beast\chrono
+
+
+ beast\chrono
+
+
+ beast\chrono
+
+
+ beast\chrono
+
@@ -1778,6 +1790,12 @@
beast\insight\impl
+
+ beast\chrono\impl
+
+
+ beast\chrono\impl
+
beast\crypto\impl
diff --git a/src/beast/beast/Chrono.h b/src/beast/beast/Chrono.h
index 027b1f5f3..c0ea88da4 100644
--- a/src/beast/beast/Chrono.h
+++ b/src/beast/beast/Chrono.h
@@ -20,6 +20,11 @@
#ifndef BEAST_CHRONO_H_INCLUDED
#define BEAST_CHRONO_H_INCLUDED
+#include "chrono/abstract_clock.h"
+#include "chrono/chrono_io.h"
+#include "chrono/manual_clock.h"
+#include "chrono/ratio_io.h"
+
#include "chrono/CPUMeter.h"
#include "chrono/RelativeTime.h"
#include "chrono/ScopedTimeInterval.h"
diff --git a/src/beast/beast/chrono/Chrono.cpp b/src/beast/beast/chrono/Chrono.cpp
index 5ce5772e6..dc50936e0 100644
--- a/src/beast/beast/chrono/Chrono.cpp
+++ b/src/beast/beast/chrono/Chrono.cpp
@@ -19,5 +19,11 @@
#include "BeastConfig.h"
+#include "../Config.h"
+#include "../../modules/beast_core/beast_core.h" // for UnitTest
+
+#include "impl/abstract_clock.cpp"
+#include "impl/chrono_io.cpp"
+
#include "impl/CPUMeter.cpp"
#include "impl/RelativeTime.cpp"
diff --git a/src/beast/beast/chrono/abstract_clock.h b/src/beast/beast/chrono/abstract_clock.h
new file mode 100644
index 000000000..c47c1bd1f
--- /dev/null
+++ b/src/beast/beast/chrono/abstract_clock.h
@@ -0,0 +1,166 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
+#define BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
+
+#include
+
+#include "chrono_io.h"
+
+namespace beast {
+
+/** Abstract interface to a clock.
+
+ The abstract clock interface allows a dependency injection to take
+ place so that the choice of implementation can be made at run-time
+ instead of compile time. The trade-off is that the Duration used to
+ represent the clock must be chosen at compile time and cannot be
+ changed. This includes both the choice of representation (integers
+ for example) and the period in ticks corresponding to one second.
+
+ Example:
+
+ @code
+
+ struct Implementation
+ {
+ abstract_clock & m_clock;
+
+ // Dependency injection
+ //
+ explicit Implementation (
+ abstract_clock & clock)
+ : m_clock (clock)
+ {
+ }
+ };
+
+ @endcode
+
+ @tparam The length of time, in seconds, corresponding to one tick.
+*/
+template
+class abstract_clock
+{
+public:
+ typedef typename Duration::rep rep;
+ typedef typename Duration::period period;
+ typedef Duration duration;
+ typedef std::chrono::time_point <
+ abstract_clock, duration> time_point;
+
+ virtual ~abstract_clock () { }
+
+ /** Returns `true` if this is a steady clock. */
+ virtual bool is_steady () const = 0;
+
+ /** Returns the current time. */
+ virtual time_point now () = 0;
+
+ /** Convert the specified time point to a string. */
+ /** @{ */
+ virtual std::string to_string (time_point const& tp) = 0;
+
+ template
+ std::string to_string (
+ std::chrono::time_point const& tp)
+ {
+ return to_string (
+ std::chrono::time_point_cast (tp));
+ }
+ /** @} */
+
+ /** Returning elapsed ticks since the epoch. */
+ rep elapsed ()
+ {
+ return now().time_since_epoch().count();
+ }
+};
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+template
+struct basic_abstract_clock_wrapper : public abstract_clock
+{
+ using typename abstract_clock ::duration;
+ using typename abstract_clock ::time_point;
+
+ bool is_steady () const
+ {
+ return TrivialClock::is_steady;
+ }
+
+ time_point now ()
+ {
+ return time_point (duration (
+ std::chrono::duration_cast (
+ TrivialClock::now().time_since_epoch ()).count ()));
+ }
+};
+
+template
+struct abstract_clock_wrapper
+ : public basic_abstract_clock_wrapper
+{
+ // generic conversion displays the duration
+ std::string to_string (typename basic_abstract_clock_wrapper <
+ TrivialClock, Duration>::time_point const& tp)
+ {
+ std::stringstream ss;
+ ss << tp.time_since_epoch();
+ return ss.str ();
+ }
+};
+
+/*
+template
+struct abstract_clock_wrapper
+ : public basic_abstract_clock_wrapper
+{
+ typedef std::chrono::system_clock clock_type;
+ std::string to_string (time_point const& tp)
+ {
+ std::stringstream ss;
+ ss << clock_type::time_point (tp.time_since_epoch ());
+ return ss.str ();
+ }
+};
+*/
+
+}
+
+//------------------------------------------------------------------------------
+
+/** Retrieve a discrete clock for a type implementing the Clock concept.
+ The interface is created as an object with static storage duration.
+*/
+template
+abstract_clock & get_abstract_clock ()
+{
+ static detail::abstract_clock_wrapper <
+ TrivialClock, Duration> clock;
+ return clock;
+}
+
+}
+
+#endif
diff --git a/src/beast/beast/chrono/chrono_io.h b/src/beast/beast/chrono/chrono_io.h
new file mode 100644
index 000000000..fdcf47555
--- /dev/null
+++ b/src/beast/beast/chrono/chrono_io.h
@@ -0,0 +1,1087 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+// chrono_io
+//
+// (C) Copyright Howard Hinnant
+// 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 BEAST_CHRONO_CHRONO_IO_H_INCLUDED
+#define BEAST_CHRONO_CHRONO_IO_H_INCLUDED
+
+#include "../Config.h"
+
+#include
+#include
+
+#define BEAST_CHRONO_NO_TIMEPOINT_IO 1
+
+/*
+
+ chrono_io synopsis
+
+#include
+#include
+
+namespace std
+{
+namespace chrono
+{
+
+enum duration_style {prefix, symbol};
+enum timezone {utc, local};
+
+// facets
+
+class durationpunct
+ : public locale::facet
+{
+public:
+ static locale::id id;
+
+ explicit durationpunct(size_t refs = 0);
+ explicit durationpunct(duration_style fmt, size_t refs = 0);
+
+ bool is_symbol_name() const noexcept;
+ bool is_prefix_name() const noexcept;
+};
+
+template
+class timepunct
+ : public locale::facet
+{
+public:
+ typedef basic_string string_type;
+
+ static locale::id id;
+
+ explicit timepunct(size_t refs = 0);
+ timepunct(timezone tz, string_type fmt, size_t refs = 0);
+
+ const string_type& fmt() const noexcept;
+ std::chrono::timezone timezone() const noexcept;
+};
+
+// manipulators
+
+class duration_fmt
+{
+public:
+ explicit duration_fmt(duration_style f) noexcept;
+ explicit operator duration_style() const noexcept;
+};
+
+unspecified time_fmt(timezone tz);
+template
+ unspecified time_fmt(timezone tz, basic_string fmt);
+template
+ unspecified time_fmt(timezone tz, const charT* fmt);
+
+template
+std::basic_ostream&
+operator<<(std::basic_ostream& os, duration_fmt d);
+
+template
+std::basic_istream&
+operator>>(std::basic_istream& is, duration_fmt d);
+
+// duration I/O
+
+template
+ basic_ostream&
+ operator<<(basic_ostream& os, const duration& d);
+
+template
+ basic_istream&
+ operator>>(basic_istream& is, duration& d);
+
+// system_clock I/O
+
+template
+ basic_ostream&
+ operator<<(basic_ostream& os,
+ const time_point& tp);
+
+template
+ basic_istream&
+ operator>>(basic_istream& is,
+ time_point& tp);
+
+// steady_clock I/O
+
+template
+ basic_ostream&
+ operator<<(basic_ostream& os,
+ const time_point& tp);
+
+template
+ basic_istream&
+ operator>>(basic_istream& is,
+ time_point& tp);
+
+// high_resolution_clock I/O
+
+template
+ basic_ostream&
+ operator<<(basic_ostream& os,
+ const time_point& tp);
+
+template
+ basic_istream&
+ operator>>(basic_istream& is,
+ time_point& tp);
+
+} // chrono
+} // std
+
+*/
+
+#include
+#include "ratio_io.h"
+
+//_LIBCPP_BEGIN_NAMESPACE_STD
+namespace std {
+
+namespace chrono
+{
+
+template
+To
+round(const duration& d)
+{
+ To t0 = duration_cast(d);
+ To t1 = t0;
+ ++t1;
+ typedef typename common_type >::type _D;
+ _D diff0 = d - t0;
+ _D diff1 = t1 - d;
+ if (diff0 == diff1)
+ {
+ if (t0.count() & 1)
+ return t1;
+ return t0;
+ }
+ else if (diff0 < diff1)
+ return t0;
+ return t1;
+}
+
+enum duration_style {prefix, symbol};
+enum timezone {utc, local};
+
+class durationpunct
+ : public locale::facet
+{
+private:
+ duration_style __style_;
+public:
+ static locale::id id;
+
+ explicit durationpunct(size_t refs = 0)
+ : locale::facet(refs), __style_(prefix) {}
+
+ explicit durationpunct(duration_style fmt, size_t refs = 0)
+ : locale::facet(refs), __style_(fmt) {}
+
+ bool is_symbol_name() const noexcept {return __style_ == symbol;}
+ bool is_prefix_name() const noexcept {return __style_ == prefix;}
+};
+
+class duration_fmt
+{
+ duration_style form_;
+public:
+ explicit duration_fmt(duration_style f) noexcept : form_(f) {}
+ // VFALCO NOTE disabled this for MSVC
+ /*explicit*/
+ operator duration_style() const noexcept {return form_;}
+};
+
+template
+basic_ostream&
+operator <<(basic_ostream& os, duration_fmt d)
+{
+ os.imbue(locale(os.getloc(), new durationpunct(static_cast(d))));
+ return os;
+}
+
+template
+basic_istream&
+operator >>(basic_istream& is, duration_fmt d)
+{
+ is.imbue(locale(is.getloc(), new durationpunct(static_cast(d))));
+ return is;
+}
+
+template
+basic_string<_CharT>
+__get_unit(bool __is_long, const duration<_Rep, _Period>& d)
+{
+ if (__is_long)
+ {
+ _CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's', 0};
+ basic_string<_CharT> s = ratio_string<_Period, _CharT>::prefix() + __p;
+ if (d.count() == 1 || d.count() == -1)
+ s.pop_back();
+ return s;
+ }
+ return ratio_string<_Period, _CharT>::symbol() + 's';
+}
+
+template
+basic_string<_CharT>
+__get_unit(bool __is_long, const duration<_Rep, ratio<1> >& d)
+{
+ if (__is_long)
+ {
+ _CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'};
+ basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
+ if (d.count() == 1 || d.count() == -1)
+ s.pop_back();
+ return s;
+ }
+ return basic_string<_CharT>(1, 's');
+}
+
+template
+basic_string<_CharT>
+__get_unit(bool __is_long, const duration<_Rep, ratio<60> >& d)
+{
+ if (__is_long)
+ {
+ _CharT __p[] = {'m', 'i', 'n', 'u', 't', 'e', 's'};
+ basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
+ if (d.count() == 1 || d.count() == -1)
+ s.pop_back();
+ return s;
+ }
+ _CharT __p[] = {'m', 'i', 'n'};
+ return basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
+}
+
+template
+basic_string<_CharT>
+__get_unit(bool __is_long, const duration<_Rep, ratio<3600> >& d)
+{
+ if (__is_long)
+ {
+ _CharT __p[] = {'h', 'o', 'u', 'r', 's'};
+ basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
+ if (d.count() == 1 || d.count() == -1)
+ s.pop_back();
+ return s;
+ }
+ return basic_string<_CharT>(1, 'h');
+}
+
+template
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d)
+{
+ typename basic_ostream<_CharT, _Traits>::sentry ok(__os);
+ if (ok)
+ {
+ typedef durationpunct _F;
+ typedef basic_string<_CharT> string_type;
+ bool failed = false;
+ try
+ {
+ bool __is_long = true;
+ locale __loc = __os.getloc();
+ if (has_facet<_F>(__loc))
+ {
+ const _F& f = use_facet<_F>(__loc);
+ __is_long = f.is_prefix_name();
+ }
+ string_type __unit = __get_unit<_CharT>(__is_long, __d);
+ __os << __d.count() << ' ' << __unit;
+ }
+ catch (...)
+ {
+ failed = true;
+ }
+ if (failed)
+ __os.setstate(ios_base::failbit | ios_base::badbit);
+ }
+ return __os;
+}
+
+template ::value>
+struct __duration_io_intermediate
+{
+ typedef _Rep type;
+};
+
+template
+struct __duration_io_intermediate<_Rep, true>
+{
+ typedef typename conditional
+ <
+ is_floating_point<_Rep>::value,
+ long double,
+ typename conditional
+ <
+ is_signed<_Rep>::value,
+ long long,
+ unsigned long long
+ >::type
+ >::type type;
+};
+
+template
+T
+__gcd(T x, T y)
+{
+ while (y != 0)
+ {
+ T old_x = x;
+ x = y;
+ y = old_x % y;
+ }
+ return x;
+}
+
+template <>
+long double
+inline
+__gcd(long double, long double)
+{
+ return 1;
+}
+
+template
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, duration<_Rep, _Period>& __d)
+{
+ typedef basic_string<_CharT> string_type;
+ typedef durationpunct _F;
+ typedef typename __duration_io_intermediate<_Rep>::type _IR;
+ _IR __r;
+ // read value into __r
+ __is >> __r;
+ if (__is.good())
+ {
+ // now determine unit
+ typedef istreambuf_iterator<_CharT, _Traits> _I;
+ _I __i(__is);
+ _I __e;
+ if (__i != __e && *__i == ' ') // mandatory ' ' after value
+ {
+ ++__i;
+ if (__i != __e)
+ {
+ locale __loc = __is.getloc();
+ // unit is num / den (yet to be determined)
+ unsigned long long num = 0;
+ unsigned long long den = 0;
+ ios_base::iostate __err = ios_base::goodbit;
+ if (*__i == '[')
+ {
+ // parse [N/D]s or [N/D]seconds format
+ ++__i;
+ _CharT __x;
+ __is >> num >> __x >> den;
+ if (!__is.good() || __x != '/')
+ {
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ __i = _I(__is);
+ if (*__i != ']')
+ {
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ ++__i;
+ const basic_string<_CharT> __units[] =
+ {
+ __get_unit<_CharT>(true, seconds(2)),
+ __get_unit<_CharT>(true, seconds(1)),
+ __get_unit<_CharT>(false, seconds(1))
+ };
+ const basic_string<_CharT>* __k = __scan_keyword(__i, __e,
+ __units, __units + sizeof(__units)/sizeof(__units[0]),
+ use_facet >(__loc),
+ __err);
+ switch ((__k - __units) / 3)
+ {
+ case 0:
+ break;
+ default:
+ __is.setstate(__err);
+ return __is;
+ }
+ }
+ else
+ {
+ // parse SI name, short or long
+ const basic_string<_CharT> __units[] =
+ {
+ __get_unit<_CharT>(true, duration<_Rep, atto>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, atto>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, atto>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, femto>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, femto>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, femto>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, pico>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, pico>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, pico>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, nano>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, nano>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, nano>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, micro>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, micro>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, micro>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, milli>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, milli>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, milli>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, centi>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, centi>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, centi>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, deci>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, deci>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, deci>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, deca>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, deca>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, deca>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, hecto>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, hecto>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, hecto>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, kilo>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, kilo>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, kilo>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, mega>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, mega>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, mega>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, giga>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, giga>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, giga>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, tera>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, tera>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, tera>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, peta>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, peta>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, peta>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, exa>(2)),
+ __get_unit<_CharT>(true, duration<_Rep, exa>(1)),
+ __get_unit<_CharT>(false, duration<_Rep, exa>(1)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<1> >(2)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<1> >(1)),
+ __get_unit<_CharT>(false, duration<_Rep, ratio<1> >(1)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<60> >(2)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<60> >(1)),
+ __get_unit<_CharT>(false, duration<_Rep, ratio<60> >(1)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<3600> >(2)),
+ __get_unit<_CharT>(true, duration<_Rep, ratio<3600> >(1)),
+ __get_unit<_CharT>(false, duration<_Rep, ratio<3600> >(1))
+ };
+ const basic_string<_CharT>* __k = __scan_keyword(__i, __e,
+ __units, __units + sizeof(__units)/sizeof(__units[0]),
+ use_facet >(__loc),
+ __err);
+ switch (__k - __units)
+ {
+ case 0:
+ case 1:
+ case 2:
+ num = 1ULL;
+ den = 1000000000000000000ULL;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ num = 1ULL;
+ den = 1000000000000000ULL;
+ break;
+ case 6:
+ case 7:
+ case 8:
+ num = 1ULL;
+ den = 1000000000000ULL;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ num = 1ULL;
+ den = 1000000000ULL;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ num = 1ULL;
+ den = 1000000ULL;
+ break;
+ case 15:
+ case 16:
+ case 17:
+ num = 1ULL;
+ den = 1000ULL;
+ break;
+ case 18:
+ case 19:
+ case 20:
+ num = 1ULL;
+ den = 100ULL;
+ break;
+ case 21:
+ case 22:
+ case 23:
+ num = 1ULL;
+ den = 10ULL;
+ break;
+ case 24:
+ case 25:
+ case 26:
+ num = 10ULL;
+ den = 1ULL;
+ break;
+ case 27:
+ case 28:
+ case 29:
+ num = 100ULL;
+ den = 1ULL;
+ break;
+ case 30:
+ case 31:
+ case 32:
+ num = 1000ULL;
+ den = 1ULL;
+ break;
+ case 33:
+ case 34:
+ case 35:
+ num = 1000000ULL;
+ den = 1ULL;
+ break;
+ case 36:
+ case 37:
+ case 38:
+ num = 1000000000ULL;
+ den = 1ULL;
+ break;
+ case 39:
+ case 40:
+ case 41:
+ num = 1000000000000ULL;
+ den = 1ULL;
+ break;
+ case 42:
+ case 43:
+ case 44:
+ num = 1000000000000000ULL;
+ den = 1ULL;
+ break;
+ case 45:
+ case 46:
+ case 47:
+ num = 1000000000000000000ULL;
+ den = 1ULL;
+ break;
+ case 48:
+ case 49:
+ case 50:
+ num = 1;
+ den = 1;
+ break;
+ case 51:
+ case 52:
+ case 53:
+ num = 60;
+ den = 1;
+ break;
+ case 54:
+ case 55:
+ case 56:
+ num = 3600;
+ den = 1;
+ break;
+ default:
+ __is.setstate(__err);
+ return __is;
+ }
+ }
+ // unit is num/den
+ // __r should be multiplied by (num/den) / _Period
+ // Reduce (num/den) / _Period to lowest terms
+ unsigned long long __gcd_n1_n2 = __gcd(num, _Period::num);
+ unsigned long long __gcd_d1_d2 = __gcd(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 > numeric_limits::max() / __d2 ||
+ den > numeric_limits::max() / __n2)
+ {
+ // (num/den) / _Period overflows
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ num *= __d2;
+ den *= __n2;
+ // num / den is now factor to multiply by __r
+ typedef typename common_type<_IR, unsigned long long>::type _CT;
+ if (is_integral<_IR>::value)
+ {
+ // Reduce __r * num / den
+ _CT __t = __gcd<_CT>(__r, den);
+ __r /= __t;
+ den /= __t;
+ if (den != 1)
+ {
+ // Conversion to _Period is integral and not exact
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ }
+ if (__r > duration_values<_CT>::max() / num)
+ {
+ // Conversion to _Period overflowed
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ _CT __t = __r * num;
+ __t /= den;
+ if (duration_values<_Rep>::max() < __t)
+ {
+ // Conversion to _Period overflowed
+ __is.setstate(__is.failbit);
+ return __is;
+ }
+ // Success! Store it.
+ __r = _Rep(__t);
+ __d = duration<_Rep, _Period>(__r);
+ __is.setstate(__err);
+ }
+ else
+ __is.setstate(__is.failbit | __is.eofbit);
+ }
+ else
+ {
+ if (__i == __e)
+ __is.setstate(__is.eofbit);
+ __is.setstate(__is.failbit);
+ }
+ }
+ else
+ __is.setstate(__is.failbit);
+ return __is;
+}
+
+template
+class timepunct
+ : public locale::facet
+{
+public:
+ typedef basic_string string_type;
+
+private:
+ string_type fmt_;
+ chrono::timezone tz_;
+
+public:
+ static locale::id id;
+
+ explicit timepunct(size_t refs = 0)
+ : locale::facet(refs), tz_(utc) {}
+ timepunct(timezone tz, string_type fmt, size_t refs = 0)
+ : locale::facet(refs), fmt_(std::move(fmt)), tz_(tz) {}
+
+ const string_type& fmt() const noexcept {return fmt_;}
+ chrono::timezone get_timezone() const noexcept {return tz_;}
+};
+
+template
+locale::id
+timepunct::id;
+
+template
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+ const time_point& __tp)
+{
+ return __os << __tp.time_since_epoch() << " since boot";
+}
+
+template
+struct __time_manip
+{
+ basic_string fmt_;
+ timezone tz_;
+
+ __time_manip(timezone tz, basic_string fmt)
+ : fmt_(std::move(fmt)),
+ tz_(tz) {}
+};
+
+template
+basic_ostream&
+operator <<(basic_ostream& os, __time_manip m)
+{
+ os.imbue(locale(os.getloc(), new timepunct(m.tz_, std::move(m.fmt_))));
+ return os;
+}
+
+template
+basic_istream&
+operator >>(basic_istream& is, __time_manip m)
+{
+ is.imbue(locale(is.getloc(), new timepunct(m.tz_, std::move(m.fmt_))));
+ return is;
+}
+
+template
+inline
+__time_manip
+time_fmt(timezone tz, const charT* fmt)
+{
+ return __time_manip(tz, fmt);
+}
+
+template
+inline
+__time_manip
+time_fmt(timezone tz, basic_string fmt)
+{
+ return __time_manip(tz, std::move(fmt));
+}
+
+class __time_man
+{
+ timezone form_;
+public:
+ explicit __time_man(timezone f) : form_(f) {}
+ // explicit
+ operator timezone() const {return form_;}
+};
+
+template
+basic_ostream&
+operator <<(basic_ostream& os, __time_man m)
+{
+ os.imbue(locale(os.getloc(), new timepunct(static_cast(m), basic_string())));
+ return os;
+}
+
+template
+basic_istream&
+operator >>(basic_istream& is, __time_man m)
+{
+ is.imbue(locale(is.getloc(), new timepunct(static_cast(m), basic_string())));
+ return is;
+}
+
+inline
+__time_man
+time_fmt(timezone f)
+{
+ return __time_man(f);
+}
+
+#if ! BEAST_CHRONO_NO_TIMEPOINT_IO
+
+template
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+ time_point& __tp)
+{
+ _Duration __d;
+ __is >> __d;
+ if (__is.good())
+ {
+ const _CharT __u[] = {' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't'};
+ const basic_string<_CharT> __units(__u, __u + sizeof(__u)/sizeof(__u[0]));
+ ios_base::iostate __err = ios_base::goodbit;
+ typedef istreambuf_iterator<_CharT, _Traits> _I;
+ _I __i(__is);
+ _I __e;
+ ptrdiff_t __k = __scan_keyword(__i, __e,
+ &__units, &__units + 1,
+ use_facet >(__is.getloc()),
+ __err) - &__units;
+ if (__k == 1)
+ {
+ // failed to read epoch string
+ __is.setstate(__err);
+ return __is;
+ }
+ __tp = time_point(__d);
+ }
+ else
+ __is.setstate(__is.failbit);
+ return __is;
+}
+
+template
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+ const time_point& __tp)
+{
+ typename basic_ostream<_CharT, _Traits>::sentry ok(__os);
+ if (ok)
+ {
+ bool failed = false;
+ try
+ {
+ const _CharT* pb = nullptr;
+ const _CharT* pe = pb;
+ timezone tz = utc;
+ typedef timepunct<_CharT> F;
+ locale loc = __os.getloc();
+ if (has_facet(loc))
+ {
+ const F& f = use_facet(loc);
+ pb = f.fmt().data();
+ pe = pb + f.fmt().size();
+ tz = f.get_timezone();
+ }
+ time_t __t = system_clock::to_time_t(__tp);
+ tm __tm;
+ if (tz == local)
+ {
+ if (localtime_r(&__t, &__tm) == 0)
+ failed = true;
+ }
+ else
+ {
+ if (gmtime_r(&__t, &__tm) == 0)
+ failed = true;
+ }
+ if (!failed)
+ {
+ const time_put<_CharT>& tp = use_facet >(loc);
+ if (pb == pe)
+ {
+ _CharT pattern[] = {'%', 'F', 'T', '%', 'H', ':', '%', 'M', ':'};
+ pb = pattern;
+ pe = pb + sizeof(pattern) / sizeof(_CharT);
+ failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
+ if (!failed)
+ {
+ duration __d = __tp - system_clock::from_time_t(__t) +
+ seconds(__tm.tm_sec);
+ if (__d.count() < 10)
+ __os << _CharT('0');
+ ios::fmtflags __flgs = __os.flags();
+ __os.setf(ios::fixed, ios::floatfield);
+ __os << __d.count();
+ __os.flags(__flgs);
+ if (tz == local)
+ {
+ _CharT sub_pattern[] = {' ', '%', 'z'};
+ pb = sub_pattern;
+ pe = pb + + sizeof(sub_pattern) / sizeof(_CharT);
+ failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
+ }
+ else
+ {
+ _CharT sub_pattern[] = {' ', '+', '0', '0', '0', '0', 0};
+ __os << sub_pattern;
+ }
+ }
+ }
+ else
+ failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
+ }
+ }
+ catch (...)
+ {
+ failed = true;
+ }
+ if (failed)
+ __os.setstate(ios_base::failbit | ios_base::badbit);
+ }
+ return __os;
+}
+
+template
+minutes
+__extract_z(_InputIterator& __b, _InputIterator __e,
+ ios_base::iostate& __err, const ctype<_CharT>& __ct)
+{
+ int __minn = 0;
+ if (__b != __e)
+ {
+ char __cn = __ct.narrow(*__b, 0);
+ if (__cn != '+' && __cn != '-')
+ {
+ __err |= 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 |= ios_base::eofbit | ios_base::failbit;
+ return minutes(0);
+ }
+ __cn = __ct.narrow(*__b, 0);
+ if (!('0' <= __cn && __cn <= '9'))
+ {
+ __err |= ios_base::failbit;
+ return minutes(0);
+ }
+ __hr = __hr * 10 + __cn - '0';
+ }
+ for (int i = 0; i < 2; ++i)
+ {
+ if (++__b == __e)
+ {
+ __err |= ios_base::eofbit | ios_base::failbit;
+ return minutes(0);
+ }
+ __cn = __ct.narrow(*__b, 0);
+ if (!('0' <= __cn && __cn <= '9'))
+ {
+ __err |= ios_base::failbit;
+ return minutes(0);
+ }
+ __minn = __minn * 10 + __cn - '0';
+ }
+ if (++__b == __e)
+ __err |= ios_base::eofbit;
+ __minn += __hr * 60;
+ __minn *= __sn;
+ }
+ else
+ __err |= ios_base::eofbit | ios_base::failbit;
+ return minutes(__minn);
+}
+
+template
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+ time_point& __tp)
+{
+ typename basic_istream<_CharT,_Traits>::sentry ok(__is);
+ if (ok)
+ {
+ ios_base::iostate err = ios_base::goodbit;
+ try
+ {
+ const _CharT* pb = nullptr;
+ const _CharT* pe = pb;
+ typedef timepunct<_CharT> F;
+ locale loc = __is.getloc();
+ timezone tz = utc;
+ if (has_facet(loc))
+ {
+ const F& f = use_facet(loc);
+ pb = f.fmt().data();
+ pe = pb + f.fmt().size();
+ tz = f.get_timezone();
+ }
+ const time_get<_CharT>& tg = use_facet >(loc);
+ const ctype<_CharT>& __ct = use_facet >(loc);
+ tm __tm = {0};
+ typedef istreambuf_iterator<_CharT, _Traits> _I;
+ if (pb == pe)
+ {
+ _CharT pattern[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd',
+ 'T', '%', 'H', ':', '%', 'M', ':'};
+ pb = pattern;
+ pe = pb + sizeof(pattern) / sizeof(_CharT);
+ tg.get(__is, 0, __is, err, &__tm, pb, pe);
+ if (err & ios_base::failbit)
+ goto __exit;
+ double __sec;
+ _CharT __c = _CharT();
+ __is >> __sec;
+ if (__is.fail())
+ {
+ err |= ios_base::failbit;
+ goto __exit;
+ }
+ _I __i(__is);
+ _I __eof;
+ __c = *__i;
+ if (++__i == __eof || __c != ' ')
+ {
+ err |= ios_base::failbit;
+ goto __exit;
+ }
+ minutes __minn = __extract_z(__i, __eof, err, __ct);
+ if (err & ios_base::failbit)
+ goto __exit;
+ time_t __t;
+ __t = timegm(&__tm);
+ __tp = system_clock::from_time_t(__t) - __minn
+ + round(duration(__sec));
+ }
+ else
+ {
+ const _CharT __z[2] = {'%', 'z'};
+ const _CharT* __fz = std::search(pb, pe, __z, __z+2);
+ tg.get(__is, 0, __is, err, &__tm, pb, __fz);
+ minutes __minn(0);
+ if (__fz != pe)
+ {
+ if (err != ios_base::goodbit)
+ {
+ err |= ios_base::failbit;
+ goto __exit;
+ }
+ _I __i(__is);
+ _I __eof;
+ __minn = __extract_z(__i, __eof, err, __ct);
+ if (err & ios_base::failbit)
+ goto __exit;
+ if (__fz+2 != pe)
+ {
+ if (err != ios_base::goodbit)
+ {
+ err |= ios_base::failbit;
+ goto __exit;
+ }
+ tg.get(__is, 0, __is, err, &__tm, __fz+2, pe);
+ if (err & ios_base::failbit)
+ goto __exit;
+ }
+ }
+ __tm.tm_isdst = -1;
+ time_t __t;
+ if (tz == utc || __fz != pe)
+ __t = timegm(&__tm);
+ else
+ __t = mktime(&__tm);
+ __tp = system_clock::from_time_t(__t) - __minn;
+ }
+ }
+ catch (...)
+ {
+ err |= ios_base::badbit | ios_base::failbit;
+ }
+ __exit:
+ __is.setstate(err);
+ }
+ return __is;
+}
+
+#endif
+
+} // chrono
+
+//_LIBCPP_END_NAMESPACE_STD
+}
+
+#endif
+
diff --git a/src/beast/beast/chrono/impl/abstract_clock.cpp b/src/beast/beast/chrono/impl/abstract_clock.cpp
new file mode 100644
index 000000000..af9892b31
--- /dev/null
+++ b/src/beast/beast/chrono/impl/abstract_clock.cpp
@@ -0,0 +1,106 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include "../abstract_clock.h"
+#include "../manual_clock.h"
+
+#include
+
+#include
+#include
+
+namespace beast {
+
+template
+std::basic_ostream & operator<< (
+ std::basic_ostream& os, std::chrono::time_point <
+ abstract_clock , Duration2> const& tp)
+{
+ return os;
+}
+
+class abstract_clock_tests : public UnitTest
+{
+public:
+ void test (abstract_clock & c)
+ {
+ {
+ auto const t1 (c.now ());
+ std::this_thread::sleep_for (
+ std::chrono::milliseconds (1500));
+ auto const t2 (c.now ());
+
+ std::stringstream ss;
+ ss <<
+ "t1= " << c.to_string (t1) <<
+ ", t2= " << c.to_string (t2) <<
+ ", elapsed= " << (t2 - t1);
+ logMessage (ss.str());
+ }
+ }
+
+ void test_manual ()
+ {
+ typedef manual_clock clock_type;
+ clock_type c;
+
+ std::stringstream ss;
+
+ ss << "now() = " << c.to_string (c.now ()) << std::endl;
+
+ c.set (clock_type::time_point (std::chrono::seconds (1)));
+ ss << "now() = " << c.to_string (c.now ()) << std::endl;
+
+ c.set (clock_type::time_point (std::chrono::seconds (2)));
+ ss << "now() = " << c.to_string (c.now ()) << std::endl;
+
+ logMessage (ss.str());
+ }
+
+ void runTest ()
+ {
+ beginTestCase ("Syntax");
+
+ logMessage ("steady_clock");
+ test (get_abstract_clock ());
+
+ logMessage ("system_clock");
+ test (get_abstract_clock ());
+
+ logMessage ("high_resolution_clock");
+ test (get_abstract_clock ());
+
+ logMessage ("manual_clock");
+ test_manual ();
+
+ pass ();
+ }
+
+ abstract_clock_tests ()
+ : UnitTest ("abstract_clock", "beast", runManual)
+ {
+ }
+};
+
+static abstract_clock_tests abstract_clock_tests_;
+
+}
diff --git a/src/beast/beast/chrono/impl/chrono_io.cpp b/src/beast/beast/chrono/impl/chrono_io.cpp
new file mode 100644
index 000000000..b6004bb6e
--- /dev/null
+++ b/src/beast/beast/chrono/impl/chrono_io.cpp
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+// chrono_io
+//
+// (C) Copyright Howard Hinnant
+// 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).
+
+#include "../chrono_io.h"
+
+//_LIBCPP_BEGIN_NAMESPACE_STD
+namespace std {
+
+namespace chrono
+{
+
+locale::id
+durationpunct::id;
+
+} // chrono
+
+//_LIBCPP_END_NAMESPACE_STD
+}
diff --git a/src/beast/beast/chrono/manual_clock.h b/src/beast/beast/chrono/manual_clock.h
new file mode 100644
index 000000000..032be6130
--- /dev/null
+++ b/src/beast/beast/chrono/manual_clock.h
@@ -0,0 +1,92 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
+#define BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
+
+#include "abstract_clock.h"
+
+namespace beast {
+
+/** Manual clock implementation.
+ This concrete class implements the @ref abstract_clock interface and
+ allows the time to be advanced manually, mainly for the purpose of
+ providing a clock in unit tests.
+ @tparam The length of time, in seconds, corresponding to one tick.
+*/
+template
+class manual_clock : public abstract_clock
+{
+public:
+ using typename abstract_clock ::rep;
+ using typename abstract_clock ::duration;
+ using typename abstract_clock ::time_point;
+
+ explicit manual_clock (time_point const& t = time_point (Duration (0)))
+ : m_now (t)
+ {
+ }
+
+ bool is_steady () const
+ {
+ return IsSteady;
+ }
+
+ time_point now ()
+ {
+ return m_now;
+ }
+
+ std::string to_string (time_point const& tp)
+ {
+ std::stringstream ss;
+ ss << tp.time_since_epoch() << " from start";
+ return ss.str ();
+ }
+
+ /** Set the current time of the manual clock.
+ Precondition:
+ ! IsSteady || t > now()
+ */
+ void set (time_point const& t)
+ {
+ //if (IsSteady)
+ m_now = t;
+ }
+
+ /** Convenience for setting the time using a duration in @ref rep units. */
+ void set (rep v)
+ {
+ set (time_point (duration (v)));
+ }
+
+ /** Convenience for advancing the clock by one. */
+ manual_clock& operator++ ()
+ {
+ m_now += duration (1);
+ return *this;
+ }
+
+private:
+ time_point m_now;
+};
+
+}
+
+#endif
diff --git a/src/beast/beast/chrono/ratio_io.h b/src/beast/beast/chrono/ratio_io.h
new file mode 100644
index 000000000..1a86e4fe8
--- /dev/null
+++ b/src/beast/beast/chrono/ratio_io.h
@@ -0,0 +1,622 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+// ratio_io
+//
+// (C) Copyright Howard Hinnant
+// 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 BEAST_CHRONO_RATIO_IO_H_INCLUDED
+#define BEAST_CHRONO_RATIO_IO_H_INCLUDED
+
+/*
+
+ ratio_io synopsis
+
+#include
+#include
+
+namespace std
+{
+
+template
+struct ratio_string
+{
+ static basic_string symbol();
+ static basic_string prefix();
+};
+
+} // std
+
+*/
+
+#include
+#include
+#include
+
+//_LIBCPP_BEGIN_NAMESPACE_STD
+namespace std {
+
+template
+struct ratio_string
+{
+ static basic_string<_CharT> symbol() {return prefix();}
+ static basic_string<_CharT> prefix();
+};
+
+template
+basic_string<_CharT>
+ratio_string<_Ratio, _CharT>::prefix()
+{
+ basic_ostringstream<_CharT> __os;
+ __os << _CharT('[') << _Ratio::num << _CharT('/')
+ << _Ratio::den << _CharT(']');
+ return __os.str();
+}
+
+// atto
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'a');}
+ static string prefix() {return string("atto");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'a');}
+ static u16string prefix() {return u16string(u"atto");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'a');}
+ static u32string prefix() {return u32string(U"atto");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'a');}
+ static wstring prefix() {return wstring(L"atto");}
+};
+
+// femto
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'f');}
+ static string prefix() {return string("femto");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'f');}
+ static u16string prefix() {return u16string(u"femto");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'f');}
+ static u32string prefix() {return u32string(U"femto");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'f');}
+ static wstring prefix() {return wstring(L"femto");}
+};
+
+// pico
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'p');}
+ static string prefix() {return string("pico");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'p');}
+ static u16string prefix() {return u16string(u"pico");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'p');}
+ static u32string prefix() {return u32string(U"pico");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'p');}
+ static wstring prefix() {return wstring(L"pico");}
+};
+
+// nano
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'n');}
+ static string prefix() {return string("nano");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'n');}
+ static u16string prefix() {return u16string(u"nano");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'n');}
+ static u32string prefix() {return u32string(U"nano");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'n');}
+ static wstring prefix() {return wstring(L"nano");}
+};
+
+// micro
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string("\xC2\xB5");}
+ static string prefix() {return string("micro");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'\xB5');}
+ static u16string prefix() {return u16string(u"micro");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'\xB5');}
+ static u32string prefix() {return u32string(U"micro");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'\xB5');}
+ static wstring prefix() {return wstring(L"micro");}
+};
+
+// milli
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'm');}
+ static string prefix() {return string("milli");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'm');}
+ static u16string prefix() {return u16string(u"milli");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'm');}
+ static u32string prefix() {return u32string(U"milli");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'm');}
+ static wstring prefix() {return wstring(L"milli");}
+};
+
+// centi
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'c');}
+ static string prefix() {return string("centi");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'c');}
+ static u16string prefix() {return u16string(u"centi");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'c');}
+ static u32string prefix() {return u32string(U"centi");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'c');}
+ static wstring prefix() {return wstring(L"centi");}
+};
+
+// deci
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'd');}
+ static string prefix() {return string("deci");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'd');}
+ static u16string prefix() {return u16string(u"deci");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'd');}
+ static u32string prefix() {return u32string(U"deci");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'd');}
+ static wstring prefix() {return wstring(L"deci");}
+};
+
+// deca
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string("da");}
+ static string prefix() {return string("deca");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(u"da");}
+ static u16string prefix() {return u16string(u"deca");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(U"da");}
+ static u32string prefix() {return u32string(U"deca");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(L"da");}
+ static wstring prefix() {return wstring(L"deca");}
+};
+
+// hecto
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'h');}
+ static string prefix() {return string("hecto");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'h');}
+ static u16string prefix() {return u16string(u"hecto");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'h');}
+ static u32string prefix() {return u32string(U"hecto");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'h');}
+ static wstring prefix() {return wstring(L"hecto");}
+};
+
+// kilo
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'k');}
+ static string prefix() {return string("kilo");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'k');}
+ static u16string prefix() {return u16string(u"kilo");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'k');}
+ static u32string prefix() {return u32string(U"kilo");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'k');}
+ static wstring prefix() {return wstring(L"kilo");}
+};
+
+// mega
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'M');}
+ static string prefix() {return string("mega");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'M');}
+ static u16string prefix() {return u16string(u"mega");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'M');}
+ static u32string prefix() {return u32string(U"mega");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'M');}
+ static wstring prefix() {return wstring(L"mega");}
+};
+
+// giga
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'G');}
+ static string prefix() {return string("giga");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'G');}
+ static u16string prefix() {return u16string(u"giga");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'G');}
+ static u32string prefix() {return u32string(U"giga");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'G');}
+ static wstring prefix() {return wstring(L"giga");}
+};
+
+// tera
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'T');}
+ static string prefix() {return string("tera");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'T');}
+ static u16string prefix() {return u16string(u"tera");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'T');}
+ static u32string prefix() {return u32string(U"tera");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'T');}
+ static wstring prefix() {return wstring(L"tera");}
+};
+
+// peta
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'P');}
+ static string prefix() {return string("peta");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'P');}
+ static u16string prefix() {return u16string(u"peta");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'P');}
+ static u32string prefix() {return u32string(U"peta");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'P');}
+ static wstring prefix() {return wstring(L"peta");}
+};
+
+// exa
+
+template <>
+struct ratio_string
+{
+ static string symbol() {return string(1, 'E');}
+ static string prefix() {return string("exa");}
+};
+
+#if HAS_UNICODE_SUPPORT
+
+template <>
+struct ratio_string
+{
+ static u16string symbol() {return u16string(1, u'E');}
+ static u16string prefix() {return u16string(u"exa");}
+};
+
+template <>
+struct ratio_string
+{
+ static u32string symbol() {return u32string(1, U'E');}
+ static u32string prefix() {return u32string(U"exa");}
+};
+
+#endif
+
+template <>
+struct ratio_string
+{
+ static wstring symbol() {return wstring(1, L'E');}
+ static wstring prefix() {return wstring(L"exa");}
+};
+
+//_LIBCPP_END_NAMESPACE_STD
+}
+
+#endif // _RATIO_IO