diff --git a/chrono_io.html b/chrono_io.html
index 5485352..ff3fd94 100644
--- a/chrono_io.html
+++ b/chrono_io.html
@@ -26,311 +26,15 @@
Howard E. Hinnant
-2016-07-30
+2017-04-13
chrono_io
-This is a small library which does nothing but add non-configurable, non-localizable
-streaming to std::chrono::duration
. The streaming operator lives in
-namespace date
for convenience purposes, and does not live in
-namespace std::chrono
as that would violate the standard.
+This library has been moved to
+"date.h"
.
-The entire API of this library is: -
- -- --namespace date -{ - -template <class CharT, class Traits, class Rep, class Period> -std::basic_ostream<CharT, Traits>& -operator<<(std::basic_ostream<CharT, Traits>& os, - const std::chrono::duration<Rep, Period>& d); - -} // namespace date -
-Just one signature for an entire library? Are you serious?! -
- --- --Very serious. -
--Parsing is not included because there are a million ways to parse durations, and none -of them are universally agreed upon. And they are all easily implementable without -private access to
-std::chrono::duration
just by parsing arithmetic types -and strings. -
-No formatting options?! -
- --- --No. -
--The formatting provided here is based on an international SI standard. There is -no need for localization. If you need other formatting options for streaming -your durations that is easy enough for you to supply. What is needed here is -zero-effort streaming of
-chrono::duration
s without hassle. -Streamingchrono::duration
s is the biggest use of -.count()
(a dangerous type cast), and that use should be handled by -a library such as this. -
- --#include "chrono_io.h" -#include <iostream> - -void f(); - -int -main() -{ - using namespace date; - using namespace std::chrono; - auto t0 = steady_clock::now(); - f(); - auto t1 = steady_clock::now(); - std::cout << t1 - t0 << '\n'; -} -
-With this library, you don't have to specify the duration type (and cast to it) in timing
-situations like this. This will create whatever duration is native to
-steady_clock
and print out the value and units for that duration,
-for example:
-
- --682580ns -
-Change steady_clock
to system_clock
(and if that clock has
-different units on your platform), and the output automatically changes units for you:
-
- --auto t0 = system_clock::now(); -f(); -auto t1 = system_clock::now(); -std::cout << t1 - t0 << '\n'; -
- --682µs -
-And yes, it really does print out the Greek letter µ
and not
-u
. When streaming to char
-based streams it uses UTF-8 encoding
-to represent the Unicode character 'MICRO SIGN' (U+00B5). Otherwise it uses UTF-16 or
-UTF-32 based on the size of character the stream is using.
-
-In general, if the duration tick period is the same type as one of the non-optional
-std::ratio
SI convenience typedefs (atto
thru exa
),
-then the unit will use the internationally accepted symbol for the
-metric prefix followed
-by 's'
.
-
-In addition, if the duration tick period is ratio<60>
, then the
-printed unit is min
. And if the duration tick period is
-ratio<3600>
, then the unit is h
.
-
- --std::cout << 1s << '\n'; -std::cout << 2min << '\n'; -std::cout << 3h << '\n'; -
-Outputs: -
- -- --1s -2min -3h -
-Sometimes odd durations pop up which have no widely recognized names. For example -consider this code: -
- -- --using frames = duration<int, ratio<1, 60>>; -std::cout << 45ms + frames{5} << '\n'; -
-This sum can't be exactly represented as either milliseconds or frames (1/60 of a second).
-The compiler figures out the coarsest unit which can exactly represent the sum of
-any millisecond and any frame and auto-generates that unit to hold the sum. For this
-example that duration will have a tick period of 1/3000 of a second. This library
-puts that ratio inside of square brackets, and then appends 's'
:
-
- --385[1/3000]s -
-If the durations tick period is a whole number of seconds (period::den == 1
),
-then the /1
is dropped inside of the square brackets. The following example
-uses months
from date.h.
-
- --std::cout << months{6} << '\n'; -
- --6[2629746]s -
-Trivia: 2,629,746s is the exact length of the average Gregorian month, which is also exactly -30.436875 24h days. -
- --Question: Why are there separate implementations for C++11 and C++14? -
- -
-Answer: The units of a duration
are always known at compile
-time. Thus the string representation of the units is always known at compile time. This
-is true even when the unit is of the form [num/den]s
. But only C++14 has
-the gravitas to do the complete string conversion at compile time. And now that I've
-claimed that, I'm sure someone will come up with a C++11 that VS-2015 won't compile anyway.
-So I need a run-time solution (based on std::basic_string<CharT>
,
-and a compile-time solution that currently only gcc and clang with -std=c++14
-can handle.
-
-For example if you compile the following code with -std=c++14
and clang:
-
- --using frames = std::chrono::duration<int, std::ratio<1, 60>>; - -void -test(std::ostream& os, std::chrono::milliseconds x, frames y) -{ - using namespace date; - os << x + y; -} -
-And then inspect the generated assembly, it contains this: -
- -- --movabsq $6714920027984703835, %rax ## imm = 0x5D303030332F315B -
-Which is assembly-speak for "[1/3000]" all boiled down to one x86_64 instruction. The
-'s'
wouldn't quite fit within this one instruction and follows in a later
-instruction. C++14 can do some amazing things at compile time! For C++11 I just
-gave up and called std::to_string
.
-
--template <class CharT, class Traits, class Rep, class Period> -std::basic_ostream<CharT, Traits>& -operator<<(std::basic_ostream<CharT, Traits>& os, - const std::chrono::duration<Rep, Period>& d); -- ----Effects: Equivalent to: -
---os << d.count() << detail::get_units<CharT>(duration<Rep, typename Period::type>{}); ---Where
- -detail::get_units<CharT>()
returns a null-terminated string of -CharT
which depends only onPeriod::type
as follows (let -period
be the typePeriod::type
): --
- -- If
-period
is typestd::atto
,as
, else- if
-period
is typestd::femto
,fs
, else- if
-period
is typestd::pico
,ps
, else- if
-period
is typestd::nano
,ns
, else- if
-period
is typestd::micro
,µs
(U+00B5), else- if
-period
is typestd::milli
,ms
, else- if
-period
is typestd::centi
,cs
, else- if
-period
is typestd::deci
,ds
, else- if
-period
is typestd::ratio<1>
,s
, else- if
-period
is typestd::deca
,das
, else- if
-period
is typestd::hecto
,hs
, else- if
-period
is typestd::kilo
,ks
, else- if
-period
is typestd::mega
,Ms
, else- if
-period
is typestd::giga
,Gs
, else- if
-period
is typestd::tera
,Ts
, else- if
-period
is typestd::peta
,Ps
, else- if
-period
is typestd::exa
,Es
, else- if
-period
is typestd::ratio<60>
,min
, else- if
-period
is typestd::ratio<3600>
,h
, else- if
-period::den == 1
,[num]s
, else- -
[num/den]s
.-In the list above the use of
- -num
andden
refer to the -static data members ofperiod
which are converted to arrays of -CharT
using a decimal conversion with no leading zeroes. --Returns:
-os
. -