Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67698 - in trunk/libs/chrono: . build doc example src test test/clock test/duration test/duration/cons test/duration/nonmember test/time_point test/time_point/comparisons test/time_point/cons test/traits
From: vicente.botet_at_[hidden]
Date: 2011-01-05 19:48:00


Author: viboes
Date: 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
New Revision: 67698
URL: http://svn.boost.org/trac/boost/changeset/67698

Log:
Boost.Chrono: Moved to trunk
Added:
   trunk/libs/chrono/
   trunk/libs/chrono/build/
   trunk/libs/chrono/build/Jamfile.v2 (contents, props changed)
   trunk/libs/chrono/doc/
   trunk/libs/chrono/doc/Jamfile.v2 (contents, props changed)
   trunk/libs/chrono/doc/chrono.qbk (contents, props changed)
   trunk/libs/chrono/doc/time2_demo.html (contents, props changed)
   trunk/libs/chrono/example/
   trunk/libs/chrono/example/await_keystroke.cpp (contents, props changed)
   trunk/libs/chrono/example/chrono_accuracy_test.cpp (contents, props changed)
   trunk/libs/chrono/example/chrono_unit_test.cpp (contents, props changed)
   trunk/libs/chrono/example/clock_name.cpp (contents, props changed)
   trunk/libs/chrono/example/clock_name.hpp (contents, props changed)
   trunk/libs/chrono/example/cycle_count.cpp (contents, props changed)
   trunk/libs/chrono/example/explore_limits.cpp (contents, props changed)
   trunk/libs/chrono/example/i_dont_like_the_default_duration_behavior.cpp (contents, props changed)
   trunk/libs/chrono/example/io_ex1.cpp (contents, props changed)
   trunk/libs/chrono/example/io_ex2.cpp (contents, props changed)
   trunk/libs/chrono/example/io_ex3.cpp (contents, props changed)
   trunk/libs/chrono/example/io_ex4.cpp (contents, props changed)
   trunk/libs/chrono/example/io_ex5.cpp (contents, props changed)
   trunk/libs/chrono/example/manipulate_clock_object.cpp (contents, props changed)
   trunk/libs/chrono/example/min_time_point.cpp (contents, props changed)
   trunk/libs/chrono/example/miscellaneous.cpp (contents, props changed)
   trunk/libs/chrono/example/run_timer_example.cpp (contents, props changed)
   trunk/libs/chrono/example/run_timer_example2.cpp (contents, props changed)
   trunk/libs/chrono/example/runtime_resolution.cpp (contents, props changed)
   trunk/libs/chrono/example/saturating.cpp (contents, props changed)
   trunk/libs/chrono/example/simulated_thread_interface_demo.cpp (contents, props changed)
   trunk/libs/chrono/example/test_clock.cpp (contents, props changed)
   trunk/libs/chrono/example/test_clock2.cpp (contents, props changed)
   trunk/libs/chrono/example/test_duration.cpp (contents, props changed)
   trunk/libs/chrono/example/test_minmax.cpp (contents, props changed)
   trunk/libs/chrono/example/test_special_values.cpp (contents, props changed)
   trunk/libs/chrono/example/test_thread_clock.cpp (contents, props changed)
   trunk/libs/chrono/example/time2_demo.cpp (contents, props changed)
   trunk/libs/chrono/example/time2_demo_output.txt (contents, props changed)
   trunk/libs/chrono/example/timeval_demo.cpp (contents, props changed)
   trunk/libs/chrono/example/xtime.cpp (contents, props changed)
   trunk/libs/chrono/src/
   trunk/libs/chrono/src/chrono.cpp (contents, props changed)
   trunk/libs/chrono/src/process_clock.cpp (contents, props changed)
   trunk/libs/chrono/src/process_cpu_clocks.cpp (contents, props changed)
   trunk/libs/chrono/src/run_timer.cpp (contents, props changed)
   trunk/libs/chrono/src/run_timer_static.cpp (contents, props changed)
   trunk/libs/chrono/src/thread_clock.cpp (contents, props changed)
   trunk/libs/chrono/test/
   trunk/libs/chrono/test/Jamfile.v2 (contents, props changed)
   trunk/libs/chrono/test/clock/
   trunk/libs/chrono/test/clock.h (contents, props changed)
   trunk/libs/chrono/test/clock/clock_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/clock/errored_clock.hpp (contents, props changed)
   trunk/libs/chrono/test/duration/
   trunk/libs/chrono/test/duration/arithmetic_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/comparisons_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/cons/
   trunk/libs/chrono/test/duration/cons/convert_float_to_int_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/cons/convert_inexact_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/cons/implicit_constructot_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/cons/non_implicit_convertible_rep_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/cons/treat_as_floating_point_Rep2_true_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/constructor_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/default_ratio_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/duration_cast_int_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/duration_cast_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/duration_duration_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/duration_values_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/nonmember/
   trunk/libs/chrono/test/duration/nonmember/divide_rep2_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/nonmember/modulus_rep2_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/nonmember/times_rep2_lhs_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/nonmember/times_rep2_rhs_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/positive_num_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/ratio_alias_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/ratio_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/typedefs_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/duration/types_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/intmax_c.cpp (contents, props changed)
   trunk/libs/chrono/test/rep.h (contents, props changed)
   trunk/libs/chrono/test/run_timer_test.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/
   trunk/libs/chrono/test/time_point/arithmetic_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/comparisons/
   trunk/libs/chrono/test/time_point/comparisons/equal_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/comparisons/less_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/comparisons_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/cons/
   trunk/libs/chrono/test/time_point/cons/implicit_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/cons/non_implicit_convertible_duration_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/constructor_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/default_duration.pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/default_duration_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/duration.fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/min_max_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/not_duration_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/time_point_cast_int_fail.cpp (contents, props changed)
   trunk/libs/chrono/test/time_point/time_point_cast_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/traits/
   trunk/libs/chrono/test/traits/common_type_duration_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/traits/common_type_time_point_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/traits/duration_values_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/traits/treat_as_floating_point_pass.cpp (contents, props changed)
   trunk/libs/chrono/test/win32_test.cpp (contents, props changed)

Added: trunk/libs/chrono/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/build/Jamfile.v2 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,91 @@
+# Boost Chrono Library Build Jamfile
+
+# Copyright Beman Dawes 2002, 2006, 2008
+
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
+
+# See library home page at http://www.boost.org/libs/chrono
+
+# uncomment one if the above lines if you build outside the Boost release
+#local BOOST_ROOT = /boost_1_41_0 ;
+#local BOOST_ROOT = c:/cygwin/boost_1_41_0 ;
+
+if ! $(BOOST_ROOT)
+{
+ BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+}
+
+project boost/chrono
+ : source-location ../src
+ : requirements
+ <os>LINUX:<threading>multi
+ # uncomment the line above if you build outside the Boost release
+ #<include>$(BOOST_ROOT)
+ # uncomment the line above if you build outside the Boost release
+ #<include>../../..
+ <library>/boost/system//boost_system
+ #<define>BOOST_SYSTEM_INLINED
+ <define>BOOST_USE_WINDOWS_H
+ #<define>BOOST_COMMON_TYPE_USES_STATIC_ASSERT
+ #<define>BOOST_RATIO_USES_STATIC_ASSERT
+ #<define>BOOST_CHRONO_USES_STATIC_ASSERT
+ #<define>BOOST_COMMON_TYPE_USES_MPL_ASSERT
+ #<define>BOOST_RATIO_USES_MPL_ASSERT
+ #<define>BOOST_CHRONO_USES_MPL_ASSERT
+ #<define>BOOST_COMMON_TYPE_USES_ARRAY_ASSERT
+ #<define>BOOST_RATIO_USES_ARRAY_ASSERT
+ #<define>BOOST_CHRONO_USES_ARRAY_ASSERT
+ #<define>BOOST_COMMON_TYPE_DONT_USE_TYPEOF
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ <toolset>gcc-3.4.4:<linkflags>--enable-auto-import
+ <toolset>gcc-4.3.4:<linkflags>--enable-auto-import
+ <toolset>gcc-mingw-4.4.0:<linkflags>--enable-auto-import
+ <toolset>gcc-mingw-4.5.0:<linkflags>--enable-auto-import
+ <warnings>all
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-pedantic
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ <toolset>darwin:<cxxflags>-Wextra
+ <toolset>darwin:<cxxflags>-pedantic
+ <toolset>darwin:<cxxflags>-Wno-long-long
+ <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
+
+ : usage-requirements # pass these requirement to dependents (i.e. users)
+ #<os>LINUX:<threading>multi
+ <library>/boost/system//boost_system
+ #<define>BOOST_SYSTEM_INLINED
+ #<define>BOOST_COMMON_TYPE_USES_STATIC_ASSERT
+ #<define>BOOST_RATIO_USES_STATIC_ASSERT
+ #<define>BOOST_CHRONO_USES_STATIC_ASSERT
+ #<define>BOOST_COMMON_TYPE_USES_MPL_ASSERT
+ #<define>BOOST_RATIO_USES_MPL_ASSERT
+ #<define>BOOST_CHRONO_USES_MPL_ASSERT
+ #<define>BOOST_COMMON_TYPE_USES_ARRAY_ASSERT
+ #<define>BOOST_RATIO_USES_ARRAY_ASSERT
+ #<define>BOOST_CHRONO_USES_ARRAY_ASSERT
+ #<define>BOOST_COMMON_TYPE_DONT_USE_TYPEOF
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ <link>shared:<define>BOOST_CHRONO_DYN_LINK=1
+ <link>static:<define>BOOST_CHRONO_STATIC_LINK=1
+ <toolset>gcc-3.4.4:<linkflags>--enable-auto-import
+ <toolset>gcc-4.3.4:<linkflags>--enable-auto-import
+ <toolset>gcc-mingw-4.4.0:<linkflags>--enable-auto-import
+ <toolset>gcc-mingw-4.5.0:<linkflags>--enable-auto-import
+ ;
+
+SOURCES = chrono thread_clock process_cpu_clocks ;
+
+#process_clock run_timer run_timer_static
+
+lib boost_chrono
+ : $(SOURCES).cpp
+ #$(BOOST_ROOT)/libs/system/build//boost_system
+ :
+ <link>shared:<define>BOOST_ALL_DYN_LINK=1 # tell source we're building dll's
+ <link>static:<define>BOOST_All_STATIC_LINK=1 # tell source we're building static lib's
+ ;
+
+#boost-install boost_chrono ;

Added: trunk/libs/chrono/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/doc/Jamfile.v2 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,74 @@
+# Boost.Chrono library documentation Jamfile ---------------------------------
+#
+# Copyright Vicente J. Botet Escriba 2009. Use, modification and
+# distribution is 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)
+#
+# See http://www.boost.org for updates, documentation, and revision history.
+
+#import doxygen ;
+using quickbook ;
+
+#doxygen autodoc
+# :
+# [ glob ../../../boost/chrono/*.hpp ]
+# [ glob ../../../boost/chrono/allocators/*.hpp ]
+# :
+# <doxygen:param>EXTRACT_ALL=NO
+# <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+# <doxygen:param>EXTRACT_PRIVATE=NO
+# <doxygen:param>EXPAND_ONLY_PREDEF=YES
+# <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
+# <xsl:param>"boost.doxygen.reftitle=Boost.Chrono Reference"
+# ;
+
+xml chrono : chrono.qbk ;
+
+boostbook standalone
+ :
+ chrono
+ :
+ # HTML options first:
+ # Use graphics not text for navigation:
+ <xsl:param>navig.graphics=1
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=2
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=4
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=2
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
+ # Path for libraries index:
+ <xsl:param>boost.libraries=../../../../libs/libraries.htm
+ # Use the main Boost stylesheet:
+ <xsl:param>html.stylesheet=../../../../doc/src/boostbook.css
+
+ # PDF Options:
+ # TOC Generation: this is needed for FOP-0.9 and later:
+ #<xsl:param>fop1.extensions=0
+ # Or enable this if you're using XEP:
+ <xsl:param>xep.extensions=1
+ # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+ <xsl:param>fop.extensions=0
+ # No indent on body text:
+ <xsl:param>body.start.indent=0pt
+ # Margin size:
+ <xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <xsl:param>page.margin.outer=0.5in
+ # Yes, we want graphics for admonishments:
+ <xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default pnd graphics are awful in PDF form,
+ # better use SVG's instead:
+ <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+ <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
+ ;
+
+install pdf-install : standalone : <location>. <install-type>PDF ;

Added: trunk/libs/chrono/doc/chrono.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/doc/chrono.qbk 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,4507 @@
+[/
+ / Copyright (c) 2008 Howard Hinnant
+ / Copyright (c) 2006, 2008 Beman Dawes
+ / Copyright (c) 2009-20010 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)
+ /]
+
+[article Boost.Chrono
+ [quickbook 1.5]
+ [version 1.0.0]
+ [authors [Hinnant, Howard]]
+ [authors [Dawes, Beman]]
+ [authors [Botet Escriba, Vicente J.]]
+ [copyright 2008 Howard Hinnant]
+ [copyright 2006, 2008 Beman Dawes]
+ [copyright 2009-2011 Vicente J. Botet Escriba]
+ [license
+ 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])
+ ]
+]
+
+[/==================]
+[def __Boost_Chrono__ [*Boost.Chrono]]
+
+[def __see_bellow__ ['see bellow]]
+
+[/===============================================]
+[def __inherit [*Inherits:]]
+[def __std_ref [*C++ Standard Reference:]]
+[def __header [*Header:]]
+[def __compat [*Compiler Compatibility:]]
+[def __examples [*Examples:]]
+[def __example [*Example:]]
+[def __type [*type:]]
+[def __returns [*Returns:]]
+[def __throws [*Throws:]]
+[def __remarks [*Remarks:]]
+[def __effects [*Effects:]]
+[def __post_conditions [*PostConditions:]]
+[def __pre_conditions [*PreConditions:]]
+[def __requires [*Requires:]]
+
+
+
+[/===============================================]
+[def __common_type `common_type`]
+
+
+[/===============================================]
+[def __ratio `ratio`]
+
+[def __ratio_add `ratio_add`]
+[def __ratio_subtract `ratio_subtract`]
+[def __ratio_multiply `ratio_multiply`]
+[def __ratio_divide `ratio_divide`]
+
+
+[def __ratio_equal `ratio_equal`]
+[def __ratio_not_equal `ratio_not_equal`]
+[def __ratio_less `ratio_less`]
+[def __ratio_less_equal `ratio_less_equal`]
+[def __ratio_greater `ratio_greater`]
+[def __ratio_greater_equal `ratio_greater_equal`]
+
+
+[def __atto `atto`]
+[def __femto `femto`]
+[def __pico `pico`]
+[def __nano `nano`]
+[def __micro `micro`]
+[def __milli `milli`]
+[def __centi `centi`]
+[def __deci `deci`]
+[def __deca `deca`]
+[def __hecto `hecto`]
+[def __kilo `kilo`]
+[def __mega `mega`]
+[def __giga `giga`]
+[def __tera `tera`]
+[def __peta `peta`]
+[def __exa `exa`]
+
+
+[/==================]
+
+
+[template chrono_conf[link_text] [link boost_chrono.reference.cpp0x.chrono_chrono_hpp.conf [link_text]]]
+
+[def __BOOST_CHRONO_INLINED [link boost_chrono.reference.cpp0x.chrono_hpp.conf.header_only `BOOST_CHRONO_INLINED`]]
+[def __BOOST_SYSTEM_INLINED `BOOST_SYSTEM_INLINED`]
+
+[def __BOOST_CHRONO_USES_STATIC_ASSERT [chrono_conf `BOOST_CHRONO_USES_STATIC_ASSERT`]]
+[def __BOOST_CHRONO_USES_MPL_ASSERT [chrono_conf `BOOST_CHRONO_USES_MPL_ASSERT`]]
+[def __BOOST_CHRONO_USES_ARRAY_ASSERT [chrono_conf `BOOST_CHRONO_USES_ARRAY_ASSERT`]]
+
+[def __BOOST_CHRONO_HAS_CLOCK_STEADY [link boost_chrono.reference.cpp0x.system_clocks_hpp.BOOST_CHRONO_HAS_CLOCK_STEADY `BOOST_CHRONO_HAS_CLOCK_STEADY`]]
+
+
+
+[template clock_concept_link[link_text] [link boost_chrono.reference.cpp0x.clock [link_text]]]
+[def __clock_req [clock_concept_link `Clock`] requirements]
+[def __Clock [clock_concept_link `Clock`]]
+[def __Clock_s [clock_concept_link `Clock`'s]]
+
+[def __duration [link boost_chrono.reference.cpp0x.duration_hpp.duration `duration`]]
+[def __durations [link boost_chrono.reference.cpp0x.duration_hpp.duration `duration`]s]
+[def __duration_s [link boost_chrono.reference.cpp0x.duration_hpp.duration `duration`]'s]
+
+[/==================]
+[def __time_point [link boost_chrono.reference.cpp0x.time_point_hpp.time_point `time_point`]]
+[def __time_points [link boost_chrono.reference.cpp0x.time_point_hpp.time_point `time_point`]s]
+[def __time_point_s [link boost_chrono.reference.cpp0x.time_point_hpp.time_point `time_point`]'s]
+
+[/==================]
+[def __system_clock [link boost_chrono.reference.cpp0x.system_clocks_hpp.system_clock `system_clock`]]
+[def __steady_clock [link boost_chrono.reference.cpp0x.system_clocks_hpp.steady_clock `steady_clock`]]
+[def __high_resolution_clock [link boost_chrono.reference.cpp0x.system_clocks_hpp.high_resolution_clock `high_resolution_clock`]]
+
+[/==================]
+
+[def __process_real_cpu_clock [link boost_chrono.reference.other_clocks.process_cpu_clocks_hpp.process_real_cpu_clock `process_real_cpu_clock`]]
+[def __process_system_cpu_clock [link boost_chrono.reference.other_clocks.process_cpu_clocks_hpp.process_system_cpu_clock `process_system_cpu_clock`]]
+[def __process_user_cpu_clock [link boost_chrono.reference.other_clocks.process_cpu_clocks_hpp.process_user_cpu_clock `process_user_cpu_clock`]]
+[def __process_cpu_clock [link boost_chrono.reference.other_clocks.process_cpu_clocks_hpp.process_cpu_clock `process_cpu_clock`]]
+[def __thread_clock [link boost_chrono.reference.other_clocks.thread_clock_hpp.thread_clock `thread_clock`]]
+
+[/==================]
+[def __duration_cast [link boost_chrono.reference.cpp0x.duration_hpp.duration_cast `duration_cast`]]
+[def __time_point_cast [link boost_chrono.reference.cpp0x.time_point_hpp.time_point_cast `time_point_cast`]]
+
+
+[def __nanoseconds [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `nanoseconds`]]
+[def __microseconds [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `microseconds`]]
+[def __milliseconds__ [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `milliseconds`]]
+[def __seconds [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `seconds`]]
+[def __minutes [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `minutes`]]
+[def __hours [link boost_chrono.reference.cpp0x.duration_hpp.duration_typedefs `hours`]]
+
+[def __common_type_spe [link boost_chrono.reference.cpp0x.duration_hpp.common_type_spe `common_type`]]
+
+[/==================]
+[def __treat_as_floating_point [link boost_chrono.reference.cpp0x.duration_hpp.traits.treat_as_floating_point `treat_as_floating_point`]]
+[def __duration_values [link boost_chrono.reference.cpp0x.duration_hpp.traits.duration_values `duration_values`]]
+[def __zero [link boost_chrono.reference.cpp0x.duration_hpp.traits.duration_values.zero `zero`]]
+[def __max [link boost_chrono.reference.cpp0x.duration_hpp.traits.duration_values.max `max`]]
+[def __min [link boost_chrono.reference.cpp0x.duration_hpp.traits.duration_values.min `min`]]
+
+
+
+[/==================]
+
+[def __duration_punct [link boost_chrono.reference.io.chrono_io_hpp.duration_punct `duration_punct`]]
+
+
+[/===============]
+[section Overview]
+[/===============]
+
+[:["What is time, then? If nobody asks me, I know; if I have to explain it to someone who has asked me, I do not know.]]
+[:[*['-- Augustine ]]]
+
+
+[/====================================]
+[heading How to Use This Documentation]
+[/====================================]
+
+This documentation makes use of the following naming and formatting conventions.
+
+* Code is in `fixed width font` and is syntax-highlighted.
+* Replaceable text that you will need to supply is in [~italics].
+* Free functions are rendered in the code font followed by `()`, as in `free_function()`.
+* If a name refers to a class template, it is specified like this: `class_template<>`; that is, it is in code font and its name is followed by `<>` to indicate that it is a class template.
+* If a name refers to a function-like macro, it is specified like this: `MACRO()`;
+ that is, it is uppercase in code font and its name is followed by `()` to indicate that it is a function-like macro. Object-like macros appear without the trailing `()`.
+* Names that refer to /concepts/ in the generic programming sense are specified in CamelCase.
+
+[note In addition, notes such as this one specify non-essential information that provides additional background or rationale.]
+
+Finally, you can mentally add the following to any code fragments in this document:
+
+ // Include all of Chrono files
+ #include <boost/chrono.hpp>
+ namespace bchrono=boost::chrono;
+
+[/=================]
+[section Motivation]
+[/=================]
+
+[heading Time]
+
+We all deal with time every day of our lives. We've intuitively known it since birth. Thus we are all very familiar with it and believe it to be a simple matter. The modeling of time in computer programs should be similarly simple. The unfortunate truth is that this perceived simplicity is only skin deep. Fortunately however, we do not need a terribly complicated solution to meet the bulk of our needs. However, overly simplistic solutions can be dangerous and inefficient, and won't adapt as the computer industry evolves.
+
+__Boost_Chrono__ aims to implement the new time facilities in C++0x, as proposed in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm [*N2661 - A Foundation to Sleep On]]. That document provides background and motivation for key design decisions and is the source of a good deal of information in this documentation.
+
+[/
+__Boost_Chrono__ proposes a solution that is precision neutral, with a very simple end user interface which supports multiple clocks, multiple precisions (both coarser and finer than we will ever need), separate types for points in time and time durations, efficiency, and compile time enforced safety.
+]
+
+[/
+In addition to the clocks provided by the standard proposal, __Boost_Chrono__ provides specific process clocks and a thread clock.
+]
+
+[/
+See [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm [*N2661 - A Foundation to Sleep On]] which is very informative and provides motivation for key design decisions for __common_type, __ratio and `chrono`. This documentation contains a lot of extracts from this document.
+]
+
+[heading Wall clock versus system and user time]
+
+To make the timing facilities of Boost.Chrono more generally useful, the library provides a number of clocks that are thin wrappers around the operating system's process time API, thereby allowing the extraction of wall clock time, user CPU time, and system CPU time of the process. Wall clock time is the sum of CPU time and system CPU time. (On POSIX-like systems, this relies on `times()`. On Windows, it relies on `GetProcessTimes()`.)
+
+[/
+It is also helpful if such timing information is broken down into real (wall clock) time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests.
+]
+
+[/
+3 concrete process clocks:
+
+# __process_real_cpu_clock,
+# __process_user_cpu_clock,
+# __process_system_cpu_clock
+
+providing a
+]
+
+[/__Boost_Chrono__ provides
+thin wrappers around the operating system's process timer API. For POSIX-like systems, that's the times() function, while for Windows, it's the GetProcessTimes() function.
+]
+
+[/These clocks capture the specific time unitarily. __Boost_Chrono__ provides also a clock __process_cpu_clock that captures the three times at once.
+]
+
+
+[endsect]
+
+[/==================]
+[section Description]
+[/==================]
+
+The __Boost_Chrono__ library provides:
+
+[heading Standard]
+
+* A means to represent time durations: managed by the generic __duration class . Examples of time durations include days, __minutes, __seconds and __nanoseconds, which can be represented with a fixed number of clock ticks per unit. All of these units of time duration are united with a generic interface by the __duration facility.
+* A type for representing points in time: __time_point. A __time_point represents an epoch plus or minus a __duration. The library leaves epochs unspecified. A __time_point is associated with a /clock/.
+* Several clocks, some of which may not be available on a particular platform: __system_clock, __steady_clock and __high_resolution_clock. A clock is a pairing of a __time_point and __duration, and a function which returns a __time_point representing ['now].
+
+[heading Other clocks]
+
+To make the timing facilities more generally useful, __Boost_Chrono__ provides a number of clocks that are thin wrappers around the operating system's time APIs, thereby allowing the extraction of wall clock time, user CPU time, system CPU time spent by the process,
+
+* __process_real_cpu_clock, captures wall clock CPU time spent by the current process.
+* __process_user_cpu_clock, captures user-CPU time spent by the current process.
+* __process_system_cpu_clock, captures system-CPU time spent by the current process.
+* A tuple-like class __process_cpu_clock, that captures real, user-CPU, and system-CPU process times together.
+* A __thread_clock thread steady clock giving the time spent by the current threrad( when supported by a platform).
+
+
+[/It is also helpful if such timing information is broken down into real (wall clock) time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests. process clocks provide a thin wrapper around the operating system's process timer API. For POSIX-like systems, that's the times() function, while for Windows, it's the GetProcessTimes() function.
+]
+
+Lastly, __Boost_Chrono__ includes [@http://www.boost.org/libs/typeof typeof] registration for __duration and __time_point to permit using emulated auto with C++03 compilers.
+
+[heading I/O]
+
+It provides I/O for __duration and __time_point. It builds on `<boost/ratio/ratio_io.hpp>` to provide readable and flexible formatting and parsing for types in `<boost/chrono.hpp>`. The __duration unit names can be customized through a new facet: __duration_punct.
+
+
+[heading Caveat emptor]
+
+The underlying clocks provided by operating systems are subject to many seemingly arbitrary policies and implementation irregularities. That's a polite way of saying they tend to be flakey, and each operating system or even each clock has its own cruel and unusual forms of flakiness. Don't bet the farm on their accuracy, unless you have become deeply familiar with exactly what the specific operating system is guaranteeing, which is often very little.
+
+
+[endsect]
+
+[endsect]
+
+
+[/==============================]
+[section:users_guide User's Guide]
+[/==============================]
+
+[/======================================]
+[section:getting_started Getting Started]
+[/======================================]
+
+[/======================================]
+[section:install Installing Chrono]
+[/======================================]
+
+[/=================================]
+[heading Getting __Boost_Chrono__ ]
+[/=================================]
+
+__Boost_Chrono__ is in the latest Boost release in the folder `/boost/chrono`. Documentation, tests and examples folder are at `boost/libs/chrono/`.
+
+You can also access the latest (unstable?) state from the [@https://svn.boost.org/svn/boost-trunk Boost trunk] directories boost/chrono and libs/chrono. Just go to [@http://svn.boost.org/trac/boost/wiki/BoostSubversion here] and follow the instructions there for anonymous SVN access.
+
+
+[/==========================================]
+[heading Where to install Boost.Chrono? ]
+[/==========================================]
+
+The simple way is to decompress (or checkout from SVN) the files in your BOOST_ROOT directory.
+
+
+[/=================================]
+[heading Building Boost.Chrono ]
+[/=================================]
+
+__Boost_Chrono__ can be configured as a header only library. When __BOOST_CHRONO_INLINED is defined the lib is header only library. Otherwise is not a header only library and you need to compile it before use.
+
+ bjam libs/chrono/build
+
+[/===================]
+[heading Requirements]
+[/===================]
+
+__Boost_Chrono__ depends on some new traits in [*Boost.TypeTraits] which have been added on Boost 1.45.
+
+In particular, __Boost_Chrono__ depends on:
+
+[variablelist
+[
+ [[@http://www.boost.org/libs/config [*Boost.Config]]] [for configuration purposes, ...]
+]
+[
+ [[@http://www.boost.org/libs/exception [*Boost.Exception]]] [for throw_exception, ...]
+]
+[
+ [[@http://www.boost.org/libs/integer [*Boost.Integer]]] [for cstdint conformance, ...]
+]
+[
+ [[@http://www.boost.org/libs/mpl [*Boost.MPL]]] [for MPL Assert and bool, logical ...]
+]
+[
+ [[@http://www.boost.org/libs/operators [*Boost.Operators]]] [for operators, ...]
+]
+[
+ [[@http://www.boost.org/libs/ratio [*Boost.Ratio]]] [for ratio, milli, micro, ...]
+]
+[
+ [[@http://www.boost.org/libs/system [*Boost.System]]] [for error_code, ...]
+]
+[
+ [[@http://www.boost.org/libs/type_traits [*Boost.TypeTraits]]] [for is_base, is_convertible, common_type, ...]
+]
+[
+ [[@http://www.boost.org/libs/utility [*Boost.Utility/EnableIf]]] [for enable_if, ...]
+]
+]
+
+
+[/=========================================================]
+[heading Building an executable that uses Boost.Chrono ]
+[/=========================================================]
+
+In addition to link with the __Boost_Chrono__ library you need also to link with the [*Boost.System] library.
+Once [*Boost.System] will be configurable to be a header only using __BOOST_SYSTEM_INLINED you will no need to link with.
+
+
+[/=========================]
+[heading Exception safety ]
+[/=========================]
+
+All functions in the library are exception-neutral and provide strong guarantee of exception safety as long as the underlying parameters provide it.
+
+
+[/=====================]
+[heading Thread safety ]
+[/=====================]
+
+All functions in the library are thread-unsafe except when noted explicitly.
+
+As Boost.Chrono doesn't use mutable global variables the thread safety analysis is limited to the access to each instance variable. It is not thread safe to use a function that modifies the access to a user variable if another can be reading or writing it.
+
+
+[/========================]
+[heading Tested compilers ]
+[/========================]
+
+The implementation will eventually work with most C++03 conforming compilers.
+Current version has been tested on:
+
+Windows with
+
+* MSVC 10.0
+
+Cygwin 1.5 with
+
+* GCC 3.4.4
+
+Cygwin 1.7 with
+
+* GCC 4.3.4
+
+MinGW with
+
+* GCC 4.4.0
+* GCC 4.5.0
+* GCC 4.5.0 -std=c++0x
+* GCC 4.6.0
+* GCC 4.6.0 -std=c++0x
+
+Initial versions were tested on:
+
+MacOS with GCC 4.2.4 (Some test are needed for the specific Mac files).
+
+Ubuntu Linux with GCC 4.2.4
+
+[note Please let us know how this works on other platforms/compilers.]
+
+[note Please send any questions, comments and bug reports to boost <at> lists <dot> boost <dot> org.]
+
+[endsect]
+[/====================]
+[section Hello World! ]
+[/====================]
+
+If all you want to do is to time a program's execution, here is a complete program (stopclock_example.cpp):
+
+ #include <boost/chrono.hpp>
+ #include <cmath>
+
+ int main()
+ {
+ bchrono::system_clock::time_point start = bchrono::system_clock::now();
+
+ for ( long i = 0; i < 10000000; ++i )
+ std::sqrt( 123.456L ); // burn some time
+
+ bchrono::__duration<double> sec = bchrono::system_clock::now() - start;
+ std::cout << "took " << sec.count() << " seconds\n";
+ return 0;
+ }
+
+Output was:
+
+ took 0.832 seconds
+
+
+[endsect]
+
+[endsect]
+
+
+[section Tutorial]
+
+[section Duration]
+
+The __duration is the heart of this library. The interface that the user will see in everyday use is nearly identical to that of [*Boost.DateTime] time __duration_s authored by Jeff Garland, both in syntax and in behavior. This has been a very popular boost library for 7 years. There is an enormous positive history with this interface.
+
+The library consists of six units of time __duration:
+
+* __hours
+* __minutes
+* __seconds
+* __milliseconds__
+* __microseconds
+* __nanoseconds
+
+These units were chosen as a subset of the boost library because they are the most common units used when sleeping, waiting on a condition variable, or waiting to obtain the lock on a mutex. Each of these units is nothing but a thin wrapper around a signed integral count. That is, when you construct __minutes`(3)`, all that happens is a `3` is stored inside of minutes. When you construct __microseconds`(3)`, all that happens is a `3` is stored inside of __microseconds.
+
+The only context in which these different types differ is when being converted to one another. At this time, unit-specific compile-time conversion constants are used to convert the source unit to the target unit. Only conversions from coarser units to finer units are allowed (in boost). This restriction ensures that all conversions are always exact. That is, __microseconds can always represent any value __minutes has.
+
+In [*Boost.DateTime], these units are united via inheritance. __Boost_Chrono__ instead unites these units through the class template __duration. That is, in __Boost_Chrono__ all six of the above units are nothing but typedefs to different instantiations of __duration. This change from Boost.DateTime has a far reaching positive impact, while not changing the syntax of the everyday use at all.
+
+The most immediate positive impact is that the library can immediately generate any unit, any precision it needs. This is sometimes necessary when doing comparisons or arithmetic between __duration_s of differing precision, assuming one wants the comparison and arithmetic to be exactly correct.
+
+A secondary benefit is that by publishing the class template __duration interface, user code can very easily create __duration_s with any precision they desire. The __ratio utility is used to specify the precision, so as long as the precision can be expressed by a rational constant with respect to seconds, this framework can exactly represent it (one third of a second is no problem, and neither is one third of a __femto second). All of this utility and flexibility comes at no cost just by making use of the no-run-time-overhead __ratio facility.
+
+In Boost.DateTime, __hours does not have the same representation as __nanoseconds. The former is usually represented with a `long` whereas a `long long` is required for the latter. The reason for this is simply range. You don't need many hours to cover an extremely large range of time. But this isn't true of nanoseconds. Being able to reduce the sizeof overhead for some units when possible, can be a significant performance advantage.
+
+__Boost_Chrono__ continues, and generalizes that philosophy. Not only can one specify the precision of a __duration, one can also specify its representation. This can be any integral type, or even a floating point type. Or it can be a user-defined type which emulates an arithmetic type. The six predefined units all use signed integral types as their representation. And they all have a minimum range of +/- 292 years. __nanoseconds needs 64 bits to cover that range. __hours needs only 23 bits to cover that range.
+
+
+[section So What Exactly is a `duration` and How Do I Use One?]
+
+A __duration has a representation and a tick period (precision).
+
+ template <class Rep, class Period = __ratio<1> > class duration;
+
+The representation is simply any arithmetic type, or an emulation of such a type. The representation stores a count of ticks. This count is the only data member stored in a __duration. If the representation is floating point, it can store fractions of a tick to the precision of the representation. The tick period is represented by a __ratio and is encoded into the __duration's type, instead of stored. The tick period only has an impact on the behavior of the __duration when a conversion between different __duration's is attempted. The tick period is completely ignored when simply doing arithmetic among like __duration_s.
+
+__example
+
+ typedef bchrono::__duration<long, boost::ratio<60> > minutes;
+ minutes m1(3); // m1 stores 3
+ minutes m2(2); // m2 stores 2
+ minutes m3 = m1 + m2; // m3 stores 5
+
+ typedef bchrono::__duration<long long, boost::micro> microseconds;
+ microseconds us1(3); // us1 stores 3
+ microseconds us2(2); // us2 stores 2
+ microseconds us3 = us1 + us2; // us3 stores 5
+
+ microseconds us4 = m3 + us3; // us4 stores 300000005
+
+In the final line of code above, there is an implicit conversion from minutes to microseconds, resulting in a relatively large number of microseconds.
+
+If you need to access the tick count within a __duration, there is a member `count()` which simply returns the stored tick count.
+
+ long long tc = us4.count(); // tc is 300000005
+
+These __duration_s have very simple, very predictable, and very observable behavior. After all, this is really nothing but the time tested interface of Jeff's boost time __duration library (unified with templates instead of inheritance).
+
+[endsect]
+
+[section What Happens if I Assign `m3 + us3` to `minutes` Instead of `microseconds`?]
+
+ minutes m4 = m3 + us3;
+
+It won't compile. The rationale is that implicit truncation error should not be allowed to happen. If this were to compile, then `m4` would hold `5`, the same value as `m3`. The value associated with `us3` has been effectively ignored. This is similar to the problem of assigning a double to an `int`: the fractional part gets silently discarded.
+[endsect]
+
+[section But what if the truncation behavior is what I want to do?]
+
+There is a __duration_cast facility to explicitly ask for this behavior:
+
+ minutes m4 = bchrono::__duration_cast<minutes>(m3 + us3); // m4.count() == 5
+
+In general, one can perform __duration arithmetic at will. If __duration_cast isn't used, and it compiles, the arithmetic is exact. Any place one wants to override this exact arithmetic behavior, __duration_cast can be used to explicitly specify that desire. The __duration_cast has the same efficiency as the implicit conversion, and will even be exact as often as it can.
+
+You can use __duration_cast`<>` to convert the __duration into whatever units you desire. This facility will round down (truncate) if an exact conversion is not possible. For example:
+
+ bchrono::__nanoseconds start;
+ bchrono::__nanoseconds end;
+ typedef bchrono::__milliseconds__ ms;
+ ms d = bchrono::__duration_cast<ms>(end - start);
+
+ // d now holds the number of milliseconds from start to end.
+
+ std::cout << ms.count() << "ms\n";
+
+We can convert to __nanoseconds, or some integral-based duration which __nanoseconds will always exactly convert to, then __duration_cast`<>` is unnecessary:
+
+ typedef bchrono::__nanoseconds ns;
+ ns d = end - start;
+ std::cout << ns.count() << "ns\n";
+
+If you need seconds with a floating point representation you can also eliminate the __duration_cast`<>`:
+
+ typedef bchrono::__duration<double> sec; // seconds, stored with a double
+ sec d = end - start;
+ std::cout << sec.count() << "s\n";
+
+If you're not sure if you need __duration_cast`<>` or not, feel free to try it without. If the conversion is exact, or if the destination has a floating point representation, it will compile: else it will not compile.
+
+
+If you need to use __duration_cast`<>`, but want to round up, instead of down when the conversion is inexact, here is a handy little helper function to do so. Writing it is actually a good starter project for understanding __Boost_Chrono__:
+
+ template <class ToDuration, class Rep, class Period>
+ ToDuration
+ round_up(bchrono::__duration<Rep, Period> d)
+ {
+ // first round down
+ ToDuration result = bchrono::__duration_cast<ToDuration>(d);
+ if (result < d) // comparisons are *always* exact
+ ++result; // increment by one tick period
+ return result;
+ }
+
+ typedef bchrono::__milliseconds__ ms;
+ ms d = round_up<ms>(end - start);
+ // d now holds the number of milliseconds from start to end, rounded up.
+ std::cout << ms.count() << "ms\n";
+
+[endsect]
+
+[section Trafficking in Floating Point Durations]
+
+I don't want to deal with writing `duration_cast` all over the place. I'm content with the precision of my floating point representation
+
+Not a problem. When the destination of a conversion has floating point representation, all conversions are allowed to happen implicitly.
+
+ typedef bchrono::__duration<double, __ratio<60> > dminutes;
+ dminutes dm4 = m3 + us3; // dm4.count() == 5.000000083333333
+
+[endsect]
+
+[section How Expensive is All of this?]
+
+If you were writing these conversions by hand, you could not make it more efficient. The use of __ratio ensures that all conversion constants are simplified as much as possible at compile time. This usually results in the numerator or denominator of the conversion factor simplifying to `1`, and being subsequently ignored in converting the run time values of the tick counts.
+
+[endsect]
+
+[section How Complicated is it to Build a Function Taking a `duration` Parameter?]
+
+There are several options open to the user:
+
+* If the author of the function wants to accept any __duration, and is willing to work in floating point __duration_s, he can simply use any floating point __duration as the parameter:
+
+ void f(bchrono::duration<double> d) // accept floating point seconds
+ {
+ // d.count() == 3.e-6 when passed bchrono::microseconds(3)
+ }
+
+ f(bchrono::microseconds(3));
+
+* If the author of the function wants to traffic only in integral __duration_s, and is content with handling nothing finer than say nanoseconds (just as an example), he can simply specify nanoseconds as the parameter:
+
+ void f(bchrono::nanoseconds d)
+ {
+ // d.count() == 3000 when passed bchrono::microseconds(3)
+ }
+
+ f(bchrono::microseconds(3));
+
+In this design, if the client wants to pass in a floating point __duration, or a __duration of finer precision than nanoseconds, then the client is responsible for choosing his own rounding mode in the conversion to nanoseconds.
+
+ bchrono::__duration<double> s(1./3); // 1/3 of a second
+ f(bchrono::duration_cast<bchrono::nanoseconds>(s)); // round towards zero in conversion to nanoseconds
+
+In the example above, the client of f has chosen "round towards zero" as the desired rounding mode to nanoseconds. If the client has a __duration that won't exactly convert to nanoseconds, and fails to choose how the conversion will take place, the compiler will refuse the call:
+
+ f(s); // does not compile
+
+* If the author of the function wants to accept any __duration, but wants to work with integral representations and wants to control the rounding mode internally, then he can template the function:
+
+ template <class Rep, class Period>
+ void f(bchrono::__duration<Rep, Period> d)
+ {
+ // convert d to nanoseconds, rounding up if it is not an exact conversion
+ bchrono::nanoseconds ns = bchrono::duration_cast<bchrono::nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ // ns.count() == 333333334 when passed 1/3 of a floating point second
+ }
+
+ f(bchrono::__duration<double>(1./3));
+
+* If the author in the example does not want to accept floating point based __duration_s, he can enforce that behavior like so:
+
+ template <class Period>
+ void f(bchrono::__duration<long long, Period> d)
+ {
+ // convert d to nanoseconds, rounding up if it is not an exact conversion
+ bchrono::nanoseconds ns = bchrono::duration_cast<nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ // ns.count() == 333333334 when passed 333333333333 picoseconds
+ }
+ // About 1/3 of a second worth of picoseconds
+ f(bchrono::__duration<long long, boost::pico>(333333333333));
+
+Clients with floating point __duration_s who want to use f will now have to convert to an integral __duration themselves before passing the result to f.
+
+In summary, the author of f has quite a bit of flexibility and control in the interface he wants to provide his clients with, and easy options for manipulating that __duration internal to his function.
+[endsect]
+
+[section Can durations overflow?]
+
+This depend on the representation. The default typedefs uses a representation that don't handle overflows. The user can define his own representation that manage overflow as required by its application.
+
+[endsect]
+[endsect]
+
+[section Clocks]
+
+While __duration_s only have precision and representation to concern themselves, clocks and __time_point_s are intimately related and refer to one another. Because clocks are simpler to explain, we will do so first without fully explaining __time_point_s. Once clocks are introduced, it will be easier to then fill in what a __time_point is.
+
+A clock is a concept which bundles 3 things:
+
+# A concrete __duration type.
+# A concrete __time_point type.
+# A function called now() which returns the concrete __time_point.
+
+The standard defines tree system-wide clocks that are associated to the computer time.
+
+* __system_clock represents system-wide realtime clock that can be synchronized with an external clock.
+
+* __steady_clock can not be changed explicitly and the time since the initial epoch increase in a steady way.
+
+* __high_resolution_clock intend to use the system-wide clock provided by the platform with the higest resolution.
+
+__Boost_Chrono__ provides them when supported by the underlying platform. A given platform may not be able to supply all three of these clocks.
+
+The library adds some clocks that are specific to a process or a thread, that is there is a clock per process or per thread.
+
+
+The user is also able to easily create more clocks.
+
+Given a clock named Clock, it will have:
+
+ class Clock {
+ public:
+ typedef an arithmetic-like type rep;
+ typedef an instantiation of ratio period;
+ typedef bchrono::__duration<rep, period> __duration;
+ typedef bchrono::__time_point<Clock> time_point;
+ static constexpr bool is_steady = true or false;
+
+ static time_point now();
+ };
+
+One can get the current time from Clock with:
+
+ Clock::time_point t1 = Clock::now();
+
+And one can get the time __duration between two __time_point_s associated with Clock with:
+
+ Clock::duration d = Clock::now() - t1;
+
+And one can specify a past or future __time_point with:
+
+ Clock::time_point t2 = Clock::now() + d;
+
+Note how even if a particular clock becomes obsolete, the next clock in line will have the same API. There is no new learning curve to come up. The only source code changes will be simply changing the type of the clock. The same __duration and __time_point framework continues to work as new clocks are introduced. And multiple clocks are safely and easily handled within the same program.
+
+
+[endsect]
+
+
+[section Time Point]
+
+A __time_point represents a point in time, as opposed to a __duration of time. Another way of saying the same thing, is that a __time_point represents an epoch plus or minus a __duration. Examples of __time_point_s include:
+
+* 3 minutes after the computer booted.
+* 03:14:07 UTC on Tuesday, January 19, 2038
+* 20 milliseconds after I started that timer.
+
+In each of the examples above, a different epoch is implied. Sometimes an epoch has meaning for several millennia. Other times the meaning of an epoch is lost after a while (such as the start of a timer, or when the computer booted). However, if two __time_point_s are known to share the same epoch, they can be subtracted, yielding a valid __duration, even if the definition of the epoch no longer has meaning.
+
+In __Boost_Chrono__, an epoch is a purely abstract and unspecified concept. There is no type representing an epoch. It is simply an idea that relates (or doesn't) __time_point_s to a clock, and in the case that they share a clock, __time_point_s to one another. __time_point_s associated with different clocks are generally not interoperable unless the relationship between the epochs associated with each clock is known.
+
+[section So What Exactly is a `time_point` and How Do I Use One?]
+
+A __time_point has a clock and a __duration.
+
+ template <class Clock, class Duration = typename Clock::duration> class __time_point;
+
+The __time_point's clock is not stored. It is simply embedded into the __time_point's type and serves two purposes:
+
+# Because __time_point_s originating from different clocks have different types, the compiler can be instructed to fail if incompatible __time_point_s are used in inappropriate ways.
+# Given a __time_point, one often needs to compare that __time_point to "now". This is very simple as long as the __time_point knows what clock it is defined with respect to.
+
+A __time_point's __duration is stored as the only data member of the __time_point. Thus __time_point_s and their corresponding __duration have exactly the same layout. But they have very different meanings. For example, it is one thing to say I want to sleep for 3 minutes. It is a completely different thing to say I want to sleep until 3 minutes past the time I started that timer (unless you just happened to start that timer now). Both meanings (and options for sleeping) have great practical value in common use cases for sleeping, waiting on a condition variable, and waiting for a mutex's lock. These same concepts and tools are found (for example) in Ada.
+
+A timer example:
+
+ void f()
+ {
+ bchrono::steady_clock::time_point start = bchrono::steady_clock::now();
+ g();
+ h();
+ __duration<double> sec = bchrono::steady_clock::now() - start;
+ cout << "f() took " << sec.count() << " seconds\n";
+ }
+
+Note that if one is using the __duration between two clock __time_point_s in a way where the precision of the __duration matters, it is good practice to convert the clock's __duration to a known __duration. This insulates the code from future changes which may be made to the clock's precision in the future. For example __steady_clock could easily be based on the clock speed of the cpu. When you upgrade to a faster machine, you do not want your code that assumed a certain tick period of this clock to start experiencing run time failures because your timing code has silently changed meaning.
+
+A delay loop example:
+
+ // delay for at least 500 nanoseconds:
+ auto go = bchrono::steady_clock::now() + bchrono::nanoseconds(500);
+ while (bchrono::steady_clock::now() < go)
+ ;
+
+The above code will delay as close as possible to half a microsecond, no matter what the precision of __steady_clock is. The more precise __steady_clock becomes, the more accurate will be the delay to 500 nanoseconds.
+
+
+[endsect]
+
+
+
+[/
+[section How to Define a Thread Clock]
+
+On posix systems for which the macro _POSIX_THREAD_CPUTIME is defined we can get the time associated to a specific thread.
+
+ class thread_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::__time_point<thread_clock> time_point;
+ static constexpr bool is_steady = BOOST_CHRONO_THREAD_CLOCK_IS_STEADY;
+
+ static time_point now( ) {
+ // get the current thread
+ pthread_t pth=pthread_self(void);
+ // get the clock_id associated to the current thread
+ clockid_t clock_id;
+ pthread_getcpuclockid(pth, clock_id);
+ // get the timespec associated to the thread clock
+ struct timespec ts;
+ if ( ::clock_gettime( clock_id, &ts ) )
+ {
+ boost::throw_exception(
+ system::system_error( errno, system::system_category, "chrono::thread_clock" ));
+ }
+
+ // transform to nanoseconds
+ return time_point(duration(
+ static_cast<thread_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec));
+
+ }
+ static time_point now( system::error_code & ec ) {
+ // get the current thread
+ pthread_t pth=pthread_self(void);
+ // get the clock_id associated to the current thread
+ clockid_t clock_id;
+ pthread_getcpuclockid(pth, clock_id);
+ // get the timespec associated to the thread clock
+ struct timespec ts;
+ if ( ::clock_gettime( clock_id, &ts ) )
+ {
+ ec.assign( errno, system::system_category );
+ return time_point();
+ }
+ ec.clear();
+ // transform to nanoseconds
+ return time_point(duration(
+ static_cast<thread_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec));
+ }
+ };
+
+[endsect]
+]
+
+
+[endsect]
+
+[section Specific Clocks]
+[section system_clock]
+
+__system_clock is useful when you need to correlate the time with a known epoch so you can convert it to a calendar time. Note the specific functions in the __system_clock class.
+
+
+[endsect]
+[section steady_clock]
+
+__steady_clock is useful when you need to wait for a specific amount of time. __steady_clock time can not be reset. As other steady clocks, it is based on the processor tick.
+
+Next is presented a polling solution, which will however be too inefficient:
+
+ bchrono::__steady_clock::time_point start= chrono::__steady_clock::now();
+ bchrono::__steady_clock::duration delay= chrono::seconds(5);
+ while (bchrono::__steady_clock::now() - start <= delay) {}
+
+[endsect]
+
+[section high_resolution_clock]
+
+When available, __high_resolution_clock is usualy more expensive than the other system-wide clocks, so they are used only when the provided resolution is required to the application.
+
+[endsect]
+
+[section process_cpu_clock]
+
+Process and thread clocks are used usualy to measure the time spent by code blocks, as a basic time-spent profiling of different blocks of code (Boost.Stopwatch is clear example of this use).
+
+
+
+[endsect]
+
+[section thread_clock]
+
+You can use __thread_clock whenever you want to measure the time spent by the current thread. For example:
+
+ bchrono::__thread_clock::time_point start=bchrono::__thread_clock::now();
+ //do something
+
+ typedef bchrono::__milliseconds__ ms;
+ ms d = bchrono::__thread_clock::now() - start;
+ // d now holds the number of milliseconds from start to end.
+ std::cout << ms.count() << "ms\n";
+
+If you need seconds with a floating point representation you can do:
+
+ typedef bchrono::__duration<double> sec; // seconds, stored with a double
+ sec d = end - start;
+ std::cout << sec.count() << "s\n";
+
+If you would like to programmatically inspect `__thread_clock::duration`, you can get the representation type with `__thread_clock::rep`, and the tick period with `__thread_clock::period` (which should be a type __ratio which has nested values `__ratio::num` and `__ratio::den`). The tick period of __thread_clock is `__thread_clock::period::num / __thread_clock::period::den` seconds: 1/1000000000 in this case (`1` billionth of a second), stored in a `long long`.
+
+[endsect]
+[endsect]
+
+[section I/O]
+
+Any __duration can be streamed out to a `basic_ostream`. The run time value of the __duration is formatted according to the rules and current format settings for __duration`::rep`. This is followed by a single space and then the compile time unit name of the __duration. This unit name is built on the string returned from `ratio_string<>` and the data used to construct the __duration_punct which was inserted into the stream's locale. If a __duration_punct has not been inserted into the stream's locale, a default constructed __duration_punct will be added to the stream's locale.
+
+__duration unit names come in two varieties: long and short. The default constructed __duration_punct provides names in the long format. These names are English descriptions. Other languages are supported by constructing a __duration_punct with the proper spellings for "hours", "minutes" and "seconds", and their abbreviations (for the short format). The short or long format can be easily chosen by streaming a `duration_short()` or `duration_long()` manipulator respectively.
+
+A __time_point is formatted by outputting its internal __duration followed by a string that describes the __time_point`::clock` epoch. This string will vary for each distinct clock, and for each implementation of the supplied clocks.
+
+__example
+
+ #include <iostream>
+ #include <boost/chrono/chrono_io.hpp>
+
+ int main()
+ {
+ using namespace std;
+ using namespace boost;
+ namespace bchrono=boost::chrono;
+
+ cout << "milliseconds(3) + microseconds(10) = "
+ << bchrono::milliseconds(3) + bchrono::microseconds(10) << '\n';
+
+ cout << "hours(3) + minutes(10) = "
+ << bchrono::hours(3) + bchrono::minutes(10) << '\n';
+
+ typedef bchrono::duration<long long, boost::ratio<1, 2500000000> > ClockTick;
+ cout << "ClockTick(3) + bchrono::nanoseconds(10) = "
+ << ClockTick(3) + bchrono::nanoseconds(10) << '\n';
+
+ cout << "\nSet cout to use short names:\n";
+ cout << bchrono::duration_short;
+
+ cout << "milliseconds(3) + microseconds(10) = "
+ << bchrono::milliseconds(3) + bchrono::microseconds(10) << '\n';
+
+ cout << "hours(3) + minutes(10) = "
+ << bchrono::hours(3) + bchrono::minutes(10) << '\n';
+
+ cout << "ClockTick(3) + nanoseconds(10) = "
+ << ClockTick(3) + bchrono::nanoseconds(10) << '\n';
+
+ cout << "\nsystem_clock::now() = " << bchrono::system_clock::now() << '\n';
+ #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
+ cout << "steady_clock::now() = " << bchrono::steady_clock::now() << '\n';
+ #endif
+ cout << "\nSet cout to use long names:\n"
+ << bchrono::duration_long
+ << "high_resolution_clock::now() = "
+ << bchrono::high_resolution_clock::now() << '\n';
+ return 0;
+ }
+
+The output could be
+
+ milliseconds(3) + microseconds(10) = 3010 microseconds
+ hours(3) + minutes(10) = 190 minutes
+ ClockTick(3) + nanoseconds(10) = 56 [1/5000000000]seconds
+
+ Set cout to use short names:
+ milliseconds(3) + microseconds(10) = 3010 us
+ hours(3) + minutes(10) = 190 m
+ ClockTick(3) + nanoseconds(10) = 56 [1/5000000000]s
+
+ system_clock::now() = 1284923218301231 us since Jan 1, 1970
+ steady_clock::now() = 18588963676886 ns since boot
+
+ Set cout to use long names:
+ high_resolution_clock::now() = 18588963785548 nanoseconds since boot
+
+Parsing a __duration follows rules analogous to the __duration converting constructor. A value and a unit (short or long) are read from the `basic_istream`. If the __duration has an integral representation, then the value parsed must be exactly representable in the target __duration (after conversion to the target __duration units), else `failbit` is set. __duration_s based on floating point representations can be parsed using any units that do not cause overflow.
+
+For example a stream containing "5000 milliseconds" can be parsed into seconds, but if the stream contains "5001 milliseconds", parsing into `seconds` will cause `failbit` to be set.
+
+__example
+
+ #include <boost/chrono/chrono_io.hpp>
+ #include <sstream>
+ #include <cassert>
+
+ int main()
+ {
+ using namespace std;
+ namespace bchrono=boost::chrono;
+
+ istringstream in("5000 milliseconds 4000 ms 3001 ms");
+ bchrono::seconds d(0);
+ in >> d;
+ assert(in.good());
+ assert(d == seconds(5));
+ in >> d;
+ assert(in.good());
+ assert(d == seconds(4));
+ in >> d;
+ assert(in.fail());
+ assert(d == seconds(4));
+
+ return 0;
+ }
+
+
+Note that a __duration failure may occur late in the parsing process. This means that the characters making up the failed parse in the stream are usually consumed despite the failure to successfully parse.
+
+Parsing a __time_point involves first parsing a __duration and then parsing the epoch string. If the epoch string does not match that associated with `time_point::clock` then failbit will be set.
+
+__example
+
+ #include <boost/chrono/chrono_io.hpp>
+ #include <sstream>
+ #include <iostream>
+ #include <cassert>
+
+ int main()
+ {
+ using namespace std;
+ namespace bchrono=boost::chrono;
+
+ bchrono::high_resolution_clock::time_point t0 = bchrono::high_resolution_clock::now();
+ stringstream io;
+ io << t0;
+ bchrono::high_resolution_clock::time_point t1;
+ io >> t1;
+ assert(!io.fail());
+ cout << io.str() << '\n';
+ cout << t0 << '\n';
+ cout << t1 << '\n';
+ bchrono::high_resolution_clock::time_point t = bchrono::high_resolution_clock::now();
+ cout << t << '\n';
+
+ cout << "That took " << t - t0 << '\n';
+ cout << "That took " << t - t1 << '\n';
+
+ return 0;
+ }
+
+The output could be:
+
+ 50908679121461 nanoseconds since boot
+ That took 649630 nanoseconds
+
+Here's a simple example to find out how many hours the computer has been up (on this platform):
+
+ #include <boost/chrono/chrono_io.hpp>
+ #include <iostream>
+
+ int main()
+ {
+ using namespace std;
+ using namespace boost;
+ namespace bchrono=boost::chrono;
+
+ typedef bchrono::time_point<bchrono::steady_clock, bchrono::duration<double, boost::ratio<3600> > > T;
+ T tp = bchrono::steady_clock::now();
+ std::cout << tp << '\n';
+ return 0;
+ }
+
+The output could be:
+
+ 17.8666 hours since boot
+
+[endsect]
+
+[endsect]
+[/===============]
+[section Examples]
+[/===============]
+
+
+
+[section Duration]
+
+[/===============]
+[section How you Override the Duration's Default Constructor]
+
+Next follows how you override the duration's default constructor to do anything you want (in this case set it to zero). All we need to do is to change the representation
+
+ namespace I_dont_like_the_default_duration_behavior {
+
+ template <class R>
+ class zero_default
+ {
+ public:
+ typedef R rep;
+
+ private:
+ rep rep_;
+ public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default& operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default& operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default& operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default& operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator< (zero_default x, zero_default y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(zero_default x, zero_default y) {return !(y < x);}
+ friend bool operator> (zero_default x, zero_default y) {return y < x;}
+ friend bool operator>=(zero_default x, zero_default y) {return !(x < y);}
+ };
+
+ typedef bchrono::__duration<zero_default<long long>, boost::nano > nanoseconds;
+ typedef bchrono::__duration<zero_default<long long>, boost::micro > microseconds;
+ typedef bchrono::__duration<zero_default<long long>, boost::milli > milliseconds;
+ typedef bchrono::__duration<zero_default<long long> > seconds;
+ typedef bchrono::__duration<zero_default<long long>, boost::ratio<60> > minutes;
+ typedef bchrono::__duration<zero_default<long long>, boost::ratio<3600> > hours;
+ }
+
+Usage
+
+ using namespace I_dont_like_the_default_duration_behavior;
+
+ milliseconds ms;
+ std::cout << ms.count() << '\n';
+
+['See the source file [@../../example/i_dont_like_the_default_duration_behavior.cpp example/i_dont_like_the_default_duration_behavior.cpp]]
+
+[endsect]
+[/
+[/=========================]
+[section runtime_resolution]
+
+This example shows how to handle duration with resolution not known until run time
+
+ class duration
+ {
+ public:
+ typedef long long rep;
+ private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+ public:
+ typedef bchrono::duration<double, boost::nano> tonanosec;
+
+ duration() {} // = default;
+ explicit duration(const rep& r) : rep_(r) {}
+
+ // conversions
+ explicit duration(const tonanosec& d)
+ : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
+
+ // explicit
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ // observer
+
+ rep count() const {return rep_;}
+
+ // arithmetic
+
+ duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ duration operator+() const {return *this;}
+ duration operator-() const {return duration(-rep_);}
+ duration& operator++() {++rep_; return *this;}
+ duration operator++(int) {return duration(rep_++);}
+ duration& operator--() {--rep_; return *this;}
+ duration operator--(int) {return duration(rep_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(duration x, duration y) {return !(y < x);}
+ friend bool operator> (duration x, duration y) {return y < x;}
+ friend bool operator>=(duration x, duration y) {return !(x < y);}
+ };
+
+['See the source file [@../../example/runtime_resolution.cpp here]]
+
+[endsect]
+]
+[/================]
+[section Saturating]
+
+A "saturating" signed integral type is developed. This type has +/- infinity and a nan (like IEEE floating point) but otherwise obeys signed integral arithmetic. This class is subsequently used as the rep in bchrono::__duration to demonstrate a duration class that does not silently ignore overflow.
+
+['See the source file [@../../example/saturating.cpp example/saturating.cpp]]
+
+
+[endsect]
+
+
+
+[/==================]
+[section xtime Conversions]
+
+Example round_up utility: converts d to To, rounding up for inexact conversions
+Being able to *easily* write this function is a major feature!
+
+ #include <boost/chrono.hpp>
+ #include <boost/type_traits.hpp>
+
+ #include <iostream>
+
+ namespace bchrono=boost::chrono;
+
+ template <class To, class Rep, class Period>
+ To
+ round_up(bchrono::duration<Rep, Period> d)
+ {
+ To result = bchrono::duration_cast<To>(d);
+ if (result < d)
+ ++result;
+ return result;
+ }
+
+Demonstrate interaction with xtime-like facility:
+
+
+ struct xtime
+ {
+ long sec;
+ unsigned long usec;
+ };
+
+ template <class Rep, class Period>
+ xtime
+ to_xtime_truncate(bchrono::__duration<Rep, Period> d)
+ {
+ xtime xt;
+ xt.sec = static_cast<long>(bchrono::__duration_cast<__seconds>(d).count());
+ xt.usec = static_cast<long>(bchrono::__duration_cast<__microseconds>(d - __seconds(xt.sec)).count());
+ return xt;
+ }
+
+ template <class Rep, class Period>
+ xtime
+ to_xtime_round_up(bchrono::__duration<Rep, Period> d)
+ {
+ xtime xt;
+ xt.sec = static_cast<long>(bchrono::__duration_cast<__seconds>(d).count());
+ xt.usec = static_cast<unsigned long>(round_up<bchrono::__microseconds>(d - bchrono::__seconds(xt.sec)).count());
+ return xt;
+ }
+
+ microseconds
+ from_xtime(xtime xt)
+ {
+ return bchrono::__seconds(xt.sec) + bchrono::__microseconds(xt.usec);
+ }
+
+ void print(xtime xt)
+ {
+ std::cout << '{' << xt.sec << ',' << xt.usec << "}\n";
+ }
+
+Usage
+
+ xtime xt = to_xtime_truncate(seconds(3) + bchrono::__milliseconds__(251));
+ print(xt);
+ bchrono::milliseconds ms = bchrono::__duration_cast<bchrono::__milliseconds__>(from_xtime(xt));
+ std::cout << ms.count() << " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(bchrono::seconds(3) + __nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(bchrono::seconds(3) + __nanoseconds(999));
+ print(xt);
+
+
+['See the source file [@../../example/xtime.cpp here]]
+
+[endsect]
+
+
+[endsect]
+[section Clocks]
+
+[/==================]
+[section Cycle count]
+
+Users can easily create their own clocks, with both points in time and time durations which have a representation and precision of their own choosing. For example if there is a hardware counter which simply increments a count with each cycle of the cpu, one can very easily build clocks, time points and durations on top of that, using only a few tens of lines of code. Such systems can be used to call the time-sensitive threading API's such as sleep, wait on a condition variable, or wait for a mutex lock. The API proposed herein is not sensitive as to whether this is a 300MHz clock (with a 3 1/3 nanosecond tick period) or a 3GHz clock (with a tick period of 1/3 of a nanosecond). And the resulting code will be just as efficient as if the user wrote a special purpose clock cycle counter.
+
+
+ #include <boost/chrono.hpp>
+ #include <boost/type_traits.hpp>
+
+ #include <iostream>
+
+ namespace bchrono=boost::chrono;
+
+
+ template <long long speed>
+ struct cycle_count
+ {
+ typedef typename boost::__ratio_multiply__<boost::__ratio<speed>, boost::__mega>::type
+ frequency; // Mhz
+ typedef typename boost::__ratio_divide__<boost::__ratio<1>, frequency>::type period;
+ typedef long long rep;
+ typedef bchrono::__duration<rep, period> duration;
+ typedef bchrono::__time_point<cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return exact cycle count
+ return time_point(duration(++tick)); // fake access to clock cycle count
+ }
+ };
+
+ template <long long speed>
+ struct approx_cycle_count
+ {
+ static const long long frequency = speed * 1000000; // MHz
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef bchrono::__time_point<approx_cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return cycle count as an approximate number of nanoseconds
+ // compute as if nanoseconds is only duration in the std::lib
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+ };
+
+['See the source file [@../../example/cycle_count.cpp here]]
+
+[endsect]
+
+[/==================]
+[section xtime_clock]
+
+This example demonstrates the use of a timeval-like struct to be used as the representation type for both __duraiton__ and __time_point.
+
+ class xtime {
+ private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec < 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+ public:
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec < 0 || tv_usec >= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec) {
+ tv_usec = static_cast<long>(usec % 1000000);
+ tv_sec = static_cast<long>(usec / 1000000);
+ fixup();
+ }
+
+ // explicit
+ operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
+
+ xtime& operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec >= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime& operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime& operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = static_cast<long>(t / 1000000);
+ tv_usec = static_cast<long>(t % 1000000);
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
+
+ friend bool operator<(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec < y.tv_usec);
+ return (x.tv_sec < y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator> (xtime x, xtime y) { return y < x; }
+ friend bool operator<=(xtime x, xtime y) { return !(y < x); }
+ friend bool operator>=(xtime x, xtime y) { return !(x < y); }
+
+ friend std::ostream& operator<<(std::ostream& os, xtime x)
+ {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
+ };
+
+Clock based on timeval-like struct.
+
+ class xtime_clock
+ {
+ public:
+ typedef xtime rep;
+ typedef boost::micro period;
+ typedef bchrono::duration<rep, period> duration;
+ typedef bchrono::time_point<xtime_clock> time_point;
+
+ static time_point now()
+ {
+ #if defined(BOOST_CHRONO_WINDOWS_API)
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&t, 0);
+ return t;
+
+ #elif defined(BOOST_CHRONO_MAC_API)
+
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&t, 0);
+ return t;
+
+ #elif defined(BOOST_CHRONO_POSIX_API)
+ //time_point t(0,0);
+
+ timespec ts;
+ ::clock_gettime( CLOCK_REALTIME, &ts );
+
+ xtime xt( ts.tv_sec, ts.tv_nsec/1000);
+ return time_point(duration(xt));
+
+ #endif // POSIX
+ }
+ };
+
+Usage of xtime_clock
+
+ std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
+ std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
+ std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
+ xtime_clock::duration delay(bchrono::milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+ while (xtime_clock::now() - start <= delay) {}
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout << "paused " << bchrono::::nanoseconds(elapsed).count() << " nanoseconds\n";
+
+
+['See the source file [@../../example/timeval_demo.cpp example/timeval_demo.cpp]]
+
+[endsect]
+[endsect]
+
+
+
+[/
+[/======================================================]
+[section Howard Hinnant's original demonstration program]
+
+['See the source file [@../../example/time2_demo.cpp example/time2_demo.cpp]]
+
+[endsect]
+]
+[section Time Point]
+
+[/==================]
+[section min Utility]
+
+The user can define a function returning the earliest __time_point as follows:
+
+ template <class Clock, class Duration1, class Duration2>
+ typename boost::__common_type<__time_point<Clock, Duration1>,
+ __time_point<Clock, Duration2> >::type
+ min(__time_point<Clock, Duration1> t1, __time_point<Clock, Duration2> t2)
+ {
+ return t2 < t1 ? t2 : t1;
+ }
+
+Being able to *easily* write this function is a major feature!
+
+ BOOST_AUTO(t1, system_clock::now() + seconds(3));
+ BOOST_AUTO(t2, system_clock::now() + nanoseconds(3));
+ BOOST_AUTO(t3, min(t1, t2));
+
+['See the source file [@../../example/min_time_point.cpp example/min_time_point.cpp]]
+
+
+[endsect]
+
+
+[/===============================================================]
+[section A Tiny Program that Times How Long Until a Key is Struck]
+
+ #include <boost/chrono.hpp>
+ #include <iostream>
+ #include <iomanip>
+
+ using namespace boost::chrono;
+
+ template< class Clock >
+ class timer
+ {
+ typename Clock::time_point start;
+ public:
+ timer() : start( Clock::now() ) {}
+ typename Clock::duration elapsed() const
+ {
+ return Clock::now() - start;
+ }
+ double seconds() const
+ {
+ return elapsed().count() * ((double)Clock::period::num/Clock::period::den);
+ }
+ };
+
+ int main()
+ {
+ timer<__system_clock> t1;
+ timer<__steady_clock> t2;
+ timer<__high_resolution_clock> t3;
+
+ std::cout << "Type the Enter key: ";
+ std::cin.get();
+
+ std::cout << std::fixed << std::setprecision(9);
+ std::cout << "system_clock-----------: "
+ << t1.seconds() << " seconds\n";
+ std::cout << "steady_clock--------: "
+ << t2.seconds() << " seconds\n";
+ std::cout << "high_resolution_clock--: "
+ << t3.seconds() << " seconds\n";
+
+ __system_clock::time_point d4 = __system_clock::now();
+ __system_clock::time_point d5 = __system_clock::now();
+
+ std::cout << "\nsystem_clock latency-----------: " << (d5 - d4).count() << std::endl;
+
+ __steady_clock::time_point d6 = __steady_clock::now();
+ __steady_clock::time_point d7 = __steady_clock::now();
+
+ std::cout << "steady_clock latency--------: " << (d7 - d6).count() << std::endl;
+
+ __high_resolution_clock::time_point d8 = __high_resolution_clock::now();
+ __high_resolution_clock::time_point d9 = __high_resolution_clock::now();
+
+ std::cout << "high_resolution_clock latency--: " << (d9 - d8).count() << std::endl;
+
+ std::time_t now = __system_clock::to_time_t(__system_clock::now());
+
+ std::cout << "\nsystem_clock::now() reports UTC is "
+ << std::asctime(std::gmtime(&now)) << "\n";
+
+ return 0;
+ }
+
+The output of this program run looks like this:
+
+
+['See the source file [@../../example/await_keystroke.cpp example/await_keystroke.cpp]]
+
+[endsect]
+
+[/
+[/===============================================================]
+[section Time Command]
+
+ #include <boost/chrono/stopclock.hpp>
+ #include <cstdlib>
+ #include <string>
+ #include <iostream>
+
+ int main( int argc, char * argv[] )
+ {
+ if ( argc == 1 )
+ {
+ std::cout << "invoke: timex [-v] command [args...]\n"
+ " command will be executed and timings displayed\n"
+ " -v option causes command and args to be displayed\n";
+ return 1;
+ }
+
+ std::string s;
+
+ bool verbose = false;
+ if ( argc > 1 && *argv[1] == '-' && *(argv[1]+1) == 'v' )
+ {
+ verbose = true;
+ ++argv;
+ --argc;
+ }
+
+ for ( int i = 1; i < argc; ++i )
+ {
+ if ( i > 1 ) s += ' ';
+ s += argv[i];
+ }
+
+ if ( verbose )
+ { std::cout << "command: \"" << s.c_str() << "\"\n"; }
+
+ bchrono::__stopclock__<> t;
+
+ return std::system( s.c_str() );
+ }
+
+['See the source file [@../../example/timex.cpp example/timex.cpp]]
+
+[endsect]
+]
+
+[section 24 Hours Display]
+
+In the example above we take advantage of the fact that __time_point_s convert as long as they have the same clock, and as long as their internal __duration_s convert. We also take advantage of the fact that a __duration with a floating point representation will convert from anything. Finally the I/O system discovers the more readable "hours" unit for our `duration<double, ratio<3600>>`.
+
+There are many other ways to format __durations and __time_points. For example see [@http://en.wikipedia.org/wiki/ISO_8601#Durations ISO 8601]. Instead of coding every possibility into `operator<<`, which would lead to significant code bloat for even the most trivial uses, this document seeks to inform the reader how to write custom I/O when desired.
+
+As an example, the function below streams arbitrary durations to arbitrary `basic_ostreams` using the format:
+
+ [-]d/hh:mm:ss.cc
+
+Where:
+
+* `d` is the number of `days`
+* `h` is the number of `hours`
+* `m` is the number of `minutes`
+* `ss.cc` is the number of `seconds` rounded to the nearest hundreth of a second
+
+ #include <boost/chrono/chrono_io.hpp>
+ #include <ostream>
+ #include <iostream>
+
+ // format duration as [-]d/hh::mm::ss.cc
+ template <class CharT, class Traits, class Rep, class Period>
+ std::basic_ostream<CharT, Traits>&
+ display(std::basic_ostream<CharT, Traits>& os,
+ bchrono::duration<Rep, Period> d)
+ {
+ using namespace std;
+ using namespace boost;
+ namespace bchrono=boost::chrono;
+
+ typedef bchrono::duration<long long, boost::ratio<86400> > days;
+ typedef bchrono::duration<long long, boost:centi> centiseconds;
+
+ // if negative, print negative sign and negate
+ if (d < bchrono::duration<Rep, Period>(0))
+ {
+ d = -d;
+ os << '-';
+ }
+ // round d to nearest centiseconds, to even on tie
+ centiseconds cs = bchrono::duration_cast<centiseconds>(d);
+ if (d - cs > bchrono::milliseconds(5)
+ || (d - cs == bchrono::milliseconds(5) && cs.count() & 1))
+ ++cs;
+ // separate seconds from centiseconds
+ bchrono::seconds s = bchrono::duration_cast<bchrono::seconds>(cs);
+ cs -= s;
+ // separate minutes from seconds
+ bchrono::minutes m = bchrono::duration_cast<bchrono::minutes>(s);
+ s -= m;
+ // separate hours from minutes
+ bchrono::hours h = bchrono::duration_cast<bchrono::hours>(m);
+ m -= h;
+ // separate days from hours
+ days dy = bchrono::duration_cast<days>(h);
+ h -= dy;
+ // print d/hh:mm:ss.cc
+ os << dy.count() << '/';
+ if (h < bchrono::hours(10))
+ os << '0';
+ os << h.count() << ':';
+ if (m < bchrono::minutes(10))
+ os << '0';
+ os << m.count() << ':';
+ if (s < bchrono::seconds(10))
+ os << '0';
+ os << s.count() << '.';
+ if (cs < bchrono::centiseconds(10))
+ os << '0';
+ os << cs.count();
+ return os;
+ }
+
+ int main()
+ {
+ using namespace std;
+ using namespace boost;
+ namespace bchrono=boost::chrono;
+
+ display(cout, bchrono::steady_clock::now().time_since_epoch()
+ + bchrono::duration<long, boost::mega>(1)) << '\n';
+ display(cout, -bchrono::milliseconds(6)) << '\n';
+ display(cout, bchrono::duration<long, boost::mega>(1)) << '\n';
+ display(cout, -bchrono::duration<long, boost::mega>(1)) << '\n';
+ }
+
+The output could be:
+
+ 12/06:03:22.95
+ -0/00:00:00.01
+ 11/13:46:40.00
+ -11/13:46:40.00
+
+[endsect]
+
+
+[/=======================================================]
+[section Simulated Thread Interface Demonstration Program]
+
+The C++0x standard library's multi-threading library requires the ability to deal with the representation of time in a manner consistent with modern C++ practices. Next follows a simulation of this interface.
+
+The non-member sleep functions can be emulated as follows:
+
+ namespace boost { namespace this_thread {
+
+ template <class Rep, class Period>
+ void sleep_for(const chrono::__duration<Rep, Period>& d) {
+ chrono::__microseconds t = chrono::__duration_cast<chrono::__microseconds>(d);
+ if (t < d)
+ ++t;
+ if (t > chrono::__microseconds(0))
+ std::cout << "sleep_for " << t.count() << " microseconds\n";
+ }
+
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::__time_point<Clock, Duration>& t) {
+ using namespace chrono;
+ typedef __time_point<Clock, Duration> Time;
+ typedef __system_clock::time_point SysTime;
+ if (t > Clock::now()) {
+ typedef typename __common_type<typename Time::duration,
+ typename SysTime::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = __duration_cast<__microseconds>(d);
+ if (us < d)
+ ++us;
+ SysTime st = __system_clock::now() + us;
+ std::cout << "sleep_until ";
+ detail::print_time(st);
+ std::cout << " which is " << (st - __system_clock::now()).count() << " microseconds away\n";
+ }
+ }
+
+ }}
+
+
+Next follows the `boost::thread::timed_mutex` modified fuctions
+
+ namespace boost {
+ struct timed_mutex {
+ // ...
+
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::__duration<Rep, Period>& d) {
+ chrono::__microseconds t = chrono::__duration_cast<chrono::__microseconds>(d);
+ if (t <= chrono::__microseconds(0))
+ return try_lock();
+ std::cout << "try_lock_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::__time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef __time_point<Clock, Duration> Time;
+ typedef __system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return try_lock();
+ typedef typename __common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = __duration_cast<__microseconds>(d);
+ SysTime st = __system_clock::now() + us;
+ std::cout << "try_lock_until ";
+ detail::print_time(st);
+ std::cout << " which is " << (st - __system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+ };
+ }
+
+`boost::thread::condition_variable` time related function are modified as follows:
+
+ namespace boost {
+ struct condition_variable
+ {
+ // ...
+
+ template <class Rep, class Period>
+ bool wait_for(mutex&, const chrono::__duration<Rep, Period>& d) {
+ chrono::microseconds t = chrono::__duration_cast<chrono::microseconds>(d);
+ std::cout << "wait_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool wait_until(mutex&, const chrono::__time_point<Clock, Duration>& t) {
+ using namespace boost::chrono;
+ typedef __time_point<Clock, Duration> Time;
+ typedef __system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return false;
+ typedef typename __common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = __duration_cast<__microseconds>(d);
+ SysTime st = __system_clock::now() + us;
+ std::cout << "wait_until ";
+ detail::print_time(st);
+ std::cout << " which is " << (st - __system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+ };
+ }
+
+Next follows how simple is the usage of this functions:
+
+ boost::mutex m;
+ boost::timed_mutex mut;
+ boost::condition_variable cv;
+
+ using namespace boost;
+
+ this_thread::sleep_for(chrono::__seconds(3));
+ this_thread::sleep_for(chrono::__nanoseconds(300));
+ chrono::__system_clock::time_point time_limit = chrono::__system_clock::now() + chrono::__seconds_(4) + chrono::__milliseconds__(500);
+ this_thread::sleep_until(time_limit);
+
+ mut.try_lock_for(chrono::__milliseconds__(30));
+ mut.try_lock_until(time_limit);
+
+ cv.wait_for(m, chrono::__minutes(1)); // real code would put this in a loop
+ cv.wait_until(m, time_limit); // real code would put this in a loop
+
+ // For those who prefer floating point
+ this_thread::sleep_for(chrono::__duration<double>(0.25));
+ this_thread::sleep_until(chrono::__system_clock::now() + chrono::__duration<double>(1.5));
+
+
+['See the source file [@../../example/simulated_thread_interface_demo.cpp example/simulated_thread_interface_demo.cpp]]
+
+[endsect]
+
+[endsect]
+[section IO]
+[endsect]
+
+[endsect]
+
+[/================================]
+[section:ext_references External Resources]
+[/================================]
+
+[variablelist
+
+[
+ [[@http://www.open-std.org/jtc1/sc22/wg21 [*C++ Standards Committee's current Working Paper]]]
+ [The most authoritative reference material for the library is the C++ Standards Committee's current Working Paper (WP). 20.11 Time utilities "time"]
+]
+
+[
+ [[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm [*N2661 - A Foundation to Sleep On]]]
+ [From Howard E. Hinnant, Walter E. Brown, Jeff Garland and Marc Paterno. Is very informative and provides motivation for key design decisions]
+]
+
+
+[
+ [[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3134.html#934 [*LGW 934. duration is missing operator%]]]
+ [From Terry Golubiewski. Is very informative and provides motivation for key design decisions]
+]
+
+]
+
+[endsect]
+
+[endsect]
+
+[/=================]
+[section:reference Reference ]
+[/=================]
+
+As `constexpr` will not be supported by some compilers, it is replaced in the code by BOOST_CHRONO_CONSTEXPR for constexpr functions and BOOST_CHRONO_CONSTEXPR_V for struct/class fields. THe documentation doesn't use these macros.
+
+[section:cpp0x Included on the C++0x Recommendation]
+
+
+[/=============================================]
+[section:chrono_hpp Header `<boost/chrono.hpp>`]
+[/=============================================]
+
+ #include <boost/chrono/duration.hpp>
+ #include <boost/chrono/time_point.hpp>
+ #include <boost/chrono/system_clocks.hpp>
+ #include <boost/chrono/process_cpu_clocks.hpp>
+ #include <boost/chrono/thread_clock.hpp>
+ #include <boost/chrono/typeof/boost/chrono/chrono.hpp>
+
+[section:limitations Limitations and Extensions]
+
+Next follows limitation respect to the C++0x recomendations:
+
+* constexpr not tested yet.
+* The recently steady_clock approved is not yet included.
+
+The current implementation provides in addition:
+
+* clock error handling as specified in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3135.html#3155 clock error handling needs to be specified].
+* process and thread clocks.
+
+
+[endsect]
+
+[section:conf Configuration Macros]
+
+[section:assert How Assert Behaves?]
+
+When `BOOST_NO_STATIC_ASSERT` is defined, the user can select the way static assertions are reported. Define
+
+* `BOOST_CHRONO_USES_STATIC_ASSERT`: define it if you want to use Boost.StaticAssert
+* `BOOST_CHRONO_USES_MPL_ASSERT`: define it if you want to use Boost.MPL static asertions
+* `BOOST_CHRONO_USES_ARRAY_ASSERT`: define it if you want to use internal static asertions
+
+The default behavior is as `BOOST_CHRONO_USES_ARRAY_ASSERT` was defined.
+
+When `BOOST_CHRONO_USES_MPL_ASSERT` is not defined the following symbols are defined as
+
+ #define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION \
+ "A duration representation can not be a duration"
+ #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO \
+ "Second template parameter of duration must be a boost::ratio"
+ #define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE \
+ "duration period must be positive"
+ #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION \
+ "Second template parameter of time_point must be a bchrono::duration"
+
+Depending on the static assertion used system you will have an hint of the failing assertion either through the symbol or through the text.
+
+[endsect]
+
+[section:header_only How to Build Boost.Chrono as a Header Only Library?]
+
+When `BOOST_CHRONO_INLINED` is defined the lib is header-only.
+
+If in addition `BOOST_USE_WINDOWS_H` is defined `<windows.h>` is included, otherwise files in `boost/detail/win` are used to reduce the impact of including `<windows.h>`.
+
+[endsect]
+
+
+[endsect]
+
+
+
+[endsect]
+
+[/=============================================]
+[section:duration_hpp Header `<boost/chrono/duration.hpp>`]
+[/=============================================]
+
+This file contains duration specific classes and non-member functions.
+
+ namespace boost {
+ namespace chrono {
+
+ template <class Rep, class Period = __ratio<1> > class __duration;
+
+ }
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ struct __common_type_spe<duration<Rep1, Period1>,
+ duration<Rep2, Period2> >;
+
+ namespace chrono {
+
+ // customization traits
+ template <class Rep> struct __treat_as_floating_point;
+ template <class Rep> struct __duration_values;
+
+ // duration arithmetic
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+ operator+(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+ operator-(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period, class Rep2>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator*(
+ const duration<Rep1, Period>& d,
+ const Rep2& s);
+
+ template <class Rep1, class Period, class Rep2>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator*(
+ const Rep1& s,
+ const duration<Rep2, Period>& d);
+
+ template <class Rep1, class Period, class Rep2>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator/(
+ const duration<Rep1, Period>& d,
+ const Rep2& s);
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename common_type<Rep1, Rep2>::type
+ operator/(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Rep2, class Period>
+ double operator/(
+ const Rep1& s,
+ const duration<Rep2, Period>& d);
+
+ // duration comparisons
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator==(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator!=(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator<(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator<=(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator> (
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ constexpr bool operator>=(
+ const duration<Rep1, Period1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+ // duration_cast
+
+ template <class ToDuration, class Rep, class Period>
+ ToDuration __duration_cast(const duration<Rep, Period>& d);
+
+ // convenience typedefs
+ typedef duration<boost::int_least64_t, nano> __nanoseconds; // at least 64 bits needed
+ typedef duration<boost::int_least64_t, micro> __microseconds; // at least 55 bits needed
+ typedef duration<boost::int_least64_t, milli> __milliseconds__; // at least 45 bits needed
+ typedef duration<boost::int_least64_t> __seconds; // at least 35 bits needed
+ typedef duration<boost::int_least32_t, ratio< 60> > __minutes; // at least 29 bits needed
+ typedef duration<boost::int_least32_t, ratio<3600> > __hours; // at least 23 bits needed
+
+ }
+ }
+
+
+[section:traits Time-related Traits]
+
+[section:treat_as_floating_point Metafunction `treat_as_floating_point<>`]
+
+ template <class Rep> struct treat_as_floating_point
+ : boost::is_floating_point<Rep> {};
+
+The __duration template uses the __treat_as_floating_point trait to help determine if a __duration with one tick period can be converted to another __duration with a different tick period. If `treat_as_floating_point<Rep>::value` is `true`, then `Rep` is a floating point type and implicit conversions are allowed among __duration_s. Otherwise, the implicit convertibility depends on the tick periods of the __duration_s. If `Rep` is a class type which emulates a floating point type, the author of `Rep` can specialize __treat_as_floating_point so that __duration will treat this `Rep` as if it were a floating point type. Otherwise `Rep` is assumed to be an integral type, or a class emulating an integral type.
+
+
+[endsect]
+[section:duration_values Class Template `duration_values`]
+
+ template <class Rep>
+ struct duration_values
+ {
+ public:
+ static constexpr Rep __zero();
+ static constexpr Rep __max();
+ static constexpr Rep __min();
+ };
+
+The __duration template uses the __duration_values trait to construct special values of the __duration_s representation (`Rep`). This is done because the representation might be a class type with behavior which requires some other implementation to return these special values. In that case, the author of that class type should specialize __duration_values to return the indicated values.
+
+[section:zero Static Member Function `zero()`]
+
+ static constexpr Rep zero();
+
+__returns `Rep(0)`. [*Note:] `Rep(0)` is specified instead of `Rep()` since `Rep()` may have some other meaning, such as an uninitialized value.
+
+__remarks The value returned corresponds to the additive identity.
+
+[endsect]
+[section:max Static Member Function `max()`]
+
+ static constexpr Rep max();
+
+__returns `numeric_limits<Rep>::max()`.
+
+__remarks The value returned compares greater than zero().
+
+[endsect]
+[section:min Static Member Function `min()`]
+
+ static constexpr Rep min();
+
+__returns `numeric_limits<Rep>::lowest()`.
+
+__remarks The value returned compares less than or equal to `zero()`.
+
+[endsect]
+
+[endsect]
+
+[endsect]
+
+[section:common_type_spe `common_type` Specialization]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ struct __common_type<chrono::__duration<Rep1, Period1>, chrono::__duration<Rep2, Period2> >
+ {
+ typedef chrono::__duration<typename __common_type<Rep1, Rep2>::type, __see_bellow__> type;
+ };
+
+The period of the __duration indicated by this specialization of __common_type is the greatest common divisor of `Period1` and `Period2`. This can be computed by forming a __ratio of the greatest common divisor of `Period1::num` and `Period2::num`, and the least common multiple of `Period1::den` and `Period2::den`.
+
+[*Note:] The typedef type is the __duration with the largest tick period possible where both __duration arguments will convert to it without requiring a division operation. The representation of this type is intended to be able to hold any value resulting from this conversion, with the possible exception of round-off error when floating point __duration_s are involved (but not truncation error).
+
+[endsect]
+
+
+[section:duration Class Template `duration<>`]
+
+A __duration measures time between two points in time (__time_point). A __duration has a representation which holds a count of ticks, and a tick period. The tick period is the amount of time which occurs from one tick to another in units of a second. It is expressed as a rational constant using __ratio.
+
+ namespace boost { namespace chrono {
+
+ template <class Rep, class Period>
+ class duration {
+ public:
+ typedef Rep rep;
+ typedef Period period;
+ private:
+ rep rep_; // exposition only
+ public:
+ constexpr duration();
+ template <class Rep2>
+ constexpr explicit duration(const Rep2& r);
+
+ template <class Rep2, class Period2>
+ constexpr duration(const duration<Rep2, Period2>& d);
+
+ duration& operator=(const duration&) = default;
+
+ constexpr rep count() const;
+
+ constexpr duration operator+();
+ constexpr duration operator-();
+ duration& operator++();
+ duration operator++(int);
+ duration& operator--();
+ duration operator--(int);
+
+ duration& operator+=(const duration& d);
+ duration& operator-=(const duration& d);
+
+ duration& operator*=(const rep& rhs);
+ duration& operator/=(const rep& rhs);
+ duration& operator%=(const rep& rhs);
+ duration& operator%=(const duration& rhs);
+
+ static constexpr duration zero();
+ static constexpr duration min();
+ static constexpr duration max();
+ };
+
+ }}
+
+`Rep` must be an arithmetic type, or a class emulating an arithmetic type, compile diagnostic otherwise. If __duration is instantiated with the type of `Rep` being a __duration, compile diagnostic is issued.
+
+`Period` must be an instantiation of `ratio`, compile diagnostic otherwise.
+
+`Period::num` must be positive, compile diagnostic otherwise.
+
+Examples:
+
+* `__duration<long, __ratio<60> >` holds a count of minutes using a long.
+
+* `__duration<long long, milli>` holds a count of milliseconds using a long long.
+
+* `__duration<double, __ratio<1, 30> >` holds a count using a double with a tick period of 1/30 second (a tick frequency of 30 Hz).
+
+The following members of __duration do not throw an exception unless the indicated operations on the representations throw an exception.
+
+[section:duration_c_1 Constructor `duration(const Rep2&)`]
+
+ template <class Rep2>
+ constexpr explicit duration(const Rep2& r);
+
+__remarks `Rep2` is implicitly convertible to `rep`, and
+
+* `treat_as_floating_point<rep>::value` is `true`, or
+* `!treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value` is `true`.
+
+If these constraints are not met, this constructor will not participate in overload resolution. [*Note:] This requirement prevents construction of an integral-based __duration with a floating point representation. Such a construction could easily lead to confusion about the value of the __duration.
+
+__example
+
+ __duration<int, milli> d(3.5); // do not compile
+ __duration<int, milli> d(3); // ok
+
+__effects Constructs an object of type __duration.
+
+__post_conditions `count() == static_cast<rep>(r)`.
+
+[endsect]
+[section:duration_c_2 Constructor `duration(const duration&)`]
+
+ template <class Rep2, class Period2>
+ constexpr __duration(const __duration<Rep2, Period2>& d);
+
+__remarks `treat_as_floating_point<rep>::value`, or `ratio_divide<Period2, period>::type::den == 1`, else this constructor will not participate in overload resolution. [*note] This requirement prevents implicit truncation error when converting between integral-based __duration_s. Such a construction could easily lead to confusion about the value of the __duration.
+
+__example
+
+ __duration<int, milli> ms(3);
+ __duration<int, micro> us = ms; // ok
+ __duration<int, milli> ms2 = us; // do not compile
+
+__effects Constructs an object of type __duration, constructing `rep_` from `duration_cast<__duration>(d).count()`.
+
+[endsect]
+[section:count Member Function `count() const`]
+
+ constexpr rep count() const;
+
+__returns `rep_`.
+
+[endsect]
+[section:duration_operator_p Member Function `operator+() const`]
+
+ constexpr __duration operator+() const;
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_m Member Function `operator-() const`]
+
+ constexpr __duration operator-() const;
+
+__returns `__duration(-rep_)`.
+
+[endsect]
+[section:duration_operator_pp Member Function `operator++()`]
+
+ __duration& operator++();
+
+__effects `++rep_`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_pp2 Member Function `operator++(int)`]
+
+ __duration operator++(int);
+
+__returns `__duration(rep_++)`.
+
+[endsect]
+[section:duration_operator_mm Member Function `operator--()`]
+
+ __duration& operator--();
+
+__effects `--rep_`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_mm2 Member Function `operator--(int)`]
+
+ __duration operator--(int);
+
+__returns `__duration(rep_--)`.
+
+[endsect]
+[section:duration_operator_pa Member Function `operator+=(const duration&)`]
+
+ __duration& operator+=(const __duration& d);
+
+__effects `rep_ += d.count()`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_ma Member Function `operator-=(const duration&)`]
+
+ __duration& operator-=(const __duration& d);
+
+__effects `rep_ -= d.count()`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_moda Member Function `operator%=(const duration&)`]
+
+ __duration& operator%=(const __duration& d);
+
+__effects `rep_ %= d.count()`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_proda Member Function `operator*=(const rep&)`]
+
+ __duration& operator*=(const rep& rhs);
+
+__effects `rep_ *= rhs`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_da Member Function `operator/=(const rep&)`]
+
+ __duration& operator/=(const rep& rhs);
+
+__effects `rep_ /= rhs`.
+
+__returns `*this`.
+
+[endsect]
+[section:duration_operator_moda_2 Member Function `operator%=(const rep&)`]
+
+ __duration& operator%=(const rep& rhs);
+
+__effects `rep_ %= rhs`.
+
+__returns `*this`.
+
+[endsect]
+
+
+[section:duration_zero Static Member Function `zero()`]
+
+ static constexpr __duration zero();
+
+__returns `__duration(__duration_values<rep>::zero())`.
+
+[endsect]
+[section:duration_min Static Member Function `min()`]
+
+ static constexpr __duration min();
+
+__returns `__duration(__duration_values<rep>::min()).`
+
+[endsect]
+[section:duration_max Static Member Function `max()`]
+
+ static constexpr __duration max();
+
+__returns `__duration(__duration_values<rep>::max())`.
+
+[endsect]
+
+[endsect]
+
+
+[section `duration` Non-Member Arithmetic]
+
+[section:duration_operator_p_1 Non-Member Function `operator+(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename __common_type<__duration<Rep1, Period1>, __duration<Rep2, Period2> >::type
+ operator+(const __duration<Rep1, Period1>& lhs, const __duration<Rep2, Period2>& rhs);
+
+__returns `CD(lhs) += rhs` where `CD` is the type of the return value.
+
+[endsect]
+[section:duration_operator_m_1 Non-Member Function `operator-(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename __common_type<__duration<Rep1, Period1>, __duration<Rep2, Period2> >::type
+ operator-(const __duration<Rep1, Period1>& lhs, const __duration<Rep2, Period2>& rhs);
+
+__returns `CD(lhs) -= rhs` where `CD` is the type of the return value.
+
+ template <class Rep1, class Period, class Rep2>
+ __duration<typename __common_type<Rep1, Rep2>::type, Period>
+ operator*(const __duration<Rep1, Period>& d, const Rep2& s);
+
+__requires Let `CR` represent the __common_type of `Rep1` and `Rep2`. This function will not participate in overload resolution unless both `Rep1` and `Rep2` are implicitly convertible to `CR`.
+
+__returns `__duration<CR, Period>(d) *= s`.
+
+[endsect]
+[section:duration_operator_prod_1 Non-Member Function `operator*(Rep1,duration)`]
+
+ template <class Rep1, class Period, class Rep2>
+ __duration<typename __common_type<Rep1, Rep2>::type, Period>
+ operator*(const Rep1& s, const __duration<Rep2, Period>& d);
+
+__requires Let `CR` represent the __common_type of `Rep1` and `Rep2`. This function will not participate in overload resolution unless both `Rep1` and `Rep2` are implicitly convertible to `CR`.
+
+__returns `d * s`.
+
+[endsect]
+[section:duration_operator_d_1 Non-Member Function `operator/(duration,Rep2)`]
+
+ template <class Rep1, class Period, class Rep2>
+ __duration<typename __common_type<Rep1, Rep2>::type, Period>
+ operator/(const __duration<Rep1, Period>& d, const Rep2& s);
+
+__requires Let `CR` represent the __common_type of `Rep1` and `Rep2`. This function will not participate in overload resolution unless both `Rep1` and `Rep2` are implicitly convertible to `CR`, and `Rep2` is not an instantiation of __duration.
+
+__returns `__duration<CR, Period>(d) /= s`.
+
+[endsect]
+[section:duration_operator_d_2 Non-Member Function `operator/(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename __common_type<Rep1, Rep2>::type
+ operator/(const __duration<Rep1, Period1>& lhs, const __duration<Rep2, Period2>& rhs);
+
+__returns Let `CD` represent the __common_type of the two __duration arguments. Returns `CD(lhs).count() / CD(rhs).count()`.
+
+[endsect]
+
+[section:duration_operator_d_3 Non-Member Function `operator/(Rep1,duration)`]
+
+This overloading could be used to get the frequency of an event counted by `Rep1`.
+
+ template <class Rep1, class Rep2, class Period>
+ double operator/(const Rep1& s, const __duration<Rep2, Period>& d);
+
+__remarks Let `CR` represent the __common_type of `Rep1` and `Rep2`. This function will not participate in overload resolution unless both `Rep1` and `Rep2` are implicitly convertible to `CR`, and `Rep1` is not an instantiation of __duration.
+
+__returns `CR(s)/__duration<CR, Period>(d).count()`.
+
+[endsect]
+
+
+[section:duration_operator_mod_1 Non-Member Function `operator%(duration,Rep2)`]
+
+ template <class Rep1, class Period, class Rep2>
+ __duration<typename __common_type<Rep1, Rep2>::type, Period>
+ operator%(const __duration<Rep1, Period>& d, const Rep2& s);
+
+[*Remarks] This function will not participate in overload resolution unless Rep2 must be implicitly convertible to CR(Rep1, Rep2) and Rep2 must not be an instantiation of __duration.
+
+__returns __duration<CR(Rep1,Rep2), Period>(d) %= s.
+[endsect]
+
+[section:duration_operator_mod_2 Non-Member Function `operator%(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ typename __common_type<__duration<Rep1, Period1>, __duration<Rep2, Period2> >::type
+ operator%(const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+[*Remarks] This function will not participate in overload resolution unless
+
+__returns CD(lhs) %= CD(rhs)
+
+[endsect]
+[endsect]
+
+[section `duration` Non-Member Comparaisons]
+
+[section:duration_operator_eq_1 Non-Member Function `operator==(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator==(const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns Let `CD` represent the __common_type of the two __duration arguments. Returns `CD(lhs).count() == CD(rhs).count()`
+
+[endsect]
+[section:duration_operator_neq_1 Non-Member Function `operator!=(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator!=(const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns `!(lhs == rhs)`.
+
+[endsect]
+[section:duration_operator_lt_1 Non-Member Function `operator<(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator< (const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns Let `CD` represent the __common_type of the two __duration arguments. Returns `CD(lhs).count() < CD(rhs).count()`
+
+[endsect]
+[section:duration_operator_leq_1 Non-Member Function `operator<=(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator<=(const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns `!(rhs < lhs)`.
+
+[endsect]
+[section:duration_operator_gt_1 Non-Member Function `operator>(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator> (const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns `rhs < lhs`.
+
+[endsect]
+[section:duration_operator_gteq_1 Non-Member Function `operator>=(duration,duration)`]
+
+ template <class Rep1, class Period1, class Rep2, class Period2>
+ bool operator>=(const __duration<Rep1, Period1>& lhs,
+ const __duration<Rep2, Period2>& rhs);
+
+__returns `!(lhs < rhs)`.
+
+[endsect]
+[endsect]
+[section:duration_cast Non-Member Function `duration_cast(duration)`]
+
+ template <class ToDuration, class Rep, class Period>
+ ToDuration duration_cast(const __duration<Rep, Period>& d);
+
+__requires This function will not participate in overload resolution unless `ToDuration` is an instantiation of __duration.
+
+__returns Forms `CF` which is a __ratio resulting from `ratio_divide<Period, typename ToDuration::period>::type`. Let `CR` be the __common_type of `ToDuration::rep`, `Rep`, and `intmax_t`.
+
+* If `CF::num == 1` and `CF::den == 1`, then returns `ToDuration(static_cast<typename ToDuration::rep>(d.count())) `
+* else if `CF::num != 1` and `CF::den == 1`, then returns
+ `ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) *
+ static_cast<CR>(CF::num)))`
+* else if `CF::num == 1` and `CF::den != 1`, then returns
+ `ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) /
+ static_cast<CR>(CF::den)))`
+* else returns
+ `ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) *
+ static_cast<CR>(CF::num) /
+ static_cast<CR>(CF::den)))`
+
+__remarks This function does not rely on any implicit conversions. All conversions must be accomplished through `static_cast`. The implementation avoids all multiplications or divisions when it is known at compile time that it can be avoided because one or more arguments are `1`. All intermediate computations are carried out in the widest possible representation and only converted to the destination representation at the final step.
+
+
+[endsect]
+
+
+[section:duration_typedefs `duration` typedefs]
+
+ // convenience typedefs
+ typedef __duration<boost::int_least64_t, nano> nanoseconds; // at least 64 bits needed
+ typedef __duration<boost::int_least64_t, micro> microseconds; // at least 55 bits needed
+ typedef __duration<boost::int_least64_t, milli> milliseconds; // at least 45 bits needed
+ typedef __duration<boost::int_least64_t> seconds; // at least 35 bits needed
+ typedef __duration<boost::int_least32_t, __ratio< 60> > minutes; // at least 29 bits needed
+ typedef __duration<boost::int_least32_t, __ratio<3600> > hours; // at least 23 bits needed
+
+[endsect]
+
+
+[endsect]
+
+[section:clock `Clock` Requirements]
+
+A clock represents a bundle consisting of a __duration, a __time_point, and a function `now()` to get the current __time_point. A clock must meet the requirements in the following Table.
+
+In this table `C1` and `C2` denote `clock` types. `t1` and `t2` are values returned from `C1::now()` where the call returning `t1` happens before the call returning `t2` and both of these calls happen before `C1::time_point::max()`.
+
+[table Clock Requirements
+ [[expression] [return type] [operational semantics]]
+ [[`C1::rep`] [An arithmetic type or class emulating an arithmetic type. ] [The representation type of the __duration and __time_point.]]
+ [[`C1::period`] [`ratio`] [The tick period of the clock in seconds.]]
+ [[`C1::duration`] [`chrono::duration<C1::rep, C1::period>`] [The __duration type of the `clock`.]]
+ [[`C1::time_point`] [`chrono::time_point<C1> or chrono::time_point<C2, C1::duration>`] [The __time_point type of the `clock`. Different clocks are permitted to share a __time_point definition if it is valid to compare their time_points by comparing their respective __duration_s. `C1` and `C2` must refer to the same epoch.]]
+ [[`C1::is_steady`] [`constexpr bool`] [`true` if `t1 <= t2` is always `true`, else `false`. *Note*: A `clock` that can be adjusted backwards is not steady]]
+ [[`C1::now()`] [`C1::time_point`] [Returns a __time_point representing the current point in time.]]
+]
+
+
+Models of Clock:
+
+* __system_clock
+* __steady_clock
+* __high_resolution_clock
+* __process_real_cpu_clock
+* __process_user_cpu_clock
+* __process_system_cpu_clock
+* __thread_clock
+
+[endsect]
+
+[/=============================================]
+[section:time_point_hpp Header `<boost/chrono/time_point.hpp>`]
+[/=============================================]
+
+This file contains __time_point specific classes and non-member functions.
+
+ namespace boost {
+ namespace chrono {
+
+ template <class Clock, class Duration = typename Clock::duration> class __time_point;
+
+ }
+ template <class Clock, class Duration1, class Duration2>
+ struct __common_type_spe<time_point<Clock, Duration1>,
+ time_point<Clock, Duration2> >;
+
+ namespace chrono {
+
+ // time_point arithmetic
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+
+ template <class Rep1, class Period1, class Clock, class Duration2>
+ time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+ operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+
+ template <class Clock, class Duration1, class Duration2>
+ typename common_type<Duration1, Duration2>::type
+ operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+
+ // time_point comparisons
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator< (const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator> (const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs);
+
+ // time_point_cast
+ template <class ToDuration, class Clock, class Duration>
+ constexpr time_point<Clock, ToDuration> __time_point_cast(const time_point<Clock, Duration>& t);
+
+ }
+ }
+
+
+[section:common_type_spe2 `common_type` specialization]
+
+ template <class Clock, class Duration1, class Duration2>
+ struct __common_type<chrono::__time_point<Clock, Duration1>, chrono::__time_point<Clock, Duration2> >
+ {
+ typedef chrono::__time_point<Clock, typename __common_type<Duration1, Duration2>::type> type;
+ };
+
+The __common_type of two __time_point_s is a __time_point with the same `clock` (both have the same `clock`), and the __common_type of the two __duration_s.
+
+[endsect]
+
+[section:time_point Class template `time_point<>`]
+
+A __time_point represents a point in time with respect to a specific clock.
+
+ template <class Clock, class Duration>
+ class time_point {
+ public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+ private:
+ duration d_; // exposition only
+ public:
+ constexpr time_point();
+ constexpr explicit time_point(const duration& d);
+
+ // conversions
+ template <class Duration2>
+ time_point(const time_point<clock, Duration2>& t);
+
+ // observer
+
+ constexpr duration time_since_epoch() const;
+
+ // arithmetic
+
+ time_point& operator+=(const duration& d);
+ time_point& operator-=(const duration& d);
+
+ // special values
+
+ static constexpr time_point min();
+ static constexpr time_point max();
+ };
+
+Clock must meet the __clock_req.
+
+Duration must be an instantiation of __duration, compile diagnostic otherwise.
+
+[section:time_point_c_1 Constructor `time_point()`]
+
+ constexpr time_point();
+
+__effects Constructs an object of __time_point, initializing `d_` with `duration::zero()`. This __time_point represents the epoch.
+
+[endsect]
+[section:time_point_c_2 Constructor `time_point(const duration&)`]
+
+ constexpr time_point(const duration& d);
+
+__effects Constructs an object of __time_point, initializing `d_` with `d`. This __time_point represents the epoch `+ d`.
+
+[endsect]
+[section:time_point_c_3 Copy Constructor `time_point(const time_point&)`]
+
+ template <class Duration2> time_point(const __time_point<clock, Duration2>& t);
+
+__requires This function will not participate in overload resolution unless `Duration2` is implicitly convertible to __duration.
+
+__effects Constructs an object of __time_point, initializing `d_` with `t.time_since_epoch()`.
+
+[endsect]
+
+[section:time_since_epoch Member Function `time_since_epoch() const`]
+
+ constexpr duration time_since_epoch() const;
+
+__returns `d_`.
+
+[endsect]
+[section:time_point_operator_pe Member Function `operator+=`]
+
+ time_point& operator+=(const duration& d);
+
+__effects `d_ += d`.
+
+__returns `*this`.
+
+[endsect]
+[section:time_point_operator_me Member Function `operator-=`]
+
+ time_point& operator-=(const duration& d);
+
+__effects `d_ -= d`
+
+__returns `*this`.
+
+[endsect]
+[section:time_point_min Static Member Function `min`]
+
+ static constexpr time_point min();
+
+__returns `time_point(duration::min())`.
+
+[endsect]
+[section:time_point_max Static Member Function `max`]
+
+ static constexpr time_point max();
+
+__returns `time_point(duration::max())`.
+
+[endsect]
+[endsect]
+
+
+[section `time_point` non-member arithmetic]
+
+
+[section:time_point_operator_p_1 Non-Member Function `operator+(time_point,duration)`]
+
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ __time_point<Clock, typename __common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator+(const __time_point<Clock, Duration1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+__returns `CT(lhs) += rhs` where `CT` is the type of the return value.
+
+[endsect]
+[section:time_point_operator_p_2 Non-Member Function `operator+(duration,time_point)`]
+
+ template <class Rep1, class Period1, class Clock, class Duration2>
+ __time_point<Clock, typename __common_type<duration<Rep1, Period1>, Duration2>::type>
+ operator+(const duration<Rep1, Period1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `rhs + lhs`.
+
+[endsect]
+[section:time_point_operator_m_1 Non-Member Function `operator-(time_point,duration)`]
+
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ __time_point<Clock, typename __common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator-(const __time_point<Clock, Duration1>& lhs,
+ const duration<Rep2, Period2>& rhs);
+
+__returns `lhs + (-rhs)`.
+
+[endsect]
+[section:time_point_operator_m_2 Non-Member Function `operator-(time_point,time_point)`]
+
+ template <class Clock, class Duration1, class Duration2>
+ typename __common_type<Duration1, Duration2>::type
+ operator-(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `lhs.time_since_epoch() - rhs.time_since_epoch()`.
+
+[endsect]
+[endsect]
+
+[section `time_point` non-member comparisons]
+[section:time_point_operator_eq Non-Member Function `operator==(time_point,time_point)`]
+
+ template <class Clock, class Duration1, class Duration2>
+ bool operator==(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `lhs.time_since_epoch() == rhs.time_since_epoch()`.
+
+[endsect]
+[section:time_point_operator_neq Non-Member Function `operator!=(time_point,time_point)`]
+
+template <class Clock, class Duration1, class Duration2>
+ bool operator!=(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `!(lhs == rhs)`.
+
+[endsect]
+[section:time_point_operator_lt Non-Member Function `operator<(time_point,time_point)`]
+
+ template <class Clock, class Duration1, class Duration2>
+ bool operator< (const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns lhs.time_since_epoch() < rhs.time_since_epoch().
+
+[endsect]
+[section:time_point_operator_leq Non-Member Function `operator<=(time_point,time_point)`]
+
+ template <class Clock, class Duration1, class Duration2>
+ bool operator<=(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `!(rhs < lhs)`.
+
+[endsect]
+[section:time_point_operator_gt Non-Member Function `operator>(time_point,time_point)`]
+
+template <class Clock, class Duration1, class Duration2>
+ bool operator>(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `rhs < lhs`.
+
+[endsect]
+[section:time_point_operator_geq Non-Member Function `operator>=(time_point,time_point)`]
+
+ template <class Clock, class Duration1, class Duration2>
+ bool operator>=(const __time_point<Clock, Duration1>& lhs,
+ const __time_point<Clock, Duration2>& rhs);
+
+__returns `!(lhs < rhs)`.
+
+[endsect]
+[endsect]
+
+
+[section:time_point_cast Non-Member Function `time_point_cast(time_point)`]
+
+ template <class ToDuration, class Clock, class Duration>
+ __time_point<Clock, ToDuration> __time_point_cast(const __time_point<Clock, Duration>& t);
+
+__requires This function will not participate in overload resolution unless `ToDuration` is an instantiation of __duration.
+
+__returns `__time_point<Clock, ToDuration>(__duration_cast<ToDuration>(t.time_since_epoch()))`.
+
+[endsect]
+
+[endsect]
+
+[/=============================================]
+[section:system_clocks_hpp Header `<boost/chrono/system_clocks.hpp>`]
+[/=============================================]
+
+This file contains the standard clock classes.
+
+ namespace boost {
+ namespace chrono {
+
+ // Clocks
+ class __system_clock;
+ class __steady_clock;
+ class __high_resolution_clock;
+
+ }
+ }
+
+
+[section:system_clock Class `system_clock`]
+
+The __system_clock class provides a means of obtaining the current wall-clock time from the system-wide real-time clock. The current time can be obtained by calling `system_clock::now()`. Instances of `system_clock::time_point` can be converted to and from time_t with the `system_clock::to_time_t()` and `system_clock::to_time_point()` functions. If system clock is not steady, a subsequent call to `system_clock::now()` may return an earlier time than a previous call (e.g. if the operating system clock is manually adjusted, or synchronized with an external clock).
+
+The current implementation of __system_clock is related an epoch (midnight UTC of January 1, 1970), but this is not in the contract. You need to use the static function static
+
+ std::time_t to_time_t(const time_point& t);
+
+which returns a `time_t` type that is based on midnight UTC of January 1, 1970.
+
+ class system_clock {
+ public:
+ typedef __see_bellow__ duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<system_clock> time_point;
+ static constexpr bool is_steady = false;
+
+ static time_point now(); // throws on error
+ static time_point now(system::error_code & ec); // never throws
+
+ // Map to C API
+ static std::time_t to_time_t(const time_point& t);
+ static time_point from_time_t(std::time_t t);
+ };
+
+__system_clock satisfy the __clock_req:
+
+* `system_clock::duration::min() < system_clock::duration::zero()` is `true`.
+
+* The nested duration typedef has a resolution that depends on the one provided by the platform.
+
+[section:to_time_t Static Member Function `to_time_t(time_point)`]
+
+time_t to_time_t(const time_point& t);
+
+__returns A `time_t` such that the `time_t` and `t` represent the same point in time, truncated to the courser of the precisions among `time_t` and `t`.
+
+[endsect]
+[section:from_time_t Static Member Function `from_time_t(time_t)`]
+
+ time_point from_time_t(time_t t);
+
+__returns A __time_point such that the __time_point and `t` represent the same point in time, truncated to the coarser of the precisions among __time_point and `t`.
+
+[endsect]
+[endsect]
+
+[section:BOOST_CHRONO_HAS_CLOCK_STEADY Macro `BOOST_CHRONO_HAS_CLOCK_STEADY`]
+
+Defined if the platform support steady clocks.
+
+[endsect]
+
+[section:steady_clock Class `steady_clock`]
+
+__steady_clock satisfy the __clock_req.
+
+__steady_clock class provides access to the system-wide steady clock. The current time can be obtained by calling `steady_clock::now()`. There is no fixed relationship between values returned by `steady_clock::now()` and wall-clock time.
+
+ #ifdef BOOST_HAS_CLOCK_STEADY
+ class steady_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<steady_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ static time_point now(); // throws on error
+ static time_point now(system::error_code & ec); // never throws
+ };
+ #endif
+
+
+
+[endsect]
+
+[section:high_resolution_clock Class `high_resolution_clock`]
+
+__high_resolution_clock satisfy the __clock_req.
+
+ #ifdef __BOOST_CHRONO_HAS_CLOCK_STEADY
+ typedef __steady_clock high_resolution_clock; // as permitted by [time.clock.hires]
+ #else
+ typedef __system_clock high_resolution_clock; // as permitted by [time.clock.hires]
+ #endif
+
+[endsect]
+
+[endsect]
+
+[/=============================================]
+[section:chrono_typeof_hpp Header `<boost/chrono/typeof/boost/chrono/chrono.hpp>`]
+[/=============================================]
+
+Register __duration`<>` and __time_point`<>` class templates to [*Boost.Typeof].
+
+[endsect]
+[endsect]
+
+[section:io Chrono I/O]
+[/==================================================================]
+[section:chrono_io_hpp Header `<boost/chrono/chrono_io.hpp>`]
+[/==================================================================]
+
+
+[/The current implementation makes use of a few utilities in libc++ as `__scan_keyword` which has also been ported and seen as implementation details.]
+
+
+ namespace boost {
+ namespace chrono {
+
+ template <class CharT>
+ class duration_punct;
+
+ template <class Clock, class CharT>
+ struct clock_string;
+
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ duration_short(std::basic_ostream<CharT, Traits>& os);
+
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ duration_long(std::basic_ostream<CharT, Traits>& 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);
+
+ 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)
+
+ 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);
+
+ 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);
+
+ }
+ }
+
+[section:duration_punct Template Class `duration_punct<>`]
+
+The __duration unit names can be customized through the facet: __duration_punct. __duration unit names come in two varieties: long and short. The default constructed __duration_punct provides names in the long format. These names are English descriptions. Other languages are supported by constructing a __duration_punct with the proper spellings for "hours", "minutes" and "seconds", and their abbreviations (for the short format).
+
+ template <class CharT>
+ class duration_punct
+ : public std::locale::facet
+ {
+ public:
+ typedef std::basic_string<CharT> string_type;
+ enum {use_long, use_short};
+
+ static std::locale::id id;
+
+ explicit duration_punct(int use = use_long);
+
+ duration_punct(int use,
+ const string_type& long_seconds, const string_type& long_minutes,
+ const string_type& long_hours, const string_type& short_seconds,
+ const string_type& short_minutes, const string_type& short_hours);
+
+ duration_punct(int use, const duration_punct& d);
+
+ template <class Period> string_type short_name() const;
+ template <class Period> string_type long_name() const;
+ template <class Period> string_type name() const;
+
+ bool is_short_name() const;
+ bool is_long_name() const;
+ };
+
+[endsect]
+
+[section:clock_string Template Class `clock_string<>`]
+
+ template <class Clock, class CharT>
+ struct clock_string;
+
+This template must be specialized for specific clocks. The specialization must define the following functions
+
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+
+`clock_string<>::name()` return the clock name, which usualy corresponds to the class name.
+`clock_string<>::since()` return the textual format of the clock epoch.
+
+
+[endsect]
+
+[section:clock_string_system_clock `clock_string<system_clock>` Specialization]
+
+ template <class CharT>
+ struct clock_string<system_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+
+`clock_string<>::name()` returns "system_clock".
+`clock_string<>::since()` returns " since Jan 1, 1970"
+
+
+[endsect]
+
+[section:clock_string_steady_clock `clock_string<steady_clock>` Specialization]
+
+ #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
+
+ template <class CharT>
+ struct clock_string<steady_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+ #endif
+
+`clock_string<>::name()` returns "steady_clock".
+`clock_string<>::since()` returns " since boot"
+
+[endsect]
+
+[section:clock_string_thread_clock `clock_string<thread_clock>` Specialization]
+
+ #if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+ template <class CharT>
+ struct clock_string<thread_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+ #endif
+
+`clock_string<>::name()` returns "thread_clock".
+`clock_string<>::since()` returns " since thread start-up"
+
+
+[endsect]
+
+[section:clock_string_process_real_cpu_clock `clock_string<process_real_cpu_clock>` Specialization]
+
+ template <class CharT>
+ struct clock_string<process_real_cpu_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+
+`clock_string<>::name()` returns "process_real_cpu_clock".
+`clock_string<>::since()` returns " since process start-up"
+
+[endsect]
+
+[section:clock_string_process_user_cpu_clock `clock_string<process_user_cpu_clock>` Specialization]
+
+ template <class CharT>
+ struct clock_string<process_user_cpu_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+
+`clock_string<>::name()` returns "process_user_cpu_clock".
+`clock_string<>::since()` returns " since process start-up"
+
+
+[endsect]
+
+[section:clock_string_process_system_cpu_clock `clock_string<process_system_cpu_clock>` Specialization]
+
+ template <class CharT>
+ struct clock_string<process_system_cpu_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+
+`clock_string<>::name()` returns "process_system_cpu_clock".
+`clock_string<>::since()` returns " since process start-up"
+
+
+[endsect]
+
+[section:clock_string_process_cpu_clock `clock_string<process_cpu_clock>` Specialization]
+
+ template <class CharT>
+ struct clock_string<process_cpu_clock, CharT>
+ {
+ static std::basic_string<CharT> name();
+ static std::basic_string<CharT> since();
+ };
+
+`clock_string<>::name()` returns "process_cpu_clock".
+`clock_string<>::since()` returns " since process start-up"
+
+
+[endsect]
+
+[section:manipulators I/O Manipulators]
+
+The short or long format can be easily chosen by streaming a `duration_short` or `duration_long` manipulator respectively.
+
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ duration_short(std::basic_ostream<CharT, Traits>& os);
+
+__effects Set the __duration_punct facet to stream __durations and __time_points as abreviations.
+
+__returns the output stream
+
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ duration_long(std::basic_ostream<CharT, Traits>& os);
+
+
+__effects Set the __duration_punct facet to stream durations and time_points as long text.
+
+__returns the output stream
+
+
+[endsect]
+
+[section:streams I/O Streams Operations]
+
+Any __duration can be streamed out to a `basic_ostream`. The run time value of the __duration is formatted according to the rules and current format settings for __duration`::rep`. This is followed by a single space and then the compile time unit name of the __duration. This unit name is built on the string returned from `ratio_string<>` and the data used to construct the __duration_punct which was inserted into the stream's locale. If a __duration_punct has not been inserted into the stream's locale, a default constructed __duration_punct will be added to the stream's locale.
+
+A __time_point is formatted by outputting its internal __duration followed by a string that describes the __time_point`::clock` epoch. This string will vary for each distinct clock, and for each implementation of the supplied clocks.
+
+ 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);
+
+__effects outputs the __duration as an abrevieated or long text format depending on the state of the __duration_punct facet.
+
+__returns the output stream
+
+ 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)
+
+__effects reads a __duration from the input stream. If a format error is found, the input stream state will be set to `failbit`.
+
+__returns the input stream
+
+ 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);
+
+__effects outputs the __time_point as an abrevieated or long text format depending on the state of the __duration_punct facet.
+
+__returns the output stream
+
+
+ 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);
+
+__effects reads a __time_point from the input stream. If a format error is found, the input stream state will be set to `failbit`.
+
+__returns the input stream
+
+[endsect]
+
+
+[endsect]
+[endsect]
+
+[section:other_clocks Other Clocks]
+
+[/==================================================================]
+[section:process_cpu_clocks_hpp Header `<boost/chrono/process_cpu_clocks.hpp>`]
+[/==================================================================]
+
+Knowing how long a program takes to execute is useful in both test and production environments. It is also helpful if such timing information is broken down into real (wall clock) time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests.
+
+Process clocks don't include the time spent by the child process.
+
+ namespace boost { namespace chrono {
+
+ class process_real_cpu_clock;
+ class process_user_cpu_clock;
+ class process_system_cpu_clock;
+ class process_cpu_clock;
+
+ struct process_cpu_clock::times;
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os,
+ process_cpu_clock::times const& rhs);
+
+ template <class CharT, class Traits>
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ process_cpu_clock::times const& rhs);
+
+ template <>
+ struct duration_values<process_cpu_clock::times>;
+ } }
+ namespace std {
+ template <>
+ class numeric_limits<boost::chrono::process_cpu_clock::times>;
+ }
+
+[section:process_real_cpu_clock Class `process_real_cpu_clock`]
+
+__process_real_cpu_clock satisfy the __clock_req.
+
+__process_real_cpu_clock class provides access to the real process wall-clock steady clock, i.e. the real CPU-time clock of the calling process. The process relative current time can be obtained by calling `process_real_cpu_clock::now()`.
+
+ class process_real_cpu_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<process_real_cpu_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ static time_point now( system::error_code & ec = system::throws );
+ };
+
+
+[endsect]
+[section:process_user_cpu_clock Class `process_user_cpu_clock`]
+
+__process_user_cpu_clock satisfy the __clock_req.
+
+__process_user_cpu_clock class provides access to the user CPU-time steady clock of the calling process. The process relative user current time can be obtained by calling `process_user_cpu_clock::now()`.
+
+ class process_user_cpu_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<process_user_cpu_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ static time_point now( system::error_code & ec = system::throws );
+ };
+
+
+[endsect]
+
+[section:process_system_cpu_clock Class `process_system_cpu_clock`]
+
+__process_system_cpu_clock satisfy the __clock_req.
+
+__process_system_cpu_clock class provides access to the system CPU-time steady clockof the calling process. The process relative system current time can be obtained by calling `process_system_cpu_clock::now()`.
+
+ class process_system_cpu_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<process_system_cpu_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ static time_point now( system::error_code & ec = system::throws );
+ };
+
+
+[endsect]
+
+[section:process_cpu_clock Class `process_cpu_clock`]
+
+`process_cpu_clock` can be considered as a `tuple<process_real_cpu_clock, process_user_cpu_clock, process_system_cpu_clock>`.
+
+`process_cpu_clock` provides a thin wrapper around the operating system's process time API. For POSIX-like systems, that's the times() function, while for Windows, it's the `GetProcessTimes()` function.
+
+The process relative real, user and system current time can be obtained at once by calling `process_clocks::now()`.
+
+ class process_cpu_clock
+ {
+ public:
+ struct times ;
+
+ typedef duration<times, nano> duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<process_cpu_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ static time_point now( system::error_code & ec = system::throws );
+ };
+
+[endsect]
+
+[section:times Class `process_cpu_clock::times`]
+
+This class is the representation of the `process_cpu_clock::duration` class. As such it needs to implements the arithmetic operators.
+
+ struct times : arithmetic<times,
+ multiplicative<times, process_real_cpu_clock::rep,
+ less_than_comparable<times> > >
+ {
+ process_real_cpu_clock::rep real; // real (i.e wall clock) time
+ process_user_cpu_clock::rep user; // user cpu time
+ process_system_cpu_clock::rep system; // system cpu time
+
+ times();
+ times(
+ process_real_cpu_clock::rep r,
+ process_user_cpu_clock::rep u,
+ process_system_cpu_clock::rep s);
+
+ bool operator==(times const& rhs);
+
+ times operator+=(times const& rhs);
+ times operator-=(times const& rhs);
+ times operator*=(times const& rhs);
+ times operator/=(times const& rhs);
+ bool operator<(times const & rhs) const;
+ };
+
+[endsect]
+
+[section:times_io `process_cpu_clock::times` Input/Output]
+
+ template <class CharT, class Traits>
+ std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os,
+ process_cpu_clock::times const& rhs);
+
+[*Effect]: Output each part separated by ';' and sourrounded by '{', '}'.
+[*Throws]: None.
+
+ template <class CharT, class Traits>
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ process_cpu_clock::times const& rhs);
+
+[*Effect]: overrides the value of rhs if the input stream has the format "{r;u;s}". Otherwise, set the input stream state as failbit | eofbit.
+[*Throws]: None.
+
+
+[endsect]
+
+[section:times_duration_values `duration_values` Specialization for `times`]
+
+ template <>
+ struct __duration_values<process_cpu_clock::times>
+ {
+ static process_cpu_clock::times zero();
+ static process_cpu_clock::times max();
+ static process_cpu_clock::times min();
+ };
+
+The `times` specific functions `zero()`, `max()` and `min()` uses the relative functions on the representation of each component.
+
+[endsect]
+
+[section:times_numeric_limits `numeric_limits` Specialization for `times`]
+
+ namespace std {
+ template <>
+ class numeric_limits<boost::chrono::process_cpu_clock::times> {
+ typedef boost::chrono::process_cpu_clock::times Rep;
+
+ public:
+ static const bool is_specialized = true;
+ static Rep min();
+ static Rep max();
+ static Rep lowest();
+ static const int digits;
+ static const int digits10;
+ static const bool is_signed = false;
+ static const bool is_integer = true;
+ static const bool is_exact = true;
+ static const int radix = 0;
+ };
+ }
+
+The `times` specialization functions `min()`, `max()` and `lowest()` uses the relative functions on the representation of each component.
+
+Notes
+
+* `min()` returns the tuple of min's
+* `max()` returns the tuple of max's
+* `lowest()' returns the tuple of lowest's
+* `digits' is the sum of digits's
+* `digits10' is the sum of digits10's
+
+[endsect]
+
+[endsect]
+
+[/==================================================================]
+[section:thread_clock_hpp Header `<boost/chrono/thread_clock.hpp>`]
+[/==================================================================]
+
+Knowing the time a thread takes to execute is useful in both test and production environments.
+
+ #define BOOST_CHRONO_HAS_THREAD_CLOCK
+ #define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY
+ namespace boost { namespace chrono {
+
+ class thread_clock;
+
+ } }
+
+[section:BOOST_CHRONO_HAS_THREAD_CLOCK Macro `BOOST_CHRONO_HAS_THREAD_CLOCK`]
+
+This macro is defined if the platform supports thread clocks.
+
+[endsect]
+
+[section:BOOST_CHRONO_THREAD_CLOCK_IS_STEADY Macro `BOOST_CHRONO_THREAD_CLOCK_IS_STEADY`]
+
+This macro is defined if the platform has a thread clockIts value is true if it is steady and false otherwise.
+
+[endsect]
+
+[section:thread_clock Class `thread_clock`]
+
+__thread_clock satisfy the __clock_req.
+
+__thread_clock class provides access to the real thread wall-clock, i.e. the real CPU-time clock of the calling thread. The thread relative current time can be obtained by calling `thread_clock::now()`.
+
+ class thread_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<thread_clock> time_point;
+ static constexpr bool is_steady = BOOST_CHRONO_THREAD_CLOCK_IS_STEADY;
+
+ static time_point now( system::error_code & ec = system::throws );
+ };
+
+
+[endsect]
+
+[endsect]
+
+
+
+[endsect]
+
+[/
+[section:deprecated Deprecated Headers]
+
+See Boost.Stopwatches for similar functionality.
+
+[/==================================================]
+[section:timer_hpp Deprecated Header `<boost/chrono/timer.hpp>`]
+[/==================================================]
+
+This header has been deprecated, use instead <boost/chrono/stopwatch.hpp>.
+
+ namespace boost { namespace chrono {
+ template <class Clock=high_resolution_clock> class timer;
+ typedef <see above> system_timer;
+ #ifdef __BOOST_CHRONO_HAS_CLOCK_STEADY
+ typedef <see above> steady_timer;
+ #endif
+ typedef <see above> high_resolution_timer;
+ }}
+
+[/
+ typedef <see above> process_real_cpu_timer;
+ typedef <see above> process_user_cpu_timer;
+ typedef <see above> process_system_cpu_timer;
+]
+[section:timer Template Class `timer<>`]
+
+Knowing how long a part of a program takes to execute is useful in both test and production environments.
+A `timer` object measures elapsed time. It is recommended to use it with clocks that measure wall clock rather than CPU time since the intended use is performance measurement on systems where total elapsed time is more important than just process or CPU time.
+
+The maximum measurable elapsed time depends on the Clock parameter. The accuracy of timings depends on the
+accuracy of timing information provided the Clock, and this coudl varies a great deal from one clock to another.
+
+ template <class Clock> class timer {
+ public:
+ typedef Clock clock;
+ typedef typename Clock::duration duration;
+ typedef typename Clock::time_point time_point;
+
+ explicit timer( system::error_code & ec = system::throws );
+
+ ~timer();
+
+ void start( system::error_code & ec = system::throws );
+ duration elapsed( system::error_code & ec = system::throws );
+
+ };
+
+[endsect]
+
+[section:timer_typedefs `timer` useful typedefs]
+
+ typedef boost::chrono::timer< boost::chrono::system_clock >
+ system_timer;
+ #ifdef __BOOST_CHRONO_HAS_CLOCK_STEADY
+ typedef boost::chrono::timer< boost::chrono::steady_clock >
+ steady_timer;
+ #endif
+ typedef boost::chrono::timer< boost::chrono::high_resolution_clock >
+ high_resolution_timer;
+
+[/
+ typedef boost::chrono::timer< boost::chrono::process_real_cpu_clock > process_real_cpu_timer;
+ typedef boost::chrono::timer< boost::chrono::process_user_cpu_clock > process_user_cpu_timer;
+ typedef boost::chrono::timer< boost::chrono::process_system_cpu_clock > process_system_cpu_timer;
+]
+[endsect]
+[endsect]
+
+
+[/==================================================================]
+[section:process_times_hpp Deprecated Header `<boost/chrono/process_times.hpp>`]
+[/==================================================================]
+
+This header has been deprecated. Use instead `<boost/chrono/process_cpu_clocks.hpp>`, `<boost/chrono/stopwatch.hpp>`, `<boost/chrono/stopwatch_reporter.hpp>` and `<boost/chrono/stopclock.hpp>` files.
+
+ namespace boost { namespace chrono {
+
+ class process_clock;
+ typedef <see below> process_times;
+ class process_timer;
+ class run_timer;
+
+ } }
+
+[section:process_clock Class `process_clock`]
+
+`process_clock` doesn't satisfy the Clock Requirements as the function now do not follows the Clock prototype.
+
+`process_clock` provides a thin wrapper around the operating system's process time API. For POSIX-like systems, that's the times() function, while for Windows, it's the GetProcessTimes() function.
+
+The process relative real, user and system current time can be obtained at once by calling `process_clock::now()`.
+
+
+ class process_clock {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::__time_point<process_clock> time_point;
+ static constexpr bool is_steady = true;
+
+ struct process_times;
+ static void now( process_times & times,
+ system::error_code & ec = system::throws );
+ };
+
+[section:process_times Class `process_times`]
+
+ struct process_times {
+ process_clock::duration real; // real (i.e wall clock) time
+ process_clock::duration user; // user cpu time
+ process_clock::duration system; // system cpu time
+ };
+
+[endsect]
+
+[endsect]
+[section:process_times Typedef `process_times`]
+
+ typedef process_clock::process_times process_times;
+
+This is a synonym of process_clock::process_times included for backward compatibility.
+
+[endsect]
+
+[section:process_timer Class `process_timer`]
+
+Knowing how long a program takes to execute is useful in both test and production environments. It is also helpful if such timing information is broken down into real (wall clock) time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests.
+
+`process_timer<>` is the `timer<>` equivalent associated to the pseudo-clock `process_clock`. It behaves like `timer<>` but it uses the specific `process_clock:now()` function.
+
+ class process_timer {
+ public:
+ typedef process_clock clock;
+ typedef process_clock::duration duration;
+ typedef process_clock::time_point time_point;
+
+ explicit process_timer( system::error_code & ec = system::throws );
+
+ ~process_timer();
+ void start( system::error_code & ec = system::throws );
+ void elapsed( process_times & times, system::error_code & ec = system::throws );
+ };
+
+[endsect]
+[section:run_timer Class `run_timer`]
+
+class `run_timer` provides a complete run time reporting package that can be invoked in a single line of code. The reporting is controlled by two parameters:
+
+* format : The output format
+* places(precision): the number of decimal placess used.
+
+The default places is given by default_places and is 3.
+
+The default format is "nreal %rs, cpu %cs (%p%), user %us, system %ss\\n", where
+
+* `%r` : real process clock
+* `%u` : user process clock
+* `%s` : system process clock
+* `%c` : user+system process clock
+* `%p` : percentage (user+system)/real process clock
+
+All the units are given using the suffix "s" following the System International d'Unites Std.
+
+ class run_timer : public process_timer {
+ public:
+ explicit run_timer( system::error_code & ec = system::throws );
+ explicit run_timer( std::ostream & os,
+ system::error_code & ec = system::throws );
+
+ explicit run_timer( const std::string & format,
+ system::error_code & ec = system::throws );
+ explicit run_timer( std::ostream & os, const std::string & format,
+ system::error_code & ec = system::throws );
+
+ explicit run_timer( const std::string & format, int places,
+ system::error_code & ec = system::throws );
+ explicit run_timer( std::ostream & os, const std::string & format, int places,
+ system::error_code & ec = system::throws );
+
+ explicit run_timer( int places,
+ system::error_code & ec = system::throws );
+ explicit run_timer( std::ostream & os, int places,
+ system::error_code & ec = system::throws );
+
+ explicit run_timer( int places, const std::string & format,
+ system::error_code & ec = system::throws );
+ explicit run_timer( std::ostream & os, int places, const std::string & format,
+ system::error_code & ec = system::throws );
+
+ ~run_timer();
+
+ void start( system::error_code & ec = system::throws );
+
+ void report( system::error_code & ec = system::throws );
+
+ void test_report( duration real_, duration user_, duration system_ );
+ bool reported() const;
+ static int default_places();
+ };
+
+
+[endsect]
+
+[endsect]
+
+[endsect]
+]
+
+[endsect]
+
+
+[/=================]
+[section Appendices]
+[/=================]
+
+[/==================================]
+[section:history Appendix A: History]
+[/==================================]
+
+[/
+[section [*Version 1.0.0, January 6, 2011] ]
+
+* Moved chrono to trunk taking in account the review remarks.
+* Documentation revision.
+
+[endsect]
+]
+[/
+[section [*Version 0.7.0, October 30, 2010] ]
+
+[*Features:]
+
+* Boost_Chrono is now a configurable header only lib that allows the user to choose in addition if the windows file is included or not.
+* Added clock_string<> traits.
+* Define chrono-io for all the clocks
+* Add input of process_times representation
+
+[*Implementation:]
+
+* Moved some details to static_integer directory.
+* Use of detail/win files to avoid the use of windows.h file.
+* Completed the error_code handling.
+* Works now with BOOST_SYSTEM_NO_DEPRECATED.
+
+[*Fixes:]
+
+* Fix some warnings.
+* Fix original error on Mac
+* Dont fix the link with boost_system to static.
+
+[*Test:]
+
+* Added test on process and thread clocks.
+* Moved to lightweight_test.hpp.
+* Able to test multiple configurations.
+
+[*Doc:]
+
+* Removed some not useful parts as the history, the test and the tickets.
+
+[endsect]
+[section [*Version 0.6.0, September 22, 2010] ]
+
+[*Features:]
+
+* Added experimental chrono_io.
+
+[*Fixes:]
+
+* Fix duration values min implementation.
+* Fix some warnings
+
+[*Test:]
+
+* Adapted test from libc++/chrono
+
+[endsect]
+
+[section [*Version 0.5.0, September 10, 2010] ]
+
+[*Features:]
+
+* Stopwatches, Ratio and CommonType have been moved to separated libraries: Boost.Stopwatches, Boost.Ratio and Boost.TypeTraits.
+
+[endsect]
+
+[section [*Version 0.4.7, September 1, 2010] ]
+
+[*New Features:]
+
+* Added __lightweight_stopwatch__.
+
+[endsect]
+
+[section [*Version 0.4.6, August 28, 2010] ]
+
+[*New Features:]
+
+* Implementation of __common_type without using Boost.TypeOf.
+* Added __stopwatch_accumulator_time_formatter__ class.
+
+[*Old Features:]
+
+* Type reporter removed from Stopwatches as well as the get_reporter metafunction.
+
+[*Bug Fixes]
+
+* __process_cpu_clock is now a valid model of Clock that can be used with __stopclocks_accumulator__.
+* eliminate or suppress a lot of warnings appearing with with warnings=all -Wextra
+* improve the error code handling
+
+[endsect]
+
+[section [*Version 0.4.5, July 6, 2010] ['Documentation update]]
+
+[*Documentation]
+
+* Overview rewriting
+* Added missing __thread_clock reference.
+* How to implement a __thread_clock tutorial removed.
+* References section renamed to External Resources.
+* Added links to source examples.
+* Added links between Models and Concepts.
+* Added macros descriptions.
+* Cleanup.
+
+[*Bug Fixes]
+
+* Valgrind fixes: "Conditional jump or move depends on uninitialised value(s)"
+* Take care of Boost.System break on version 1.44
+* gcc.4.4 "warning: suggest parentheses around '&&' within '||' " removal.
+
+[endsect]
+
+[section [*Version 0.4.4, February 22, 2010] [' Warning fixes]]
+
+[*Bug Fixes]
+
+* `scoped_suspend` warning removal
+* `error_code` management completed
+
+[endsect]
+
+[section [*Version 0.4.3, June 18, 2010] ['Missing file fixe]]
+
+[*Bug Fixes]
+
+* boost/thread/detail/cv_status.hpp file was not commited.
+
+[endsect]
+
+[section [*Version 0.4.2, June 18, 2010] ['Packaging fixe]]
+
+* Boost.Conversion library, used by Boost.Thread porting to Boost.Chrono was not packaged.
+
+[endsect]
+
+[section [*Version 0.4.1, June 17, 2010] ['Added thread clock implementation on Windows]]
+
+[*New Features:]
+
+* Added __thread_clock implementation on Windows.
+* Added *Boost.Thread* using *Boost.Chrono*.
+
+[endsect]
+
+[section [*Version 0.4, February 28, 2010] ['New thread clock and Suspendible clock ]]
+
+[*New Features:]
+
+* __SuspendibleClock__ concept + template class _suspendible_clock__.
+* Added `scope_suspend` which do `suspend`/`resume` if the __Clock is a model of __SuspendibleClock__ concept, and nothing otherwise.
+* __thread_clock support on platforms providing it natively.
+* Added support for wide character for __stopwatch_reporter__, `stopclock`, and `stopclock_accumulator`.
+* `digital_time` renamed `t24_hours`.
+
+[*Perf]
+
+Added performances measures.
+
+[*Bug Fixes]
+
+* Bug on timeval_demo.
+
+ time_point t(duration(xtime(0))); // this was taken as a function declaration
+ gettimeofday((timeval*)&t, 0);
+ return t;
+by
+
+ timeval tv;
+ gettimeofday(&tv, 0);
+ xtime xt( tv.tv_sec, tv.tv_usec);
+ return time_point(duration(xt));
+
+* Bug on run_timer_test (add a global variable to avoid optimization that removes completely the code to be measured
+
+[endsect]
+
+[section [*Version 0.3.2, January 25, 2010] ['New frequency, lifetime and percentage stopwatch_accumulator features]]
+[*Features:]
+
+* Added overloading for `operator/(Integer/Duration)`
+* Added frequency, lifetime and percentage to the default `stopwatch_accumulator_formatter`.
+
+[*Bug Fixes]
+* Specific formatters didn't work completly.
+* Replace `duration(0)` by `duration::zero()` on template classes.
+* `suspend` doesn't works: `partial_` not initialized neither taken in account by the elapsed function.
+
+[endsect]
+
+[section [*Version 0.3.1, January 20, 2010] ['New support for wide characters]]
+[*Features:]
+
+* Support for wide characters on formatters and stopclocks
+* added `chrono.hpp` and `stopwatches.hpp` at the boost level
+
+
+[endsect]
+
+[section [*Version 0.3.0, January 17, 2010] ['New stopwatch/stopclock feature + Bug fixes]]
+[*Features:]
+
+* Added independent process cpu clocks for real, user, system process CPU time
+* Added global process cpu clock for real, user, system process CPU time
+* Added `digital_time` (looking for a better name)
+* Added new __Stopwatch__ concept measuring elapsed time between different points in time associated to the operations `start`, `stop`, `suspend` and `resume`.
+* Added __stopwatch__ is a model __Stopwatch__ measuring the elapsed time between the `start` and the `stop` operations.
+* Added __stopwatch_accumulator__ is a model __Stopwatch__ allowing to accumulate several time samples and gives the average, ...
+* Added scoped helper classes allowing to pairwise `start`/`stop` operations, `suspend`/`resume` and `resume`/`suspend` a __Stopwatch__.
+* Added new stopwatch __Formatter__ concept
+ * Added stopwatch formatter "%ds\\n"
+ * Added stopwatch accumulator formatter "%c times, sum=%ss, min=%ms, max=%Ms, mean=%as\\n"
+ * Added time formatter "real %rs, cpu %cs (%p%), user %us, system %ss\\n"
+ * Added digital_time formatter "%d days(s) %h:%m:%s.%n\\n"
+* __stopwatch_reporter__ is a convenient generic class reporting elapsed time for the Stopwatch concept.
+* Added `stopclock<Clock>` shortcut `stopwatch_reporter<stopwatch<Clock>>`
+* Added __scoped_stopclock__ which trace at the constuctor and destructor.
+* Added `typeof` registration for classes __duration and __time_point
+
+* The old classes `process_times`, `process_clock`, `process_timer`, `timer` and `run_timer` are deprecated as the preceding additions are more generic. However for backward compatibility they preserved until inclusion of the library in Boost. Next follows the equivalences:
+ * `timer<>` ~ `stopwatch<>`
+ * `process_timer` ~ `stopwatch<process_cpu_clock>`
+ * `run_timer` ~ `stopclock<>`
+
+[*Bug Fixes]
+
+* Try to correct warning "C4251: 'boost::chrono::run_timer::m_format' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'boost::chrono::run_timer'", by don't including inlines functions using the std::string `m_format`.
+
+[endsect]
+
+[section [*Version 0.2.1, December 13, 2009] ['Bug fixes]]
+
+[*Bug Fixes]
+
+* Replace `INTMAX_C` by `BOOST_INTMAX_C` until `boost/cstdint.hpp` ensures `INTMAX_C` is always defined.
+* Define __BOOST_CHRONO_HAS_CLOCK_STEADY__ when `BOOST_CHRONO_WINDOWS_API`
+* Commenting invalid operator declarations
+* Take care of Boost `min`/`max` recommendations
+* Complete qualification when defining nested typedef duration on clocks to avoid the following compile error:
+
+ ./boost/chrono/chrono.hpp:945: error: declaration of 'typedef class boost::chrono::duration<long long int, boost::__ratio<1ll, 10000000ll> > boost::chrono::system_clock::duration'
+ ./boost/chrono/chrono.hpp:458: error: changes meaning of 'duration' from 'class boost::chrono::duration<long long int, boost::__ratio<1ll, 10000000ll> >'
+
+* cleanup of simulated...
+* warning removal on `posix/process_clock.cpp`.
+* disable VC++ foolishness.
+* Update Jamfiles to manage with dll.
+* removal of conversion warning in test_duration.
+* manage with MSVC reporting a warning instead of an error when there is an integral constant overflow.
+* Use `STATIC_ASSERT` specific macro to solve the compile failing issue.
+* Qualify with `boost::detail` `boost::chrono::detail` to avoid ambiguities with MSVC.
+
+
+[*Documentation:]
+
+More updated documentation.
+
+[endsect]
+
+[section [*Version 0.2.0, December 8, 2009] ['+ Features + Bug fixes + Updated documentation]]
+
+[*Features:]
+
+* Added __ratio construction and assignment from an equivalent __ratio ([@http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#1281 [*LWG 1281. CopyConstruction and Assignment between ratios having the same normalized form]])
+* Added nested __ratio typedef type ([@http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#1281 [*LWG 1281. CopyConstruction and Assignment between ratios having the same normalized form]])
+* Added __BOOST_CHRONO_HAS_CLOCK_STEADY__ macro to state if __steady_clock is provided on this platform.
+* Added __duration `operator%` ([@http://home.roadrunner.com/~hinnant/issue_review/lwg-defects.html#934 [*LGW 934. duration is missing operator%]])
+* Added constexpr when constexpr should be used.
+* Complete __duration `operator*` and `operator/`.
+
+
+[*Implementation:]
+
+* Use `INTMAC_C` to name `intmax_t` constants instead of `LL`.
+* Separate `chrono.cpp` on # files `win/chrono.cpp`, `mac/chrono.cpp` and `posix/chrono.cpp` to make easier the maintenance on different platforms.
+* Separate `process_clock.cpp` on # files `win/process_clock.cpp`, `mac/process_clock.cpp` and `posix/process_clock.cpp` to make easier the maintenace on different platforms.
+* Added the `error_code` prototype for `steady_clock::now` for `mac/chrono.cpp`.
+* Fully implement `mac/chrono.cpp` with error handling.
+* Take care on POSIX systems when `CLOCK_STEADY` is not defined.
+
+[*Documentation:]
+
+* The documentation is written now using quick-book using as base [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm [*N2661 - A Foundation to Sleep On]] .
+
+[*Bug Fixes]
+
+* `operator/` was ambiguous: Disambiguate duration `operator/`.
+* `CLOCK_STEADY` is not defined with cygwin/gcc 3.4: Disable code when __BOOST_CHRONO_HAS_CLOCK_STEADY__ is not defined.
+* result of metafunctions `ratio_multiply` and `ratio_divide` were not normalized ratios: Use of the nested __ratio typedef type on __ratio arithmetic operations.
+* Copy constructor from similar __duration masked the defaulted operations: Added duration defaulted implementations
+
+
+[endsect]
+[section [*Version 0.1.0, April 29, 2009] ['Beman's boostified version Chrono]]
+
+[*Features:]
+
+* The C++0x Standard Library's __common_type.
+* The C++0x Standard Library's compile-time rational arithmetic.
+* The C++0x Standard Library's time utilities, including:
+ * Class template __duration
+ * Class template __time_point
+ * Clocks:
+ * __system_clock
+ * __steady_clock
+ * `high_resolution_clock`
+
+* Class template timer, with typedefs:
+ * `system_timer`
+ * `steady_timer`
+ * `high_resolution_timer`
+
+* Process clocks and timers:
+ * `process_clock`, capturing real, user-CPU, and system-CPU times.
+ * `process_timer`, capturing elapsed real, user-CPU, and system-CPU times.
+ * `run_timer`, convenient reporting of process_timer results.
+
+
+[endsect]
+]
+[endsect]
+
+[/======================================]
+[section:rationale Appendix B: Rationale]
+
+See [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm [*N2661 - A Foundation to Sleep On]] which is very informative and provides motivation for key design decisions. This section contains some extracts from this document.
+
+[heading Is it possible for the user to pass a __duration to a function with the units being ambiguous?]
+
+No. No matter which option the author of `f` chooses above, the following client code will not compile:
+
+ f(3); // Will not compile, 3 is not implicitly convertible to any __duration
+
+[heading Why duration needs operator%]
+
+This operator is convenient for computing where in a time frame a given duration lies. A motivating example is converting a duration into a "broken-down" time duration such as hours::minutes::seconds:
+
+ class ClockTime
+ {
+ typedef boost::chrono::hours hours;
+ typedef boost::chrono::minutes minutes;
+ typedef boost::chrono::seconds seconds;
+ public:
+ hours hours_;
+ minutes minutes_;
+ seconds seconds_;
+
+ template <class Rep, class Period>
+ explicit ClockTime(const boost::chrono::duration<Rep, Period>& d)
+ : hours_ (boost::chrono::duration_cast<hours> (d)),
+ minutes_(boost::chrono::duration_cast<minutes>(d % hours(1))),
+ seconds_(boost::chrono::duration_cast<seconds>(d % minutes(1)))
+ {}
+ };
+
+[endsect]
+
+
+[/======================================================]
+[section:implementation Appendix C: Implementation Notes]
+
+[heading Which APIs have been chosen to implement each clock on each platform?]
+
+The following table presents a resume of which API is uused for each clock on each platform
+[table Clock API correspondence
+ [[Clock] [Windows Platform] [Posix Platform] [Mac Platform] ]
+ [[__system_clock] [GetSystemTimeAsFileTime] [clock_gettime( CLOCK_REALTIME)] [gettimeofday] ]
+ [[__steady_clock] [QueryPerformanceCounter and QueryPerformanceFrequency]
+ [clock_gettime( CLOCK_STEADY)] [mach_timebase_info,mach_absolute_time] ]
+ [[__process_real_cpu_clock] [GetProcessTimes] [times] [times] ]
+ [[__process_system_cpu_clock] [GetProcessTimes] [times] [times] ]
+ [[__process_user_cpu_clock] [GetProcessTimes] [times] [times] ]
+ [[__process_cpu_clock] [GetProcessTimes] [times] [times] ]
+ [[__thread_clock] [GetThreadTimes] [clock_gettime(pthread_getcpuclockid)] [pthread_getcpuclockid] ]
+]
+
+[endsect]
+
+[/======================================================]
+[section:faq Appendix D: FAQ]
+
+[heading Why does process_cpu_clock sometimes give more cpu seconds than real seconds?]
+
+Ask your operating system supplier. The results have been inspected with a debugger, and both for Windows and Linux, that's what the OS appears to be reporting at times.
+
+
+[heading Are integer overflows in the duration arithmetic detected and reported?]
+
+[*Boost.Ratio] avoids all kind of overflow that could result of arithmetic operation and that can be simplified. The typedefs durations don't detect overflow. You will need a representation that handles with.
+
+[heading What clock should be used to benchmarking?]
+
+Each clock has his own features. It depends on what do you need to benchmark. Most of the time, you could be interested in using a thread clock, but if you need to measure code subject to synchronization a process clock would be better. If you have a multi-process application, a system-wide clock will be needed.
+
+
+[endsect]
+
+[/====================================================]
+[section:acknowledgements Appendix E: Acknowledgements]
+
+The library's code was derived from Howard Hinnant's time2_demo prototype. Many thanks to Howard for making his code available under the Boost license. The original code was modified by Beman Dawes to conform to Boost conventions.
+
+time2_demo contained this comment:
+
+Much thanks to Andrei Alexandrescu, Walter Brown, Peter Dimov, Jeff Garland, Terry Golubiewski, Daniel Krugler, Anthony Williams.
+
+The file <boost/chrono_io.hpp> has been adapted from the experimental header `<chrono_io>` from Howard Hinnant. Thanks for all Howard.
+
+Howard Hinnant, who is the real author of the library, has provided valuable feedback and suggestions during the development of the library. In particular, The chrono_io_io.hpp source has been adapted from the experimental header `<chrono_io>` from Howard Hinnant.
+
+The acceptance review of Boost.Ratio took place between November 5th and 15th 2010. Many thanks to Anthony Williams, the review manager, and to all the reviewers: David Deakins, John Bytheway, Roland Bock and Paul A. Bristol.
+
+Thanks to Ronald Bock, Andrew Chinoff, Paul A. Bristol and John Bytheway for his help polishing the documentation.
+
+Thanks to Tom Tan for reporting some compiler issues with MSVC V10 beta and MinGW-gcc-4.4.0 and for the many pushing for an homogeneous `process_cpu_clock` clock.
+
+Thanks to Ronald Bock for reporting Valgind issues and for the many suggestion he did concerning the documentation.
+
+[endsect]
+
+[/
+[/====================================================]
+[section:tests Appendix F: Tests]
+
+In order to test you need to do.
+
+ bjam libs/chrono/test
+
+You can also run a specific suite of test by doing
+
+ cd libs/chrono/test
+ bjam chrono
+
+
+[section chrono]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[chrono_unit_test] [run] [...] [Pass] [#]]
+ [[explore_limits] [run] [...] [Pass] [#]]
+ [[test_duration] [run] [...] [Pass] [#]]
+ [[test_clock] [run] [...] [Pass] [#]]
+ [[miscellaneous] [run] [...] [Pass] [#]]
+ [[test_special_values] [run] [...] [Pass] [#]]
+ [[manipulate_clock_object] [run] [...] [Pass] [#]]
+ [[chrono_accuracy_test] [run] [...] [Pass] [#]]
+
+]
+[endsect]
+
+[section examples]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[cycle_count] [run] [...] [Pass] [#]]
+ [[runtime_resolution] [run] [...] [Pass] [#]]
+ [[xtime] [run] [...] [Pass] [#]]
+ [[saturating] [run] [...] [Pass] [#]]
+ [[min_time_point] [run] [...] [Pass] [#]]
+ [[i_dont_like_the_default_duration_behavior] [run] [...] [Pass] [#]]
+ [[simulated_thread_interface_demo] [run] [...] [Pass] [#]]
+ [[timeval_demo] [run] [...] [Pass] [#]]
+]
+[endsect]
+
+
+[section Other Clocks]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[test_thread_clock] [run] [test basic uses of thread_clock.] [Pass] [#]]
+]
+[endsect]
+
+[section:typedefs Duration Typedef's]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[hours.pass] [run] [check how many hours we can count.] [Pass] [#]]
+ [[minutes.pass] [run] [check how many minutes we can count.] [Pass] [#]]
+ [[seconds.pass] [run] [check how many seconds we can count.] [Pass] [#]]
+ [[milliseconds.pass] [run] [check how many milliseconds we can count.] [Pass] [#]]
+ [[microseconds.pass] [run] [check how many microseconds we can count.] [Pass] [#]]
+ [[nanoseconds.pass] [run] [check how many nanoseconds we can count.] [Pass] [#]]
+]
+[endsect]
+
+[section traits]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[specialization.duration.pass] [run] [check the correct common_type specialization has been done for duration.] [Pass] [#]]
+ [[specialization.time_point.pass] [run] [check the correct common_type specialization has been done for time_point.] [Pass] [#]]
+ [[is_fp.treat_as_floating_point.pass] [run] [check treat_as_floating_point<T> inherits from is_floating_point<T>.] [Pass] [#]]
+ [[duration_values.max.pass] [run] [check max() corresponds to std::numeric_limits<T>::max().] [Pass] [#]]
+ [[duration_values.min.pass] [run] [check min() corresponds to std::numeric_limits<T>::lowest().] [Pass] [#]]
+ [[duration_values.zero.pass] [run] [check zero is 0.] [Pass] [#]]
+]
+[endsect]
+
+[section duration]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[duration.fail] [compile-fail] [If a program instantiates duration with a duration type for the template argument Rep a diagnostic is required.] [Pass] [#]]
+ [[ratio.fail] [compile-fail] [Period shall be a specialization of ratio, diagnostic required..] [Pass] [#]]
+ [[positive.fail] [compile-fail] [Period::num shall be positive, diagnostic required..] [Pass] [#]]
+ [[defaul_ratio.pass] [run] [Test default template arg.] [Pass] [#]]
+ [[types.pass] [run] [Test nested types.] [Pass] [#]]
+
+ [[arithmetic.op_divide_ass.pass] [run] [check duration& operator/=(const rep& rhs);] [Pass] [#]]
+ [[arithmetic.op_minusminusint.pass] [run] [check duration operator--(int);] [Pass] [#]]
+ [[arithmetic.op_plus_ass.pass] [run] [check duration& operator+=(const duration& d);] [Pass] [#]]
+ [[arithmetic.op_minus.pass] [run] [check duration operator-() const;] [Pass] [#]]
+ [[arithmetic.op_mod_ass_duration.pass] [run] [check duration& operator%=(const duration& rhs);] [Pass] [#]]
+ [[arithmetic.op_plusplus.pass] [run] [check duration& operator++();.] [Pass] [#]]
+ [[arithmetic.op_minus_ass.pass] [run] [check duration& operator-=(const duration& d);] [Pass] [#]]
+ [[arithmetic.op_mod_ass_rep.pass] [run] [check duration& operator%=(const rep& rhs)] [Pass] [#]]
+ [[arithmetic.op_plusplusint.pass] [run] [check duration operator++(int);] [Pass] [#]]
+ [[arithmetic.op_minusminus.pass] [run] [check duration operator--();] [Pass] [#]]
+ [[arithmetic.op_plus.pass] [run] [check duration operator+() const;] [Pass] [#]]
+ [[arithmetic.op_times_ass.pass] [run] [check duration& operator*=(const rep& rhs);.] [Pass] [#]]
+
+ [[cast.duration_cast.pass] [run] [check template <class ToDuration, class Rep, class Period> ToDuration duration_cast(const duration<Rep, Period>& d);] [Pass] [#]]
+ [[cast.toduration.fail] [compile-fail] [check ToDuration shall be an instantiation of duration.] [Pass] [#]]
+
+ [[comparisons.op_equal.pass] [run] [check operator==() and operator!=().] [Pass] [#]]
+ [[comparisons.op_less.pass] [run] [check operators <,<=,>,>=.] [Pass] [#]]
+
+]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+
+ [[cons.convert_exact.pass] [run] [check exact conversions allowed for integral reps.] [Pass] [#]]
+ [[cons.convert_float_to_int.fail] [compile-fail] [check conversions from floating point to integral durations disallowed.] [Pass] [#]]
+ [[cons.convert_inexact.fail] [compile-fail] [check inexact conversions disallowed for integral reps.] [Pass] [#]]
+ [[cons.convert_inexact.pass] [run] [check inexact conversions allowed for floating point reps.] [Pass] [#]]
+ [[cons.convert_int_to_float.pass] [run] [check conversions from integral to floating point durations allowed.] [Pass] [#]]
+ [[cons.default.pass] [run] [check Rep must be default initialized, not initialized with 0.] [Pass] [#]]
+ [[cons.rep.pass] [run] [check explicit duration(const Rep2& r).] [Pass] [#]]
+ [[cons.rep01.fail] [compile-fail] [test for explicit.] [Pass] [#]]
+ [[cons.rep02.fail] [compile-fail] [check Rep2 shall be implicitly convertible to rep.] [Pass] [#]]
+ [[cons.rep02.pass] [run] [check construct double with int.] [Pass] [#]]
+ [[cons.rep03.fail] [compile-fail] [treat_as_floating_point<Rep2>::value shall be false.] [Pass] [#]]
+
+ [[nonmember.op_plus.pass] [run] [check operator+(d,d).] [Pass] [#]]
+ [[nonmember.op_minus.pass] [run] [check operator-(d,d).] [Pass] [#]]
+ [[nonmember.op_divide_duration.pass] [run] [check operator/(d,d).] [Pass] [#]]
+ [[nonmember.op_divide_rep.fail] [compile-fail] [check operator/(d,r) fails with different rep.] [Pass] [#]]
+ [[nonmember.op_divide_rep.pass] [run] [check operator/(d,r).] [Pass] [#]]
+ [[nonmember.op_mod_duration.pass] [run] [check operator%(d,d).] [Pass] [#]]
+ [[nonmember.op_mod_rep.pass] [run] [check operator%(d,r).] [Pass] [#]]
+ [[nonmember.op_times_rep.pass] [run] [check operator*(d,r).] [Pass] [#]]
+ [[nonmember.op_times_rep1.fail] [compile-fail] [check operator*(d,r) fails with different rep.] [Pass] [#]]
+ [[nonmember.op_times_rep2.fail] [compile-fail] [check operator*(r,d) fails with different rep.] [Pass] [#]]
+ [[special.max.pass] [run] [check coherency between max and duration_values traits.] [Pass] [#]]
+ [[special.min.pass] [run] [check coherency between min and duration_values traits.] [Pass] [#]]
+ [[special.zero.pass] [run] [check coherency between zero and duration_values traits.] [Pass] [#]]
+]
+[endsect]
+
+[section time_point]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[default_duration.pass] [run] [check .] [Pass] [#]]
+ [[duration.fail] [compile-fail] [check .] [Pass] [#]]
+
+ [[arithmetic.op_plus_ass.pass] [run] [check .] [Pass] [#]]
+ [[arithmetic.op_plus_ass.pass] [run] [check .] [Pass] [#]]
+ [[cast.time_point_cast.pass] [run] [check .] [Pass] [#]]
+ [[cast.toduration.fail] [compile-fail] [check .] [Pass] [#]]
+ [[comparisons.op_equal.fail] [compile-fail] [check .] [Pass] [#]]
+ [[comparisons.op_equal.pass] [run] [check .] [Pass] [#]]
+ [[comparisons.op_less.fail] [compile-fail] [check .] [Pass] [#]]
+ [[comparisons.op_less.pass] [run] [check .] [Pass] [#]]
+ [[cons.convert.fail] [compile-fail] [check .] [Pass] [#]]
+ [[cons.convert.pass] [run] [check .] [Pass] [#]]
+ [[cons.default.pass] [run] [check .] [Pass] [#]]
+ [[cons.duration..fail] [compile-fail] [check .] [Pass] [#]]
+ [[cons.duration.pass] [run] [check .] [Pass] [#]]
+ [[nonmember.op_plus.pass] [run] [check .] [Pass] [#]]
+ [[nonmember.op_minus_time_point.pass] [run] [check .] [Pass] [#]]
+ [[nonmember.op_minus_duration.pass] [run] [check .] [Pass] [#]]
+ [[special.max.pass] [run] [check .] [Pass] [#]]
+ [[special.min.pass] [run] [check .] [Pass] [#]]
+]
+[endsect]
+
+[section clock]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[hires.consistency.pass] [run] [check .] [Pass] [#]]
+ [[hires.now.pass] [run] [check .] [Pass] [#]]
+ [[steady.consistency.pass] [run] [check .] [Pass] [#]]
+ [[steady.now.pass] [run] [check .] [Pass] [#]]
+ [[system.consistency.pass] [run] [check .] [Pass] [#]]
+ [[system.now.pass] [run] [check .] [Pass] [#]]
+ [[system.from_time_t.pass] [run] [check .] [Pass] [#]]
+ [[system.rep_signed.pass] [run] [check .] [Pass] [#]]
+ [[system.rep_signed.pass] [run] [check .] [Pass] [#]]
+ [[process.consistency.pass] [run] [check .] [Pass] [#]]
+ [[process.now.pass] [run] [check .] [Pass] [#]]
+ [[thread.consistency.pass] [run] [check .] [Pass] [#]]
+ [[thread.now.pass] [run] [check .] [Pass] [#]]
+]
+
+
+[endsect]
+
+
+[section io examples]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[io_ex1.pass] [run] [check .] [Pass] [#]]
+ [[io_ex2.pass] [run] [check .] [Pass] [#]]
+ [[io_ex3.pass] [run] [check .] [Pass] [#]]
+ [[io_ex4.pass] [run] [check .] [Pass] [#]]
+ [[io_ex5.pass] [run] [check .] [Pass] [#]]
+]
+[endsect]
+
+
+
+[endsect]
+[/=====================================]
+[section:tickets Appendix G: Tickets]
+
+[table
+ [[Ticket] [Description] [Resolution] [State]]
+ [[0] [ Issues raised by Michael Marcin: In the past I've seen QueryPerformanceCounter give incorrect results,
+ especially with SpeedStep processors on laptops. This was many years ago and
+ might have been fixed by service packs and drivers.
+
+ Typically you check the results of QPC against GetTickCount to see if the
+ results are reasonable.
+ http://support.microsoft.com/kb/274323
+
+ I've also heard of problems with QueryPerformanceCounter in multi-processor
+ systems.
+
+ I know some people SetThreadAffinityMask to 1 for the current thread call
+ their QueryPerformance* functions then restore SetThreadAffinityMask. This
+ seems horrible to me because it forces your program to jump to another
+ physical processor if it isn't already on cpu0 but they claim it worked well
+ in practice because they called the timing functions infrequently.
+
+ In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for
+ high resolution timers to avoid these issues.
+ ] [???] [*Open*]]
+ [[1] [operator/ was ambiguous] [Disambiguate duration operator/] [Closed]]
+ [[2] [CLOCK_STEADY is not defined with cygwin/gcc 3.4] [Disable code when BOOST_CHRONO_HAS_CLOCK_STEADY is not defined.] [Closed]]
+ [[3] [result of metafunctions ratio_multiply and ratio_divide were not normalized ratios] [Use of the nested ratio typedef type on ratio arithmetic operations.] [Closed]]
+ [[4] [Copy constructor from similar duration masked the defaulted operations] [Added duration defaulted implementations] [Closed]]
+ [[5] [INTMAX_C is not always defined] [Replace INTMAX_C by BOOST_INTMAX_C until boost/cstdint.hpp ensures INTMAX_C is always defined.] [Closed]]
+ [[6] [undefined BOOST_CHRONO_HAS_CLOCK_STEADY when BOOST_CHRONO_WINDOWS_API] [Define BOOST_CHRONO_HAS_CLOCK_STEADY when BOOST_CHRONO_WINDOWS_API] [Closed]]
+ [[7] [min/max macros intrussion] [Take care of Boost min/max recommendations] [Closed]]
+ [[8] [declaration of 'typedef class boost::chrono::duration<..> changes meaning of 'duration'] [complete qualification when defining nested typedef duration on clocks to avoid the following compile error:] [Closed]]
+ [[9] [VC++ warnings] [disable VC++ foolishness] [Closed]]
+]
+[table
+ [[Ticket] [Description] [Resolution] [State]]
+
+ [[10] [conversion warning in test_duration] [removal of conversion warning in test_duration] [Closed]]
+ [[11] [MSVC reports a warning instead of an error when there is an integral constant overflow] [manage with MSVC reporting a warning instead of an error when there is an integral constant overflow] [Closed]]
+ [[12] [ambiguities with MSVC when using detail:: namespace] [Qualify with boost::detail boost::chrono::detail ] [Closed]]
+ [[13] [warning C4251: 'boost::chrono::run_timer::m_format' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'boost::chrono::run_timer'] [don't include inlines functions using the std::string m_format] [Closed]]
+ [[14] [Bad use of duration(0) on template classes] [remplace by duration::zero()] [Closed]]
+ [[15] [suspend doesn't works: partial_ not initialized] [initialize with duration::zero()] [Closed]]
+ [[16] [suspend doesn't works: elapsed doesn't take care of partial_] [take care of partial] [Closed]]
+ [[17] [suspend doesn't works: bad use of system::error_code & ec] [replace by system::error_code ec] [Closed]]
+ [[18] [warnings on mingw-gcc.4.4:
+
+..\..\../boost/chrono/chrono.hpp: In copy constructor 'boost::chrono::time_point<boost::chrono::process_cpu_clock,
+boost::chrono::duration<boost::chrono::process_cpu_clock::times, boost::ratio<1ll, 1000000000ll> >
+>::time_point(const boost::chrono::time_point<boost::chrono::process_cpu_clock,
+boost::chrono::duration<boost::chrono::process_cpu_clock::times, boost::ratio<1ll, 1000000000ll> > >&)':
+..\..\../boost/chrono/chrono.hpp:816: warning: suggest parentheses around '&&' within '||'
+..\..\../boost/chrono/chrono.hpp:816: warning: suggest parentheses around '&&' within '||'
+
+] [???] [Closed]]
+ [[19] [Use of Specific formatters doesn't works] [] [Closed]]
+
+ [[20] [boost/chrono/scoped_suspend.hpp(31) : warning C4520: 'boost::chrono::scoped_suspend<Clock>' : multiple default constructors specified
+] [Remove the default constructor deletion ] [Closed]]
+ [[21] [suspendible_clock_test doesn't works in my mingw environement] [(issue with tss)] [*Open*]]
+ [[22] [error_code not initialized] [Use ec.clear() before throwing a exception.] [Closed]]
+ [[23] [boost/thread/detail/cv_status.hpp file was not commited] [commit file] [Closed]]
+ [[24] [Boost.Conversion was not packaged] [Package it] [Closed]]
+ [[25] [Valgrind issue: Conditional jump or move depends on uninitialised value(s)] [Replace the test] [Closed]]
+ [/[#] [XXXX] [XXXX] [Closed]]
+]
+
+
+
+
+
+[endsect]
+
+]
+[/=====================================]
+[section:todo Appendix F: Future plans]
+[/=====================================]
+
+[heading For later releases]
+
+* Implement `steady_clock` if accepted by the standard.
+
+[endsect]
+[endsect]

Added: trunk/libs/chrono/doc/time2_demo.html
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/doc/time2_demo.html 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,4040 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+
+ <title>time2_demo</title>
+</head><body>
+
+<pre><font color="#c80000">/*
+Copyright (c) 2008 Howard Hinnant
+
+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)
+
+
+A prototype of a proposal for a time/duration/clock library for the C++ standard.
+It is intended that this be a solid foundation upon which higher level libraries
+can be based. Examples of such libraries include a date/time library and a
+physical quantities library.
+
+Two general purpose facilities are proposed:
+
+ common_type
+ ratio
+
+And 5 time/duration/clock facilities are proposed
+
+ duration
+ time_point
+ system_clock
+ monotonic_clock <font color="#c80000">// optional</font>
+ high_resolution_clock <font color="#c80000">// optional</font>
+
+Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krügler,
+ Anthony Williams.
+
+Synopsis
+
+namespace std
+{
+
+<font color="#c80000">// &lt;type_traits&gt;</font>
+
+<font color="#c80000">// common_type</font>
+
+<font color="#c80000">// common_type is ageneral purpose trait that can be specialized for user-defined types.</font>
+<font color="#c80000">// The semantics are intended to be identical to finding the resulting type of a</font>
+<font color="#c80000">// the conditional operator.</font>
+<font color="#c80000">// The client may need to specialize common_type if he wishes to convert to or from</font>
+<font color="#c80000">// another type only explicitly. It is used to determine the result type</font>
+<font color="#c80000">// in "mixed-mode" duration and time_point arithmetic. It will also find use in</font>
+<font color="#c80000">// similar "mixed-mode" arithmetic applications.</font>
+
+template &lt;class T, class U&gt;
+struct common_type
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+<font color="#c80000">// or...</font>
+
+template &lt;class ...T&gt; struct common_type;
+
+template &lt;class T&gt;
+struct common_type&lt;T&gt;
+{
+ typedef T type;
+};
+
+template &lt;class T, class U&gt;
+struct common_type&lt;T, U&gt;
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+template &lt;class T, class U, class ...V&gt;
+struct common_type&lt;T, U, V...&gt;
+{
+ typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
+};
+
+<font color="#c80000">// This alternative variadic formulation of common_type has some advantages:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 1. The obvious advantage is that it can handle 3 or more arguments seamlessly.</font>
+<font color="#c80000">// This can come in handy when writing template functions that take more than</font>
+<font color="#c80000">// two arguments, such as fma(x, y, z).</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 2. We could just get rid of identity (avoiding the legacy conflict) and use</font>
+<font color="#c80000">// common_type&lt;T&gt;::type in the one place we use identity&lt;T&gt;::type today.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 3. For clients that need to specialize common_type (such as duration and time_point),</font>
+<font color="#c80000">// the client still needs to specialize only the two-argument version. The default</font>
+<font color="#c80000">// definition of the higher-order common_type will automatically use the client's</font>
+<font color="#c80000">// specialized two-argument version.</font>
+<font color="#c80000">// For example:</font>
+<font color="#c80000">// common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type is duration&lt;double, micro&gt;</font>
+
+<font color="#c80000">// ... end or</font>
+
+<font color="#c80000">// The cost of not including either version of common_type is that it is very likely that</font>
+<font color="#c80000">// the implementation would include it anyway, but spell it __common_type instead. This</font>
+<font color="#c80000">// would prevent authors of arithmetic emulators from using their classes as representations</font>
+<font color="#c80000">// with durations unless the emulator had exactly one implicit conversion to or from an</font>
+<font color="#c80000">// arithmetic type. This would be a large loss of functionality from the client's point</font>
+<font color="#c80000">// of view, possibly mandating a less safe interface for the client's arithmetic emulator.</font>
+
+<font color="#c80000">// ratio</font>
+
+<font color="#c80000">// ratio is a general purpose type allowing one to easily and safely compute integral</font>
+<font color="#c80000">// ratio values at compile time. The ratio class catches all errors (such as divide by</font>
+<font color="#c80000">// zero and overflow) at compile time. It is used in the duration and time_point libraries</font>
+<font color="#c80000">// to efficiently create units of time. It can also be used in other "quantity"</font>
+<font color="#c80000">// libraries (both std-defined and user-defined), or anywhere there is an integral</font>
+<font color="#c80000">// ratio which is known at compile time. The use of this utility can greatly reduce</font>
+<font color="#c80000">// the chances of run time overflow because the ratio (and any ratios resulting from</font>
+<font color="#c80000">// ratio arithmetic) are always reduced to lowest terms.</font>
+
+<font color="#c80000">// The cost of not including ratio would mean that the implementor would likely have this</font>
+<font color="#c80000">// functionality anyway, but spell it __ratio instead. This would prevent the client from</font>
+<font color="#c80000">// using ratio in his own code as demonstrated in the "User1" example. Furthermore duration</font>
+<font color="#c80000">// would have to be templated on two long long's instead of on ratio like so:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// template &lt;class Rep, long long N, long long D&gt; duration.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// This would mean that clients wanting to build a custom duration type (say a nanosecond</font>
+<font color="#c80000">// represented by a double) would have to write:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// duration&lt;double, 1, 1000000000LL&gt;</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// instead of:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// duration&lt;double, nano&gt;</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// This lack of syntatic niceness, along with the loss of functionality in the reuse of</font>
+<font color="#c80000">// ratio in user-written code seems to indicate that the loss of ratio would be a sizeable</font>
+<font color="#c80000">// loss to client code.</font>
+
+template &lt;intmax_t N, intmax_t D = 1&gt;
+class ratio
+{
+ <font color="#c80000">// For every possible value of N and D, abs(N) &gt;= 0 and abs(D) &gt; 0</font>
+ static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");
+ static_assert(__static_abs&lt;D&gt;::value &gt; 0, "ratio denominator is out of range");
+public:
+ static const intmax_t num; <font color="#c80000">// Reduced by greatest common divisor of N and D, has sign of sign(N) * sign(D)</font>
+ static const intmax_t den; <font color="#c80000">// Reduced by greatest common divisor of N and D, always positive</font>
+ <font color="#c80000">// When num == 0, den == 1</font>
+};
+
+<font color="#c80000">// The static_asserts in ratio are there to catch any values which have a negative absolute value.</font>
+<font color="#c80000">// In a typical 2's complement representation this is only LLONG_MIN. The reason for prohibiting</font>
+<font color="#c80000">// this value is because ratio must take the absolute values of its arguments and generally depends</font>
+<font color="#c80000">// on that number being non-negative in order to maintain invariants such as den &gt; 0.</font>
+
+<font color="#c80000">// convenience typedefs</font>
+
+typedef ratio&lt;1, 1000000000000000000000000&gt; yocto; <font color="#c80000">// conditionally supported</font>
+typedef ratio&lt;1, 1000000000000000000000&gt; zepto; <font color="#c80000">// conditionally supported</font>
+typedef ratio&lt;1, 1000000000000000000&gt; atto;
+typedef ratio&lt;1, 1000000000000000&gt; femto;
+typedef ratio&lt;1, 1000000000000&gt; pico;
+typedef ratio&lt;1, 1000000000&gt; nano;
+typedef ratio&lt;1, 1000000&gt; micro;
+typedef ratio&lt;1, 1000&gt; milli;
+typedef ratio&lt;1, 100&gt; centi;
+typedef ratio&lt;1, 10&gt; deci;
+typedef ratio&lt; 10, 1&gt; deca;
+typedef ratio&lt; 100, 1&gt; hecto;
+typedef ratio&lt; 1000, 1&gt; kilo;
+typedef ratio&lt; 1000000, 1&gt; mega;
+typedef ratio&lt; 1000000000, 1&gt; giga;
+typedef ratio&lt; 1000000000000, 1&gt; tera;
+typedef ratio&lt; 1000000000000000, 1&gt; peta;
+typedef ratio&lt; 1000000000000000000, 1&gt; exa;
+typedef ratio&lt; 1000000000000000000000, 1&gt; zetta; <font color="#c80000">// conditionally supported</font>
+typedef ratio&lt;1000000000000000000000000, 1&gt; yotta; <font color="#c80000">// conditionally supported</font>
+
+<font color="#c80000">// Compile time arithmetic and comparisons should either avoid overflow or not compile</font>
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_add
+{
+ typedef ratio&lt;pseudo code: R1 + R2&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_subtract
+{
+ typedef ratio&lt;pseudo code: R1 - R2&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_multiply
+{
+ typedef ratio&lt;pseudo code: R1 * R2&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_divide
+{
+ typedef ratio&lt;pseudo code: R1 / R2&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_equal
+ : public integral_constant&lt;bool, pseudo code: R1 == R2&gt; {};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_not_equal
+ : public integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_less
+ : public integral_constant&lt;bool, pseudo code: R1 &lt; R2&gt; {};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_less_equal
+ : public integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_greater
+ : public integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+requires R1 and R2 are instantiations of ratio
+struct ratio_greater_equal
+ : public integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
+
+namespace datetime
+{
+
+<font color="#c80000">// duration customization traits</font>
+
+<font color="#c80000">// Authors of arithmetic emulation types should specialize treat_as_floating_point</font>
+<font color="#c80000">// if their class emulates floating point and they want to use it as a duration's</font>
+<font color="#c80000">// representation.</font>
+
+template &lt;class Rep&gt; struct treat_as_floating_point
+ : is_floating_point&lt;Rep&gt; {};
+
+<font color="#c80000">// Authors of arithmetic emulation types should specialize duration_values</font>
+<font color="#c80000">// if they want to use it as a duration's representation, and the default</font>
+<font color="#c80000">// definition of duration_values does not have the correct behavior.</font>
+
+template &lt;class Rep&gt;
+struct duration_values
+{
+public:
+ static constexpr Rep zero() {return Rep(0);}
+ static constexpr Rep max() {return numeric_limits&lt;Rep&gt;::max();}
+ static constexpr Rep min() {return -max();}
+};
+
+<font color="#c80000">// Note: Rep(0) instead of Rep() is used for zero() because the author of Rep may</font>
+<font color="#c80000">// chose to have Rep() refer to an inderminant or unitialized value.</font>
+
+<font color="#c80000">// duration</font>
+
+<font color="#c80000">// A duration has a representation and a period.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// The representation is an arithmetic type, or a class emulating an arithmetic type.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// The period is the rational number of seconds between "ticks" of the duration. The</font>
+<font color="#c80000">// duration simply holds a count of the elapsed number of ticks (using the</font>
+<font color="#c80000">// representation), and that is related to seconds by multiplying by the period.</font>
+<font color="#c80000">// Note, this multiplication is only required when one needs to convert between</font>
+<font color="#c80000">// durations with different tick periods (e.g. milliseconds to microseconds).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration has defalt construction and default copy semantics. One can also explicitly</font>
+<font color="#c80000">// construct a duration from its representation or something implicitly convertible to</font>
+<font color="#c80000">// its representation. If the representation is integral (or emulated integral) the</font>
+<font color="#c80000">// duration may not be constructed from a floating point (or emulated floating point)</font>
+<font color="#c80000">// type, even if that type is impilcitly convertible to the representation (the client</font>
+<font color="#c80000">// must explicitly convert such an argument as they pass it to the constructor if such</font>
+<font color="#c80000">// a conversion is desired).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration may be implicitly constructible from another duration if the representations</font>
+<font color="#c80000">// of the two durations meet certain requirements. Let the representation of this duration</font>
+<font color="#c80000">// be Rep1 and the representation of the other duration be Rep2. Example representations</font>
+<font color="#c80000">// include int, long long, double, or a user-defined class which emulates one of these</font>
+<font color="#c80000">// arithmetic types. To qualify for implicit constructability Rep1 must be explicitly</font>
+<font color="#c80000">// constructible from Rep2. Note that implicit constructibility of Rep1 from Rep2 is not</font>
+<font color="#c80000">// required for this implicit construction between durations. Additionally the trait</font>
+<font color="#c80000">// common_type&lt;Rep1, Rep2&gt;::type must be well defined. If a conditional expression involving</font>
+<font color="#c80000">// these two types isn't valid, there must exist a common_type specialization which makes</font>
+<font color="#c80000">// the trait valid.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,</font>
+<font color="#c80000">// and not require implicit conversions (which could be considered error prone by the author</font>
+<font color="#c80000">// of either of these representations).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// In addition to the above relationship between the representations, implicit constructability</font>
+<font color="#c80000">// also depends on whether the representation is considered floating point (or emulated floating</font>
+<font color="#c80000">// point) or integral (or emulated integral).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// If a duration has a floating point (or emulated floating point) representation it</font>
+<font color="#c80000">// is implicitly constructible from all other durations of any period (as long as</font>
+<font color="#c80000">// the representations are compatible as described above).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// If a duration has an integral (or emulated integral) representation it is implicitly</font>
+<font color="#c80000">// constructible from other integral-based durations which have a period which will exactly convert</font>
+<font color="#c80000">// to the period of this duration with no truncation error. More specifically, if the</font>
+<font color="#c80000">// period of this duration is P1, and the period of the other duration is P2, this</font>
+<font color="#c80000">// duration is implicitly constructible from the other duration if P2/P1 is a whole number</font>
+<font color="#c80000">// (as long as the representations are compatible as described above). Example:</font>
+<font color="#c80000">// microseconds has a period p1 = 1/1000000 seconds. milliseconds has a period</font>
+<font color="#c80000">// P2 = 1/1000 seconds. P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.</font>
+<font color="#c80000">// Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// These rules involving integral representations are meant to prevent accidental truncatation</font>
+<font color="#c80000">// error. If truncation error is desired, a duration_cast facility is available to force it.</font>
+<font color="#c80000">// Example:</font>
+<font color="#c80000">// milliseconds ms(3); // ok, ms.count() == 3, which is 0.003 seconds</font>
+<font color="#c80000">// microseconds us = ms; // ok, us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// ++us; // ok, us.count() == 3001 which is 0.003001 seconds</font>
+<font color="#c80000">// ms = us; // won't compile, might truncate</font>
+<font color="#c80000">// ms = duration_cast&lt;milliseconds&gt;(us); // ok, ms.count() = 3, truncated a microsecond</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration has a single observer: rep count() const; which returns the stored</font>
+<font color="#c80000">// representation which holds the number of elapsed "ticks".</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration supports the following member arithmetic:</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration operator+() const;</font>
+<font color="#c80000">// duration operator-() const;</font>
+<font color="#c80000">// duration&amp; operator++();</font>
+<font color="#c80000">// duration operator++(int);</font>
+<font color="#c80000">// duration&amp; operator--();</font>
+<font color="#c80000">// duration operator--(int);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration&amp; operator+=(duration d);</font>
+<font color="#c80000">// duration&amp; operator-=(duration d);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration&amp; operator*=(rep rhs);</font>
+<font color="#c80000">// duration&amp; operator/=(rep rhs);</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++</font>
+<font color="#c80000">// increments the tick count by 1).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration supports the following non-member arithmetic.</font>
+<font color="#c80000">// Let D1 represent duration&lt;Rep1, Period1&gt; and D2 represent duration&lt;Rep2, Period2&gt;.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// common_type&lt;D1, D2&gt;::type operator+( D1, D2); // returns a duration</font>
+<font color="#c80000">// common_type&lt;D1, D2&gt;::type operator-( D1, D2); // returns a duration</font>
+<font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*( D1, Rep2); // returns a duration</font>
+<font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*(Rep2, D1); // returns a duration</font>
+<font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator/( D1, Rep2); // returns a duration</font>
+<font color="#c80000">// common_type&lt;D1::rep, D2::rep&gt;::type operator/( D1, D2); // returns a scalar</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration D1 is fully equality and less-than comparable with any other duration D2, as</font>
+<font color="#c80000">// long as common_type&lt;D1::rep, D2::rep&gt; is well defined.</font>
+<font color="#c80000">// Example:</font>
+<font color="#c80000">// milliseconds ms(3); // ms.count() == 3, which is 0.003 seconds</font>
+<font color="#c80000">// microseconds us = ms; // us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// --us; // us.count() == 2999 which is 0.002999 seconds</font>
+<font color="#c80000">// assert(ms != us); // 3 milliseconds is not equal to 2999 microseconds</font>
+<font color="#c80000">// assert(ms &gt; us); // 3 milliseconds is greater than 2999 microseconds</font>
+<font color="#c80000">// ++us; // us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// assert(ms == us); // 3 milliseconds is equal to 3000 microseconds</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Durations based on floating point representations are subject to round off error precisely the</font>
+<font color="#c80000">// same way their representations are.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Arithmetic and comparisons among integral-based durations is not subject to truncation error or</font>
+<font color="#c80000">// round off error. If truncation error would result from the arithmetic (say</font>
+<font color="#c80000">// by converting a smaller period duration to a larger one) the expression will</font>
+<font color="#c80000">// not compile (unless duration_cast is used). If one performs arithmetic</font>
+<font color="#c80000">// involving the duration's representation (such as division), then truncation</font>
+<font color="#c80000">// will happen implicitly.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Overflow error may silently happen with a duration. The std-defined durations</font>
+<font color="#c80000">// have a minimum range of +/- 292 years.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration is a thin wrapper around its representation. sizeof(duration&lt;Rep, Period&gt;) == sizeof(Rep).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds</font>
+<font color="#c80000">// (about 30 billion years). The range of a duration is based on the range of its representation</font>
+<font color="#c80000">// combined with its period.</font>
+
+<font color="#c80000">// The cost of not including the flexibility to represent different "tick periods" in the duration</font>
+<font color="#c80000">// type would be a great loss of both flexibility, convenience and safety for the client. For example</font>
+<font color="#c80000">// if had just one duration type which counted nanoseconds (no matter how that count was represented),</font>
+<font color="#c80000">// then clients could never have the ability to traffic in picoseconds. And the only hope of reaching</font>
+<font color="#c80000">// beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation</font>
+<font color="#c80000">// (such as a long long). Furthermore, if the client wanted to traffic in units larger than a nanosecond</font>
+<font color="#c80000">// (e.g. seconds) for convience, they would likely need to set up their own conversion constants and</font>
+<font color="#c80000">// convert manually.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// If the conversion constants are specified at run time, rather than as compile time integral constants,</font>
+<font color="#c80000">// then the client suffers a significant performance penalty as for every conversion one will have to</font>
+<font color="#c80000">// perform both a multiplication and a division. In contrast, when converting among any two units of</font>
+<font color="#c80000">// the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a</font>
+<font color="#c80000">// single multiplication *or* division (never both). This proposal makes every unit conversion as</font>
+<font color="#c80000">// efficient as if it had been coded by hand (see duration_cast). Furthermore duration_cast encapsulates</font>
+<font color="#c80000">// all unit conversions within a single uniform-syntax function which is easily used in generic code. There</font>
+<font color="#c80000">// is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion</font>
+<font color="#c80000">// functions is O(N) rather than O(N^2).</font>
+
+template &lt;class Rep, class Period = ratio&lt;1&gt;&gt;
+requires Rep is an arithmetic type, or a class emulating an arithmetic type,
+ and not an instantiation of duration
+requires Period is an instantiation of ratio and represents a positive fraction
+class duration
+{
+public:
+ typedef Rep rep;
+ typedef Period period;
+private:
+ rep rep_; <font color="#c80000">// exposition only</font>
+public:
+ <font color="#c80000">// construction / destruction</font>
+ duration() = default;
+ template &lt;class Rep2&gt;
+ requires is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
+ (treat_as_floating_point&lt;rep&gt;::value ||
+ !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
+ explicit duration(const Rep2&amp; r);
+ ~duration() = default;
+
+ <font color="#c80000">// copy semantics</font>
+ duration(const duration&amp;) = default;
+ duration&amp; operator=(const duration&amp;) = default;
+
+ <font color="#c80000">// conversions</font>
+ template &lt;class Rep2, class Period2&gt;
+ requires Rep2 is explicitly convertible to rep &amp;&amp;
+ (treat_as_floating_point&lt;rep&gt;::value ||
+ !treat_as_floating_point&lt;Rep2&gt;::value &amp;&amp; ratio_divide&lt;Period2, period&gt;::type::den == 1)
+ duration(const duration&lt;Rep2, Period2&gt;&amp; d);
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const;
+
+ <font color="#c80000">// arithmetic</font>
+
+ duration operator+() const;
+ duration operator-() const;
+ duration&amp; operator++();
+ duration operator++(int);
+ duration&amp; operator--();
+ duration operator--(int);
+
+ duration&amp; operator+=(const duration&amp; d);
+ duration&amp; operator-=(const duration&amp; d);
+
+ duration&amp; operator*=(const rep&amp; rhs);
+ duration&amp; operator/=(const rep&amp; rhs);
+
+ <font color="#c80000">// special values</font>
+
+ static constexpr duration zero();
+ static constexpr duration min();
+ static constexpr duration max();
+};
+
+<font color="#c80000">// convenience typedefs</font>
+
+typedef duration&lt;int_least64_t, nano&gt; nanoseconds; <font color="#c80000">// 10^-9 seconds</font>
+typedef duration&lt;int_least55_t, micro&gt; microseconds; <font color="#c80000">// 10^-6 seconds</font>
+typedef duration&lt;int_least45_t, milli&gt; milliseconds; <font color="#c80000">// 10^-3 seconds</font>
+typedef duration&lt;int_least35_t &gt; seconds; <font color="#c80000">// 1 second</font>
+typedef duration&lt;int_least29_t, ratio&lt; 60&gt;&gt; minutes; <font color="#c80000">// 60 seconds</font>
+typedef duration&lt;int_least23_t, ratio&lt;3600&gt;&gt; hours; <font color="#c80000">// 3600 seconds</font>
+
+<font color="#c80000">// duration_cast can be used to force a conversion between two durations (assuming</font>
+<font color="#c80000">// the source representation can be explicitly converted to the target representation).</font>
+<font color="#c80000">// Not all integral-based durations are implicitly convertible to another (to</font>
+<font color="#c80000">// avoid accidental truncation error). When truncation error is desired, the client</font>
+<font color="#c80000">// uses duration_cast to explicitly request the non-exact conversion. When</font>
+<font color="#c80000">// duration_cast is used to convert between durations which have an implicit conversion,</font>
+<font color="#c80000">// the behavior and performance of the conversion using duration_cast is identical to</font>
+<font color="#c80000">// that of the implicit conversion.</font>
+
+template &lt;class ToDuration, class Rep, class Period&gt;
+ requires ToDuration is an instantiation of duration
+ ToDuration duration_cast(const duration&lt;Rep, Period&gt;&amp; fd);
+
+<font color="#c80000">// Examples:</font>
+<font color="#c80000">// microseconds us(3500); // 3500 microseconds</font>
+<font color="#c80000">// milliseconds ms = us; // Does not compile (implicit truncation)</font>
+<font color="#c80000">// milliseconds ms = duration_cast&lt;milliseconds&gt;(us); // 3 milliseconds (explicit truncation)</font>
+<font color="#c80000">// us = ms; // 3000 microseconds</font>
+<font color="#c80000">// us = duration_cast&lt;microseconds&gt;(ms); // 3000 microseconds</font>
+
+} <font color="#c80000">// datetime</font>
+
+<font color="#c80000">// Given two durations: duration&lt;Rep1, Period1&gt; and duration&lt;Rep2, Period2&gt;, the common_type</font>
+<font color="#c80000">// of those two durations is a duration with a representation of common_type&lt;Rep1, Rep2&gt;,</font>
+<font color="#c80000">// and a period which is the "greatest common period" of Period1 and Period2. The GCP</font>
+<font color="#c80000">// (Greatest Common Period) of Period1 and Period2 is the largest period which will divide</font>
+<font color="#c80000">// both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and</font>
+<font color="#c80000">// Period2). This can be computed (by the implementation at compile time) by</font>
+<font color="#c80000">// GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is</font>
+<font color="#c80000">// "Greatest Common Divisor" and LCM is "Least Common Multiple".</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
+{
+ typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
+ ratio&lt;GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)&gt;&gt; type;
+};
+
+<font color="#c80000">// Note: For any two durations D1 and D2, they will both exactly convert to common_type&lt;D1, D2&gt;::type.</font>
+<font color="#c80000">// common_type&lt;D1, D2&gt;::type will have the largest possible period to make this possible, and</font>
+<font color="#c80000">// may be the same type as D1 or D2. Examples:</font>
+<font color="#c80000">// common_type&lt;minutes, microseconds&gt;::type is microseconds.</font>
+<font color="#c80000">// common_type&lt;milliseconds, microseconds&gt;::type is microseconds.</font>
+<font color="#c80000">// common_type&lt;nanoseconds, microseconds&gt;::type is nanoseconds.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// A more complex example:</font>
+<font color="#c80000">// common_type&lt; duration&lt;long, milli&gt;, duration&lt;int, ratio&lt;1,30&gt;&gt; &gt;::type is</font>
+<font color="#c80000">// duration&lt;long, ratio&lt;1,3000&gt;&gt;. And both duration&lt;long, milli&gt; and </font>
+<font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to duration&lt;long, ratio&lt;1,3000&gt;&gt;.</font>
+<font color="#c80000">// The former multitplies its representation by 3L and the latter converts its</font>
+<font color="#c80000">// representation to long and multiplies that result by 1000L. There exists no</font>
+<font color="#c80000">// duration with a larger period such that both duration&lt;long, milli&gt; and</font>
+<font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to it.</font>
+
+namespace datetime {
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ bool operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
+ operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
+ operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+ requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
+ Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
+ duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
+ operator*(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+ requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
+ Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
+ duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
+ operator*(const Rep2&amp; s, const duration&lt;Rep, Period&gt;&amp; d);
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+ requires Rep2 is not a duration &amp;&amp;
+ Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
+ Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
+ duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
+ operator/(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
+
+<font color="#c80000">// Note: the above 3 signatures can be approximated with is_convertible if concepts do not</font>
+<font color="#c80000">// make it into the language. Requiring only *explicit* convertibility between the Rep</font>
+<font color="#c80000">// types is strongly desired. One way or another, Rep2 must be constrained. Otherwise</font>
+<font color="#c80000">// the operators are overly generic.</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+ typename common_type&lt;Rep1, Rep2&gt;::type
+ operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+<font color="#c80000">// time_point</font>
+
+<font color="#c80000">// A time_point represents an epoch plus or minus a duration. The relationship between a time_point</font>
+<font color="#c80000">// which represents "now" and the time_point's epoch is obtained via a clock. Each time_point is</font>
+<font color="#c80000">// tied to a specific clock. Thus, for any time_point, one can find the duration between that</font>
+<font color="#c80000">// point in time and now, and between that point in time, and its epoch.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point may be default constructed. This time_point represents the epoch. time_point has</font>
+<font color="#c80000">// default copy semantics.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// time_point may be explicitly constructed by a duration having the same representation and period as</font>
+<font color="#c80000">// the time_point. Any other duration which is implicitly convertible to the time_point's "native" duration can</font>
+<font color="#c80000">// also be used to explicitly construct the time_point. The meaning of this construction is identical to</font>
+<font color="#c80000">// time_point() + d.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// A time_point is implicitly constructible from another time_point if they share the same clock,</font>
+<font color="#c80000">// and the duration of this time_point is implicitly constructible from the duration of the other</font>
+<font color="#c80000">// time_point. A time_point constructed in this fashion will compare equal to the source time_point</font>
+<font color="#c80000">// after the construction.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point supports the following member arithmetic:</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// time_point&amp; operator+=(duration d);</font>
+<font color="#c80000">// time_point&amp; operator-=(duration d);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point supports the following non-member arithmetic.</font>
+<font color="#c80000">// Let T1 represent time_point&lt;Clock, Duration1&gt;,</font>
+<font color="#c80000">// T2 represent time_point&lt;Clock, Duration2&gt;,</font>
+<font color="#c80000">// and D represent duration&lt;Rep3, Period3&gt;. Note that T1 and T2 must have the same Clock.</font>
+<font color="#c80000">// Attempts to interoperate times having different clocks results in a compile time failure.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// T2 operator+(T1, D); // return type is a time_point</font>
+<font color="#c80000">// T2 operator+( D, T1); // return type is a time_point</font>
+<font color="#c80000">// T2 operator-(T1, D); // return type is a time_point</font>
+<font color="#c80000">// D operator-(T1, T2); // return type is a duration</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point T1 is fully equality and less-than comparable with any other time_point T2 which</font>
+<font color="#c80000">// has the same clock, and for which their durations are comparable.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Times based on floating point representations are subject to round off error precisely the</font>
+<font color="#c80000">// same way their representations are.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Times based on integral representations are not subject to truncation error or round off</font>
+<font color="#c80000">// error. A compile time error will result if truncation error is possible. Truncation error</font>
+<font color="#c80000">// is only possible with construction or the member arithmetic (and won't compile). Non-member</font>
+<font color="#c80000">// arithmetic and comparison is always exact. Overflow error with integral based times remains a</font>
+<font color="#c80000">// possibility.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point is a thin wrapper around its representation.</font>
+<font color="#c80000">// sizeof(time_point&lt;Clock, Duration&gt;) == sizeof(Duration) == sizeof(Duration::rep).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point can represent units as small as 10^-18 seconds and as large as 10^18 seconds. The range</font>
+<font color="#c80000">// of a time_point is based on the range of its representation combined with its period.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Because no two clocks report the exact same time, even clocks which nominally have the same</font>
+<font color="#c80000">// epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.</font>
+<font color="#c80000">// Converting time_points from one clock to another will involve synchronization of the clocks,</font>
+<font color="#c80000">// which can be viewed as a synchronization of their epochs. Such synchronization is clock specific</font>
+<font color="#c80000">// and beyond the scope of this API. A future API, or a platform specific API, can easily</font>
+<font color="#c80000">// write such a synchronization API, basing it on this API.</font>
+
+<font color="#c80000">// The cost of not including a time_point class is the lack of the ability to safely interact with</font>
+<font color="#c80000">// the concept of "epoch + duration". Without a separate type, the client is in danger of accidently</font>
+<font color="#c80000">// writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2". Algebraically this</font>
+<font color="#c80000">// results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning. What</font>
+<font color="#c80000">// would it mean to add New Years 1970 to the point in time at which your computer booted up? Or for</font>
+<font color="#c80000">// that matter, what is the meaning of "New Years 1970" + "New Years 1970"?</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Additionally this would force the duration type to play double duty as a time_point leading to</font>
+<font color="#c80000">// client confusion. For example POSIX has timespec represent a duration in nanosleep, and yet the</font>
+<font color="#c80000">// same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock. The</font>
+<font color="#c80000">// confusion seems even more likely with a function such as clock_nanosleep where timespec can mean</font>
+<font color="#c80000">// either a duration or a time_point depending upon another argument to the function.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// In C++ we can easily mitigate such errors by detecting them at compile time. This is done through</font>
+<font color="#c80000">// the use of distinct types for these distinct concepts (even though both types have identical layout!).</font>
+
+template &lt;class Clock, class Duration = typename Clock::duration&gt;
+requires Duration is an instantiation of duration
+class time_point
+{
+public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+private:
+ duration d_; <font color="#c80000">// exposition only</font>
+
+public:
+ time_point(); <font color="#c80000">// has value "epoch"</font>
+ explicit time_point(const duration&amp; d); <font color="#c80000">// same as time_point() + d</font>
+
+ <font color="#c80000">// conversions</font>
+ template &lt;class Duration2&gt;
+ requires Convertible&lt;Duration2, duration&gt;
+ time_point(const time_point&lt;clock, Duration2&gt;&amp; t);
+
+ <font color="#c80000">// observer</font>
+
+ duration time_since_epoch() const;
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point&amp; operator+=(const duration&amp; d);
+ time_point&amp; operator-=(const duration&amp; d);
+
+ <font color="#c80000">// special values</font>
+
+ static time_point min();
+ static time_point max();
+};
+
+} <font color="#c80000">// datetime</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
+{
+ typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
+};
+
+namespace datetime {
+
+template &lt;class ToDuration, class Clock, class Duration&gt;
+ time_point&lt;Clock, ToDuration&gt; time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t);
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator&lt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator&gt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ bool operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+
+template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
+ time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
+ operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
+ time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
+ operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+
+template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
+ time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
+ operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+ typename common_type&lt;Duration1, Duration2&gt;::type
+ operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
+
+<font color="#c80000">// clocks</font>
+
+<font color="#c80000">// A clock specifies a representation, and a period. These specifications are used to</font>
+<font color="#c80000">// to define a clock's native duration and time_point types. A clock also has a function to get the current</font>
+<font color="#c80000">// time_point. A clock need not have any state.</font>
+
+<font color="#c80000">// The cost of not including separate types for clocks is that there is no better place to</font>
+<font color="#c80000">// bundle the "native" duration and time_point types for a clock with the functionality to</font>
+<font color="#c80000">// get the current time_point (what time is it now?). By bundling this information into a</font>
+<font color="#c80000">// type, the extension to support multiple clocks is both easy and obvious. The ability to</font>
+<font color="#c80000">// easily support multiple clocks in such a flexible yet simple and efficient manner is</font>
+<font color="#c80000">// very important. A client might (for example) write code with the clock as a generic</font>
+<font color="#c80000">// template parameter, and then easily experiment with different timers.</font>
+
+class system_clock
+{
+public:
+ typedef &lt;unspecified&gt; rep;
+ typedef ratio&lt;unspecified, unspecified&gt; period;
+ typedef datetime::duration&lt;rep, period&gt; duration;
+ typedef datetime::time_point&lt;system_clock&gt; time_point;
+ static const bool is_mononontic = &lt;unspecified&gt;;
+
+ static time_point now();
+
+ <font color="#c80000">// Map to C API</font>
+ static time_t to_time_t (const time_point&amp; t);
+ static time_point from_time_t(time_t t);
+};
+
+class monotonic_clock <font color="#c80000">// optional</font>
+{
+public:
+ typedef &lt;unspecified&gt; rep;
+ typedef ratio&lt;unspecified, unspecified&gt; period;
+ typedef datetime::duration&lt;rep, period&gt; duration;
+ typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
+ static const bool is_mononontic = true;
+
+ static time_point now();
+};
+
+class high_resolution_clock <font color="#c80000">// optional</font>
+{
+public:
+ typedef &lt;unspecified&gt; rep;
+ typedef ratio&lt;unspecified, unspecified&gt; period;
+ typedef datetime::duration&lt;rep, period&gt; duration;
+ typedef datetime::time_point&lt;high_resolution_clock&gt; time_point;
+ static const bool is_mononontic = &lt;unspecified&gt;;
+
+ static time_point now();
+};
+
+<font color="#c80000">// Note: These clocks may be three separate types, or typedefs to one or two common types.</font>
+
+} <font color="#c80000">// datetime</font>
+
+<font color="#c80000">//////////////////////////</font>
+<font color="#c80000">// Threading interface //</font>
+<font color="#c80000">//////////////////////////</font>
+
+<font color="#c80000">// timed_mutex</font>
+
+struct timed_mutex
+{
+public:
+ timed_mutex();
+ ~timed_mutex();
+
+ timed_mutex(const timed_mutex&amp;) = delete;
+ timed_mutex&amp; operator=(const timed_mutex&amp;) = delete;
+
+ void lock();
+ bool try_lock();
+ template &lt;class Rep, class Period&gt;
+ bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
+ template &lt;class Clock, class Duration&gt;
+ bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
+ native_handle_type native_handle(); <font color="#c80000">// optional</font>
+};
+
+<font color="#c80000">// recursive_timed_mutex</font>
+
+struct recursive_timed_mutex
+{
+public:
+ recursive_timed_mutex();
+ ~recursive_timed_mutex();
+
+ recursive_timed_mutex(const recursive_timed_mutex&amp;) = delete;
+ recursive_timed_mutex&amp; operator=(const recursive_timed_mutex&amp;) = delete;
+
+ void lock();
+ bool try_lock();
+ template &lt;class Rep, class Period&gt;
+ bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
+ template &lt;class Clock, class Duration&gt;
+ bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
+ native_handle_type native_handle(); <font color="#c80000">// optional</font>
+};
+
+<font color="#c80000">// unique_lock</font>
+
+template &lt;class Mutex&gt;
+class unique_lock
+{
+public:
+ typedef Mutex mutex_type;
+
+ unique_lock();
+ explicit unique_lock(mutex_type&amp; m);
+ unique_lock(mutex_type&amp; m, defer_lock_t);
+ unique_lock(mutex_type&amp; m, try_to_lock_t);
+ unique_lock(mutex_type&amp; m, adopt_lock_t);
+ template &lt;class Rep, class Period&gt;
+ unique_lock(mutex_type&amp; m, const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
+ template &lt;class Clock, class Duration&gt;
+ unique_lock(mutex_type&amp; m, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ ~unique_lock();
+
+ unique_lock(unique_lock const&amp;) = delete;
+ unique_lock&amp; operator=(unique_lock const&amp;) = delete;
+
+ unique_lock(unique_lock&amp;&amp; u);
+ unique_lock&amp; operator=(unique_lock&amp;&amp; u);
+
+ void lock();
+ bool try_lock();
+ template &lt;class Rep, class Period&gt;
+ bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
+ template &lt;class Clock, class Duration&gt;
+ bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ void unlock();
+
+ bool owns_lock() const;
+ operator unspecified-bool-type () const;
+ mutex_type* mutex() const;
+
+ void swap(unique_lock&amp;&amp; u);
+ mutex_type* release();
+};
+
+<font color="#c80000">// condition_variable</font>
+
+class condition_variable
+{
+public:
+
+ condition_variable();
+ ~condition_variable();
+
+ condition_variable(const condition_variable&amp;) = delete;
+ condition_variable&amp; operator=(const condition_variable&amp;) = delete;
+
+ void notify_one();
+ void notify_all();
+
+ void wait(unique_lock&lt;mutex&gt;&amp; lock);
+ template &lt;class Predicate&gt;
+ void wait(unique_lock&lt;mutex&gt;&amp; lock, Predicate pred);
+
+ template &lt;class Clock, class Duration&gt;
+ bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
+ const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ template &lt;class Clock, class Duration, class Predicate&gt;
+ bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
+ const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
+ Predicate pred);
+
+ template &lt;class Rep, class Period&gt;
+ bool wait_for(unique_lock&lt;mutex&gt;&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
+ template &lt;class Rep, class Period, class Predicate&gt;
+ bool wait_for(unique_lock&lt;mutex&gt;&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time,
+ Predicate pred);
+
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle();
+};
+
+<font color="#c80000">// condition_variable_any</font>
+
+class condition_variable_any
+{
+public:
+
+ condition_variable_any();
+ ~condition_variable_any();
+
+ condition_variable_any(const condition_variable_any&amp;) = delete;
+ condition_variable_any&amp; operator=(const condition_variable_any&amp;) = delete;
+
+ void notify_one();
+ void notify_all();
+
+ template &lt;class Lock&gt;
+ void wait(Lock&amp; lock);
+ template &lt;class Lock, class Predicate&gt;
+ void wait(Lock&amp; lock, Predicate pred);
+
+ template &lt;class Lock, class Clock, class Duration&gt;
+ bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+ template &lt;class Lock, class Clock, class Duration, class Predicate&gt;
+ bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
+ Predicate pred);
+
+ template &lt;class Lock, class Rep, class Period&gt;
+ bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
+ template &lt;class Lock, class Rep, class Period, class Predicate&gt;
+ bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time, Predicate pred);
+};
+
+<font color="#c80000">// sleep</font>
+
+namespace this_thread
+{
+
+ template &lt;class Rep, class Period&gt;
+ void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
+
+ template &lt;class Clock, class Duration&gt;
+ void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
+
+} <font color="#c80000">// this_thread</font>
+
+} <font color="#c80000">// std</font>
+
+*/</font>
+
+#include &lt;ctime&gt;
+#include &lt;climits&gt;
+#include &lt;inttypes.h&gt;
+#include &lt;limits&gt;
+#include "type_traits"
+
+#define decltype __typeof__
+
+namespace std
+{
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">////////////////////// common_type ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+#define VARIADIC_COMMON_TYPE 0
+
+#if VARIADIC_COMMON_TYPE == 0
+
+template &lt;class T, class U&gt;
+struct common_type
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+#else
+
+template &lt;class ...T&gt; struct common_type;
+
+template &lt;class T&gt;
+struct common_type&lt;T&gt;
+{
+ typedef T type;
+};
+
+template &lt;class T, class U&gt;
+struct common_type&lt;T, U&gt;
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+template &lt;class T, class U, class ...V&gt;
+struct common_type&lt;T, U, V...&gt;
+{
+ typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
+};
+
+#endif
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////////// ratio ////////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// __static_gcd</font>
+
+template &lt;intmax_t X, intmax_t Y&gt;
+struct __static_gcd
+{
+ static const intmax_t value = __static_gcd&lt;Y, X % Y&gt;::value;
+};
+
+template &lt;intmax_t X&gt;
+struct __static_gcd&lt;X, 0&gt;
+{
+ static const intmax_t value = X;
+};
+
+<font color="#c80000">// __static_lcm</font>
+
+template &lt;intmax_t X, intmax_t Y&gt;
+struct __static_lcm
+{
+ static const intmax_t value = X / __static_gcd&lt;X, Y&gt;::value * Y;
+};
+
+template &lt;intmax_t X&gt;
+struct __static_abs
+{
+ static const intmax_t value = X &lt; 0 ? -X : X;
+};
+
+template &lt;intmax_t X&gt;
+struct __static_sign
+{
+ static const intmax_t value = X == 0 ? 0 : (X &lt; 0 ? -1 : 1);
+};
+
+template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
+class __ll_add;
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_add&lt;X, Y, 1&gt;
+{
+ static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[X &lt;= max - Y];
+<font color="#c80000">// static_assert(X &lt;= max - Y, "overflow in __ll_add");</font>
+public:
+ static const intmax_t value = X + Y;
+};
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_add&lt;X, Y, 0&gt;
+{
+public:
+ static const intmax_t value = X;
+};
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_add&lt;X, Y, -1&gt;
+{
+ static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[min - Y &lt;= X];
+<font color="#c80000">// static_assert(min - Y &lt;= X, "overflow in __ll_add");</font>
+public:
+ static const intmax_t value = X + Y;
+};
+
+template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
+class __ll_sub;
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_sub&lt;X, Y, 1&gt;
+{
+ static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[min + Y &lt;= X];
+<font color="#c80000">// static_assert(min + Y &lt;= X, "overflow in __ll_sub");</font>
+public:
+ static const intmax_t value = X - Y;
+};
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_sub&lt;X, Y, 0&gt;
+{
+public:
+ static const intmax_t value = X;
+};
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_sub&lt;X, Y, -1&gt;
+{
+ static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[X &lt;= max + Y];
+<font color="#c80000">// static_assert(X &lt;= max + Y, "overflow in __ll_sub");</font>
+public:
+ static const intmax_t value = X - Y;
+};
+
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_mul
+{
+ static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
+ static const intmax_t min = nan + 1;
+ static const intmax_t max = -min;
+ static const intmax_t __a_x = __static_abs&lt;X&gt;::value;
+ static const intmax_t __a_y = __static_abs&lt;Y&gt;::value;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test[__a_x &lt;= max / __a_y];
+<font color="#c80000">// static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; __a_x &lt;= max / __a_y, "overflow in __ll_mul");</font>
+public:
+ static const intmax_t value = X * Y;
+};
+
+template &lt;intmax_t Y&gt;
+class __ll_mul&lt;0, Y&gt;
+{
+public:
+ static const intmax_t value = 0;
+};
+
+template &lt;intmax_t X&gt;
+class __ll_mul&lt;X, 0&gt;
+{
+public:
+ static const intmax_t value = 0;
+};
+
+template &lt;&gt;
+class __ll_mul&lt;0, 0&gt;
+{
+public:
+ static const intmax_t value = 0;
+};
+
+<font color="#c80000">// Not actually used but left here in case needed in future maintenance</font>
+template &lt;intmax_t X, intmax_t Y&gt;
+class __ll_div
+{
+ static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
+ static const intmax_t min = nan + 1;
+ static const intmax_t max = -min;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test3[Y != 0];
+<font color="#c80000">// static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; Y != 0, "overflow in __ll_div");</font>
+public:
+ static const intmax_t value = X / Y;
+};
+
+template &lt;intmax_t N, intmax_t D = 1&gt;
+class ratio
+{
+ static char test1[__static_abs&lt;N&gt;::value &gt;= 0];
+ static char test2[__static_abs&lt;D&gt;::value &gt; 0];
+<font color="#c80000">// static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");</font>
+<font color="#c80000">// static_assert(D != 0, "ratio divide by 0");</font>
+<font color="#c80000">// static_assert(__static_abs&lt;D&gt;::value &gt; 0, "ratio denominator is out of range");</font>
+ static const intmax_t __na = __static_abs&lt;N&gt;::value;
+ static const intmax_t __da = __static_abs&lt;D&gt;::value;
+ static const intmax_t __s = __static_sign&lt;N&gt;::value * __static_sign&lt;D&gt;::value;
+ static const intmax_t __gcd = __static_gcd&lt;__na, __da&gt;::value;
+public:
+ static const intmax_t num = __s * __na / __gcd;
+ static const intmax_t den = __da / __gcd;
+};
+
+template &lt;class T&gt; struct ___is_ratio : tmp::false_type {};
+template &lt;intmax_t N, intmax_t D&gt; struct ___is_ratio&lt;ratio&lt;N, D&gt; &gt; : tmp::true_type {};
+template &lt;class T&gt; struct __is_ratio : ___is_ratio&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
+
+typedef ratio&lt;1LL, 1000000000000000000LL&gt; atto;
+typedef ratio&lt;1LL, 1000000000000000LL&gt; femto;
+typedef ratio&lt;1LL, 1000000000000LL&gt; pico;
+typedef ratio&lt;1LL, 1000000000LL&gt; nano;
+typedef ratio&lt;1LL, 1000000LL&gt; micro;
+typedef ratio&lt;1LL, 1000LL&gt; milli;
+typedef ratio&lt;1LL, 100LL&gt; centi;
+typedef ratio&lt;1LL, 10LL&gt; deci;
+typedef ratio&lt; 10LL, 1LL&gt; deca;
+typedef ratio&lt; 100LL, 1LL&gt; hecto;
+typedef ratio&lt; 1000LL, 1LL&gt; kilo;
+typedef ratio&lt; 1000000LL, 1LL&gt; mega;
+typedef ratio&lt; 1000000000LL, 1LL&gt; giga;
+typedef ratio&lt; 1000000000000LL, 1LL&gt; tera;
+typedef ratio&lt; 1000000000000000LL, 1LL&gt; peta;
+typedef ratio&lt;1000000000000000000LL, 1LL&gt; exa;
+
+template &lt;class R1, class R2&gt;
+struct ratio_add
+{
+ typedef ratio&lt;__ll_add&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
+ __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
+ __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+struct ratio_subtract
+{
+ typedef ratio&lt;__ll_sub&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
+ __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
+ __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+struct ratio_multiply
+{
+ typedef ratio&lt;__ll_mul&lt;R1::num, R2::num&gt;::value, __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
+};
+
+template &lt;class R1, class R2&gt;
+struct ratio_divide
+{
+ typedef ratio&lt;__ll_mul&lt;R1::num, R2::den&gt;::value, __ll_mul&lt;R1::den, R2::num&gt;::value&gt; type;
+};
+
+<font color="#c80000">// ratio_equal</font>
+
+template &lt;class R1, class R2&gt;
+struct ratio_equal
+ : public tmp::integral_constant&lt;bool, R1::num == R2::num &amp;&amp; R1::den == R2::den&gt; {};
+
+template &lt;class R1, class R2&gt;
+struct ratio_not_equal
+ : public tmp::integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
+
+<font color="#c80000">// ratio_less</font>
+
+<font color="#c80000">// Protect against overflow, and still get the right answer as much as possible.</font>
+<font color="#c80000">// This just demonstrates for fun how far you can push things without hitting</font>
+<font color="#c80000">// overflow. The obvious and simple implementation is conforming.</font>
+
+template &lt;class R1, class R2, bool ok1, bool ok2&gt;
+struct __ratio_less3 <font color="#c80000">// true, true and false, false</font>
+{
+ static const bool value = __ll_mul&lt;R1::num, R2::den&gt;::value &lt; __ll_mul&lt;R2::num, R1::den&gt;::value;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less3&lt;R1, R2, true, false&gt;
+{
+ static const bool value = true;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less3&lt;R1, R2, false, true&gt;
+{
+ static const bool value = false;
+};
+
+template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
+struct __ratio_less2 <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
+{
+ static const intmax_t max = -((1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
+ static const bool ok1 = R1::num &lt;= max / R2::den;
+ static const bool ok2 = R2::num &lt;= max / R1::den;
+ static const bool value = __ratio_less3&lt;R1, R2, ok1, ok2&gt;::value;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less2&lt;R1, R2, false&gt; <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
+{
+ static const bool value = R1::num &lt; R1::den;
+};
+
+template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
+struct __ratio_less1 <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
+{
+ static const bool value = __ratio_less2&lt;ratio&lt;R1::num, R2::num&gt;, ratio&lt;R1::den, R2::den&gt; &gt;::value;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less1&lt;R1, R2, false&gt; <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
+{
+ static const bool value = R1::num &lt; R1::den;
+};
+
+template &lt;class R1, class R2, intmax_t S1 = __static_sign&lt;R1::num&gt;::value,
+ intmax_t S2 = __static_sign&lt;R2::num&gt;::value&gt;
+struct __ratio_less
+{
+ static const bool value = S1 &lt; S2;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less&lt;R1, R2, 1LL, 1LL&gt;
+{
+ static const bool value = __ratio_less1&lt;R1, R2&gt;::value;
+};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_less&lt;R1, R2, -1LL, -1LL&gt;
+{
+ static const bool value = __ratio_less1&lt;ratio&lt;-R2::num, R2::den&gt;, ratio&lt;-R1::num, R1::den&gt; &gt;::value;
+};
+
+template &lt;class R1, class R2&gt;
+struct ratio_less
+ : public tmp::integral_constant&lt;bool, __ratio_less&lt;R1, R2&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+struct ratio_less_equal
+ : public tmp::integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+struct ratio_greater
+ : public tmp::integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+struct ratio_greater_equal
+ : public tmp::integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
+
+template &lt;class R1, class R2&gt;
+struct __ratio_gcd
+{
+ typedef ratio&lt;__static_gcd&lt;R1::num, R2::num&gt;::value,
+ __static_lcm&lt;R1::den, R2::den&gt;::value&gt; type;
+};
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">////////////////////// duration //////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+namespace datetime
+{
+
+template &lt;class RepType, class Period = ratio&lt;1&gt; &gt; class duration;
+
+template &lt;class T&gt; struct ___is_duration : tmp::false_type {};
+template &lt;class Rep, class Period&gt; struct ___is_duration&lt;duration&lt;Rep, Period&gt; &gt; : tmp::true_type {};
+template &lt;class T&gt; struct __is_duration : ___is_duration&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
+
+<font color="#c80000">// duration_cast</font>
+
+<font color="#c80000">// duration_cast is the heart of this whole prototype. It can convert any</font>
+<font color="#c80000">// duration to any other. It is also (implicitly) used in converting</font>
+<font color="#c80000">// time_points. The conversion is always exact if possible. And it is</font>
+<font color="#c80000">// always as efficient as hand written code. If different representations</font>
+<font color="#c80000">// are involved, care is taken to never require implicit conversions.</font>
+<font color="#c80000">// Instead static_cast is used explicitly for every required conversion.</font>
+<font color="#c80000">// If there are a mixture of integral and floating point representations,</font>
+<font color="#c80000">// the use of common_type ensures that the most logical "intermediate"</font>
+<font color="#c80000">// representation is used.</font>
+template &lt;class FromDuration, class ToDuration,
+ class Period = typename ratio_divide&lt;typename FromDuration::period, typename ToDuration::period&gt;::type,
+ bool = Period::num == 1,
+ bool = Period::den == 1&gt;
+struct __duration_cast;
+
+<font color="#c80000">// When the two periods are the same, all that is left to do is static_cast from</font>
+<font color="#c80000">// the source representation to the target representation (which may be a no-op).</font>
+<font color="#c80000">// This conversion is always exact as long as the static_cast from the source</font>
+<font color="#c80000">// representation to the destination representation is exact.</font>
+template &lt;class FromDuration, class ToDuration, class Period&gt;
+struct __duration_cast&lt;FromDuration, ToDuration, Period, true, true&gt;
+{
+ ToDuration operator()(const FromDuration&amp; fd) const
+ {
+ return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(fd.count()));
+ }
+};
+
+<font color="#c80000">// When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
+<font color="#c80000">// divide by the denominator of FromPeriod / ToPeriod. The common_type of</font>
+<font color="#c80000">// the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
+<font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
+template &lt;class FromDuration, class ToDuration, class Period&gt;
+struct __duration_cast&lt;FromDuration, ToDuration, Period, true, false&gt;
+{
+ ToDuration operator()(const FromDuration&amp; fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type&lt;
+ typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
+ intmax_t&gt;::type C;
+#else
+ typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
+#endif
+ return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
+ static_cast&lt;C&gt;(fd.count()) / static_cast&lt;C&gt;(Period::den)));
+ }
+};
+
+<font color="#c80000">// When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
+<font color="#c80000">// multiply by the numerator of FromPeriod / ToPeriod. The common_type of</font>
+<font color="#c80000">// the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is always exact as long as the static_cast's involved are exact.</font>
+template &lt;class FromDuration, class ToDuration, class Period&gt;
+struct __duration_cast&lt;FromDuration, ToDuration, Period, false, true&gt;
+{
+ ToDuration operator()(const FromDuration&amp; fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type&lt;
+ typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
+ intmax_t&gt;::type C;
+#else
+ typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
+#endif
+ return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
+ static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num)));
+ }
+};
+
+<font color="#c80000">// When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to</font>
+<font color="#c80000">// multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The</font>
+<font color="#c80000">// common_type of the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
+<font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
+template &lt;class FromDuration, class ToDuration, class Period&gt;
+struct __duration_cast&lt;FromDuration, ToDuration, Period, false, false&gt;
+{
+ ToDuration operator()(const FromDuration&amp; fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type&lt;
+ typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
+ intmax_t&gt;::type C;
+#else
+ typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
+#endif
+ return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
+ static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num) / static_cast&lt;C&gt;(Period::den)));
+ }
+};
+
+<font color="#c80000">// Compile-time select the most efficient algorithm for the conversion...</font>
+template &lt;class ToDuration, class Rep, class Period&gt;
+inline
+typename tmp::enable_if
+&lt;
+ __is_duration&lt;ToDuration&gt;::value,
+ ToDuration
+&gt;::type
+duration_cast(const duration&lt;Rep, Period&gt;&amp; fd)
+{
+ return __duration_cast&lt;duration&lt;Rep, Period&gt;, ToDuration&gt;()(fd);
+}
+
+<font color="#c80000">// Support bidirectional (non-exact) conversions for floating point rep types</font>
+<font color="#c80000">// (or user defined rep types which specialize treat_as_floating_point).</font>
+template &lt;class Rep&gt; struct treat_as_floating_point : tmp::is_floating_point&lt;Rep&gt; {};
+
+template &lt;class Rep&gt;
+struct duration_values
+{
+ static Rep __min_imp(tmp::false_type) {return -max();}
+ static Rep __min_imp(tmp::true_type) {return zero();}
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return numeric_limits&lt;Rep&gt;::max();}
+ static Rep min() {return __min_imp(tmp::is_unsigned&lt;Rep&gt;());}
+};
+
+<font color="#c80000">// duration</font>
+
+template &lt;class Rep, class Period&gt;
+class duration
+{
+ static char test0[!__is_duration&lt;Rep&gt;::value];
+<font color="#c80000">// static_assert(!__is_duration&lt;Rep&gt;::value, "A duration representation can not be a duration");</font>
+ static char test1[__is_ratio&lt;Period&gt;::value];
+<font color="#c80000">// static_assert(__is_ratio&lt;Period&gt;::value, "Second template parameter of duration must be a std::ratio");</font>
+ static char test2[Period::num &gt; 0];
+<font color="#c80000">// static_assert(Period::num &gt; 0, "duration period must be positive");</font>
+public:
+ typedef Rep rep;
+ typedef Period period;
+private:
+ rep rep_;
+public:
+
+ duration() {} <font color="#c80000">// = default;</font>
+ template &lt;class Rep2&gt;
+ explicit duration(const Rep2&amp; r,
+ typename tmp::enable_if
+ &lt;
+ tmp::is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
+ (treat_as_floating_point&lt;rep&gt;::value ||
+ !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
+ &gt;::type* = 0)
+ : rep_(r) {}
+
+ <font color="#c80000">// conversions</font>
+ template &lt;class Rep2, class Period2&gt;
+ duration(const duration&lt;Rep2, Period2&gt;&amp; d,
+ typename tmp::enable_if
+ &lt;
+ treat_as_floating_point&lt;rep&gt;::value ||
+ (ratio_divide&lt;Period2, period&gt;::type::den == 1 &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
+ &gt;::type* = 0)
+ : rep_(duration_cast&lt;duration&gt;(d).count()) {}
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const {return rep_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ duration operator+() const {return *this;}
+ duration operator-() const {return duration(-rep_);}
+ duration&amp; operator++() {++rep_; return *this;}
+ duration operator++(int) {return duration(rep_++);}
+ duration&amp; operator--() {--rep_; return *this;}
+ duration operator--(int) {return duration(rep_--);}
+
+ duration&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
+ duration&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
+
+ duration&amp; operator*=(const rep&amp; rhs) {rep_ *= rhs; return *this;}
+ duration&amp; operator/=(const rep&amp; rhs) {rep_ /= rhs; return *this;}
+
+ <font color="#c80000">// special values</font>
+
+ static duration zero() {return duration(duration_values&lt;rep&gt;::zero());}
+ static duration min() {return duration(duration_values&lt;rep&gt;::min());}
+ static duration max() {return duration(duration_values&lt;rep&gt;::max());}
+};
+
+typedef duration&lt;long long, nano&gt; nanoseconds;
+typedef duration&lt;long long, micro&gt; microseconds;
+typedef duration&lt;long long, milli&gt; milliseconds;
+typedef duration&lt;long long &gt; seconds;
+typedef duration&lt; long, ratio&lt; 60&gt; &gt; minutes;
+typedef duration&lt; long, ratio&lt;3600&gt; &gt; hours;
+
+} <font color="#c80000">// datetime</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
+{
+ typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
+ typename __ratio_gcd&lt;Period1, Period2&gt;::type&gt; type;
+};
+
+namespace datetime {
+
+<font color="#c80000">// Duration ==</font>
+
+template &lt;class LhsDuration, class RhsDuration&gt;
+struct __duration_eq
+{
+ bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
+ {
+ typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
+ return CD(lhs).count() == CD(rhs).count();
+ }
+};
+
+template &lt;class LhsDuration&gt;
+struct __duration_eq&lt;LhsDuration, LhsDuration&gt;
+{
+ bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
+ {return lhs.count() == rhs.count();}
+};
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return __duration_eq&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
+}
+
+<font color="#c80000">// Duration !=</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return !(lhs == rhs);
+}
+
+<font color="#c80000">// Duration &lt;</font>
+
+template &lt;class LhsDuration, class RhsDuration&gt;
+struct __duration_lt
+{
+ bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
+ {
+ typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
+ return CD(lhs).count() &lt; CD(rhs).count();
+ }
+};
+
+template &lt;class LhsDuration&gt;
+struct __duration_lt&lt;LhsDuration, LhsDuration&gt;
+{
+ bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
+ {return lhs.count() &lt; rhs.count();}
+};
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return __duration_lt&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
+}
+
+<font color="#c80000">// Duration &gt;</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return rhs &lt; lhs;
+}
+
+<font color="#c80000">// Duration &lt;=</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return !(rhs &lt; lhs);
+}
+
+<font color="#c80000">// Duration &gt;=</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+bool
+operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return !(lhs &lt; rhs);
+}
+
+<font color="#c80000">// Duration +</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
+operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
+ result += rhs;
+ return result;
+}
+
+<font color="#c80000">// Duration -</font>
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
+operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
+ result -= rhs;
+ return result;
+}
+
+<font color="#c80000">// Duration *</font>
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+inline
+typename tmp::enable_if
+&lt;
+ tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
+ tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
+ duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
+&gt;::type
+operator*(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
+{
+ typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
+ duration&lt;CR, Period&gt; r = d;
+ r *= static_cast&lt;CR&gt;(s);
+ return r;
+}
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+inline
+typename tmp::enable_if
+&lt;
+ tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
+ tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
+ duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
+&gt;::type
+operator*(const Rep1&amp; s, const duration&lt;Rep2, Period&gt;&amp; d)
+{
+ return d * s;
+}
+
+<font color="#c80000">// Duration /</font>
+
+template &lt;class Duration, class Rep, bool = __is_duration&lt;Rep&gt;::value&gt;
+struct __duration_divide_result
+{
+};
+
+template &lt;class Duration, class Rep2,
+ bool = tmp::is_convertible&lt;typename Duration::rep,
+ typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value &amp;&amp;
+ tmp::is_convertible&lt;Rep2,
+ typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value&gt;
+struct __duration_divide_imp
+{
+};
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+struct __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2, true&gt;
+{
+ typedef duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; type;
+};
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+struct __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2, false&gt;
+ : __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;
+{
+};
+
+template &lt;class Rep1, class Period, class Rep2&gt;
+inline
+typename __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;::type
+operator/(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
+{
+ typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
+ duration&lt;CR, Period&gt; r = d;
+ r /= static_cast&lt;CR&gt;(s);
+ return r;
+}
+
+template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
+inline
+typename common_type&lt;Rep1, Rep2&gt;::type
+operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ typedef typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type CD;
+ return CD(lhs).count() / CD(rhs).count();
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">///////////////////// time_point /////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+template &lt;class Clock, class Duration = typename Clock::duration&gt;
+class time_point
+{
+ static char test1[__is_duration&lt;Duration&gt;::value];
+<font color="#c80000">// static_assert(__is_duration&lt;Duration&gt;::value,</font>
+<font color="#c80000">// "Second template parameter of time_point must be a std::datetime::duration");</font>
+public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+private:
+ duration d_;
+
+public:
+ time_point() : d_(duration::zero()) {}
+ explicit time_point(const duration&amp; d) : d_(d) {}
+
+ <font color="#c80000">// conversions</font>
+ template &lt;class Duration2&gt;
+ time_point(const time_point&lt;clock, Duration2&gt;&amp; t,
+ typename tmp::enable_if
+ &lt;
+ tmp::is_convertible&lt;Duration2, duration&gt;::value
+ &gt;::type* = 0)
+ : d_(t.time_since_epoch()) {}
+
+ <font color="#c80000">// observer</font>
+
+ duration time_since_epoch() const {return d_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point&amp; operator+=(const duration&amp; d) {d_ += d; return *this;}
+ time_point&amp; operator-=(const duration&amp; d) {d_ -= d; return *this;}
+
+ <font color="#c80000">// special values</font>
+
+ static time_point min() {return time_point(duration::min());}
+ static time_point max() {return time_point(duration::max());}
+};
+
+} <font color="#c80000">// datetime</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
+{
+ typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
+};
+
+namespace datetime {
+
+template &lt;class ToDuration, class Clock, class Duration&gt;
+inline
+time_point&lt;Clock, ToDuration&gt;
+time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t)
+{
+ return time_point&lt;Clock, ToDuration&gt;(duration_cast&lt;ToDuration&gt;(t.time_since_epoch()));
+}
+
+<font color="#c80000">// time_point ==</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return lhs.time_since_epoch() == rhs.time_since_epoch();
+}
+
+<font color="#c80000">// time_point !=</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return !(lhs == rhs);
+}
+
+<font color="#c80000">// time_point &lt;</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator&lt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return lhs.time_since_epoch() &lt; rhs.time_since_epoch();
+}
+
+<font color="#c80000">// time_point &gt;</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator&gt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return rhs &lt; lhs;
+}
+
+<font color="#c80000">// time_point &lt;=</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return !(rhs &lt; lhs);
+}
+
+<font color="#c80000">// time_point &gt;=</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+bool
+operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return !(lhs &lt; rhs);
+}
+
+<font color="#c80000">// time_point operator+(time_point x, duration y);</font>
+
+template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
+inline
+time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
+operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ typedef time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt; TimeResult;
+ TimeResult r(lhs);
+ r += rhs;
+ return r;
+}
+
+<font color="#c80000">// time_point operator+(duration x, time_point y);</font>
+
+template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
+inline
+time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
+operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return rhs + lhs;
+}
+
+<font color="#c80000">// time_point operator-(time_point x, duration y);</font>
+
+template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
+inline
+time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
+operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
+{
+ return lhs + (-rhs);
+}
+
+<font color="#c80000">// duration operator-(time_point x, time_point y);</font>
+
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+typename common_type&lt;Duration1, Duration2&gt;::type
+operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
+{
+ return lhs.time_since_epoch() - rhs.time_since_epoch();
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////////// clocks ///////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// If you're porting, clocks are the system-specific (non-portable) part.</font>
+<font color="#c80000">// You'll need to know how to get the current time and implement that under now().</font>
+<font color="#c80000">// You'll need to know what units (tick period) and representation makes the most</font>
+<font color="#c80000">// sense for your clock and set those accordingly.</font>
+<font color="#c80000">// If you know how to map this clock to time_t (perhaps your clock is std::time, which</font>
+<font color="#c80000">// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().</font>
+
+class system_clock
+{
+public:
+ typedef microseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef datetime::time_point&lt;system_clock&gt; time_point;
+ static const bool is_monotonic = false;
+
+ static time_point now();
+ static time_t to_time_t (const time_point&amp; t);
+ static time_point from_time_t(time_t t);
+};
+
+class monotonic_clock
+{
+public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
+ static const bool is_monotonic = true;
+
+ static time_point now();
+};
+
+typedef monotonic_clock high_resolution_clock;
+
+} <font color="#c80000">// datetime</font>
+} <font color="#c80000">// std</font>
+
+<font color="#c80000">// clocks.cpp</font>
+
+#include &lt;sys/time.h&gt; <font color="#c80000">//for gettimeofday and timeval</font>
+#include &lt;mach/mach_time.h&gt; <font color="#c80000">// mach_absolute_time, mach_timebase_info_data_t</font>
+
+namespace std {
+namespace datetime {
+
+<font color="#c80000">// system_clock</font>
+
+<font color="#c80000">// gettimeofday is the most precise "system time" available on this platform.</font>
+<font color="#c80000">// It returns the number of microseconds since New Years 1970 in a struct called timeval</font>
+<font color="#c80000">// which has a field for seconds and a field for microseconds.</font>
+<font color="#c80000">// Fill in the timeval and then convert that to the time_point</font>
+system_clock::time_point
+system_clock::now()
+{
+ timeval tv;
+ gettimeofday(&amp;tv, 0);
+ return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
+}
+
+<font color="#c80000">// Take advantage of the fact that on this platform time_t is nothing but</font>
+<font color="#c80000">// an integral count of seconds since New Years 1970 (same epoch as timeval).</font>
+<font color="#c80000">// Just get the duration out of the time_point and truncate it to seconds.</font>
+time_t
+system_clock::to_time_t(const time_point&amp; t)
+{
+ return time_t(duration_cast&lt;seconds&gt;(t.time_since_epoch()).count());
+}
+
+<font color="#c80000">// Just turn the time_t into a count of seconds and construct a time_point with it.</font>
+system_clock::time_point
+system_clock::from_time_t(time_t t)
+{
+ return system_clock::time_point(seconds(t));
+}
+
+<font color="#c80000">// monotonic_clock</font>
+
+<font color="#c80000">// Note, in this implementation monotonic_clock and high_resolution_clock</font>
+<font color="#c80000">// are the same clock. They are both based on mach_absolute_time().</font>
+<font color="#c80000">// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of</font>
+<font color="#c80000">// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom</font>
+<font color="#c80000">// are run time constants supplied by the OS. This clock has no relationship</font>
+<font color="#c80000">// to the Gregorian calendar. It's main use is as a high resolution timer.</font>
+
+<font color="#c80000">// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize</font>
+<font color="#c80000">// for that case as an optimization.</font>
+static
+monotonic_clock::rep
+monotonic_simplified()
+{
+ return mach_absolute_time();
+}
+
+static
+double
+compute_monotonic_factor()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&amp;MachInfo);
+ return static_cast&lt;double&gt;(MachInfo.numer) / MachInfo.denom;
+}
+
+static
+monotonic_clock::rep
+monotonic_full()
+{
+ static const double factor = compute_monotonic_factor();
+ return static_cast&lt;monotonic_clock::rep&gt;(mach_absolute_time() * factor);
+}
+
+typedef monotonic_clock::rep (*FP)();
+
+static
+FP
+init_monotonic_clock()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&amp;MachInfo);
+ if (MachInfo.numer == MachInfo.denom)
+ return &amp;monotonic_simplified;
+ return &amp;monotonic_full;
+}
+
+monotonic_clock::time_point
+monotonic_clock::now()
+{
+ static FP fp = init_monotonic_clock();
+ return time_point(duration(fp()));
+}
+
+<font color="#c80000">// clocks.cpp end</font>
+
+} } <font color="#c80000">// std::datetime</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">///////////// simulated thread interface /////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+#include &lt;iostream&gt;
+
+namespace std {
+
+void __print_time(datetime::system_clock::time_point t)
+{
+ using namespace datetime;
+ time_t c_time = system_clock::to_time_t(t);
+ std::tm* tmptr = std::localtime(&amp;c_time);
+ system_clock::duration d = t.time_since_epoch();
+ std::cout &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec
+ &lt;&lt; '.' &lt;&lt; (d - duration_cast&lt;seconds&gt;(d)).count();
+}
+
+namespace this_thread {
+
+template &lt;class Rep, class Period&gt;
+void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
+{
+ datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
+ if (t &lt; d)
+ ++t;
+ if (t &gt; datetime::microseconds(0))
+ std::cout &lt;&lt; "sleep_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
+}
+
+template &lt;class Clock, class Duration&gt;
+void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
+{
+ using namespace datetime;
+ typedef time_point&lt;Clock, Duration&gt; Time;
+ typedef system_clock::time_point SysTime;
+ if (t &gt; Clock::now())
+ {
+ typedef typename common_type&lt;typename Time::duration, typename SysTime::duration&gt;::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast&lt;microseconds&gt;(d);
+ if (us &lt; d)
+ ++us;
+ SysTime st = system_clock::now() + us;
+ std::cout &lt;&lt; "sleep_until ";
+ __print_time(st);
+ std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
+ }
+}
+
+} <font color="#c80000">// this_thread</font>
+
+struct mutex {};
+
+struct timed_mutex
+{
+ bool try_lock() {std::cout &lt;&lt; "timed_mutex::try_lock()\n";}
+
+ template &lt;class Rep, class Period&gt;
+ bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
+ {
+ datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
+ if (t &lt;= datetime::microseconds(0))
+ return try_lock();
+ std::cout &lt;&lt; "try_lock_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
+ return true;
+ }
+
+ template &lt;class Clock, class Duration&gt;
+ bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
+ {
+ using namespace datetime;
+ typedef time_point&lt;Clock, Duration&gt; Time;
+ typedef system_clock::time_point SysTime;
+ if (t &lt;= Clock::now())
+ return try_lock();
+ typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast&lt;microseconds&gt;(d);
+ SysTime st = system_clock::now() + us;
+ std::cout &lt;&lt; "try_lock_until ";
+ __print_time(st);
+ std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
+ }
+};
+
+struct condition_variable
+{
+ template &lt;class Rep, class Period&gt;
+ bool wait_for(mutex&amp;, const datetime::duration&lt;Rep, Period&gt;&amp; d)
+ {
+ datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
+ std::cout &lt;&lt; "wait_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
+ return true;
+ }
+
+ template &lt;class Clock, class Duration&gt;
+ bool wait_until(mutex&amp;, const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
+ {
+ using namespace datetime;
+ typedef time_point&lt;Clock, Duration&gt; Time;
+ typedef system_clock::time_point SysTime;
+ if (t &lt;= Clock::now())
+ return false;
+ typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast&lt;microseconds&gt;(d);
+ SysTime st = system_clock::now() + us;
+ std::cout &lt;&lt; "wait_until ";
+ __print_time(st);
+ std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
+ }
+};
+
+} <font color="#c80000">// std</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////// End of implemetation ////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////// Simple sleep and wait examples //////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+std::mutex m;
+std::timed_mutex mut;
+std::condition_variable cv;
+
+void basic_examples()
+{
+ std::cout &lt;&lt; "Running basic examples\n";
+ using namespace std;
+ using namespace std::datetime;
+ system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
+ this_thread::sleep_for(seconds(3));
+ this_thread::sleep_for(nanoseconds(300));
+ this_thread::sleep_until(time_limit);
+<font color="#c80000">// this_thread::sleep_for(time_limit); // desired compile-time error</font>
+<font color="#c80000">// this_thread::sleep_until(seconds(3)); // desired compile-time error</font>
+ mut.try_lock_for(milliseconds(30));
+ mut.try_lock_until(time_limit);
+<font color="#c80000">// mut.try_lock_for(time_limit); // desired compile-time error</font>
+<font color="#c80000">// mut.try_lock_until(milliseconds(30)); // desired compile-time error</font>
+ cv.wait_for(m, minutes(1)); <font color="#c80000">// real code would put this in a loop</font>
+ cv.wait_until(m, time_limit); <font color="#c80000">// real code would put this in a loop</font>
+ <font color="#c80000">// For those who prefer floating point</font>
+ this_thread::sleep_for(duration&lt;double&gt;(0.25));
+ this_thread::sleep_until(system_clock::now() + duration&lt;double&gt;(1.5));
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////////////// User1 Example ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+namespace User1
+{
+<font color="#c80000">// Example type-safe "physics" code interoperating with std::datetime::duration types</font>
+<font color="#c80000">// and taking advantage of the std::ratio infrastructure and design philosophy.</font>
+
+<font color="#c80000">// length - mimics std::datetime::duration except restricts representation to double.</font>
+<font color="#c80000">// Uses std::ratio facilities for length units conversions.</font>
+
+template &lt;class Ratio&gt;
+class length
+{
+public:
+ typedef Ratio ratio;
+private:
+ double len_;
+public:
+
+ length() : len_(1) {}
+ length(const double&amp; len) : len_(len) {}
+
+ <font color="#c80000">// conversions</font>
+ template &lt;class R&gt;
+ length(const length&lt;R&gt;&amp; d)
+ : len_(d.count() * std::ratio_divide&lt;Ratio, R&gt;::type::den /
+ std::ratio_divide&lt;Ratio, R&gt;::type::num) {}
+
+ <font color="#c80000">// observer</font>
+
+ double count() const {return len_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ length&amp; operator+=(const length&amp; d) {len_ += d.count(); return *this;}
+ length&amp; operator-=(const length&amp; d) {len_ -= d.count(); return *this;}
+
+ length operator+() const {return *this;}
+ length operator-() const {return length(-len_);}
+
+ length&amp; operator*=(double rhs) {len_ *= rhs; return *this;}
+ length&amp; operator/=(double rhs) {len_ /= rhs; return *this;}
+};
+
+<font color="#c80000">// Sparse sampling of length units</font>
+typedef length&lt;std::ratio&lt;1&gt; &gt; meter; <font color="#c80000">// set meter as "unity"</font>
+typedef length&lt;std::centi&gt; centimeter; <font color="#c80000">// 1/100 meter</font>
+typedef length&lt;std::kilo&gt; kilometer; <font color="#c80000">// 1000 meters</font>
+typedef length&lt;std::ratio&lt;254, 10000&gt; &gt; inch; <font color="#c80000">// 254/10000 meters</font>
+<font color="#c80000">// length takes ratio instead of two integral types so that definitions can be made like so:</font>
+typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;12&gt;, inch::ratio&gt;::type&gt; foot; <font color="#c80000">// 12 inchs</font>
+typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;5280&gt;, foot::ratio&gt;::type&gt; mile; <font color="#c80000">// 5280 feet</font>
+
+<font color="#c80000">// Need a floating point definition of seconds</font>
+typedef std::datetime::duration&lt;double&gt; seconds; <font color="#c80000">// unity</font>
+<font color="#c80000">// Demo of (scientific) support for sub-nanosecond resolutions</font>
+typedef std::datetime::duration&lt;double, std::pico&gt; picosecond; <font color="#c80000">// 10^-12 seconds</font>
+typedef std::datetime::duration&lt;double, std::femto&gt; femtosecond; <font color="#c80000">// 10^-15 seconds</font>
+typedef std::datetime::duration&lt;double, std::atto&gt; attosecond; <font color="#c80000">// 10^-18 seconds</font>
+
+<font color="#c80000">// A very brief proof-of-concept for SIUnits-like library</font>
+<font color="#c80000">// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())</font>
+template &lt;class R1, class R2&gt;
+class quantity
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template &lt;&gt;
+class quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt;
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(seconds d) : q_(d.count()) {} <font color="#c80000">// note: only User1::seconds needed here</font>
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template &lt;&gt;
+class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt;
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(meter d) : q_(d.count()) {} <font color="#c80000">// note: only User1::meter needed here</font>
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template &lt;&gt;
+class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt;
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(double d) : q_(d) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+<font color="#c80000">// Example SI-Units</font>
+typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt; Scalar;
+typedef quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt; Time; <font color="#c80000">// second</font>
+typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt; Distance; <font color="#c80000">// meter</font>
+typedef quantity&lt;std::ratio&lt;-1&gt;, std::ratio&lt;1&gt; &gt; Speed; <font color="#c80000">// meter/second</font>
+typedef quantity&lt;std::ratio&lt;-2&gt;, std::ratio&lt;1&gt; &gt; Acceleration; <font color="#c80000">// meter/second^2</font>
+
+template &lt;class R1, class R2, class R3, class R4&gt;
+quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt;
+operator/(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
+{
+ typedef quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt; R;
+ R r;
+ r.set(x.get() / y.get());
+ return r;
+}
+
+template &lt;class R1, class R2, class R3, class R4&gt;
+quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt;
+operator*(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
+{
+ typedef quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt; R;
+ R r;
+ r.set(x.get() * y.get());
+ return r;
+}
+
+template &lt;class R1, class R2&gt;
+quantity&lt;R1, R2&gt;
+operator+(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
+{
+ typedef quantity&lt;R1, R2&gt; R;
+ R r;
+ r.set(x.get() + y.get());
+ return r;
+}
+
+template &lt;class R1, class R2&gt;
+quantity&lt;R1, R2&gt;
+operator-(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
+{
+ typedef quantity&lt;R1, R2&gt; R;
+ R r;
+ r.set(x.get() - y.get());
+ return r;
+}
+
+<font color="#c80000">// Example type-safe physics function</font>
+Distance
+compute_distance(Speed v0, Time t, Acceleration a)
+{
+ return v0 * t + Scalar(.5) * a * t * t; <font color="#c80000">// if a units mistake is made here it won't compile</font>
+}
+
+} <font color="#c80000">// User1</font>
+
+#include &lt;iostream&gt;
+
+<font color="#c80000">// Exercise example type-safe physics function and show interoperation</font>
+<font color="#c80000">// of custom time durations (User1::seconds) and standard time durations (std::hours).</font>
+<font color="#c80000">// Though input can be arbitrary (but type-safe) units, output is always in SI-units</font>
+<font color="#c80000">// (a limitation of the simplified Units lib demoed here).</font>
+void testUser1()
+{
+ std::cout &lt;&lt; "*************\n";
+ std::cout &lt;&lt; "* testUser1 *\n";
+ std::cout &lt;&lt; "*************\n";
+ User1::Distance d( User1::mile(110) );
+ User1::Time t( std::datetime::hours(2) );
+ User1::Speed s = d / t;
+ std::cout &lt;&lt; "Speed = " &lt;&lt; s.get() &lt;&lt; " meters/sec\n";
+ User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
+ std::cout &lt;&lt; "Acceleration = " &lt;&lt; a.get() &lt;&lt; " meters/sec^2\n";
+ User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
+ std::cout &lt;&lt; "Distance = " &lt;&lt; df.get() &lt;&lt; " meters\n";
+ std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::den &lt;&lt; '/' &lt;&lt; User1::mile::ratio::num &lt;&lt; " miles/meter";
+ User1::meter mt = 1;
+ User1::mile mi = mt;
+ std::cout &lt;&lt; " which is approximately " &lt;&lt; mi.count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::num &lt;&lt; '/' &lt;&lt; User1::mile::ratio::den &lt;&lt; " meters/mile";
+ mi = 1;
+ mt = mi;
+ std::cout &lt;&lt; " which is approximately " &lt;&lt; mt.count() &lt;&lt; '\n';
+ User1::attosecond as(1);
+ User1::seconds sec = as;
+ std::cout &lt;&lt; "1 attosecond is " &lt;&lt; sec.count() &lt;&lt; " seconds\n";
+ std::cout &lt;&lt; "sec = as; <font color="#c80000">// compiles\n";</font>
+ sec = User1::seconds(1);
+ as = sec;
+ std::cout &lt;&lt; "1 second is " &lt;&lt; as.count() &lt;&lt; " attoseconds\n";
+ std::cout &lt;&lt; "as = sec; <font color="#c80000">// compiles\n";</font>
+ std::cout &lt;&lt; "\n";
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////////////// User2 Example ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// Demonstrate User2:</font>
+<font color="#c80000">// A "saturating" signed integral type is developed. This type has +/- infinity and a nan</font>
+<font color="#c80000">// (like IEEE floating point) but otherwise obeys signed integral arithmetic.</font>
+<font color="#c80000">// This class is subsequently used as the rep in std::datetime::duration to demonstrate a</font>
+<font color="#c80000">// duration class that does not silently ignore overflow.</font>
+#include &lt;ostream&gt;
+#include &lt;stdexcept&gt;
+#include &lt;climits&gt;
+
+namespace User2
+{
+
+template &lt;class I&gt;
+class saturate
+{
+public:
+ typedef I int_type;
+
+ static const int_type nan = int_type(int_type(1) &lt;&lt; (sizeof(int_type) * CHAR_BIT - 1));
+ static const int_type neg_inf = nan + 1;
+ static const int_type pos_inf = -neg_inf;
+private:
+ int_type i_;
+
+<font color="#c80000">// static_assert(std::is_integral&lt;int_type&gt;::value &amp;&amp; std::is_signed&lt;int_type&gt;::value,</font>
+<font color="#c80000">// "saturate only accepts signed integral types");</font>
+<font color="#c80000">// static_assert(nan == -nan &amp;&amp; neg_inf &lt; pos_inf,</font>
+<font color="#c80000">// "saturate assumes two's complement hardware for signed integrals");</font>
+
+public:
+ saturate() : i_(nan) {}
+ explicit saturate(int_type i) : i_(i) {}
+ <font color="#c80000">// explicit</font>
+ operator int_type() const;
+
+ saturate&amp; operator+=(saturate x);
+ saturate&amp; operator-=(saturate x) {return *this += -x;}
+ saturate&amp; operator*=(saturate x);
+ saturate&amp; operator/=(saturate x);
+ saturate&amp; operator%=(saturate x);
+
+ saturate operator- () const {return saturate(-i_);}
+ saturate&amp; operator++() {*this += saturate(int_type(1)); return *this;}
+ saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
+ saturate&amp; operator--() {*this -= saturate(int_type(1)); return *this;}
+ saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
+
+ friend saturate operator+(saturate x, saturate y) {return x += y;}
+ friend saturate operator-(saturate x, saturate y) {return x -= y;}
+ friend saturate operator*(saturate x, saturate y) {return x *= y;}
+ friend saturate operator/(saturate x, saturate y) {return x /= y;}
+ friend saturate operator%(saturate x, saturate y) {return x %= y;}
+
+ friend bool operator==(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ == y.i_;
+ }
+
+ friend bool operator!=(saturate x, saturate y) {return !(x == y);}
+
+ friend bool operator&lt;(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ &lt; y.i_;
+ }
+
+ friend bool operator&lt;=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ &lt;= y.i_;
+ }
+
+ friend bool operator&gt;(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ &gt; y.i_;
+ }
+
+ friend bool operator&gt;=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ &gt;= y.i_;
+ }
+
+ friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, saturate s)
+ {
+ switch (s.i_)
+ {
+ case pos_inf:
+ return os &lt;&lt; "inf";
+ case nan:
+ return os &lt;&lt; "nan";
+ case neg_inf:
+ return os &lt;&lt; "-inf";
+ };
+ return os &lt;&lt; s.i_;
+ }
+};
+
+template &lt;class I&gt;
+saturate&lt;I&gt;::operator int_type() const
+{
+ switch (i_)
+ {
+ case nan:
+ case neg_inf:
+ case pos_inf:
+ throw std::out_of_range("saturate special value can not convert to int_type");
+ }
+ return i_;
+}
+
+template &lt;class I&gt;
+saturate&lt;I&gt;&amp;
+saturate&lt;I&gt;::operator+=(saturate x)
+{
+ switch (i_)
+ {
+ case pos_inf:
+ switch (x.i_)
+ {
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = x.i_;
+ return *this;
+ }
+ if (x.i_ &gt;= 0)
+ {
+ if (i_ &lt; pos_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = pos_inf;
+ return *this;
+ }
+ if (i_ &gt; neg_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = neg_inf;
+ return *this;
+}
+
+template &lt;class I&gt;
+saturate&lt;I&gt;&amp;
+saturate&lt;I&gt;::operator*=(saturate x)
+{
+ switch (i_)
+ {
+ case 0:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case pos_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ &lt; 0)
+ i_ = neg_inf;
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ &lt; 0)
+ i_ = pos_inf;
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case 0:
+ i_ = 0;
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case pos_inf:
+ if (i_ &lt; 0)
+ i_ = neg_inf;
+ else
+ i_ = pos_inf;
+ return *this;
+ case neg_inf:
+ if (i_ &lt; 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ int s = (i_ &lt; 0 ? -1 : 1) * (x.i_ &lt; 0 ? -1 : 1);
+ i_ = i_ &lt; 0 ? -i_ : i_;
+ int_type x_i_ = x.i_ &lt; 0 ? -x.i_ : x.i_;
+ if (i_ &lt;= pos_inf / x_i_)
+ i_ *= x_i_;
+ else
+ i_ = pos_inf;
+ i_ *= s;
+ return *this;
+}
+
+template &lt;class I&gt;
+saturate&lt;I&gt;&amp;
+saturate&lt;I&gt;::operator/=(saturate x)
+{
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ break;
+ default:
+ i_ = 0;
+ break;
+ }
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case 0:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ return *this;
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (i_ &gt; 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ switch (i_)
+ {
+ case 0:
+ case nan:
+ return *this;
+ case pos_inf:
+ case neg_inf:
+ if (x.i_ &lt; 0)
+ i_ = -i_;
+ return *this;
+ }
+ i_ /= x.i_;
+ return *this;
+}
+
+template &lt;class I&gt;
+saturate&lt;I&gt;&amp;
+saturate&lt;I&gt;::operator%=(saturate x)
+{
+<font color="#c80000">// *this -= *this / x * x; // definition</font>
+ switch (x.i_)
+ {
+ case nan:
+ case neg_inf:
+ case 0:
+ case pos_inf:
+ i_ = nan;
+ return *this;
+ }
+ switch (i_)
+ {
+ case neg_inf:
+ case pos_inf:
+ i_ = nan;
+ case nan:
+ return *this;
+ }
+ i_ %= x.i_;
+ return *this;
+}
+
+<font color="#c80000">// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution</font>
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::pico &gt; picoseconds;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::nano &gt; nanoseconds;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::micro &gt; microseconds;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::milli &gt; milliseconds;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt; &gt; seconds;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 60LL&gt; &gt; minutes;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 3600LL&gt; &gt; hours;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 86400LL&gt; &gt; days;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 31556952LL&gt; &gt; years;
+typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;31556952000LL&gt; &gt; millennium;
+
+} <font color="#c80000">// User2</font>
+
+<font color="#c80000">// Demonstrate custom promotion rules (needed only if there are no implicit conversions)</font>
+namespace User2 { namespace detail {
+
+template &lt;class T1, class T2, bool = tmp::is_integral&lt;T1&gt;::value&gt;
+struct promote_helper;
+
+template &lt;class T1, class T2&gt;
+struct promote_helper&lt;T1, saturate&lt;T2&gt;, true&gt; <font color="#c80000">// integral</font>
+{
+ typedef typename std::common_type&lt;T1, T2&gt;::type rep;
+ typedef User2::saturate&lt;rep&gt; type;
+};
+
+template &lt;class T1, class T2&gt;
+struct promote_helper&lt;T1, saturate&lt;T2&gt;, false&gt; <font color="#c80000">// floating</font>
+{
+ typedef T1 type;
+};
+
+} }
+
+namespace std
+{
+
+template &lt;class T1, class T2&gt;
+struct common_type&lt;User2::saturate&lt;T1&gt;, User2::saturate&lt;T2&gt; &gt;
+{
+ typedef typename common_type&lt;T1, T2&gt;::type rep;
+ typedef User2::saturate&lt;rep&gt; type;
+};
+
+template &lt;class T1, class T2&gt;
+struct common_type&lt;T1, User2::saturate&lt;T2&gt; &gt;
+ : User2::detail::promote_helper&lt;T1, User2::saturate&lt;T2&gt; &gt; {};
+
+template &lt;class T1, class T2&gt;
+struct common_type&lt;User2::saturate&lt;T1&gt;, T2&gt;
+ : User2::detail::promote_helper&lt;T2, User2::saturate&lt;T1&gt; &gt; {};
+
+
+<font color="#c80000">// Demonstrate specialization of duration_values:</font>
+
+namespace datetime {
+
+template &lt;class I&gt;
+struct duration_values&lt;User2::saturate&lt;I&gt; &gt;
+{
+ typedef User2::saturate&lt;I&gt; Rep;
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return Rep(Rep::pos_inf-1);}
+ static Rep min() {return -max();}
+};
+
+}
+
+}
+
+#include &lt;iostream&gt;
+
+void testUser2()
+{
+ std::cout &lt;&lt; "*************\n";
+ std::cout &lt;&lt; "* testUser2 *\n";
+ std::cout &lt;&lt; "*************\n";
+ using namespace User2;
+ typedef seconds::rep sat;
+ years yr(sat(100));
+ std::cout &lt;&lt; "100 years expressed as years = " &lt;&lt; yr.count() &lt;&lt; '\n';
+ nanoseconds ns = yr;
+ std::cout &lt;&lt; "100 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+ ns += yr;
+ std::cout &lt;&lt; "200 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+ ns += yr;
+ std::cout &lt;&lt; "300 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+<font color="#c80000">// yr = ns; // does not compile</font>
+ std::cout &lt;&lt; "yr = ns; <font color="#c80000">// does not compile\n";</font>
+<font color="#c80000">// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic</font>
+ std::cout &lt;&lt; "ps = yr; <font color="#c80000">// does not compile\n";</font>
+ ns = yr;
+ picoseconds ps = ns;
+ std::cout &lt;&lt; "100 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
+ ps = ns / sat(1000);
+ std::cout &lt;&lt; "0.1 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
+ yr = years(sat(-200000000));
+ std::cout &lt;&lt; "200 million years ago encoded in years: " &lt;&lt; yr.count() &lt;&lt; '\n';
+ days d = std::datetime::duration_cast&lt;days&gt;(yr);
+ std::cout &lt;&lt; "200 million years ago encoded in days: " &lt;&lt; d.count() &lt;&lt; '\n';
+ millennium c = std::datetime::duration_cast&lt;millennium&gt;(yr);
+ std::cout &lt;&lt; "200 million years ago encoded in millennium: " &lt;&lt; c.count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "Demonstrate \"uninitialized protection\" behavior:\n";
+ seconds sec;
+ for (++sec; sec &lt; seconds(sat(10)); ++sec)
+ ;
+ std::cout &lt;&lt; sec.count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "\n";
+}
+
+void testStdUser()
+{
+ std::cout &lt;&lt; "***************\n";
+ std::cout &lt;&lt; "* testStdUser *\n";
+ std::cout &lt;&lt; "***************\n";
+ using namespace std::datetime;
+ hours hr = hours(100);
+ std::cout &lt;&lt; "100 hours expressed as hours = " &lt;&lt; hr.count() &lt;&lt; '\n';
+ nanoseconds ns = hr;
+ std::cout &lt;&lt; "100 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+ ns += hr;
+ std::cout &lt;&lt; "200 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+ ns += hr;
+ std::cout &lt;&lt; "300 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
+<font color="#c80000">// hr = ns; // does not compile</font>
+ std::cout &lt;&lt; "hr = ns; <font color="#c80000">// does not compile\n";</font>
+<font color="#c80000">// hr * ns; // does not compile</font>
+ std::cout &lt;&lt; "hr * ns; <font color="#c80000">// does not compile\n";</font>
+ duration&lt;double&gt; fs(2.5);
+ std::cout &lt;&lt; "duration&lt;double&gt; has count() = " &lt;&lt; fs.count() &lt;&lt; '\n';
+<font color="#c80000">// seconds sec = fs; // does not compile</font>
+ std::cout &lt;&lt; "seconds sec = duration&lt;double&gt; won't compile\n";
+ seconds sec = duration_cast&lt;seconds&gt;(fs);
+ std::cout &lt;&lt; "seconds has count() = " &lt;&lt; sec.count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "\n";
+}
+
+<font color="#c80000">// timeval clock demo</font>
+<font color="#c80000">// Demonstrate the use of a timeval-like struct to be used as the representation</font>
+<font color="#c80000">// type for both duraiton and time_point.</font>
+
+namespace timeval_demo
+{
+
+class xtime {
+private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec &lt; 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+public:
+
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec &lt; 0 || tv_usec &gt;= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec)
+ {
+ tv_usec = static_cast&lt;long&gt;(usec % 1000000);
+ tv_sec = static_cast&lt;long&gt;(usec / 1000000);
+ fixup();
+ }
+
+ <font color="#c80000">// explicit</font>
+ operator long long() const {return static_cast&lt;long long&gt;(tv_sec) * 1000000 + tv_usec;}
+
+ xtime&amp; operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec &gt;= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime&amp; operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime&amp; operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = t / 1000000;
+ tv_usec = t % 1000000;
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec &amp;&amp; x.tv_usec == y.tv_usec); }
+
+ friend bool operator&lt;(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec &lt; y.tv_usec);
+ return (x.tv_sec &lt; y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator&gt; (xtime x, xtime y) { return y &lt; x; }
+ friend bool operator&lt;=(xtime x, xtime y) { return !(y &lt; x); }
+ friend bool operator&gt;=(xtime x, xtime y) { return !(x &lt; y); }
+
+ friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, xtime x)
+ {return os &lt;&lt; '{' &lt;&lt; x.tv_sec &lt;&lt; ',' &lt;&lt; x.tv_usec &lt;&lt; '}';}
+};
+
+class xtime_clock
+{
+public:
+ typedef xtime rep;
+ typedef std::micro period;
+ typedef std::datetime::duration&lt;rep, period&gt; duration;
+ typedef std::datetime::time_point&lt;xtime_clock&gt; time_point;
+
+ static time_point now();
+};
+
+xtime_clock::time_point
+xtime_clock::now()
+{
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&amp;t, 0);
+ return t;
+}
+
+void test_xtime_clock()
+{
+ using namespace std::datetime;
+ std::cout &lt;&lt; "timeval_demo system clock test\n";
+ std::cout &lt;&lt; "sizeof xtime_clock::time_point = " &lt;&lt; sizeof(xtime_clock::time_point) &lt;&lt; '\n';
+ std::cout &lt;&lt; "sizeof xtime_clock::duration = " &lt;&lt; sizeof(xtime_clock::duration) &lt;&lt; '\n';
+ std::cout &lt;&lt; "sizeof xtime_clock::rep = " &lt;&lt; sizeof(xtime_clock::rep) &lt;&lt; '\n';
+ xtime_clock::duration delay(milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+ while (xtime_clock::now() - start &lt;= delay)
+ ;
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
+}
+
+} <font color="#c80000">// timeval_demo</font>
+
+<font color="#c80000">// Handle duration with resolution not known until run time</font>
+
+namespace runtime_resolution
+{
+
+class duration
+{
+public:
+ typedef long long rep;
+private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+public:
+ typedef std::datetime::duration&lt;double, std::nano&gt; tonanosec;
+
+ duration() {} <font color="#c80000">// = default;</font>
+ explicit duration(const rep&amp; r) : rep_(r) {}
+
+ <font color="#c80000">// conversions</font>
+ explicit duration(const tonanosec&amp; d)
+ : rep_(static_cast&lt;rep&gt;(d.count() * ticks_per_nanosecond)) {}
+
+ <font color="#c80000">// explicit</font>
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const {return rep_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ duration&amp; operator+=(const duration&amp; d) {rep_ += d.rep_; return *this;}
+ duration&amp; operator-=(const duration&amp; d) {rep_ += d.rep_; return *this;}
+ duration&amp; operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration&amp; operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ duration operator+() const {return *this;}
+ duration operator-() const {return duration(-rep_);}
+ duration&amp; operator++() {++rep_; return *this;}
+ duration operator++(int) {return duration(rep_++);}
+ duration&amp; operator--() {--rep_; return *this;}
+ duration operator--(int) {return duration(rep_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator&lt; (duration x, duration y) {return x.rep_ &lt; y.rep_;}
+ friend bool operator&lt;=(duration x, duration y) {return !(y &lt; x);}
+ friend bool operator&gt; (duration x, duration y) {return y &lt; x;}
+ friend bool operator&gt;=(duration x, duration y) {return !(x &lt; y);}
+};
+
+static
+double
+init_duration()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&amp;MachInfo);
+ return static_cast&lt;double&gt;(MachInfo.denom) / MachInfo.numer;
+}
+
+const double duration::ticks_per_nanosecond = init_duration();
+
+class clock;
+
+class time_point
+{
+public:
+ typedef runtime_resolution::clock clock;
+ typedef long long rep;
+private:
+ rep rep_;
+
+
+ rep count() const {return rep_;}
+public:
+
+ time_point() : rep_(0) {}
+ explicit time_point(const duration&amp; d)
+ : rep_(d.count()) {}
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
+ time_point&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
+
+ friend time_point operator+(time_point x, duration y) {return x += y;}
+ friend time_point operator+(duration x, time_point y) {return y += x;}
+ friend time_point operator-(time_point x, duration y) {return x -= y;}
+ friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
+};
+
+class clock
+{
+public:
+ typedef duration::rep rep;
+ typedef runtime_resolution::duration duration;
+ typedef runtime_resolution::time_point time_point;
+
+ static time_point now() {return time_point(duration(mach_absolute_time()));}
+};
+
+void test()
+{
+ using namespace std::datetime;
+ std::cout &lt;&lt; "runtime_resolution test\n";
+ clock::duration delay(std::datetime::milliseconds(5));
+ clock::time_point start = clock::now();
+ while (clock::now() - start &lt;= delay)
+ ;
+ clock::time_point stop = clock::now();
+ clock::duration elapsed = stop - start;
+ std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(duration_cast&lt;nanoseconds&gt;(duration::tonanosec(elapsed))).count()
+ &lt;&lt; " nanoseconds\n";
+}
+
+} <font color="#c80000">// runtime_resolution</font>
+
+<font color="#c80000">// miscellaneous tests and demos:</font>
+
+#include &lt;cassert&gt;
+#include &lt;iostream&gt;
+
+using namespace std::datetime;
+
+void physics_function(duration&lt;double&gt; d)
+{
+ std::cout &lt;&lt; "d = " &lt;&lt; d.count() &lt;&lt; '\n';
+}
+
+void drive_physics_function()
+{
+ physics_function(nanoseconds(3));
+ physics_function(hours(3));
+ physics_function(duration&lt;double&gt;(2./3));
+ std::cout.precision(16);
+ physics_function( hours(3) + nanoseconds(-3) );
+}
+
+void test_range()
+{
+ using namespace std::datetime;
+ hours h1 = hours(24 * ( 365 * 292 + 292/4));
+ nanoseconds n1 = h1 + nanoseconds(1);
+ nanoseconds delta = n1 - h1;
+ std::cout &lt;&lt; "292 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
+ std::cout &lt;&lt; "Add a nanosecond = " &lt;&lt; n1.count() &lt;&lt; "ns\n";
+ std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "ns\n";
+}
+
+void test_extended_range()
+{
+ using namespace std::datetime;
+ hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
+ <font color="#c80000">/*auto*/</font> microseconds u1 = h1 + microseconds(1);
+ <font color="#c80000">/*auto*/</font> microseconds delta = u1 - h1;
+ std::cout &lt;&lt; "244,000 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
+ std::cout &lt;&lt; "Add a microsecond = " &lt;&lt; u1.count() &lt;&lt; "us\n";
+ std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "us\n";
+}
+
+template &lt;class Rep, class Period&gt;
+void inspect_duration(std::datetime::duration&lt;Rep, Period&gt; d, const std::string&amp; name)
+{
+ typedef std::datetime::duration&lt;Rep, Period&gt; Duration;
+ std::cout &lt;&lt; "********* " &lt;&lt; name &lt;&lt; " *********\n";
+ std::cout &lt;&lt; "The period of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::num/Period::den &lt;&lt; " seconds.\n";
+ std::cout &lt;&lt; "The frequency of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::den/Period::num &lt;&lt; " Hz.\n";
+ std::cout &lt;&lt; "The representation is ";
+ if (tmp::is_floating_point&lt;Rep&gt;::value)
+ {
+ std::cout &lt;&lt; "floating point\n";
+ std::cout &lt;&lt; "The precision is the most significant ";
+ std::cout &lt;&lt; std::numeric_limits&lt;Rep&gt;::digits10 &lt;&lt; " decimal digits.\n";
+ }
+ else if (tmp::is_integral&lt;Rep&gt;::value)
+ {
+ std::cout &lt;&lt; "integral\n";
+ d = Duration(Rep(1));
+ std::datetime::duration&lt;double&gt; dsec = d;
+ std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
+ }
+ else
+ {
+ std::cout &lt;&lt; "a class type\n";
+ d = Duration(Rep(1));
+ std::datetime::duration&lt;double&gt; dsec = d;
+ std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
+ }
+ d = Duration(std::numeric_limits&lt;Rep&gt;::max());
+ using namespace std::datetime;
+ using namespace std;
+ typedef duration&lt;double, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
+ Years years = d;
+ std::cout &lt;&lt; "The range is +/- " &lt;&lt; years.count() &lt;&lt; " years.\n";
+ std::cout &lt;&lt; "sizeof(" &lt;&lt; name &lt;&lt; ") = " &lt;&lt; sizeof(d) &lt;&lt; '\n';
+}
+
+void inspect_all()
+{
+ using namespace std::datetime;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration&lt;double&gt;(), "duration&lt;double&gt;");
+}
+
+void test_milliseconds()
+{
+ using namespace std::datetime;
+ milliseconds ms(250);
+ ms += milliseconds(1);
+ milliseconds ms2(150);
+ milliseconds msdiff = ms - ms2;
+ if (msdiff == milliseconds(101))
+ std::cout &lt;&lt; "success\n";
+ else
+ std::cout &lt;&lt; "failure: " &lt;&lt; msdiff.count() &lt;&lt; '\n';
+}
+
+ using namespace std;
+ using namespace std::datetime;
+
+<font color="#c80000">// Example round_up utility: converts d to To, rounding up for inexact conversions</font>
+<font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
+template &lt;class To, class Rep, class Period&gt;
+To
+round_up(duration&lt;Rep, Period&gt; d)
+{
+ To result = duration_cast&lt;To&gt;(d);
+ if (result &lt; d)
+ ++result;
+ return result;
+}
+
+<font color="#c80000">// demonstrate interaction with xtime-like facility:</font>
+
+using namespace std::datetime;
+
+struct xtime
+{
+ long sec;
+ unsigned long usec;
+};
+
+template &lt;class Rep, class Period&gt;
+xtime
+to_xtime_truncate(duration&lt;Rep, Period&gt; d)
+{
+ xtime xt;
+ xt.sec = duration_cast&lt;seconds&gt;(d).count();
+ xt.usec = duration_cast&lt;microseconds&gt;(d - seconds(xt.sec)).count();
+ return xt;
+}
+
+template &lt;class Rep, class Period&gt;
+xtime
+to_xtime_round_up(duration&lt;Rep, Period&gt; d)
+{
+ xtime xt;
+ xt.sec = duration_cast&lt;seconds&gt;(d).count();
+ xt.usec = round_up&lt;microseconds&gt;(d - seconds(xt.sec)).count();
+ return xt;
+}
+
+microseconds
+from_xtime(xtime xt)
+{
+ return seconds(xt.sec) + microseconds(xt.usec);
+}
+
+void print(xtime xt)
+{
+ cout &lt;&lt; '{' &lt;&lt; xt.sec &lt;&lt; ',' &lt;&lt; xt.usec &lt;&lt; "}\n";
+}
+
+void test_with_xtime()
+{
+ cout &lt;&lt; "test_with_xtime\n";
+ xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
+ print(xt);
+ milliseconds ms = duration_cast&lt;milliseconds&gt;(from_xtime(xt));
+ cout &lt;&lt; ms.count() &lt;&lt; " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
+ print(xt);
+}
+
+void test_system_clock()
+{
+ cout &lt;&lt; "system_clock test" &lt;&lt; endl;
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = system_clock::now();
+ while (system_clock::now() - start &lt;= delay)
+ ;
+ system_clock::time_point stop = system_clock::now();
+ system_clock::duration elapsed = stop - start;
+ cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
+ start = system_clock::now();
+ stop = system_clock::now();
+ cout &lt;&lt; "system_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+ cout &lt;&lt; "monotonic_clock test" &lt;&lt; endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start &lt;= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ cout &lt;&lt; "monotonic_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
+}
+
+void test_hi_resolution_clock()
+{
+ cout &lt;&lt; "high_resolution_clock test" &lt;&lt; endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start &lt;= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ cout &lt;&lt; "high_resolution_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
+}
+
+void test_mixed_clock()
+{
+ cout &lt;&lt; "mixed clock test" &lt;&lt; endl;
+ high_resolution_clock::time_point hstart = high_resolution_clock::now();
+ cout &lt;&lt; "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+ monotonic_clock::time_point mend = hstart + milliseconds(5);
+ bool b = hstart == mend;
+ system_clock::time_point sstart = system_clock::now();
+ std::cout &lt;&lt; "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+<font color="#c80000">// mend - sstart; // doesn't compile</font>
+ cout &lt;&lt; "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+ " and add that to a system_clock::time_point\n";
+ system_clock::time_point send = sstart + duration_cast&lt;system_clock::duration&gt;(mend - hstart);
+ cout &lt;&lt; "subtract two system_clock::time_point's and output that in microseconds:\n";
+ microseconds ms = send - sstart;
+ cout &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
+}
+
+void test_c_mapping()
+{
+ cout &lt;&lt; "C map test\n";
+ using namespace std::datetime;
+ system_clock::time_point t1 = system_clock::now();
+ std::time_t c_time = system_clock::to_time_t(t1);
+ std::tm* tmptr = std::localtime(&amp;c_time);
+ std::cout &lt;&lt; "It is now " &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec &lt;&lt; ' '
+ &lt;&lt; tmptr-&gt;tm_year + 1900 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mon + 1 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mday &lt;&lt; '\n';
+ c_time = std::mktime(tmptr);
+ system_clock::time_point t2 = system_clock::from_time_t(c_time);
+ microseconds ms = t1 - t2;
+ std::cout &lt;&lt; "Round-tripping through the C interface truncated the precision by " &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
+}
+
+void test_duration_division()
+{
+ cout &lt;&lt; hours(3) / milliseconds(5) &lt;&lt; '\n';
+ cout &lt;&lt; milliseconds(5) / hours(3) &lt;&lt; '\n';
+ cout &lt;&lt; hours(1) / milliseconds(1) &lt;&lt; '\n';
+}
+
+namespace I_dont_like_the_default_duration_behavior
+{
+
+<font color="#c80000">// Here's how you override the duration's default constructor to do anything you want (in this case zero)</font>
+
+template &lt;class R&gt;
+class zero_default
+{
+public:
+ typedef R rep;
+
+private:
+ rep rep_;
+public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default&amp; operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default&amp; operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default&amp; operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default&amp; operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default&amp; operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default&amp; operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator&lt; (zero_default x, zero_default y) {return x.rep_ &lt; y.rep_;}
+ friend bool operator&lt;=(zero_default x, zero_default y) {return !(y &lt; x);}
+ friend bool operator&gt; (zero_default x, zero_default y) {return y &lt; x;}
+ friend bool operator&gt;=(zero_default x, zero_default y) {return !(x &lt; y);}
+};
+
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::nano &gt; nanoseconds;
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::micro &gt; microseconds;
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::milli &gt; milliseconds;
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt; &gt; seconds;
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;60&gt; &gt; minutes;
+typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;3600&gt; &gt; hours;
+
+void test()
+{
+ milliseconds ms;
+ cout &lt;&lt; ms.count() &lt;&lt; '\n';
+}
+
+} <font color="#c80000">// I_dont_like_the_default_duration_behavior</font>
+
+<font color="#c80000">// Build a min for two time_points</font>
+
+template &lt;class Rep, class Period&gt;
+void
+print_duration(ostream&amp; os, duration&lt;Rep, Period&gt; d)
+{
+ os &lt;&lt; d.count() &lt;&lt; " * " &lt;&lt; Period::num &lt;&lt; '/' &lt;&lt; Period::den &lt;&lt; " seconds\n";
+}
+
+<font color="#c80000">// Example min utility: returns the earliest time_point</font>
+<font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
+template &lt;class Clock, class Duration1, class Duration2&gt;
+inline
+typename common_type&lt;time_point&lt;Clock, Duration1&gt;, time_point&lt;Clock, Duration2&gt; &gt;::type
+min(time_point&lt;Clock, Duration1&gt; t1, time_point&lt;Clock, Duration2&gt; t2)
+{
+ return t2 &lt; t1 ? t2 : t1;
+}
+
+void test_min()
+{
+ typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, seconds&gt;::type&gt; T1;
+ typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, nanoseconds&gt;::type&gt; T2;
+ typedef common_type&lt;T1, T2&gt;::type T3;
+ <font color="#c80000">/*auto*/</font> T1 t1 = system_clock::now() + seconds(3);
+ <font color="#c80000">/*auto*/</font> T2 t2 = system_clock::now() + nanoseconds(3);
+ <font color="#c80000">/*auto*/</font> T3 t3 = min(t1, t2);
+ print_duration(cout, t1 - t3);
+ print_duration(cout, t2 - t3);
+}
+
+void explore_limits()
+{
+ typedef duration&lt;long long, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
+ monotonic_clock::time_point t1( Years(250));
+ monotonic_clock::time_point t2(-Years(250));
+ <font color="#c80000">// nanosecond resolution is likely to overflow. "up cast" to microseconds.</font>
+ <font color="#c80000">// The "up cast" trades precision for range.</font>
+ microseconds d = time_point_cast&lt;microseconds&gt;(t1) - time_point_cast&lt;microseconds&gt;(t2);
+ cout &lt;&lt; d.count() &lt;&lt; " microseconds\n";
+}
+
+void manipulate_clock_object(system_clock clock)
+{
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = clock.now();
+ while (clock.now() - start &lt;= delay)
+ ;
+ system_clock::time_point stop = clock.now();
+ system_clock::duration elapsed = stop - start;
+ cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
+};
+
+template &lt;long long speed&gt;
+struct cycle_count
+{
+ typedef typename ratio_multiply&lt;ratio&lt;speed&gt;, mega&gt;::type frequency; <font color="#c80000">// Mhz</font>
+ typedef typename ratio_divide&lt;ratio&lt;1&gt;, frequency&gt;::type period;
+ typedef long long rep;
+ typedef std::datetime::duration&lt;rep, period&gt; duration;
+ typedef std::datetime::time_point&lt;cycle_count&gt; time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ <font color="#c80000">// return exact cycle count</font>
+ return time_point(duration(++tick)); <font color="#c80000">// fake access to clock cycle count</font>
+ }
+};
+
+template &lt;long long speed&gt;
+struct approx_cycle_count
+{
+ static const long long frequency = speed * 1000000; <font color="#c80000">// MHz</font>
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef std::datetime::time_point&lt;approx_cycle_count&gt; time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ <font color="#c80000">// return cycle count as an approximate number of nanoseconds</font>
+ <font color="#c80000">// compute as if nanoseconds is only duration in the std::lib</font>
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+};
+
+void cycle_count_delay()
+{
+ {
+ typedef cycle_count&lt;400&gt; clock;
+ cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
+ &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
+ cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() &lt; stop) <font color="#c80000">// no multiplies or divides in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
+ cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count&lt;400&gt; clock;
+ cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
+ }
+ {
+ typedef cycle_count&lt;1500&gt; clock;
+ cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
+ &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
+ cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() &lt; stop) <font color="#c80000">// no multiplies or divides in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
+ cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count&lt;1500&gt; clock;
+ cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
+ }
+}
+
+void test_special_values()
+{
+ std::cout &lt;&lt; "duration&lt;unsigned&gt;::min().count() = " &lt;&lt; duration&lt;unsigned&gt;::min().count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "duration&lt;unsigned&gt;::zero().count() = " &lt;&lt; duration&lt;unsigned&gt;::zero().count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "duration&lt;unsigned&gt;::max().count() = " &lt;&lt; duration&lt;unsigned&gt;::max().count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "duration&lt;int&gt;::min().count() = " &lt;&lt; duration&lt;int&gt;::min().count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "duration&lt;int&gt;::zero().count() = " &lt;&lt; duration&lt;int&gt;::zero().count() &lt;&lt; '\n';
+ std::cout &lt;&lt; "duration&lt;int&gt;::max().count() = " &lt;&lt; duration&lt;int&gt;::max().count() &lt;&lt; '\n';
+}
+
+int main()
+{
+ basic_examples();
+ testStdUser();
+ testUser1();
+ testUser2();
+ drive_physics_function();
+ test_range();
+ test_extended_range();
+ inspect_all();
+ test_milliseconds();
+ test_with_xtime();
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ test_mixed_clock();
+ timeval_demo::test_xtime_clock();
+ runtime_resolution::test();
+ test_c_mapping();
+ test_duration_division();
+ I_dont_like_the_default_duration_behavior::test();
+ test_min();
+#if VARIADIC_COMMON_TYPE
+ inspect_duration(common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type(),
+ "common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type");
+#endif
+ explore_limits();
+ manipulate_clock_object(system_clock());
+ duration&lt;double, milli&gt; d = milliseconds(3) * 2.5;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ cout &lt;&lt; d.count() &lt;&lt; '\n';
+<font color="#c80000">// milliseconds ms(3.5); // doesn't compile</font>
+ cout &lt;&lt; "milliseconds ms(3.5) doesn't compile\n";
+ cycle_count_delay();
+ test_special_values();
+}
+
+<font color="#c80000">/*
+Output
+
+Running basic examples
+sleep_for 3000000 microseconds
+sleep_for 1 microseconds
+sleep_until 10:47:17.728293 which is 4499340 microseconds away
+try_lock_for 30000 microseconds
+try_lock_until 10:47:17.728285 which is 4499303 microseconds away
+wait_for 60000000 microseconds
+wait_until 10:47:17.728285 which is 4499264 microseconds away
+sleep_for 250000 microseconds
+sleep_until 10:47:14.729077 which is 1499979 microseconds away
+***************
+* testStdUser *
+***************
+100 hours expressed as hours = 100
+100 hours expressed as nanoseconds = 360000000000000
+200 hours expressed as nanoseconds = 720000000000000
+300 hours expressed as nanoseconds = 1080000000000000
+hr = ns; <font color="#c80000">// does not compile</font>
+hr * ns; <font color="#c80000">// does not compile</font>
+duration&lt;double&gt; has count() = 2.5
+seconds sec = duration&lt;double&gt; won't compile
+seconds has count() = 2
+
+*************
+* testUser1 *
+*************
+Speed = 24.5872 meters/sec
+Acceleration = 9.81456 meters/sec^2
+Distance = 13.5204 meters
+There are 125/201168 miles/meter which is approximately 0.000621371
+There are 201168/125 meters/mile which is approximately 1609.34
+1 attosecond is 1e-18 seconds
+sec = as; <font color="#c80000">// compiles</font>
+1 second is 1e+18 attoseconds
+as = sec; <font color="#c80000">// compiles</font>
+
+*************
+* testUser2 *
+*************
+100 years expressed as years = 100
+100 years expressed as nanoseconds = 3155695200000000000
+200 years expressed as nanoseconds = 6311390400000000000
+300 years expressed as nanoseconds = inf
+yr = ns; <font color="#c80000">// does not compile</font>
+ps = yr; <font color="#c80000">// does not compile</font>
+100 years expressed as picoseconds = inf
+0.1 years expressed as picoseconds = 3155695200000000000
+200 million years ago encoded in years: -200000000
+200 million years ago encoded in days: -73048500000
+200 million years ago encoded in millennium: -200000
+Demonstrate "uninitialized protection" behavior:
+nan
+
+d = 3e-09
+d = 10800
+d = 0.666667
+d = 10799.999999997
+292 years of hours = 2559672hr
+Add a nanosecond = 9214819200000000001ns
+Find the difference = 1ns
+244,000 years of hours = 2138904000hr
+Add a microsecond = 7700054400000000001us
+Find the difference = 1us
+********* nanoseconds *********
+The period of nanoseconds is 1e-09 seconds.
+The frequency of nanoseconds is 1e+09 Hz.
+The representation is integral
+The precision is 1e-09 seconds.
+The range is +/- 292.277 years.
+sizeof(nanoseconds) = 8
+********* microseconds *********
+The period of microseconds is 1e-06 seconds.
+The frequency of microseconds is 1e+06 Hz.
+The representation is integral
+The precision is 1e-06 seconds.
+The range is +/- 292277 years.
+sizeof(microseconds) = 8
+********* milliseconds *********
+The period of milliseconds is 0.001 seconds.
+The frequency of milliseconds is 1000 Hz.
+The representation is integral
+The precision is 0.001 seconds.
+The range is +/- 2.92277e+08 years.
+sizeof(milliseconds) = 8
+********* seconds *********
+The period of seconds is 1 seconds.
+The frequency of seconds is 1 Hz.
+The representation is integral
+The precision is 1 seconds.
+The range is +/- 2.92277e+11 years.
+sizeof(seconds) = 8
+********* minutes *********
+The period of minutes is 60 seconds.
+The frequency of minutes is 0.0166667 Hz.
+The representation is integral
+The precision is 60 seconds.
+The range is +/- 4083.06 years.
+sizeof(minutes) = 4
+********* hours *********
+The period of hours is 3600 seconds.
+The frequency of hours is 0.000277778 Hz.
+The representation is integral
+The precision is 3600 seconds.
+The range is +/- 244984 years.
+sizeof(hours) = 4
+********* duration&lt;double&gt; *********
+The period of duration&lt;double&gt; is 1 seconds.
+The frequency of duration&lt;double&gt; is 1 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+300 years.
+sizeof(duration&lt;double&gt;) = 8
+success
+test_with_xtime
+{3,251000}
+3251 milliseconds
+{3,251000}
+{3,0}
+{3,1}
+system_clock test
+paused 5001000 nanoseconds
+system_clock resolution estimate: 0 nanoseconds
+monotonic_clock test
+paused 5000181 nanoseconds
+monotonic_clock resolution estimate: 97 nanoseconds
+high_resolution_clock test
+paused 5000277 nanoseconds
+high_resolution_clock resolution estimate: 96 nanoseconds
+mixed clock test
+Add 5 milliseconds to a high_resolution_clock::time_point
+Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
+subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
+subtract two system_clock::time_point's and output that in microseconds:
+5000 microseconds
+timeval_demo system clock test
+sizeof xtime_clock::time_point = 8
+sizeof xtime_clock::duration = 8
+sizeof xtime_clock::rep = 8
+paused 5001000 nanoseconds
+runtime_resolution test
+paused 5000205 nanoseconds
+C map test
+It is now 10:47:13 2008-4-22
+Round-tripping through the C interface truncated the precision by 255445 microseconds
+2160000
+0
+3600000
+0
+2999998997 * 1/1000000000 seconds
+0 * 1/1000000000 seconds
+15778476000000000 microseconds
+paused 5001000 nanoseconds
+********* milliseconds(3) * 2.5 *********
+The period of milliseconds(3) * 2.5 is 0.001 seconds.
+The frequency of milliseconds(3) * 2.5 is 1000 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+297 years.
+sizeof(milliseconds(3) * 2.5) = 8
+7.5
+milliseconds ms(3.5) doesn't compile
+
+Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
+delay = 500 nanoseconds which is 200 cycles
+paused 201 cycles which is 502 nanoseconds
+
+Simulated 400MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 503 nanoseconds
+
+Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
+delay = 500 nanoseconds which is 750 cycles
+paused 751 cycles which is 500 nanoseconds
+
+Simulated 1500MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 500 nanoseconds
+duration&lt;unsigned&gt;::min().count() = 0
+duration&lt;unsigned&gt;::zero().count() = 0
+duration&lt;unsigned&gt;::max().count() = 4294967295
+duration&lt;int&gt;::min().count() = -2147483647
+duration&lt;int&gt;::zero().count() = 0
+duration&lt;int&gt;::max().count() = 2147483647
+*/</font>
+
+<font color="#c80000">/*
+Example disassemblies (to show efficiency).
+Disclaimer: I don't pretend to understand the optimizations made.
+
+Compiled with
+g++ -O3 -arch x86_64 -S test2.cpp
+
+x86 64-bit architecture
+
+********************
+
+system_clock::duration
+time_subtraction(system_clock::time_point x, system_clock::time_point y)
+{
+ return x - y;
+}
+
+ pushq %rbp
+LCFI25:
+ subq %rsi, %rdi
+ movq %rdi, %rax
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ ret
+
+********************
+
+seconds
+time_subtract_to_seconds(system_clock::time_point x, system_clock::time_point y)
+{
+ return duration_cast&lt;seconds&gt;(x - y);
+}
+
+ subq %rsi, %rdi
+ movabsq $4835703278458516699, %rdx
+ pushq %rbp
+LCFI25:
+ movq %rdi, %rax
+ sarq $63, %rdi
+ imulq %rdx
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ sarq $18, %rdx
+ subq %rdi, %rdx
+ movq %rdx, %rax
+ ret
+
+********************
+
+nanoseconds
+time_subtract_to_nanoseconds(system_clock::time_point x, system_clock::time_point y)
+{
+ return x - y;
+}
+
+ pushq %rbp
+LCFI25:
+ subq %rsi, %rdi
+ imulq $1000, %rdi, %rax
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ ret
+
+********************
+
+system_clock::time_point
+time_plus_duration(system_clock::time_point x, system_clock::duration y)
+{
+ return x + y;
+}
+
+ pushq %rbp
+LCFI37:
+ movq %rsp, %rbp
+LCFI38:
+ leaq (%rsi,%rdi), %rax
+ leave
+ ret
+
+********************
+
+milliseconds
+duration_plus_duration(milliseconds x, milliseconds y)
+{
+ return x + y;
+}
+
+ pushq %rbp
+LCFI11:
+ leaq (%rdi,%rsi), %rax
+ movq %rsp, %rbp
+LCFI12:
+ leave
+ ret
+
+********************
+
+nanoseconds
+milliseconds_plus_nanoseconds(milliseconds x, nanoseconds y)
+{
+ return x + y;
+}
+
+ imulq $1000000, %rdi, %rdi
+ pushq %rbp
+LCFI20:
+ movq %rsp, %rbp
+LCFI21:
+ leave
+ leaq (%rdi,%rsi), %rax
+ ret
+
+********************
+
+milliseconds
+nanoseconds_to_milliseconds(nanoseconds x)
+{
+ return duration_cast&lt;milliseconds&gt;(x);
+}
+
+ movq %rdi, %rax
+ movabsq $4835703278458516699, %rdx
+ pushq %rbp
+LCFI13:
+ imulq %rdx
+ sarq $63, %rdi
+ movq %rsp, %rbp
+LCFI14:
+ leave
+ sarq $18, %rdx
+ subq %rdi, %rdx
+ movq %rdx, %rax
+ ret
+
+********************
+
+nanoseconds
+milliseconds_to_nanoseconds(milliseconds x)
+{
+ return x;
+}
+
+ pushq %rbp
+LCFI13:
+ imulq $1000000, %rdi, %rax
+ movq %rsp, %rbp
+LCFI14:
+ leave
+ ret
+
+********************
+
+hours
+increment_hours(hours x)
+{
+ return ++x;
+}
+
+ pushq %rbp
+LCFI11:
+ leaq 1(%rdi), %rax
+ movq %rsp, %rbp
+LCFI12:
+ leave
+ ret
+
+*/</font>
+</pre>
+
+</body></html>
\ No newline at end of file

Added: trunk/libs/chrono/example/await_keystroke.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/await_keystroke.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,73 @@
+// await_keystroke.cpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <boost/chrono/chrono.hpp>
+#include <iostream>
+#include <iomanip>
+
+using namespace boost::chrono;
+
+template< class Clock >
+class timer
+{
+ typename Clock::time_point start;
+public:
+
+ timer() : start( Clock::now() ) {}
+
+ typename Clock::duration elapsed() const
+ {
+ return Clock::now() - start;
+ }
+
+ double seconds() const
+ {
+ return elapsed().count() * ((double)Clock::period::num/Clock::period::den);
+ }
+};
+
+int main()
+{
+ timer<system_clock> t1;
+ timer<monotonic_clock> t2;
+ timer<high_resolution_clock> t3;
+
+ std::cout << "Strike any key: ";
+ std::cin.get();
+
+ std::cout << std::fixed << std::setprecision(9);
+ std::cout << "system_clock-----------: "
+ << t1.seconds() << " seconds\n";
+ std::cout << "monotonic_clock--------: "
+ << t2.seconds() << " seconds\n";
+ std::cout << "high_resolution_clock--: "
+ << t3.seconds() << " seconds\n";
+
+ system_clock::time_point d4 = system_clock::now();
+ system_clock::time_point d5 = system_clock::now();
+
+ std::cout << "\nsystem_clock latency-----------: " << (d5 - d4).count() << std::endl;
+
+ monotonic_clock::time_point d6 = monotonic_clock::now();
+ monotonic_clock::time_point d7 = monotonic_clock::now();
+
+ std::cout << "monotonic_clock latency--------: " << (d7 - d6).count() << std::endl;
+
+ high_resolution_clock::time_point d8 = high_resolution_clock::now();
+ high_resolution_clock::time_point d9 = high_resolution_clock::now();
+
+ std::cout << "high_resolution_clock latency--: " << (d9 - d8).count() << std::endl;
+
+ std::time_t now = system_clock::to_time_t(system_clock::now());
+
+ std::cout << "\nsystem_clock::now() reports UTC is "
+ << std::asctime(std::gmtime(&now)) << "\n";
+
+ return 0;
+}

Added: trunk/libs/chrono/example/chrono_accuracy_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/chrono_accuracy_test.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,102 @@
+// boost run_timer_test.cpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2006, 2008
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//#include <boost/chrono/process_cpu_clocks.hpp>
+#include <boost/chrono/timer.hpp>
+#include <cstdlib> // for atol()
+#include <iostream>
+#include <sstream>
+#include <locale>
+#include <ctime>
+#include <cmath> // for sqrt(), used to burn time
+
+//using boost::chrono::run_timer;
+using boost::system::error_code;
+
+#include <boost/detail/lightweight_test.hpp>
+
+namespace
+{
+ typedef boost::chrono::nanoseconds ns;
+
+ // accuracy test
+ void accuracy_test( int argc, char * argv[] )
+ {
+ long timeout_in_secs = 1;
+ if ( argc > 1 ) timeout_in_secs = std::atol( argv[1] );
+ std::cout << "accuracy test for " << timeout_in_secs << " second(s)...";
+
+ std::clock_t timeout_in_clock_t = std::clock();
+ timeout_in_clock_t += (timeout_in_secs * CLOCKS_PER_SEC);
+
+ boost::chrono::system_timer sys;
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ boost::chrono::monotonic_timer mono;
+#endif
+ boost::chrono::high_resolution_timer hires;
+ boost::chrono::timer<boost::chrono::process_cpu_clock> process;
+
+ std::clock_t now;
+ do
+ {
+ now = std::clock();
+ } while ( now < timeout_in_clock_t );
+
+ boost::chrono::system_timer::duration sys_dur = sys.elapsed();
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ boost::chrono::monotonic_timer::duration mono_dur = mono.elapsed();
+#endif
+ boost::chrono::high_resolution_timer::duration hires_dur = hires.elapsed();
+ boost::chrono::process_cpu_clock::duration times;
+ times = process.elapsed();
+
+ std::cout << std::endl;
+
+ ns timeout_in_nanoseconds( static_cast<long long>(timeout_in_secs) * 1000000000LL );
+
+ // Allow 20% leeway. Particularly on Linux, there seems to be a large discrepancy
+ // between std::clock() and higher resolution clocks.
+ ns maximum_delta ( static_cast<long long>(timeout_in_nanoseconds.count() * 0.20 ) );
+
+ std::cout << timeout_in_nanoseconds.count() << " timeout_in_nanoseconds\n";
+ std::cout << maximum_delta.count() << " maximum_delta\n";
+
+ std::cout << sys_dur.count() << " sys_dur\n";
+
+ BOOST_TEST( sys_dur > timeout_in_nanoseconds - maximum_delta
+ && sys_dur < timeout_in_nanoseconds + maximum_delta );
+
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ std::cout << mono_dur.count() << " mono_dur\n";
+
+ BOOST_TEST( mono_dur > timeout_in_nanoseconds - maximum_delta
+ && mono_dur < timeout_in_nanoseconds + maximum_delta );
+#endif
+
+ std::cout << hires_dur.count() << " hires_dur\n";
+
+ BOOST_TEST( hires_dur > timeout_in_nanoseconds - maximum_delta
+ && hires_dur < timeout_in_nanoseconds + maximum_delta );
+
+ std::cout << times.count().real << " times.real\n";
+
+// BOOST_TEST( times.count().real > timeout_in_nanoseconds - maximum_delta
+// && times.count().real < timeout_in_nanoseconds + maximum_delta );
+ }
+
+}
+
+int main( int argc, char * argv[] )
+{
+ accuracy_test( argc, argv );
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/chrono/example/chrono_unit_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/chrono_unit_test.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,31 @@
+// chrono_unit_test.cpp ----------------------------------------------------//
+
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <iostream>
+
+
+int main()
+{
+ boost::chrono::nanoseconds nanosecs;
+ boost::chrono::microseconds microsecs;
+ boost::chrono::milliseconds millisecs;
+ boost::chrono::seconds secs;
+ boost::chrono::minutes mins;
+ boost::chrono::hours hrs;
+
+ std::time_t sys_time
+ = boost::chrono::system_clock::to_time_t(boost::chrono::system_clock::now());
+
+ std::cout
+ << "system_clock::to_time_t(system_clock::now()) is "
+ << std::asctime(std::gmtime(&sys_time)) << std::endl;
+
+ return 0;
+}

Added: trunk/libs/chrono/example/clock_name.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/clock_name.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,20 @@
+// stopclock_perf.cpp ---------------------------------------------------//
+
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#include "clock_name.hpp"
+#include <iostream>
+
+int main()
+{
+ std::cout << name<boost::chrono::system_clock>::apply() << '\n';
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ std::cout << name<boost::chrono::monotonic_clock>::apply() << '\n';
+#endif
+ std::cout << name<boost::chrono::high_resolution_clock>::apply() << '\n';
+}

Added: trunk/libs/chrono/example/clock_name.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/clock_name.hpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,68 @@
+// stopclock_perf.cpp ---------------------------------------------------//
+
+// Copyright 2009 Vicente J. Botet Escriba
+// Copyright 2009 Howard Hinnant
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#ifndef BOOST_CHRONO_CLOCK_NAME_HPP
+#define BOOST_CHRONO_CLOCK_NAME_HPP
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+template <typename Clock,
+ bool = boost::is_same<Clock, boost::chrono::system_clock>::value,
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ bool = boost::is_same<Clock, boost::chrono::monotonic_clock>::value,
+#else
+ bool = false,
+#endif
+ bool = boost::is_same<Clock, boost::chrono::high_resolution_clock>::value
+ >
+struct name;
+
+template <typename Clock>
+struct name<Clock, false, false, false> {
+ static const char* apply() { return "unknown clock";}
+};
+
+template <typename Clock>
+struct name<Clock, true, false, false> {
+ static const char* apply() { return "system_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, false, true, false> {
+ static const char* apply() { return "monotonic_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, false, false, true> {
+ static const char* apply() { return "high_resolution_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, false, true, true> {
+ static const char* apply() { return "monotonic_clock and high_resolution_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, true, false, true> {
+ static const char* apply() { return "system_clock and high_resolution_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, true, true, false> {
+ static const char* apply() { return "system_clock and monotonic_clock";}
+};
+
+template <typename Clock>
+struct name<Clock, true, true, true> {
+ static const char* apply() { return "system_clock, monotonic_clock and high_resolution_clock";}
+};
+
+#endif

Added: trunk/libs/chrono/example/cycle_count.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/cycle_count.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,140 @@
+// cycle_count.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+
+template <long long speed>
+struct cycle_count
+{
+ typedef typename boost::ratio_multiply<boost::ratio<speed>, boost::mega>::type frequency; // Mhz
+ typedef typename boost::ratio_divide<boost::ratio<1>, frequency>::type period;
+ typedef long long rep;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return exact cycle count
+ return time_point(duration(++tick)); // fake access to clock cycle count
+ }
+};
+
+template <long long speed>
+struct approx_cycle_count
+{
+ static const long long frequency = speed * 1000000; // MHz
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef boost::chrono::time_point<approx_cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return cycle count as an approximate number of nanoseconds
+ // compute as if nanoseconds is only duration in the std::lib
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+};
+
+void cycle_count_delay()
+{
+ {
+ typedef cycle_count<400> clock;
+ std::cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ std::cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ std::cout << "paused " << elapsed.count() << " cycles ";
+ std::cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<400> clock;
+ std::cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ std::cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ std::cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+ {
+ typedef cycle_count<1500> clock;
+ std::cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ std::cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ std::cout << "paused " << elapsed.count() << " cycles ";
+ std::cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<1500> clock;
+ std::cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ std::cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ std::cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+}
+
+int main()
+{
+ cycle_count_delay();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/explore_limits.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/explore_limits.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,60 @@
+// explore_limits.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+
+void explore_limits()
+{
+ typedef duration<long long, boost::ratio_multiply<boost::ratio<24*3652425,10000>,
+ hours::period>::type> Years;
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ monotonic_clock::time_point t1( Years(250));
+ monotonic_clock::time_point t2(-Years(250));
+#else
+ system_clock::time_point t1( Years(250));
+ system_clock::time_point t2(-Years(250));
+#endif
+ // nanosecond resolution is likely to overflow. "up cast" to microseconds.
+ // The "up cast" trades precision for range.
+ microseconds d = time_point_cast<microseconds>(t1) - time_point_cast<microseconds>(t2);
+ std::cout << d.count() << " microseconds\n";
+}
+
+
+int main()
+{
+ explore_limits();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/i_dont_like_the_default_duration_behavior.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/i_dont_like_the_default_duration_behavior.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,97 @@
+// i_dont_like_the_default_duration_behavior.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+namespace I_dont_like_the_default_duration_behavior
+{
+
+// Here's how you override the duration's default constructor to do anything you want (in this case zero)
+
+template <class R>
+class zero_default
+{
+public:
+ typedef R rep;
+
+private:
+ rep rep_;
+public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default& operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default& operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default& operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default& operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator< (zero_default x, zero_default y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(zero_default x, zero_default y) {return !(y < x);}
+ friend bool operator> (zero_default x, zero_default y) {return y < x;}
+ friend bool operator>=(zero_default x, zero_default y) {return !(x < y);}
+};
+
+typedef boost::chrono::duration<zero_default<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<zero_default<long long> > seconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<60> > minutes;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<3600> > hours;
+
+void test()
+{
+ milliseconds ms;
+ std::cout << ms.count() << '\n';
+}
+
+} // I_dont_like_the_default_duration_behavior
+
+
+int main()
+{
+ I_dont_like_the_default_duration_behavior::test();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/io_ex1.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/io_ex1.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,61 @@
+// io_ex1.cpp ----------------------------------------------------------//
+
+// Copyright 2010 Howard Hinnant
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation.
+Many thanks to Howard for making his code available under the Boost license.
+
+*/
+
+#include <iostream>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/chrono/thread_clock.hpp>
+
+int main()
+{
+ using namespace std;
+ using namespace boost;
+ using namespace boost::chrono;
+
+ cout << "milliseconds(3) + microseconds(10) = "
+ << milliseconds(3) + microseconds(10) << '\n';
+
+ cout << "hours(3) + minutes(10) = "
+ << hours(3) + minutes(10) << '\n';
+
+ typedef duration<long long, ratio<1, 2500000000ULL> > ClockTick;
+ cout << "ClockTick(3) + nanoseconds(10) = "
+ << ClockTick(3) + nanoseconds(10) << '\n';
+
+ cout << "\nSet cout to use short names:\n";
+ cout << duration_short;
+
+ cout << "milliseconds(3) + microseconds(10) = "
+ << milliseconds(3) + microseconds(10) << '\n';
+
+ cout << "hours(3) + minutes(10) = "
+ << hours(3) + minutes(10) << '\n';
+
+ cout << "ClockTick(3) + nanoseconds(10) = "
+ << ClockTick(3) + nanoseconds(10) << '\n';
+
+ cout << "\nsystem_clock::now() = " << system_clock::now() << '\n';
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ cout << "monotonic_clock::now() = " << monotonic_clock::now() << '\n';
+#endif
+ cout << "\nSet cout to use long names:\n" << duration_long
+ << "high_resolution_clock::now() = " << high_resolution_clock::now() << '\n';
+#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+ cout << "\nthread_clock::now() = " << thread_clock::now() << '\n';
+#endif
+ cout << "\nprocess_real_cpu_clock::now() = " << process_real_cpu_clock::now() << '\n';
+ cout << "\nprocess_user_cpu_clock::now() = " << process_user_cpu_clock::now() << '\n';
+ cout << "\nprocess_system_cpu_clock::now() = " << process_system_cpu_clock::now() << '\n';
+ cout << "\nprocess_cpu_clock::now() = " << process_cpu_clock::now() << '\n';
+ return 0;
+}

Added: trunk/libs/chrono/example/io_ex2.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/io_ex2.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,39 @@
+// io_ex2.cpp ----------------------------------------------------------//
+
+// Copyright 2010 Howard Hinnant
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation.
+Many thanks to Howard for making his code available under the Boost license.
+
+*/
+
+#include <boost/chrono/chrono_io.hpp>
+#include <sstream>
+#include <boost/assert.hpp>
+
+int main()
+{
+ using namespace std;
+ using namespace boost::chrono;
+
+#ifdef BOOST_CHRONO_IO_INPUT
+ istringstream in("5000 milliseconds 4000 ms 3001 ms");
+ seconds d(0);
+ in >> d;
+ BOOST_ASSERT(in.good());
+ BOOST_ASSERT(d == seconds(5));
+ in >> d;
+ BOOST_ASSERT(in.good());
+ BOOST_ASSERT(d == seconds(4));
+ in >> d;
+ BOOST_ASSERT(in.fail());
+ BOOST_ASSERT(d == seconds(4));
+#endif
+ return 0;
+}
+

Added: trunk/libs/chrono/example/io_ex3.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/io_ex3.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,49 @@
+// io_ex1.cpp ----------------------------------------------------------//
+
+// Copyright 2010 Howard Hinnant
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation.
+Many thanks to Howard for making his code available under the Boost license.
+
+*/
+
+#include <boost/chrono/chrono_io.hpp>
+#include <sstream>
+#include <iostream>
+#include <boost/assert.hpp>
+
+int main()
+{
+ using namespace std;
+ using namespace boost::chrono;
+
+ high_resolution_clock::time_point t0 = high_resolution_clock::now();
+ stringstream io;
+ io << t0;
+ high_resolution_clock::time_point t1;
+#ifdef BOOST_CHRONO_IO_INPUT
+ io >> t1;
+ BOOST_ASSERT(!io.fail());
+ cout << io.str() << '\n';
+#else
+ t1=t0;
+#endif
+ cout << t0 << '\n';
+ cout << t1 << '\n';
+ high_resolution_clock::time_point t = high_resolution_clock::now();
+ cout << t << '\n';
+
+ cout << "That took " << t - t0 << '\n';
+ cout << "That took " << t - t1 << '\n';
+
+ return 0;
+}
+
+//~ 50908679121461 nanoseconds since boot
+//~ That took 649630 nanoseconds
+

Added: trunk/libs/chrono/example/io_ex4.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/io_ex4.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,32 @@
+// io_ex1.cpp ----------------------------------------------------------//
+
+// Copyright 2010 Howard Hinnant
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation.
+Many thanks to Howard for making his code available under the Boost license.
+
+*/
+
+#include <boost/chrono/chrono_io.hpp>
+#include <iostream>
+
+int main()
+{
+ using namespace std;
+ using namespace boost;
+ using namespace boost::chrono;
+
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ typedef time_point<monotonic_clock, duration<double, ratio<3600> > > T;
+ T tp = monotonic_clock::now();
+ std::cout << tp << '\n';
+#endif
+ return 0;
+}
+
+//~ 17.8666 hours since boot

Added: trunk/libs/chrono/example/io_ex5.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/io_ex5.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,90 @@
+// io_ex1.cpp ----------------------------------------------------------//
+
+// Copyright 2010 Howard Hinnant
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation.
+Many thanks to Howard for making his code available under the Boost license.
+
+*/
+
+#include <boost/chrono/chrono_io.hpp>
+#include <ostream>
+#include <iostream>
+
+// format duration as [-]d/hh::mm::ss.cc
+template <class CharT, class Traits, class Rep, class Period>
+std::basic_ostream<CharT, Traits>&
+display(std::basic_ostream<CharT, Traits>& os,
+ boost::chrono::duration<Rep, Period> d)
+{
+ using namespace std;
+ using namespace boost;
+ using namespace boost::chrono;
+
+ typedef duration<long long, ratio<86400> > days;
+ typedef duration<long long, centi> centiseconds;
+
+ // if negative, print negative sign and negate
+ if (d < duration<Rep, Period>(0))
+ {
+ d = -d;
+ os << '-';
+ }
+ // round d to nearest centiseconds, to even on tie
+ centiseconds cs = duration_cast<centiseconds>(d);
+ if (d - cs > milliseconds(5)
+ || (d - cs == milliseconds(5) && cs.count() & 1))
+ ++cs;
+ // separate seconds from centiseconds
+ seconds s = duration_cast<seconds>(cs);
+ cs -= s;
+ // separate minutes from seconds
+ minutes m = duration_cast<minutes>(s);
+ s -= m;
+ // separate hours from minutes
+ hours h = duration_cast<hours>(m);
+ m -= h;
+ // separate days from hours
+ days dy = duration_cast<days>(h);
+ h -= dy;
+ // print d/hh:mm:ss.cc
+ os << dy.count() << '/';
+ if (h < hours(10))
+ os << '0';
+ os << h.count() << ':';
+ if (m < minutes(10))
+ os << '0';
+ os << m.count() << ':';
+ if (s < seconds(10))
+ os << '0';
+ os << s.count() << '.';
+ if (cs < centiseconds(10))
+ os << '0';
+ os << cs.count();
+ return os;
+}
+
+int main()
+{
+ using namespace std;
+ using namespace boost;
+ using namespace boost::chrono;
+
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ display(cout, monotonic_clock::now().time_since_epoch()
+ + duration<long, mega>(1)) << '\n';
+#endif
+ display(cout, -milliseconds(6)) << '\n';
+ display(cout, duration<long, mega>(1)) << '\n';
+ display(cout, -duration<long, mega>(1)) << '\n';
+}
+
+//~ 12/06:03:22.95
+//~ -0/00:00:00.01
+//~ 11/13:46:40.00
+//~ -11/13:46:40.00

Added: trunk/libs/chrono/example/manipulate_clock_object.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/manipulate_clock_object.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,61 @@
+// manipulate_clock_object.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4100)
+#endif
+void manipulate_clock_object(system_clock clock)
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+{
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = clock.now();
+
+ while ((clock.now() - start) <= delay) {}
+
+ system_clock::time_point stop = clock.now();
+ system_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+}
+
+
+int main()
+{
+ manipulate_clock_object(system_clock());
+ return 0;
+}
+

Added: trunk/libs/chrono/example/min_time_point.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/min_time_point.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,78 @@
+// min_time_point.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/typeof/boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+template <class Rep, class Period>
+void print_duration(std::ostream& os, duration<Rep, Period> d)
+{
+ os << d.count() << " * " << Period::num << '/' << Period::den << " seconds\n";
+}
+
+// Example min utility: returns the earliest time_point
+// Being able to *easily* write this function is a major feature!
+template <class Clock, class Duration1, class Duration2>
+inline
+typename boost::common_type<time_point<Clock, Duration1>,
+ time_point<Clock, Duration2> >::type
+min BOOST_PREVENT_MACRO_SUBSTITUTION (time_point<Clock, Duration1> t1, time_point<Clock, Duration2> t2)
+{
+ return t2 < t1 ? t2 : t1;
+}
+
+void test_min()
+{
+#if 0
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, seconds>::type> T1;
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, nanoseconds>::type> T2;
+ typedef boost::common_type<T1, T2>::type T3;
+ /*auto*/ T1 t1 = system_clock::now() + seconds(3);
+ /*auto*/ T2 t2 = system_clock::now() + nanoseconds(3);
+ /*auto*/ T3 t3 = (min)(t1, t2);
+#else
+ BOOST_AUTO(t1, system_clock::now() + seconds(3));
+ BOOST_AUTO(t2, system_clock::now() + nanoseconds(3));
+ BOOST_AUTO(t3, (min)(t1, t2));
+#endif
+ print_duration(std::cout, t1 - t3);
+ print_duration(std::cout, t2 - t3);
+}
+
+int main()
+{
+ test_min();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/miscellaneous.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/miscellaneous.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,157 @@
+// miscellaneous.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+// miscellaneous tests and demos:
+
+#include <cassert>
+#include <iostream>
+
+using namespace boost::chrono;
+
+void physics_function(duration<double> d)
+{
+ std::cout << "d = " << d.count() << '\n';
+}
+
+void drive_physics_function()
+{
+ physics_function(nanoseconds(3));
+ physics_function(hours(3));
+ physics_function(duration<double>(2./3));
+ std::cout.precision(16);
+ physics_function( hours(3) + nanoseconds(-3) );
+}
+
+void test_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 292 + 292/4));
+ nanoseconds n1 = h1 + nanoseconds(1);
+ nanoseconds delta = n1 - h1;
+ std::cout << "292 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a nanosecond = " << n1.count() << "ns\n";
+ std::cout << "Find the difference = " << delta.count() << "ns\n";
+}
+
+void test_extended_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
+ /*auto*/ microseconds u1 = h1 + microseconds(1);
+ /*auto*/ microseconds delta = u1 - h1;
+ std::cout << "244,000 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a microsecond = " << u1.count() << "us\n";
+ std::cout << "Find the difference = " << delta.count() << "us\n";
+}
+
+template <class Rep, class Period>
+void inspect_duration(boost::chrono::duration<Rep, Period> d, const std::string& name)
+{
+ typedef boost::chrono::duration<Rep, Period> Duration;
+ std::cout << "********* " << name << " *********\n";
+ std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n";
+ std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n";
+ std::cout << "The representation is ";
+ if (boost::is_floating_point<Rep>::value)
+ {
+ std::cout << "floating point\n";
+ std::cout << "The precision is the most significant ";
+ std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n";
+ }
+ else if (boost::is_integral<Rep>::value)
+ {
+ std::cout << "integral\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ else
+ {
+ std::cout << "a class type\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ d = Duration((std::numeric_limits<Rep>::max)());
+ using namespace boost::chrono;
+ using namespace std;
+ typedef duration<double, boost::ratio_multiply<boost::ratio<24*3652425,10000>, hours::period>::type> Years;
+ Years years = d;
+ std::cout << "The range is +/- " << years.count() << " years.\n";
+ std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n';
+}
+
+void inspect_all()
+{
+ using namespace boost::chrono;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration<double>(), "duration<double>");
+}
+
+void test_milliseconds()
+{
+ using namespace boost::chrono;
+ milliseconds ms(250);
+ ms += milliseconds(1);
+ milliseconds ms2(150);
+ milliseconds msdiff = ms - ms2;
+ if (msdiff == milliseconds(101))
+ std::cout << "success\n";
+ else
+ std::cout << "failure: " << msdiff.count() << '\n';
+}
+
+int main()
+{
+ using namespace boost;
+ drive_physics_function();
+ test_range();
+ test_extended_range();
+ inspect_all();
+ test_milliseconds();
+ inspect_duration(common_type<duration<double>, hours, microseconds>::type(),
+ "common_type<duration<double>, hours, microseconds>::type");
+ duration<double, boost::milli> d = milliseconds(3) * 2.5;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ std::cout << d.count() << '\n';
+// milliseconds ms(3.5); // doesn't compile
+// std::cout << "milliseconds ms(3.5) doesn't compile\n";
+ return 0;
+}
+

Added: trunk/libs/chrono/example/run_timer_example.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/run_timer_example.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+// run_timer_example.cpp ---------------------------------------------------//
+
+// Copyright Beman Dawes 2006, 2008
+// Copyright 2009/2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#include <boost/chrono/process_times.hpp>
+#include <cmath>
+
+int main()
+{
+ boost::chrono::run_timer t;
+
+ for ( long i = 0; i < 10000; ++i )
+ std::sqrt( 123.456L ); // burn some time
+
+ return 0;
+}

Added: trunk/libs/chrono/example/run_timer_example2.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/run_timer_example2.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,24 @@
+// run_timer_example.cpp ---------------------------------------------------//
+
+// Copyright Beman Dawes 2006, 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#include <boost/chrono/process_times.hpp>
+#include <cmath>
+
+int main( int argc, char * argv[] )
+{
+ const char * format = argc > 1 ? argv[1] : "%t cpu seconds\n";
+ int places = argc > 2 ? std::atoi( argv[2] ) : 2;
+
+ boost::chrono::run_timer t( format, places );
+
+ for ( long i = 0; i < 10000; ++i )
+ std::sqrt( 123.456L ); // burn some time
+
+ return 0;
+}

Added: trunk/libs/chrono/example/runtime_resolution.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/runtime_resolution.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,227 @@
+// runtime_resolution.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+#if defined(BOOST_CHRONO_WINDOWS_API)
+#include <windows.h>
+
+namespace
+{
+ //struct timeval {
+ // long tv_sec; /* seconds */
+ // long tv_usec; /* and microseconds */
+ //};
+
+ int gettimeofday(struct timeval * tp, void *)
+ {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime( &ft ); // never fails
+ long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+ # else
+ t -= 116444736000000000;
+ # endif
+ t /= 10; // microseconds
+ tp->tv_sec = static_cast<long>( t / 1000000UL);
+ tp->tv_usec = static_cast<long>( t % 1000000UL);
+ return 0;
+ }
+} // unnamed namespace
+
+#endif
+
+// Handle duration with resolution not known until run time
+using namespace boost::chrono;
+
+namespace runtime_resolution
+{
+
+class duration
+{
+public:
+ typedef long long rep;
+private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+public:
+ typedef boost::chrono::duration<double, boost::nano> tonanosec;
+
+ duration() {} // = default;
+ explicit duration(const rep& r) : rep_(r) {}
+
+ // conversions
+ explicit duration(const tonanosec& d)
+ : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
+
+ // explicit
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ // observer
+
+ rep count() const {return rep_;}
+
+ // arithmetic
+
+ duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ duration operator+() const {return *this;}
+ duration operator-() const {return duration(-rep_);}
+ duration& operator++() {++rep_; return *this;}
+ duration operator++(int) {return duration(rep_++);}
+ duration& operator--() {--rep_; return *this;}
+ duration operator--(int) {return duration(rep_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(duration x, duration y) {return !(y < x);}
+ friend bool operator> (duration x, duration y) {return y < x;}
+ friend bool operator>=(duration x, duration y) {return !(x < y);}
+};
+
+static
+double
+init_duration()
+{
+#if defined(BOOST_CHRONO_WINDOWS_API)
+ return static_cast<double>(1) / 1000; // Windows FILETIME is 1 per microsec
+#elif defined(BOOST_CHRONO_MAC_API)
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ return static_cast<double>(MachInfo.denom) / MachInfo.numer;
+#elif defined(BOOST_CHRONO_POSIX_API)
+ return static_cast<double>(1) / 1000;
+#endif
+
+}
+
+const double duration::ticks_per_nanosecond = init_duration();
+
+class clock;
+
+class time_point
+{
+public:
+ typedef runtime_resolution::clock clock;
+ typedef long long rep;
+private:
+ rep rep_;
+
+
+ rep count() const {return rep_;}
+public:
+
+ time_point() : rep_(0) {}
+ explicit time_point(const duration& d)
+ : rep_(d.count()) {}
+
+ // arithmetic
+
+ time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
+ time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
+
+ friend time_point operator+(time_point x, duration y) {return x += y;}
+ friend time_point operator+(duration x, time_point y) {return y += x;}
+ friend time_point operator-(time_point x, duration y) {return x -= y;}
+ friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
+};
+
+
+class clock
+{
+public:
+ typedef runtime_resolution::duration::rep rep;
+ typedef runtime_resolution::duration duration;
+ typedef runtime_resolution::time_point time_point;
+
+ static time_point now()
+ {
+
+#if defined(BOOST_CHRONO_WINDOWS_API)
+ timeval tv;
+ gettimeofday( &tv, 0 );
+ return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
+
+#elif defined(BOOST_CHRONO_MAC_API)
+
+ timeval tv;
+ gettimeofday( &tv, 0 );
+ return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
+
+#elif defined(BOOST_CHRONO_POSIX_API)
+ timespec ts;
+ ::clock_gettime( CLOCK_REALTIME, &ts );
+
+ return time_point(duration((static_cast<rep>(ts.tv_sec)<<32) | ts.tv_nsec/1000));
+
+
+#endif // POSIX
+
+ }
+};
+
+void test()
+{
+ using namespace boost::chrono;
+ std::cout << "runtime_resolution test\n";
+ clock::duration delay(boost::chrono::milliseconds(5));
+ clock::time_point start = clock::now();
+ while (clock::now() - start <= delay)
+ ;
+ clock::time_point stop = clock::now();
+ clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(duration_cast<nanoseconds>(duration::tonanosec(elapsed))).count()
+ << " nanoseconds\n";
+}
+
+} // runtime_resolution
+
+
+int main()
+{
+ runtime_resolution::test();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/saturating.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/saturating.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,505 @@
+// saturating.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+//////////////////////////////////////////////////////////
+//////////////////// User2 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+// Demonstrate User2:
+// A "saturating" signed integral type is developed. This type has +/- infinity and a nan
+// (like IEEE floating point) but otherwise obeys signed integral arithmetic.
+// This class is subsequently used as the rep in boost::chrono::duration to demonstrate a
+// duration class that does not silently ignore overflow.
+#include <ostream>
+#include <stdexcept>
+#include <climits>
+
+namespace User2
+{
+
+template <class I>
+class saturate
+{
+public:
+ typedef I int_type;
+
+ static const int_type nan = int_type(int_type(1) << (sizeof(int_type) * CHAR_BIT - 1));
+ static const int_type neg_inf = nan + 1;
+ static const int_type pos_inf = -neg_inf;
+private:
+ int_type i_;
+
+// static_assert(std::is_integral<int_type>::value && std::is_signed<int_type>::value,
+// "saturate only accepts signed integral types");
+// static_assert(nan == -nan && neg_inf < pos_inf,
+// "saturate assumes two's complement hardware for signed integrals");
+
+public:
+ saturate() : i_(nan) {}
+ explicit saturate(int_type i) : i_(i) {}
+ // explicit
+ operator int_type() const;
+
+ saturate& operator+=(saturate x);
+ saturate& operator-=(saturate x) {return *this += -x;}
+ saturate& operator*=(saturate x);
+ saturate& operator/=(saturate x);
+ saturate& operator%=(saturate x);
+
+ saturate operator- () const {return saturate(-i_);}
+ saturate& operator++() {*this += saturate(int_type(1)); return *this;}
+ saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
+ saturate& operator--() {*this -= saturate(int_type(1)); return *this;}
+ saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
+
+ friend saturate operator+(saturate x, saturate y) {return x += y;}
+ friend saturate operator-(saturate x, saturate y) {return x -= y;}
+ friend saturate operator*(saturate x, saturate y) {return x *= y;}
+ friend saturate operator/(saturate x, saturate y) {return x /= y;}
+ friend saturate operator%(saturate x, saturate y) {return x %= y;}
+
+ friend bool operator==(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ == y.i_;
+ }
+
+ friend bool operator!=(saturate x, saturate y) {return !(x == y);}
+
+ friend bool operator<(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ < y.i_;
+ }
+
+ friend bool operator<=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ <= y.i_;
+ }
+
+ friend bool operator>(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ > y.i_;
+ }
+
+ friend bool operator>=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ >= y.i_;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, saturate s)
+ {
+ switch (s.i_)
+ {
+ case pos_inf:
+ return os << "inf";
+ case nan:
+ return os << "nan";
+ case neg_inf:
+ return os << "-inf";
+ };
+ return os << s.i_;
+ }
+};
+
+template <class I>
+saturate<I>::operator int_type() const
+{
+ switch (i_)
+ {
+ case nan:
+ case neg_inf:
+ case pos_inf:
+ throw std::out_of_range("saturate special value can not convert to int_type");
+ }
+ return i_;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator+=(saturate x)
+{
+ switch (i_)
+ {
+ case pos_inf:
+ switch (x.i_)
+ {
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = x.i_;
+ return *this;
+ }
+ if (x.i_ >= 0)
+ {
+ if (i_ < pos_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = pos_inf;
+ return *this;
+ }
+ if (i_ > neg_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = neg_inf;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator*=(saturate x)
+{
+ switch (i_)
+ {
+ case 0:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case pos_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = neg_inf;
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = pos_inf;
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case 0:
+ i_ = 0;
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case pos_inf:
+ if (i_ < 0)
+ i_ = neg_inf;
+ else
+ i_ = pos_inf;
+ return *this;
+ case neg_inf:
+ if (i_ < 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ int s = (i_ < 0 ? -1 : 1) * (x.i_ < 0 ? -1 : 1);
+ i_ = i_ < 0 ? -i_ : i_;
+ int_type x_i_ = x.i_ < 0 ? -x.i_ : x.i_;
+ if (i_ <= pos_inf / x_i_)
+ i_ *= x_i_;
+ else
+ i_ = pos_inf;
+ i_ *= s;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator/=(saturate x)
+{
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ break;
+ default:
+ i_ = 0;
+ break;
+ }
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case 0:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ return *this;
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (i_ > 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ switch (i_)
+ {
+ case 0:
+ case nan:
+ return *this;
+ case pos_inf:
+ case neg_inf:
+ if (x.i_ < 0)
+ i_ = -i_;
+ return *this;
+ }
+ i_ /= x.i_;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator%=(saturate x)
+{
+// *this -= *this / x * x; // definition
+ switch (x.i_)
+ {
+ case nan:
+ case neg_inf:
+ case 0:
+ case pos_inf:
+ i_ = nan;
+ return *this;
+ }
+ switch (i_)
+ {
+ case neg_inf:
+ case pos_inf:
+ i_ = nan;
+ case nan:
+ return *this;
+ }
+ i_ %= x.i_;
+ return *this;
+}
+
+// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution
+typedef boost::chrono::duration<saturate<long long>, boost::pico > picoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<saturate<long long> > seconds;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 60LL> > minutes;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 3600LL> > hours;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 86400LL> > days;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 31556952LL> > years;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio<31556952000LL> > millennium;
+
+} // User2
+
+// Demonstrate custom promotion rules (needed only if there are no implicit conversions)
+namespace User2 { namespace detail {
+
+template <class T1, class T2, bool = boost::is_integral<T1>::value>
+struct promote_helper;
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, true> // integral
+{
+ typedef typename boost::common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, false> // floating
+{
+ typedef T1 type;
+};
+
+} }
+
+namespace boost
+{
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, User2::saturate<T2> >
+{
+ typedef typename common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct common_type<T1, User2::saturate<T2> >
+ : User2::detail::promote_helper<T1, User2::saturate<T2> > {};
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, T2>
+ : User2::detail::promote_helper<T2, User2::saturate<T1> > {};
+
+
+// Demonstrate specialization of duration_values:
+
+namespace chrono {
+
+template <class I>
+struct duration_values<User2::saturate<I> >
+{
+ typedef User2::saturate<I> Rep;
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () {return Rep(Rep::pos_inf-1);}
+ static Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () {return -(max)();}
+};
+
+} // namespace chrono
+
+} // namespace boost
+
+#include <iostream>
+
+void testUser2()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser2 *\n";
+ std::cout << "*************\n";
+ using namespace User2;
+ typedef seconds::rep sat;
+ years yr(sat(100));
+ std::cout << "100 years expressed as years = " << yr.count() << '\n';
+ nanoseconds ns = yr;
+ std::cout << "100 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "200 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "300 years expressed as nanoseconds = " << ns.count() << '\n';
+// yr = ns; // does not compile
+ std::cout << "yr = ns; // does not compile\n";
+// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic
+ std::cout << "ps = yr; // does not compile\n";
+ ns = yr;
+ picoseconds ps = ns;
+ std::cout << "100 years expressed as picoseconds = " << ps.count() << '\n';
+ ps = ns / sat(1000);
+ std::cout << "0.1 years expressed as picoseconds = " << ps.count() << '\n';
+ yr = years(sat(-200000000));
+ std::cout << "200 million years ago encoded in years: " << yr.count() << '\n';
+ days d = boost::chrono::duration_cast<days>(yr);
+ std::cout << "200 million years ago encoded in days: " << d.count() << '\n';
+ millennium c = boost::chrono::duration_cast<millennium>(yr);
+ std::cout << "200 million years ago encoded in millennium: " << c.count() << '\n';
+ std::cout << "Demonstrate \"uninitialized protection\" behavior:\n";
+ seconds sec;
+ for (++sec; sec < seconds(sat(10)); ++sec)
+ ;
+ std::cout << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+void testStdUser()
+{
+ std::cout << "***************\n";
+ std::cout << "* testStdUser *\n";
+ std::cout << "***************\n";
+ using namespace boost::chrono;
+ hours hr = hours(100);
+ std::cout << "100 hours expressed as hours = " << hr.count() << '\n';
+ nanoseconds ns = hr;
+ std::cout << "100 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "200 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "300 hours expressed as nanoseconds = " << ns.count() << '\n';
+// hr = ns; // does not compile
+ std::cout << "hr = ns; // does not compile\n";
+// hr * ns; // does not compile
+ std::cout << "hr * ns; // does not compile\n";
+ duration<double> fs(2.5);
+ std::cout << "duration<double> has count() = " << fs.count() << '\n';
+// seconds sec = fs; // does not compile
+ std::cout << "seconds sec = duration<double> won't compile\n";
+ seconds sec = duration_cast<seconds>(fs);
+ std::cout << "seconds has count() = " << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+
+int main()
+{
+ testStdUser();
+ testUser2();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/simulated_thread_interface_demo.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/simulated_thread_interface_demo.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,198 @@
+// simulated_thread_interface_demo.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+#include <ostream>
+#include <stdexcept>
+#include <climits>
+
+//////////////////////////////////////////////////////////
+///////////// simulated thread interface /////////////////
+//////////////////////////////////////////////////////////
+
+namespace boost {
+
+namespace detail {
+void print_time(boost::chrono::system_clock::time_point t)
+{
+ using namespace boost::chrono;
+ time_t c_time = system_clock::to_time_t(t);
+ std::tm* tmptr = std::localtime(&c_time);
+ system_clock::duration d = t.time_since_epoch();
+ std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec
+ << '.' << (d - duration_cast<seconds>(d)).count();
+}
+}
+namespace this_thread {
+
+template <class Rep, class Period>
+void sleep_for(const boost::chrono::duration<Rep, Period>& d)
+{
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t < d)
+ ++t;
+ if (t > boost::chrono::microseconds(0))
+ std::cout << "sleep_for " << t.count() << " microseconds\n";
+}
+
+template <class Clock, class Duration>
+void sleep_until(const boost::chrono::time_point<Clock, Duration>& t)
+{
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t > Clock::now())
+ {
+ typedef typename boost::common_type<typename Time::duration,
+ typename SysTime::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ if (us < d)
+ ++us;
+ SysTime st = system_clock::now() + us;
+ std::cout << "sleep_until ";
+ boost::detail::print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+}
+
+} // this_thread
+
+struct mutex {};
+
+struct timed_mutex
+{
+ bool try_lock() {std::cout << "timed_mutex::try_lock()\n"; return true;}
+
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t <= boost::chrono::microseconds(0))
+ return try_lock();
+ std::cout << "try_lock_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return try_lock();
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "try_lock_until ";
+ boost::detail::print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+struct condition_variable
+{
+ template <class Rep, class Period>
+ bool wait_for(mutex&, const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ std::cout << "wait_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool wait_until(mutex&, const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return false;
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "wait_until ";
+ boost::detail::print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+}
+
+//////////////////////////////////////////////////////////
+//////////// Simple sleep and wait examples //////////////
+//////////////////////////////////////////////////////////
+
+boost::mutex m;
+boost::timed_mutex mut;
+boost::condition_variable cv;
+
+void basic_examples()
+{
+ std::cout << "Running basic examples\n";
+ using namespace boost;
+ using namespace boost::chrono;
+ system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
+ this_thread::sleep_for(seconds(3));
+ this_thread::sleep_for(nanoseconds(300));
+ this_thread::sleep_until(time_limit);
+// this_thread::sleep_for(time_limit); // desired compile-time error
+// this_thread::sleep_until(seconds(3)); // desired compile-time error
+ mut.try_lock_for(milliseconds(30));
+ mut.try_lock_until(time_limit);
+// mut.try_lock_for(time_limit); // desired compile-time error
+// mut.try_lock_until(milliseconds(30)); // desired compile-time error
+ cv.wait_for(m, minutes(1)); // real code would put this in a loop
+ cv.wait_until(m, time_limit); // real code would put this in a loop
+ // For those who prefer floating point
+ this_thread::sleep_for(duration<double>(0.25));
+ this_thread::sleep_until(system_clock::now() + duration<double>(1.5));
+}
+
+
+
+int main()
+{
+ basic_examples();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/test_clock.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_clock.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,182 @@
+// test_system_clock.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+#include "clock_name.hpp"
+
+#if defined(BOOST_NO_CONSTEXPR)
+
+using namespace boost::chrono;
+
+template <typename Clock>
+void test_clock()
+{
+ std::cout << "\n"<< name<Clock>::apply() << " test" << std::endl;
+{
+ typename Clock::duration delay = milliseconds(5);
+ typename Clock::time_point start = Clock::now();
+ while (Clock::now() - start <= delay)
+ ;
+ typename Clock::time_point stop = Clock::now();
+ //typename Clock::duration elapsed = stop - start;
+ std::cout << "5 milliseconds paused " << nanoseconds(stop - start).count() << " nanoseconds\n";
+}
+{
+ typename Clock::time_point start = Clock::now();
+ typename Clock::time_point stop;
+ std::size_t count=1;
+ while ((stop=Clock::now()) == start) {
+ ++count;
+ }
+ //typename Clock::duration elapsed = stop - start;
+ std::cout << "After " << count << " trials, elapsed time " << nanoseconds(stop - start).count() << " nanoseconds\n";
+
+ start = Clock::now();
+ for (std::size_t c=count; c>0; --c) {
+ stop=Clock::now();;
+ }
+ std::cout << "After " << count << " trials, elapsed time " << nanoseconds(stop - start).count() << " nanoseconds\n";
+
+
+}
+{
+ typename Clock::time_point start = Clock::now();
+ typename Clock::time_point stop = Clock::now();
+ std::cout << "Resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+}
+
+void test_system_clock()
+{
+ std::cout << "system_clock test" << std::endl;
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = system_clock::now();
+ while (system_clock::now() - start <= delay)
+ ;
+ system_clock::time_point stop = system_clock::now();
+ system_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = system_clock::now();
+ stop = system_clock::now();
+ std::cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ std::cout << "monotonic_clock test" << std::endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start <= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ std::cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+#endif
+}
+void test_hi_resolution_clock()
+{
+ std::cout << "high_resolution_clock test" << std::endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start <= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ std::cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+//void test_mixed_clock()
+//{
+// std::cout << "mixed clock test" << std::endl;
+// high_resolution_clock::time_point hstart = high_resolution_clock::now();
+// std::cout << "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+// monotonic_clock::time_point mend = hstart + milliseconds(5);
+// bool b = hstart == mend;
+// system_clock::time_point sstart = system_clock::now();
+// std::cout << "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+//// mend - sstart; // doesn't compile
+// std::cout << "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+// " and add that to a system_clock::time_point\n";
+// system_clock::time_point send = sstart + duration_cast<system_clock::duration>(mend - hstart);
+// std::cout << "subtract two system_clock::time_point's and output that in microseconds:\n";
+// microseconds ms = send - sstart;
+// std::cout << ms.count() << " microseconds\n";
+//}
+//
+//void test_c_mapping()
+//{
+// std::cout << "C map test\n";
+// using namespace boost::chrono;
+// system_clock::time_point t1 = system_clock::now();
+// std::time_t c_time = system_clock::to_time_t(t1);
+// std::tm* tmptr = std::localtime(&c_time);
+// std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' '
+// << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\n';
+// c_time = std::mktime(tmptr);
+// system_clock::time_point t2 = system_clock::from_time_t(c_time);
+// microseconds ms = t1 - t2;
+// std::cout << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n";
+//}
+
+
+int main()
+{
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ //test_mixed_clock();
+ test_clock<system_clock>();
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ test_clock<monotonic_clock>();
+#endif
+ test_clock<high_resolution_clock>();
+
+
+
+ return 0;
+}
+
+#else
+int main()
+{
+
+
+ return 0;
+}
+#endif

Added: trunk/libs/chrono/example/test_clock2.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_clock2.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,210 @@
+// test_system_clock.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+#include "clock_name.hpp"
+
+namespace boost {
+ namespace detail_chrono {
+ class monotonic_clock {};
+ class system_clock {};
+ }
+ namespace chrono {
+ namespace chrono_detail {
+ using namespace detail_chrono;
+ struct has_monotonic_clock {
+ template< class T > static char sfinae( typename T::rep );
+ template< class > static int sfinae( ... );
+
+ enum { value = sizeof sfinae< monotonic_clock >( 0 ) == sizeof(char) };
+ };
+ struct has_system_clock {
+ template< class T > static char sfinae( typename T::rep );
+ template< class > static int sfinae( ... );
+
+ enum { value = sizeof sfinae< system_clock >( 0 ) == sizeof(char) };
+ };
+ }
+ struct has_monotonic_clock
+ : integral_constant<bool, chrono_detail::has_monotonic_clock::value> {};
+ struct has_system_clock
+ : integral_constant<bool, chrono_detail::has_system_clock::value> {};
+ }
+
+}
+
+BOOST_STATIC_ASSERT(boost::chrono::has_system_clock::value);
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+BOOST_STATIC_ASSERT(boost::chrono::has_monotonic_clock::value);
+#else
+BOOST_STATIC_ASSERT(!boost::chrono::has_monotonic_clock::value);
+#endif
+
+using namespace boost::chrono;
+using namespace boost;
+
+template <typename Clock>
+void test_clock()
+{
+ std::cout << "\n"<< name<Clock>::apply() << " test" << std::endl;
+{
+ typename Clock::duration delay = milliseconds(5);
+ typename Clock::time_point start = Clock::now();
+ while (Clock::now() - start <= delay)
+ ;
+ typename Clock::time_point stop = Clock::now();
+ //typename Clock::duration elapsed = stop - start;
+ std::cout << "5 milliseconds paused " << nanoseconds(stop - start).count() << " nanoseconds\n";
+}
+{
+ typename Clock::time_point start = Clock::now();
+ typename Clock::time_point stop;
+ std::size_t count=1;
+ while ((stop=Clock::now()) == start) {
+ ++count;
+ }
+ //typename Clock::duration elapsed = stop - start;
+ std::cout << "After " << count << " trials, elapsed time " << nanoseconds(stop - start).count() << " nanoseconds\n";
+
+ start = Clock::now();
+ for (std::size_t c=count; c>0; --c) {
+ stop=Clock::now();;
+ }
+ std::cout << "After " << count << " trials, elapsed time " << nanoseconds(stop - start).count() << " nanoseconds\n";
+
+
+}
+{
+ typename Clock::time_point start = Clock::now();
+ typename Clock::time_point stop = Clock::now();
+ std::cout << "Resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+}
+
+void test_system_clock()
+{
+ std::cout << "system_clock test" << std::endl;
+ //~ system_clock clk;
+ chrono::system_clock::duration delay = milliseconds(5);
+ chrono::system_clock::time_point start = system_clock::now();
+ while (chrono::system_clock::now() - start <= delay)
+ ;
+ chrono::system_clock::time_point stop = system_clock::now();
+ chrono::system_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = chrono::system_clock::now();
+ stop = chrono::system_clock::now();
+ std::cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ std::cout << "monotonic_clock test" << std::endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start <= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ std::cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+#endif
+}
+void test_hi_resolution_clock()
+{
+ std::cout << "high_resolution_clock test" << std::endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start <= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ std::cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+//void test_mixed_clock()
+//{
+// std::cout << "mixed clock test" << std::endl;
+// high_resolution_clock::time_point hstart = high_resolution_clock::now();
+// std::cout << "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+// monotonic_clock::time_point mend = hstart + milliseconds(5);
+// bool b = hstart == mend;
+// system_clock::time_point sstart = system_clock::now();
+// std::cout << "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+//// mend - sstart; // doesn't compile
+// std::cout << "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+// " and add that to a system_clock::time_point\n";
+// system_clock::time_point send = sstart + duration_cast<system_clock::duration>(mend - hstart);
+// std::cout << "subtract two system_clock::time_point's and output that in microseconds:\n";
+// microseconds ms = send - sstart;
+// std::cout << ms.count() << " microseconds\n";
+//}
+//
+//void test_c_mapping()
+//{
+// std::cout << "C map test\n";
+// using namespace boost::chrono;
+// system_clock::time_point t1 = system_clock::now();
+// std::time_t c_time = system_clock::to_time_t(t1);
+// std::tm* tmptr = std::localtime(&c_time);
+// std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' '
+// << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\n';
+// c_time = std::mktime(tmptr);
+// system_clock::time_point t2 = system_clock::from_time_t(c_time);
+// microseconds ms = t1 - t2;
+// std::cout << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n";
+//}
+
+
+int main()
+{
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ //test_mixed_clock();
+ test_clock<system_clock>();
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ test_clock<monotonic_clock>();
+#endif
+ test_clock<high_resolution_clock>();
+
+
+
+ return 0;
+}
+

Added: trunk/libs/chrono/example/test_duration.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_duration.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,199 @@
+// test_duration.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/assert.hpp>
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+template <class Rep, class Period>
+void inspect_duration(boost::chrono::duration<Rep, Period> d, const std::string& name)
+{
+ typedef boost::chrono::duration<Rep, Period> Duration;
+ std::cout << "********* " << name << " *********\n";
+ std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n";
+ std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n";
+ std::cout << "The representation is ";
+ if (boost::is_floating_point<Rep>::value)
+ {
+ std::cout << "floating point\n";
+ std::cout << "The precision is the most significant ";
+ std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n";
+ }
+ else if (boost::is_integral<Rep>::value)
+ {
+ std::cout << "integral\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ else
+ {
+ std::cout << "a class type\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ d = Duration((std::numeric_limits<Rep>::max)());
+ using namespace boost::chrono;
+ using namespace std;
+ typedef duration<double, boost::ratio_multiply<boost::ratio<24*3652425,10000>, hours::period>::type> Years;
+ Years years = d;
+ std::cout << "The range is +/- " << years.count() << " years.\n";
+ std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n';
+}
+
+void inspect_all()
+{
+ using namespace boost::chrono;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration<double>(), "duration<double>");
+}
+
+
+
+using namespace boost::chrono;
+void test_duration_division()
+{
+ typedef boost::common_type<boost::chrono::hours::rep, boost::chrono::minutes::rep>::type h_min_rep;
+ h_min_rep r3 = hours(3) / minutes(5);
+ std::cout << r3 << '\n';
+ std::cout << hours(3) / minutes(5) << '\n';
+ std::cout << hours(3) / milliseconds(5) << '\n';
+ std::cout << milliseconds(5) / hours(3) << '\n';
+ std::cout << hours(1) / milliseconds(1) << '\n';
+}
+
+void test_duration_multiply()
+{
+ hours h15= 5 * hours(3);
+ hours h6= hours(3) *2;
+}
+
+void f(duration<double> d, double res) // accept floating point seconds
+{
+ // d.count() == 3.e-6 when passed microseconds(3)
+ BOOST_ASSERT(d.count()==res);
+}
+
+void g(nanoseconds d, boost::intmax_t res)
+{
+ // d.count() == 3000 when passed microseconds(3)
+ std::cout << d.count() << " " <<res << std::endl;
+ BOOST_ASSERT(d.count()==res);
+}
+
+template <class Rep, class Period>
+void tmpl(duration<Rep, Period> d, boost::intmax_t res)
+{
+ // convert d to nanoseconds, rounding up if it is not an exact conversion
+ nanoseconds ns = duration_cast<nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ // ns.count() == 333333334 when passed 1/3 of a floating point second
+ BOOST_ASSERT(ns.count()==res);
+}
+
+template <class Period>
+void tmpl2(duration<long long, Period> d, boost::intmax_t res)
+{
+ // convert d to nanoseconds, rounding up if it is not an exact conversion
+ nanoseconds ns = duration_cast<nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ // ns.count() == 333333334 when passed 333333333333 picoseconds
+ BOOST_ASSERT(ns.count()==res);
+}
+
+
+
+int main()
+{
+ minutes m1(3); // m1 stores 3
+ minutes m2(2); // m2 stores 2
+ minutes m3 = m1 + m2; // m3 stores 5
+ BOOST_ASSERT(m3.count()==5);
+
+ microseconds us1(3); // us1 stores 3
+ microseconds us2(2); // us2 stores 2
+ microseconds us3 = us1 + us2; // us3 stores 5
+ BOOST_ASSERT(us3.count()==5);
+
+ microseconds us4 = m3 + us3; // us4 stores 300000005
+ BOOST_ASSERT(us4.count()==300000005);
+ microseconds us5 = m3; // us4 stores 300000000
+ BOOST_ASSERT(us5.count()==300000000);
+
+ //minutes m4 = m3 + us3; // won't compile
+
+ minutes m4 = duration_cast<minutes>(m3 + us3); // m4.count() == 5
+ BOOST_ASSERT(m4.count()==5);
+
+ typedef duration<double, boost::ratio<60> > dminutes;
+ dminutes dm4 = m3 + us3; // dm4.count() == 5.000000083333333
+ BOOST_ASSERT(dm4.count()==5.000000083333333);
+
+ f(microseconds(3), 0.000003);
+ g(microseconds(3), 3000);
+ duration<double> s(1./3); // 1/3 of a second
+ g(duration_cast<nanoseconds>(s), 333333333); // round towards zero in conversion to nanoseconds
+ //f(s); // does not compile
+ tmpl(duration<double>(1./3), 333333334);
+ tmpl2(duration<long long, boost::pico>(333333333333LL), 333333334); // About 1/3 of a second worth of picoseconds
+
+ //f(3,3); // Will not compile, 3 is not implicitly convertible to any `duration`
+ //g(3,3); // Will not compile, 3 is not implicitly convertible to any `duration`
+ //tmpl(3,3); // Will not compile, 3 is not implicitly convertible to any `duration`
+ //tmpl2(3,3); // Will not compile, 3 is not implicitly convertible to any `duration`
+
+ {
+ double r = double(milliseconds(3) / milliseconds(3));
+ std::cout << r << '\n';
+
+ duration<double, boost::milli> d = milliseconds(3) * 2.5;
+ duration<double, boost::milli> d2 = 2.5 * milliseconds(3) ;
+ duration<double, boost::milli> d3 = milliseconds(3) / 2.5;
+ duration<double, boost::milli> d4 = milliseconds(3) + milliseconds(5) ;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ std::cout << d.count() << '\n';
+// milliseconds ms(3.5); // doesn't compile
+ std::cout << "milliseconds ms(3.5) doesn't compile\n";
+ }
+
+ test_duration_division();
+ test_duration_multiply();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/test_minmax.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_minmax.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,17 @@
+// test_duration.cpp ----------------------------------------------------------//
+
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#if !defined(__GNUC__)
+
+#define min(A,B) ((A)<(B)?(A):(B))
+#define max(A,B) ((A)>(B)?(A):(B))
+
+#include <boost/chrono/chrono.hpp>
+
+#endif
+
+

Added: trunk/libs/chrono/example/test_special_values.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_special_values.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,51 @@
+// test_special_values.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+void test_special_values()
+{
+ std::cout << "duration<unsigned>::min().count() = " << ((duration<unsigned>::min)()).count() << '\n';
+ std::cout << "duration<unsigned>::zero().count() = " << duration<unsigned>::zero().count() << '\n';
+ std::cout << "duration<unsigned>::max().count() = " << ((duration<unsigned>::max)()).count() << '\n';
+ std::cout << "duration<int>::min().count() = " << ((duration<int>::min)()).count() << '\n';
+ std::cout << "duration<int>::zero().count() = " << duration<int>::zero().count() << '\n';
+ std::cout << "duration<int>::max().count() = " << ((duration<int>::max)()).count() << '\n';
+}
+
+int main()
+{
+ test_special_values();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/test_thread_clock.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/test_thread_clock.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,41 @@
+// test_thread_clock.cpp ----------------------------------------------------------//
+
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#include <boost/chrono/thread_clock.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+void test_thread_clock()
+{
+#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+ std::cout << "thread_clock test" << std::endl;
+ thread_clock::duration delay = milliseconds(5);
+ thread_clock::time_point start = thread_clock::now();
+ while (thread_clock::now() - start <= delay)
+ ;
+ thread_clock::time_point stop = thread_clock::now();
+ thread_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = thread_clock::now();
+ stop = thread_clock::now();
+ std::cout << "thread_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+#else
+ std::cout << "thread_clock not available\n";
+#endif
+}
+
+
+int main()
+{
+ test_thread_clock();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/time2_demo.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/time2_demo.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,1655 @@
+// time2_demo.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+
+This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <cassert>
+#include <climits>
+#include <iostream>
+#include <ostream>
+#include <stdexcept>
+
+#include <windows.h>
+
+namespace
+{
+ //struct timeval {
+ // long tv_sec; /* seconds */
+ // long tv_usec; /* and microseconds */
+ //};
+
+ int gettimeofday(struct timeval * tp, void *)
+ {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime( &ft ); // never fails
+ long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+ # else
+ t -= 116444736000000000;
+ # endif
+ t /= 10; // microseconds
+ tp->tv_sec = static_cast<long>( t / 1000000UL);
+ tp->tv_usec = static_cast<long>( t % 1000000UL);
+ return 0;
+ }
+} // unnamed namespace
+
+//////////////////////////////////////////////////////////
+///////////// simulated thread interface /////////////////
+//////////////////////////////////////////////////////////
+
+
+namespace std {
+
+void __print_time(boost::chrono::system_clock::time_point t)
+{
+ using namespace boost::chrono;
+ time_t c_time = system_clock::to_time_t(t);
+ std::tm* tmptr = std::localtime(&c_time);
+ system_clock::duration d = t.time_since_epoch();
+ std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec
+ << '.' << (d - duration_cast<seconds>(d)).count();
+}
+
+namespace this_thread {
+
+template <class Rep, class Period>
+void sleep_for(const boost::chrono::duration<Rep, Period>& d)
+{
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t < d)
+ ++t;
+ if (t > boost::chrono::microseconds(0))
+ std::cout << "sleep_for " << t.count() << " microseconds\n";
+}
+
+template <class Clock, class Duration>
+void sleep_until(const boost::chrono::time_point<Clock, Duration>& t)
+{
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t > Clock::now())
+ {
+ typedef typename boost::common_type<typename Time::duration,
+ typename SysTime::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ if (us < d)
+ ++us;
+ SysTime st = system_clock::now() + us;
+ std::cout << "sleep_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+}
+
+} // this_thread
+
+struct mutex {};
+
+struct timed_mutex
+{
+ bool try_lock() {std::cout << "timed_mutex::try_lock()\n"; return true;}
+
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t <= boost::chrono::microseconds(0))
+ return try_lock();
+ std::cout << "try_lock_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return try_lock();
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "try_lock_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+struct condition_variable
+{
+ template <class Rep, class Period>
+ bool wait_for(mutex&, const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ std::cout << "wait_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool wait_until(mutex&, const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return false;
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "wait_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+} // namespace std
+
+//////////////////////////////////////////////////////////
+//////////// Simple sleep and wait examples //////////////
+//////////////////////////////////////////////////////////
+
+std::mutex m;
+std::timed_mutex mut;
+std::condition_variable cv;
+
+void basic_examples()
+{
+ std::cout << "Running basic examples\n";
+ using namespace std;
+ using namespace boost::chrono;
+ system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
+ this_thread::sleep_for(seconds(3));
+ this_thread::sleep_for(nanoseconds(300));
+ this_thread::sleep_until(time_limit);
+// this_thread::sleep_for(time_limit); // desired compile-time error
+// this_thread::sleep_until(seconds(3)); // desired compile-time error
+ mut.try_lock_for(milliseconds(30));
+ mut.try_lock_until(time_limit);
+// mut.try_lock_for(time_limit); // desired compile-time error
+// mut.try_lock_until(milliseconds(30)); // desired compile-time error
+ cv.wait_for(m, minutes(1)); // real code would put this in a loop
+ cv.wait_until(m, time_limit); // real code would put this in a loop
+ // For those who prefer floating point
+ this_thread::sleep_for(duration<double>(0.25));
+ this_thread::sleep_until(system_clock::now() + duration<double>(1.5));
+}
+
+//////////////////////////////////////////////////////////
+//////////////////// User1 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+namespace User1
+{
+// Example type-safe "physics" code interoperating with boost::chrono::duration types
+// and taking advantage of the boost::ratio infrastructure and design philosophy.
+
+// length - mimics boost::chrono::duration except restricts representation to double.
+// Uses boost::ratio facilities for length units conversions.
+
+template <class Ratio>
+class length
+{
+public:
+ typedef Ratio ratio;
+private:
+ double len_;
+public:
+
+ length() : len_(1) {}
+ length(const double& len) : len_(len) {}
+
+ // conversions
+ template <class R>
+ length(const length<R>& d)
+ : len_(d.count() * boost::ratio_divide<Ratio, R>::type::den /
+ boost::ratio_divide<Ratio, R>::type::num) {}
+
+ // observer
+
+ double count() const {return len_;}
+
+ // arithmetic
+
+ length& operator+=(const length& d) {len_ += d.count(); return *this;}
+ length& operator-=(const length& d) {len_ -= d.count(); return *this;}
+
+ length operator+() const {return *this;}
+ length operator-() const {return length(-len_);}
+
+ length& operator*=(double rhs) {len_ *= rhs; return *this;}
+ length& operator/=(double rhs) {len_ /= rhs; return *this;}
+};
+
+// Sparse sampling of length units
+typedef length<boost::ratio<1> > meter; // set meter as "unity"
+typedef length<boost::centi> centimeter; // 1/100 meter
+typedef length<boost::kilo> kilometer; // 1000 meters
+typedef length<boost::ratio<254, 10000> > inch; // 254/10000 meters
+// length takes ratio instead of two integral types so that definitions can be made like so:
+typedef length<boost::ratio_multiply<boost::ratio<12>, inch::ratio>::type> foot; // 12 inchs
+typedef length<boost::ratio_multiply<boost::ratio<5280>, foot::ratio>::type> mile; // 5280 feet
+
+// Need a floating point definition of seconds
+typedef boost::chrono::duration<double> seconds; // unity
+// Demo of (scientific) support for sub-nanosecond resolutions
+typedef boost::chrono::duration<double, boost::pico> picosecond; // 10^-12 seconds
+typedef boost::chrono::duration<double, boost::femto> femtosecond; // 10^-15 seconds
+typedef boost::chrono::duration<double, boost::atto> attosecond; // 10^-18 seconds
+
+// A very brief proof-of-concept for SIUnits-like library
+// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())
+template <class R1, class R2>
+class quantity
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<1>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(seconds d) : q_(d.count()) {} // note: only User1::seconds needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<1> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(meter d) : q_(d.count()) {} // note: only User1::meter needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(double d) : q_(d) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+// Example SI-Units
+typedef quantity<boost::ratio<0>, boost::ratio<0> > Scalar;
+typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; // second
+typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; // meter
+typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; // meter/second
+typedef quantity<boost::ratio<-2>, boost::ratio<1> > Acceleration; // meter/second^2
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type>
+operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type> R;
+ R r;
+ r.set(x.get() / y.get());
+ return r;
+}
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type>
+operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type> R;
+ R r;
+ r.set(x.get() * y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() + y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() - y.get());
+ return r;
+}
+
+// Example type-safe physics function
+Distance
+compute_distance(Speed v0, Time t, Acceleration a)
+{
+ return v0 * t + Scalar(.5) * a * t * t; // if a units mistake is made here it won't compile
+}
+
+} // User1
+
+
+// Exercise example type-safe physics function and show interoperation
+// of custom time durations (User1::seconds) and standard time durations (std::hours).
+// Though input can be arbitrary (but type-safe) units, output is always in SI-units
+// (a limitation of the simplified Units lib demoed here).
+void testUser1()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser1 *\n";
+ std::cout << "*************\n";
+ User1::Distance d( User1::mile(110) );
+ User1::Time t( boost::chrono::hours(2) );
+ User1::Speed s = d / t;
+ std::cout << "Speed = " << s.get() << " meters/sec\n";
+ User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
+ std::cout << "Acceleration = " << a.get() << " meters/sec^2\n";
+ User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
+ std::cout << "Distance = " << df.get() << " meters\n";
+ std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter";
+ User1::meter mt = 1;
+ User1::mile mi = mt;
+ std::cout << " which is approximately " << mi.count() << '\n';
+ std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile";
+ mi = 1;
+ mt = mi;
+ std::cout << " which is approximately " << mt.count() << '\n';
+ User1::attosecond as(1);
+ User1::seconds sec = as;
+ std::cout << "1 attosecond is " << sec.count() << " seconds\n";
+ std::cout << "sec = as; // compiles\n";
+ sec = User1::seconds(1);
+ as = sec;
+ std::cout << "1 second is " << as.count() << " attoseconds\n";
+ std::cout << "as = sec; // compiles\n";
+ std::cout << "\n";
+}
+
+//////////////////////////////////////////////////////////
+//////////////////// User2 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+// Demonstrate User2:
+// A "saturating" signed integral type is developed. This type has +/- infinity and a nan
+// (like IEEE floating point) but otherwise obeys signed integral arithmetic.
+// This class is subsequently used as the rep in boost::chrono::duration to demonstrate a
+// duration class that does not silently ignore overflow.
+
+namespace User2
+{
+
+template <class I>
+class saturate
+{
+public:
+ typedef I int_type;
+
+ static const int_type nan = int_type(int_type(1) << (sizeof(int_type) * CHAR_BIT - 1));
+ static const int_type neg_inf = nan + 1;
+ static const int_type pos_inf = -neg_inf;
+private:
+ int_type i_;
+
+// static_assert(std::is_integral<int_type>::value && std::is_signed<int_type>::value,
+// "saturate only accepts signed integral types");
+// static_assert(nan == -nan && neg_inf < pos_inf,
+// "saturate assumes two's complement hardware for signed integrals");
+
+public:
+ saturate() : i_(nan) {}
+ explicit saturate(int_type i) : i_(i) {}
+ // explicit
+ operator int_type() const;
+
+ saturate& operator+=(saturate x);
+ saturate& operator-=(saturate x) {return *this += -x;}
+ saturate& operator*=(saturate x);
+ saturate& operator/=(saturate x);
+ saturate& operator%=(saturate x);
+
+ saturate operator- () const {return saturate(-i_);}
+ saturate& operator++() {*this += saturate(int_type(1)); return *this;}
+ saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
+ saturate& operator--() {*this -= saturate(int_type(1)); return *this;}
+ saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
+
+ friend saturate operator+(saturate x, saturate y) {return x += y;}
+ friend saturate operator-(saturate x, saturate y) {return x -= y;}
+ friend saturate operator*(saturate x, saturate y) {return x *= y;}
+ friend saturate operator/(saturate x, saturate y) {return x /= y;}
+ friend saturate operator%(saturate x, saturate y) {return x %= y;}
+
+ friend bool operator==(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ == y.i_;
+ }
+
+ friend bool operator!=(saturate x, saturate y) {return !(x == y);}
+
+ friend bool operator<(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ < y.i_;
+ }
+
+ friend bool operator<=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ <= y.i_;
+ }
+
+ friend bool operator>(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ > y.i_;
+ }
+
+ friend bool operator>=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ >= y.i_;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, saturate s)
+ {
+ switch (s.i_)
+ {
+ case pos_inf:
+ return os << "inf";
+ case nan:
+ return os << "nan";
+ case neg_inf:
+ return os << "-inf";
+ };
+ return os << s.i_;
+ }
+};
+
+template <class I>
+saturate<I>::operator int_type() const
+{
+ switch (i_)
+ {
+ case nan:
+ case neg_inf:
+ case pos_inf:
+ throw std::out_of_range("saturate special value can not convert to int_type");
+ }
+ return i_;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator+=(saturate x)
+{
+ switch (i_)
+ {
+ case pos_inf:
+ switch (x.i_)
+ {
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = x.i_;
+ return *this;
+ }
+ if (x.i_ >= 0)
+ {
+ if (i_ < pos_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = pos_inf;
+ return *this;
+ }
+ if (i_ > neg_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = neg_inf;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator*=(saturate x)
+{
+ switch (i_)
+ {
+ case 0:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case pos_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = neg_inf;
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = pos_inf;
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case 0:
+ i_ = 0;
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case pos_inf:
+ if (i_ < 0)
+ i_ = neg_inf;
+ else
+ i_ = pos_inf;
+ return *this;
+ case neg_inf:
+ if (i_ < 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ int s = (i_ < 0 ? -1 : 1) * (x.i_ < 0 ? -1 : 1);
+ i_ = i_ < 0 ? -i_ : i_;
+ int_type x_i_ = x.i_ < 0 ? -x.i_ : x.i_;
+ if (i_ <= pos_inf / x_i_)
+ i_ *= x_i_;
+ else
+ i_ = pos_inf;
+ i_ *= s;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator/=(saturate x)
+{
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ break;
+ default:
+ i_ = 0;
+ break;
+ }
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case 0:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ return *this;
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (i_ > 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ switch (i_)
+ {
+ case 0:
+ case nan:
+ return *this;
+ case pos_inf:
+ case neg_inf:
+ if (x.i_ < 0)
+ i_ = -i_;
+ return *this;
+ }
+ i_ /= x.i_;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator%=(saturate x)
+{
+// *this -= *this / x * x; // definition
+ switch (x.i_)
+ {
+ case nan:
+ case neg_inf:
+ case 0:
+ case pos_inf:
+ i_ = nan;
+ return *this;
+ }
+ switch (i_)
+ {
+ case neg_inf:
+ case pos_inf:
+ i_ = nan;
+ case nan:
+ return *this;
+ }
+ i_ %= x.i_;
+ return *this;
+}
+
+// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution
+typedef boost::chrono::duration<saturate<long long>, boost::pico > picoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<saturate<long long> > seconds;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 60LL> > minutes;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 3600LL> > hours;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 86400LL> > days;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 31556952LL> > years;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio<31556952000LL> > millennium;
+
+} // User2
+
+// Demonstrate custom promotion rules (needed only if there are no implicit conversions)
+namespace User2 { namespace detail {
+
+template <class T1, class T2, bool = boost::is_integral<T1>::value>
+struct promote_helper;
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, true> // integral
+{
+ typedef typename boost::common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, false> // floating
+{
+ typedef T1 type;
+};
+
+} }
+
+namespace boost
+{
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, User2::saturate<T2> >
+{
+ typedef typename common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct common_type<T1, User2::saturate<T2> >
+ : User2::detail::promote_helper<T1, User2::saturate<T2> > {};
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, T2>
+ : User2::detail::promote_helper<T2, User2::saturate<T1> > {};
+
+
+// Demonstrate specialization of duration_values:
+
+namespace chrono {
+
+template <class I>
+struct duration_values<User2::saturate<I> >
+{
+ typedef User2::saturate<I> Rep;
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () {return Rep(Rep::pos_inf-1);}
+ static Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () {return -(max) ();}
+};
+
+} // namespace chrono
+
+} // namespace boost
+
+
+void testUser2()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser2 *\n";
+ std::cout << "*************\n";
+ using namespace User2;
+ typedef seconds::rep sat;
+ years yr(sat(100));
+ std::cout << "100 years expressed as years = " << yr.count() << '\n';
+ nanoseconds ns = yr;
+ std::cout << "100 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "200 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "300 years expressed as nanoseconds = " << ns.count() << '\n';
+// yr = ns; // does not compile
+ std::cout << "yr = ns; // does not compile\n";
+// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic
+ std::cout << "ps = yr; // does not compile\n";
+ ns = yr;
+ picoseconds ps = ns;
+ std::cout << "100 years expressed as picoseconds = " << ps.count() << '\n';
+ ps = ns / sat(1000);
+ std::cout << "0.1 years expressed as picoseconds = " << ps.count() << '\n';
+ yr = years(sat(-200000000));
+ std::cout << "200 million years ago encoded in years: " << yr.count() << '\n';
+ days d = boost::chrono::duration_cast<days>(yr);
+ std::cout << "200 million years ago encoded in days: " << d.count() << '\n';
+ millennium c = boost::chrono::duration_cast<millennium>(yr);
+ std::cout << "200 million years ago encoded in millennium: " << c.count() << '\n';
+ std::cout << "Demonstrate \"uninitialized protection\" behavior:\n";
+ seconds sec;
+ for (++sec; sec < seconds(sat(10)); ++sec)
+ ;
+ std::cout << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+void testStdUser()
+{
+ std::cout << "***************\n";
+ std::cout << "* testStdUser *\n";
+ std::cout << "***************\n";
+ using namespace boost::chrono;
+ hours hr = hours(100);
+ std::cout << "100 hours expressed as hours = " << hr.count() << '\n';
+ nanoseconds ns = hr;
+ std::cout << "100 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "200 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "300 hours expressed as nanoseconds = " << ns.count() << '\n';
+// hr = ns; // does not compile
+ std::cout << "hr = ns; // does not compile\n";
+// hr * ns; // does not compile
+ std::cout << "hr * ns; // does not compile\n";
+ duration<double> fs(2.5);
+ std::cout << "duration<double> has count() = " << fs.count() << '\n';
+// seconds sec = fs; // does not compile
+ std::cout << "seconds sec = duration<double> won't compile\n";
+ seconds sec = duration_cast<seconds>(fs);
+ std::cout << "seconds has count() = " << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+// timeval clock demo
+// Demonstrate the use of a timeval-like struct to be used as the representation
+// type for both duraiton and time_point.
+
+namespace timeval_demo
+{
+
+class xtime {
+private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec < 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+public:
+
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec < 0 || tv_usec >= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec)
+ {
+ tv_usec = static_cast<long>(usec % 1000000);
+ tv_sec = static_cast<long>(usec / 1000000);
+ fixup();
+ }
+
+ // explicit
+ operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
+
+ xtime& operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec >= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime& operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime& operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = static_cast<long>(t / 1000000);
+ tv_usec = static_cast<long>(t % 1000000);
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
+
+ friend bool operator<(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec < y.tv_usec);
+ return (x.tv_sec < y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator> (xtime x, xtime y) { return y < x; }
+ friend bool operator<=(xtime x, xtime y) { return !(y < x); }
+ friend bool operator>=(xtime x, xtime y) { return !(x < y); }
+
+ friend std::ostream& operator<<(std::ostream& os, xtime x)
+ {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
+};
+
+class xtime_clock
+{
+public:
+ typedef xtime rep;
+ typedef boost::micro period;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<xtime_clock> time_point;
+
+ static time_point now();
+};
+
+xtime_clock::time_point
+xtime_clock::now()
+{
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&t, 0);
+ return t;
+}
+
+void test_xtime_clock()
+{
+ using namespace boost::chrono;
+ std::cout << "timeval_demo system clock test\n";
+ std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
+ std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
+ std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
+ xtime_clock::duration delay(milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+ while (xtime_clock::now() - start <= delay)
+ {
+ }
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+}
+
+} // timeval_demo
+
+// Handle duration with resolution not known until run time
+
+namespace runtime_resolution
+{
+
+class duration
+{
+public:
+ typedef long long rep;
+private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+public:
+ typedef boost::chrono::duration<double, boost::nano> tonanosec;
+
+ duration() {} // = default;
+ explicit duration(const rep& r) : rep_(r) {}
+
+ // conversions
+ explicit duration(const tonanosec& d)
+ : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
+
+ // explicit
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ // observer
+
+ rep count() const {return rep_;}
+
+ // arithmetic
+
+ duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ duration operator+() const {return *this;}
+ duration operator-() const {return duration(-rep_);}
+ duration& operator++() {++rep_; return *this;}
+ duration operator++(int) {return duration(rep_++);}
+ duration& operator--() {--rep_; return *this;}
+ duration operator--(int) {return duration(rep_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(duration x, duration y) {return !(y < x);}
+ friend bool operator> (duration x, duration y) {return y < x;}
+ friend bool operator>=(duration x, duration y) {return !(x < y);}
+};
+
+static
+double
+init_duration()
+{
+ //mach_timebase_info_data_t MachInfo;
+ //mach_timebase_info(&MachInfo);
+ //return static_cast<double>(MachInfo.denom) / MachInfo.numer;
+ return static_cast<double>(1) / 1000; // Windows FILETIME is 1 per microsec
+}
+
+const double duration::ticks_per_nanosecond = init_duration();
+
+class clock;
+
+class time_point
+{
+public:
+ typedef runtime_resolution::clock clock;
+ typedef long long rep;
+private:
+ rep rep_;
+
+
+ rep count() const {return rep_;}
+public:
+
+ time_point() : rep_(0) {}
+ explicit time_point(const duration& d)
+ : rep_(d.count()) {}
+
+ // arithmetic
+
+ time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
+ time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
+
+ friend time_point operator+(time_point x, duration y) {return x += y;}
+ friend time_point operator+(duration x, time_point y) {return y += x;}
+ friend time_point operator-(time_point x, duration y) {return x -= y;}
+ friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
+};
+
+class clock
+{
+public:
+ typedef duration::rep rep;
+ typedef runtime_resolution::duration duration;
+ typedef runtime_resolution::time_point time_point;
+
+ static time_point now()
+ {
+ timeval tv;
+ gettimeofday( &tv, 0 );
+ return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
+ }
+};
+
+void test()
+{
+ using namespace boost::chrono;
+ std::cout << "runtime_resolution test\n";
+ clock::duration delay(boost::chrono::milliseconds(5));
+ clock::time_point start = clock::now();
+ while (clock::now() - start <= delay)
+ ;
+ clock::time_point stop = clock::now();
+ clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(duration_cast<nanoseconds>(duration::tonanosec(elapsed))).count()
+ << " nanoseconds\n";
+}
+
+} // runtime_resolution
+
+// miscellaneous tests and demos:
+
+
+using namespace boost::chrono;
+
+void physics_function(duration<double> d)
+{
+ std::cout << "d = " << d.count() << '\n';
+}
+
+void drive_physics_function()
+{
+ physics_function(nanoseconds(3));
+ physics_function(hours(3));
+ physics_function(duration<double>(2./3));
+ std::cout.precision(16);
+ physics_function( hours(3) + nanoseconds(-3) );
+}
+
+void test_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 292 + 292/4));
+ nanoseconds n1 = h1 + nanoseconds(1);
+ nanoseconds delta = n1 - h1;
+ std::cout << "292 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a nanosecond = " << n1.count() << "ns\n";
+ std::cout << "Find the difference = " << delta.count() << "ns\n";
+}
+
+void test_extended_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
+ /*auto*/ microseconds u1 = h1 + microseconds(1);
+ /*auto*/ microseconds delta = u1 - h1;
+ std::cout << "244,000 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a microsecond = " << u1.count() << "us\n";
+ std::cout << "Find the difference = " << delta.count() << "us\n";
+}
+
+template <class Rep, class Period>
+void inspect_duration(boost::chrono::duration<Rep, Period> d, const std::string& name)
+{
+ typedef boost::chrono::duration<Rep, Period> Duration;
+ std::cout << "********* " << name << " *********\n";
+ std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n";
+ std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n";
+ std::cout << "The representation is ";
+ if (boost::is_floating_point<Rep>::value)
+ {
+ std::cout << "floating point\n";
+ std::cout << "The precision is the most significant ";
+ std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n";
+ }
+ else if (boost::is_integral<Rep>::value)
+ {
+ std::cout << "integral\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ else
+ {
+ std::cout << "a class type\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ d = Duration((std::numeric_limits<Rep>::max)());
+ using namespace boost::chrono;
+ using namespace std;
+ typedef duration<double, boost::ratio_multiply<boost::ratio<24*3652425,10000>, hours::period>::type> Years;
+ Years years = d;
+ std::cout << "The range is +/- " << years.count() << " years.\n";
+ std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n';
+}
+
+void inspect_all()
+{
+ using namespace boost::chrono;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration<double>(), "duration<double>");
+}
+
+void test_milliseconds()
+{
+ using namespace boost::chrono;
+ milliseconds ms(250);
+ ms += milliseconds(1);
+ milliseconds ms2(150);
+ milliseconds msdiff = ms - ms2;
+ if (msdiff == milliseconds(101))
+ std::cout << "success\n";
+ else
+ std::cout << "failure: " << msdiff.count() << '\n';
+}
+
+ using namespace std;
+ using namespace boost::chrono;
+
+// Example round_up utility: converts d to To, rounding up for inexact conversions
+// Being able to *easily* write this function is a major feature!
+template <class To, class Rep, class Period>
+To
+round_up(duration<Rep, Period> d)
+{
+ To result = duration_cast<To>(d);
+ if (result < d)
+ ++result;
+ return result;
+}
+
+// demonstrate interaction with xtime-like facility:
+
+using namespace boost::chrono;
+
+struct xtime
+{
+ long sec;
+ unsigned long usec;
+};
+
+template <class Rep, class Period>
+xtime
+to_xtime_truncate(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<long>(duration_cast<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+template <class Rep, class Period>
+xtime
+to_xtime_round_up(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<unsigned long>(round_up<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+microseconds
+from_xtime(xtime xt)
+{
+ return seconds(xt.sec) + microseconds(xt.usec);
+}
+
+void print(xtime xt)
+{
+ cout << '{' << xt.sec << ',' << xt.usec << "}\n";
+}
+
+void test_with_xtime()
+{
+ cout << "test_with_xtime\n";
+ xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
+ print(xt);
+ milliseconds ms = duration_cast<milliseconds>(from_xtime(xt));
+ cout << ms.count() << " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
+ print(xt);
+}
+
+void test_system_clock()
+{
+ cout << "system_clock test" << endl;
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = system_clock::now();
+ while (system_clock::now() - start <= delay)
+ ;
+ system_clock::time_point stop = system_clock::now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = system_clock::now();
+ stop = system_clock::now();
+ cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+ cout << "monotonic_clock test" << endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start <= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_hi_resolution_clock()
+{
+ cout << "high_resolution_clock test" << endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start <= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+//void test_mixed_clock()
+//{
+// cout << "mixed clock test" << endl;
+// high_resolution_clock::time_point hstart = high_resolution_clock::now();
+// cout << "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+// monotonic_clock::time_point mend = hstart + milliseconds(5);
+// bool b = hstart == mend;
+// system_clock::time_point sstart = system_clock::now();
+// std::cout << "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+//// mend - sstart; // doesn't compile
+// cout << "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+// " and add that to a system_clock::time_point\n";
+// system_clock::time_point send = sstart + duration_cast<system_clock::duration>(mend - hstart);
+// cout << "subtract two system_clock::time_point's and output that in microseconds:\n";
+// microseconds ms = send - sstart;
+// cout << ms.count() << " microseconds\n";
+//}
+//
+//void test_c_mapping()
+//{
+// cout << "C map test\n";
+// using namespace boost::chrono;
+// system_clock::time_point t1 = system_clock::now();
+// std::time_t c_time = system_clock::to_time_t(t1);
+// std::tm* tmptr = std::localtime(&c_time);
+// std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' '
+// << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\n';
+// c_time = std::mktime(tmptr);
+// system_clock::time_point t2 = system_clock::from_time_t(c_time);
+// microseconds ms = t1 - t2;
+// std::cout << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n";
+//}
+
+void test_duration_division()
+{
+ cout << hours(3) / milliseconds(5) << '\n';
+ cout << milliseconds(5) / hours(3) << '\n';
+ cout << hours(1) / milliseconds(1) << '\n';
+}
+
+namespace I_dont_like_the_default_duration_behavior
+{
+
+// Here's how you override the duration's default constructor to do anything you want (in this case zero)
+
+template <class R>
+class zero_default
+{
+public:
+ typedef R rep;
+
+private:
+ rep rep_;
+public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default& operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default& operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default& operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default& operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator< (zero_default x, zero_default y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(zero_default x, zero_default y) {return !(y < x);}
+ friend bool operator> (zero_default x, zero_default y) {return y < x;}
+ friend bool operator>=(zero_default x, zero_default y) {return !(x < y);}
+};
+
+typedef boost::chrono::duration<zero_default<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<zero_default<long long> > seconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<60> > minutes;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<3600> > hours;
+
+void test()
+{
+ milliseconds ms;
+ cout << ms.count() << '\n';
+}
+
+} // I_dont_like_the_default_duration_behavior
+
+// Build a min for two time_points
+
+template <class Rep, class Period>
+void
+print_duration(ostream& os, duration<Rep, Period> d)
+{
+ os << d.count() << " * " << Period::num << '/' << Period::den << " seconds\n";
+}
+
+// Example min utility: returns the earliest time_point
+// Being able to *easily* write this function is a major feature!
+template <class Clock, class Duration1, class Duration2>
+inline
+typename boost::common_type<time_point<Clock, Duration1>,
+ time_point<Clock, Duration2> >::type
+min BOOST_PREVENT_MACRO_SUBSTITUTION (time_point<Clock, Duration1> t1, time_point<Clock, Duration2> t2)
+{
+ return t2 < t1 ? t2 : t1;
+}
+
+void test_min()
+{
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, seconds>::type> T1;
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, nanoseconds>::type> T2;
+ typedef boost::common_type<T1, T2>::type T3;
+ /*auto*/ T1 t1 = system_clock::now() + seconds(3);
+ /*auto*/ T2 t2 = system_clock::now() + nanoseconds(3);
+ /*auto*/ T3 t3 = (min)(t1, t2);
+ print_duration(cout, t1 - t3);
+ print_duration(cout, t2 - t3);
+}
+
+void explore_limits()
+{
+ typedef duration<long long, boost::ratio_multiply<boost::ratio<24*3652425,10000>,
+ hours::period>::type> Years;
+ monotonic_clock::time_point t1( Years(250));
+ monotonic_clock::time_point t2(-Years(250));
+ // nanosecond resolution is likely to overflow. "up cast" to microseconds.
+ // The "up cast" trades precision for range.
+ microseconds d = time_point_cast<microseconds>(t1) - time_point_cast<microseconds>(t2);
+ cout << d.count() << " microseconds\n";
+}
+
+void manipulate_clock_object(system_clock clock)
+{
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = clock.now();
+ while (clock.now() - start <= delay)
+ ;
+ system_clock::time_point stop = clock.now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+};
+
+template <long long speed>
+struct cycle_count
+{
+ typedef typename boost::ratio_multiply<boost::ratio<speed>, boost::mega>::type frequency; // Mhz
+ typedef typename boost::ratio_divide<boost::ratio<1>, frequency>::type period;
+ typedef long long rep;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return exact cycle count
+ return time_point(duration(++tick)); // fake access to clock cycle count
+ }
+};
+
+template <long long speed>
+struct approx_cycle_count
+{
+ static const long long frequency = speed * 1000000; // MHz
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef boost::chrono::time_point<approx_cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return cycle count as an approximate number of nanoseconds
+ // compute as if nanoseconds is only duration in the std::lib
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+};
+
+void cycle_count_delay()
+{
+ {
+ typedef cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+ {
+ typedef cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+}
+
+void test_special_values()
+{
+ std::cout << "duration<unsigned>::min().count() = " << (duration<unsigned>::min)().count() << '\n';
+ std::cout << "duration<unsigned>::zero().count() = " << duration<unsigned>::zero().count() << '\n';
+ std::cout << "duration<unsigned>::max().count() = " << (duration<unsigned>::max)().count() << '\n';
+ std::cout << "duration<int>::min().count() = " << (duration<int>::min)().count() << '\n';
+ std::cout << "duration<int>::zero().count() = " << duration<int>::zero().count() << '\n';
+ std::cout << "duration<int>::max().count() = " << (duration<int>::max)().count() << '\n';
+}
+
+int main()
+{
+ basic_examples();
+ testStdUser();
+ testUser1();
+ testUser2();
+ drive_physics_function();
+ test_range();
+ test_extended_range();
+ inspect_all();
+ test_milliseconds();
+ test_with_xtime();
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ //test_mixed_clock();
+ timeval_demo::test_xtime_clock();
+ runtime_resolution::test();
+ //test_c_mapping();
+ test_duration_division();
+ I_dont_like_the_default_duration_behavior::test();
+ test_min();
+ inspect_duration(common_type<duration<double>, hours, microseconds>::type(),
+ "common_type<duration<double>, hours, microseconds>::type");
+ explore_limits();
+ manipulate_clock_object(system_clock());
+ duration<double, boost::milli> d = milliseconds(3) * 2.5;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ cout << d.count() << '\n';
+// milliseconds ms(3.5); // doesn't compile
+ cout << "milliseconds ms(3.5) doesn't compile\n";
+ cycle_count_delay();
+ test_special_values();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/time2_demo_output.txt
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/time2_demo_output.txt 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,191 @@
+// time2_demo.output ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+Running basic examples
+sleep_for 3000000 microseconds
+sleep_for 1 microseconds
+sleep_until 10:47:17.728293 which is 4499340 microseconds away
+try_lock_for 30000 microseconds
+try_lock_until 10:47:17.728285 which is 4499303 microseconds away
+wait_for 60000000 microseconds
+wait_until 10:47:17.728285 which is 4499264 microseconds away
+sleep_for 250000 microseconds
+sleep_until 10:47:14.729077 which is 1499979 microseconds away
+***************
+* testStdUser *
+***************
+100 hours expressed as hours = 100
+100 hours expressed as nanoseconds = 360000000000000
+200 hours expressed as nanoseconds = 720000000000000
+300 hours expressed as nanoseconds = 1080000000000000
+hr = ns; // does not compile
+hr * ns; // does not compile
+duration<double> has count() = 2.5
+seconds sec = duration<double> won't compile
+seconds has count() = 2
+
+*************
+* testUser1 *
+*************
+Speed = 24.5872 meters/sec
+Acceleration = 9.81456 meters/sec^2
+Distance = 13.5204 meters
+There are 125/201168 miles/meter which is approximately 0.000621371
+There are 201168/125 meters/mile which is approximately 1609.34
+1 attosecond is 1e-18 seconds
+sec = as; // compiles
+1 second is 1e+18 attoseconds
+as = sec; // compiles
+
+*************
+* testUser2 *
+*************
+100 years expressed as years = 100
+100 years expressed as nanoseconds = 3155695200000000000
+200 years expressed as nanoseconds = 6311390400000000000
+300 years expressed as nanoseconds = inf
+yr = ns; // does not compile
+ps = yr; // does not compile
+100 years expressed as picoseconds = inf
+0.1 years expressed as picoseconds = 3155695200000000000
+200 million years ago encoded in years: -200000000
+200 million years ago encoded in days: -73048500000
+200 million years ago encoded in millennium: -200000
+Demonstrate "uninitialized protection" behavior:
+nan
+
+d = 3e-09
+d = 10800
+d = 0.666667
+d = 10799.999999997
+292 years of hours = 2559672hr
+Add a nanosecond = 9214819200000000001ns
+Find the difference = 1ns
+244,000 years of hours = 2138904000hr
+Add a microsecond = 7700054400000000001us
+Find the difference = 1us
+********* nanoseconds *********
+The period of nanoseconds is 1e-09 seconds.
+The frequency of nanoseconds is 1e+09 Hz.
+The representation is integral
+The precision is 1e-09 seconds.
+The range is +/- 292.277 years.
+sizeof(nanoseconds) = 8
+********* microseconds *********
+The period of microseconds is 1e-06 seconds.
+The frequency of microseconds is 1e+06 Hz.
+The representation is integral
+The precision is 1e-06 seconds.
+The range is +/- 292277 years.
+sizeof(microseconds) = 8
+********* milliseconds *********
+The period of milliseconds is 0.001 seconds.
+The frequency of milliseconds is 1000 Hz.
+The representation is integral
+The precision is 0.001 seconds.
+The range is +/- 2.92277e+08 years.
+sizeof(milliseconds) = 8
+********* seconds *********
+The period of seconds is 1 seconds.
+The frequency of seconds is 1 Hz.
+The representation is integral
+The precision is 1 seconds.
+The range is +/- 2.92277e+11 years.
+sizeof(seconds) = 8
+********* minutes *********
+The period of minutes is 60 seconds.
+The frequency of minutes is 0.0166667 Hz.
+The representation is integral
+The precision is 60 seconds.
+The range is +/- 4083.06 years.
+sizeof(minutes) = 4
+********* hours *********
+The period of hours is 3600 seconds.
+The frequency of hours is 0.000277778 Hz.
+The representation is integral
+The precision is 3600 seconds.
+The range is +/- 244984 years.
+sizeof(hours) = 4
+********* duration<double> *********
+The period of duration<double> is 1 seconds.
+The frequency of duration<double> is 1 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+300 years.
+sizeof(duration<double>) = 8
+success
+test_with_xtime
+{3,251000}
+3251 milliseconds
+{3,251000}
+{3,0}
+{3,1}
+system_clock test
+paused 5001000 nanoseconds
+system_clock resolution estimate: 0 nanoseconds
+monotonic_clock test
+paused 5000181 nanoseconds
+monotonic_clock resolution estimate: 97 nanoseconds
+high_resolution_clock test
+paused 5000277 nanoseconds
+high_resolution_clock resolution estimate: 96 nanoseconds
+mixed clock test
+Add 5 milliseconds to a high_resolution_clock::time_point
+Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
+subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
+subtract two system_clock::time_point's and output that in microseconds:
+5000 microseconds
+timeval_demo system clock test
+sizeof xtime_clock::time_point = 8
+sizeof xtime_clock::duration = 8
+sizeof xtime_clock::rep = 8
+paused 5001000 nanoseconds
+runtime_resolution test
+paused 5000205 nanoseconds
+C map test
+It is now 10:47:13 2008-4-22
+Round-tripping through the C interface truncated the precision by 255445 microseconds
+2160000
+0
+3600000
+0
+2999998997 * 1/1000000000 seconds
+0 * 1/1000000000 seconds
+15778476000000000 microseconds
+paused 5001000 nanoseconds
+********* milliseconds(3) * 2.5 *********
+The period of milliseconds(3) * 2.5 is 0.001 seconds.
+The frequency of milliseconds(3) * 2.5 is 1000 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+297 years.
+sizeof(milliseconds(3) * 2.5) = 8
+7.5
+milliseconds ms(3.5) doesn't compile
+
+Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
+delay = 500 nanoseconds which is 200 cycles
+paused 201 cycles which is 502 nanoseconds
+
+Simulated 400MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 503 nanoseconds
+
+Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
+delay = 500 nanoseconds which is 750 cycles
+paused 751 cycles which is 500 nanoseconds
+
+Simulated 1500MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 500 nanoseconds
+duration<unsigned>::min().count() = 0
+duration<unsigned>::zero().count() = 0
+duration<unsigned>::max().count() = 4294967295
+duration<int>::min().count() = -2147483647
+duration<int>::zero().count() = 0
+duration<int>::max().count() = 2147483647

Added: trunk/libs/chrono/example/timeval_demo.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/timeval_demo.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,221 @@
+// timeval_demo.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+#if defined(BOOST_CHRONO_WINDOWS_API)
+# include <windows.h>
+#endif
+
+#if defined(BOOST_CHRONO_WINDOWS_API)
+
+namespace
+{
+ //struct timeval {
+ // long tv_sec; /* seconds */
+ // long tv_usec; /* and microseconds */
+ //};
+
+ int gettimeofday(struct timeval * tp, void *)
+ {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime( &ft ); // never fails
+ long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+ # else
+ t -= 116444736000000000;
+ # endif
+ t /= 10; // microseconds
+ tp->tv_sec = static_cast<long>( t / 1000000UL);
+ tp->tv_usec = static_cast<long>( t % 1000000UL);
+ return 0;
+ }
+} // unnamed namespace
+
+#endif
+
+// timeval clock demo
+// Demonstrate the use of a timeval-like struct to be used as the representation
+// type for both duraiton and time_point.
+
+namespace timeval_demo
+{
+
+class xtime {
+private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec < 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+public:
+
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec < 0 || tv_usec >= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec)
+ {
+ tv_usec = static_cast<long>(usec % 1000000);
+ tv_sec = static_cast<long>(usec / 1000000);
+ fixup();
+ }
+
+ // explicit
+ operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
+
+ xtime& operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec >= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime& operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime& operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = static_cast<long>(t / 1000000);
+ tv_usec = static_cast<long>(t % 1000000);
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
+
+ friend bool operator<(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec < y.tv_usec);
+ return (x.tv_sec < y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator> (xtime x, xtime y) { return y < x; }
+ friend bool operator<=(xtime x, xtime y) { return !(y < x); }
+ friend bool operator>=(xtime x, xtime y) { return !(x < y); }
+
+ friend std::ostream& operator<<(std::ostream& os, xtime x)
+ {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
+};
+
+class xtime_clock
+{
+public:
+ typedef xtime rep;
+ typedef boost::micro period;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<xtime_clock> time_point;
+
+ static time_point now();
+};
+
+
+xtime_clock::time_point
+xtime_clock::now()
+{
+#if defined(BOOST_CHRONO_WINDOWS_API)
+ timeval tv;
+ gettimeofday(&tv, 0);
+ xtime xt( tv.tv_sec, tv.tv_usec);
+ return time_point(duration(xt));
+
+#elif defined(BOOST_CHRONO_MAC_API)
+
+ timeval tv;
+ gettimeofday(&tv, 0);
+ xtime xt( tv.tv_sec, tv.tv_usec);
+ return time_point(duration(xt));
+
+#elif defined(BOOST_CHRONO_POSIX_API)
+ //time_point t(0,0);
+
+ timespec ts;
+ ::clock_gettime( CLOCK_REALTIME, &ts );
+
+ xtime xt( ts.tv_sec, ts.tv_nsec/1000);
+ return time_point(duration(xt));
+#endif // POSIX
+
+}
+
+void test_xtime_clock()
+{
+ using namespace boost::chrono;
+ std::cout << "timeval_demo system clock test\n";
+ std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
+ std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
+ std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
+ xtime_clock::duration delay(milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+
+ while (xtime_clock::now() - start <= delay)
+ {
+ }
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+}
+
+} // timeval_demo
+
+int main()
+{
+ timeval_demo::test_xtime_clock();
+ return 0;
+}
+

Added: trunk/libs/chrono/example/xtime.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/example/xtime.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,108 @@
+// xtime.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
+was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.9 Time utilities [time] of the C++ committee's working paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krugler,
+ Anthony Williams.
+*/
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+using namespace boost::chrono;
+
+// Example round_up utility: converts d to To, rounding up for inexact conversions
+// Being able to *easily* write this function is a major feature!
+template <class To, class Rep, class Period>
+To
+round_up(duration<Rep, Period> d)
+{
+ To result = duration_cast<To>(d);
+ if (result < d)
+ ++result;
+ return result;
+}
+
+// demonstrate interaction with xtime-like facility:
+
+struct xtime
+{
+ long sec;
+ unsigned long usec;
+};
+
+template <class Rep, class Period>
+xtime
+to_xtime_truncate(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<long>(duration_cast<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+template <class Rep, class Period>
+xtime
+to_xtime_round_up(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<unsigned long>(round_up<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+microseconds
+from_xtime(xtime xt)
+{
+ return seconds(xt.sec) + microseconds(xt.usec);
+}
+
+void print(xtime xt)
+{
+ std::cout << '{' << xt.sec << ',' << xt.usec << "}\n";
+}
+
+void test_with_xtime()
+{
+ std::cout << "test_with_xtime\n";
+ xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
+ print(xt);
+ milliseconds ms = duration_cast<milliseconds>(from_xtime(xt));
+ std::cout << ms.count() << " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
+ print(xt);
+}
+
+
+int main()
+{
+ test_with_xtime();
+ return 0;
+}
+

Added: trunk/libs/chrono/src/chrono.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/chrono.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,15 @@
+// chrono.cpp --------------------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+// Copyright Vicente J. Botet Escriba 2009-2010
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// define BOOST_CHRONO_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/chrono.hpp>
+

Added: trunk/libs/chrono/src/process_clock.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/process_clock.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,19 @@
+// boost process_timer.cpp -----------------------------------------------------------//
+
+// Copyright Beman Dawes 1994, 2006, 2008
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_CHRONO_SOURCE so that <boost/chrono/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/process_clock.hpp>
+

Added: trunk/libs/chrono/src/process_cpu_clocks.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/process_cpu_clocks.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,18 @@
+// boost process_cpu_clocks.cpp -----------------------------------------------------------//
+
+// Copyright 2009-2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_CHRONO_SOURCE so that <boost/chrono/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/process_cpu_clocks.hpp>
+

Added: trunk/libs/chrono/src/run_timer.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/run_timer.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,19 @@
+// boost run_timer.cpp ---------------------------------------------------------------//
+
+// Copyright Beman Dawes 1994, 2006, 2008
+// Copyright 2009-2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_CHRONO_SOURCE so that <boost/chrono/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/run_timer.hpp>
+

Added: trunk/libs/chrono/src/run_timer_static.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/run_timer_static.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,26 @@
+// boost run_timer_static.cpp --------------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+// Copyright 2009-2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+// This function is defined in a separate translation so that it will not be linked
+// in except if actually used. This is more efficient because header <iostream> is
+// required, and it incurs the cost of the standard stream objects even if they are
+// not actually used.
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_CHRONO_SOURCE so that <boost/chrono/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/run_timer_static.hpp>
+

Added: trunk/libs/chrono/src/thread_clock.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/src/thread_clock.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,19 @@
+// boost thread_clock.cpp -----------------------------------------------------------//
+
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+
+// define BOOST_CHRONO_SOURCE so that <boost/chrono/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+
+#define BOOST_CHRONO_SOURCE
+
+#include <boost/chrono/detail/inlined/thread_clock.hpp>
+

Added: trunk/libs/chrono/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/Jamfile.v2 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,254 @@
+# Boost Chrono Library test Jamfile
+
+# Copyright Beman Dawes 2008
+# Copyright Vicente J. Botet Escriba 2009-2010
+
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
+
+# See library home page at http://www.boost.org/libs/chrono
+
+# uncomment one if the above lines if you build outside the Boost release
+#local BOOST_ROOT = /boost_1_41_0 ;
+#local BOOST_ROOT = c:/cygwin/boost_1_41_0 ;
+
+import os ;
+import feature ;
+
+if ! $(BOOST_ROOT)
+{
+ BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+}
+#feature.feature chrono_level : sh st hd;
+#feature.set-default chrono_level : [ hd ] ;
+
+#feature.feature chrono_stub : yes no;
+#feature.set-default chrono_stub : [ no ] ;
+
+project
+ : requirements
+ <os>LINUX:<threading>multi
+ #<library>/boost/system//boost_system
+ #<define>BOOST_SYSTEM_INLINED
+
+ # uncomment the line above if you build outside the Boost release
+ #<include>$(BOOST_ROOT)
+ # uncomment the line above if you build outside the Boost release
+ #<include>../../..
+
+ <toolset>msvc:<asynch-exceptions>on
+ <define>BOOST_CHRONO_USES_MPL_ASSERT
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ <warnings>all
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-pedantic
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ <toolset>darwin:<cxxflags>-Wextra
+ <toolset>darwin:<cxxflags>-pedantic
+ <toolset>darwin:<cxxflags>-Wno-long-long
+ <toolset>gcc-mingw-4.5.0:<cxxflags>-Wno-missing-field-initializers
+ <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>msvc:<cxxflags>/wd4127
+ ;
+
+rule chrono-run ( sources )
+{
+ return
+ [ run $(sources) ../build//boost_chrono
+ : :
+ : <define>BOOST_USE_WINDOWS_H
+ <library>/boost/system//boost_system
+ : $(sources[1]:B)_shared ]
+ [ run $(sources) ../build//boost_chrono/<link>static
+ : :
+ : <library>/boost/system//boost_system
+ : $(sources[1]:B)_static ]
+# [ run $(sources)
+# : :
+# : <define>BOOST_CHRONO_INLINED
+# # comment one of the following lines
+# #<define>BOOST_SYSTEM_INLINED
+# <library>/boost/system//boost_system
+# : $(sources[1]:B)_header ]
+# [ run $(sources)
+# : :
+# : <define>BOOST_CHRONO_INLINED
+# <define>BOOST_USE_WINDOWS_H
+# # comment one of the following lines
+# #<define>BOOST_SYSTEM_INLINED
+# <library>/boost/system//boost_system
+# : $(sources[1]:B)_header_win ]
+ ;
+}
+rule chrono-run2 ( sources : name )
+{
+ return
+ [ run $(sources) ../build//boost_chrono
+ : :
+ : <define>BOOST_USE_WINDOWS_H
+ <library>/boost/system//boost_system
+ : $(name)_shared ]
+ [ run $(sources) ../build//boost_chrono/<link>static
+ : :
+ : <library>/boost/system//boost_system
+ : $(name)_static ]
+# [ run $(sources)
+# : :
+# : <define>BOOST_CHRONO_INLINED
+# # comment one of the following lines
+# #<define>BOOST_SYSTEM_INLINED
+# <library>/boost/system//boost_system
+# : $(name)_header ]
+# [ run $(sources)
+# : :
+# : <define>BOOST_CHRONO_INLINED
+# <define>BOOST_USE_WINDOWS_H
+# # comment one of the following lines
+# #<define>BOOST_SYSTEM_INLINED
+# <library>/boost/system//boost_system
+# : $(name)_header_win ]
+ ;
+}
+
+rule chrono-compile ( sources )
+{
+ return
+ [ compile $(sources)
+ :
+ : $(sources[1]:B)_lib ]
+# [ compile $(sources)
+# : <define>BOOST_CHRONO_INLINED
+# # comment the following line
+# <define>BOOST_SYSTEM_INLINED
+# : $(sources[1]:B)_header ]
+# [ compile $(sources)
+# : <define>BOOST_CHRONO_INLINED
+# <define>BOOST_USE_WINDOWS_H
+# # comment the following line
+# <define>BOOST_SYSTEM_INLINED
+# : $(sources[1]:B)_header_win ]
+ ;
+}
+
+rule chrono-compile2 ( sources : name )
+{
+ return
+ [ compile $(sources)
+ :
+ : $(name)_lib ]
+# [ compile $(sources)
+# : <define>BOOST_CHRONO_INLINED
+# # comment the following line
+# <define>BOOST_SYSTEM_INLINED
+# : $(name)_header ]
+# [ compile $(sources)
+# : <define>BOOST_CHRONO_INLINED
+# <define>BOOST_USE_WINDOWS_H
+# # comment the following line
+# <define>BOOST_SYSTEM_INLINED
+# : $(name)_header_win ]
+ ;
+}
+
+ test-suite "examples"
+ :
+ [ chrono-run ../example/cycle_count.cpp ]
+ [ chrono-run ../example/runtime_resolution.cpp ]
+ [ chrono-run ../example/xtime.cpp ]
+ [ chrono-run ../example/saturating.cpp ]
+ [ chrono-run ../example/min_time_point.cpp ]
+ [ chrono-run ../example/i_dont_like_the_default_duration_behavior.cpp ]
+ [ chrono-run ../example/simulated_thread_interface_demo.cpp ]
+ [ chrono-run ../example/timeval_demo.cpp ]
+ [ chrono-run ../example/chrono_unit_test.cpp ]
+ [ chrono-run ../example/explore_limits.cpp ]
+ [ chrono-run ../example/test_duration.cpp ]
+ [ chrono-run ../example/test_clock.cpp ]
+ [ chrono-run ../example/miscellaneous.cpp ]
+ [ chrono-run ../example/test_special_values.cpp ]
+ [ chrono-run ../example/manipulate_clock_object.cpp ]
+ [ chrono-run ../example/chrono_accuracy_test.cpp ]
+ [ chrono-run ../example/test_thread_clock.cpp ]
+ ;
+
+# test-suite "timer"
+# :
+# [ chrono-run ../example/run_timer_example.cpp ]
+# [ chrono-run ../example/run_timer_example2.cpp ]
+# [ chrono-run run_timer_test.cpp ]
+# ;
+
+ test-suite "traits"
+ :
+ [ chrono-compile2 traits/common_type_duration_pass.cpp : traits_common_type_duration_pass ]
+ [ chrono-compile2 traits/common_type_time_point_pass.cpp : traits_common_type_time_point_pass ]
+ [ chrono-compile2 traits/treat_as_floating_point_pass.cpp : traits_treat_as_floating_point_pass ]
+ [ chrono-run2 traits/duration_values_pass.cpp : traits_duration_values_pass ]
+ ;
+
+ test-suite "duration"
+ :
+ [ compile-fail duration/duration_duration_fail.cpp ]
+ [ compile-fail duration/ratio_fail.cpp ]
+ [ compile-fail duration/positive_num_fail.cpp ]
+ [ chrono-compile duration/default_ratio_pass.cpp ]
+ [ chrono-compile duration/types_pass.cpp ]
+ [ chrono-compile duration/ratio_alias_pass.cpp ]
+ [ chrono-compile duration/typedefs_pass.cpp ]
+ [ chrono-run duration/arithmetic_pass.cpp ]
+ [ chrono-run duration/duration_cast_pass.cpp ]
+ [ compile-fail duration/duration_cast_int_fail.cpp ]
+ [ chrono-run duration/comparisons_pass.cpp ]
+ [ chrono-run duration/constructor_pass.cpp ]
+ [ compile-fail duration/cons/convert_float_to_int_fail.cpp ]
+ [ compile-fail duration/cons/convert_inexact_fail.cpp ]
+ [ compile-fail duration/cons/implicit_constructot_fail.cpp ]
+ [ compile-fail duration/cons/non_implicit_convertible_rep_fail.cpp ]
+ [ compile-fail duration/cons/treat_as_floating_point_Rep2_true_fail.cpp ]
+ [ compile-fail duration/nonmember/divide_rep2_fail.cpp ]
+ [ compile-fail duration/nonmember/modulus_rep2_fail.cpp ]
+ [ compile-fail duration/nonmember/times_rep2_lhs_fail.cpp ]
+ [ compile-fail duration/nonmember/times_rep2_rhs_fail.cpp ]
+ [ chrono-run duration/duration_values_pass.cpp ]
+ ;
+
+ test-suite "time_point"
+ :
+ [ chrono-compile2 time_point/default_duration_pass.cpp : time_point.default_duration_pass ]
+ [ compile-fail time_point/not_duration_fail.cpp : : time_point_not_duration_fail ]
+ [ chrono-run2 time_point/arithmetic_pass.cpp : time_point_arithmetic_pass ]
+ [ chrono-run2 time_point/time_point_cast_pass.cpp : time_point_time_point_cast_pass ]
+ [ compile-fail time_point/time_point_cast_int_fail.cpp : : time_point_time_point_cast_int_fail ]
+ [ chrono-run2 time_point/comparisons_pass.cpp : time_point_comparisons_pass ]
+ [ compile-fail time_point/comparisons/equal_fail.cpp : : time_point_equal_fail ]
+ [ compile-fail time_point/comparisons/less_fail.cpp : : time_point_less_fail ]
+ [ chrono-run2 time_point/constructor_pass.cpp : time_point_constructor_pass ]
+ [ compile-fail time_point/cons/implicit_fail.cpp : : time_point_implicit_fail ]
+ [ compile-fail time_point/cons/non_implicit_convertible_duration_fail.cpp : : time_point_non_implicit_convertible_duration_fail ]
+ [ chrono-run2 time_point/min_max_pass.cpp : time_point_min_max_pass ]
+ ;
+
+ test-suite "clock"
+ :
+ [ chrono-run2 clock/clock_pass.cpp : clock_clock_pass_ ]
+ ;
+
+ test-suite "io"
+ :
+ [ chrono-run ../example/io_ex1.cpp ]
+ [ chrono-run ../example/io_ex2.cpp ]
+ [ chrono-run ../example/io_ex3.cpp ]
+ [ chrono-run ../example/io_ex4.cpp ]
+ [ chrono-run ../example/io_ex5.cpp ]
+ ;
+
+ test-suite "win32"
+ :
+ [ chrono-run win32_test.cpp ]
+ ;
+
+# test-suite "static_string"
+# :
+# [ chrono-run io/match_pass.cpp ]
+# ;
+
\ No newline at end of file

Added: trunk/libs/chrono/test/clock.h
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/clock.h 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef CLOCK_H
+#define CLOCK_H
+
+#include <boost/chrono.hpp>
+
+class Clock
+{
+ typedef boost::chrono::nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock, duration> time_point;
+ static const bool is_monotonic = false;
+
+ static time_point now();
+};
+
+#endif // CLOCK_H

Added: trunk/libs/chrono/test/clock/clock_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/clock/clock_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/chrono.hpp>
+#include <boost/chrono/process_cpu_clocks.hpp>
+#include <boost/chrono/thread_clock.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <typename Clock>
+void check_clock_invariants()
+{
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<typename Clock::rep, typename Clock::duration::rep>::value), NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<typename Clock::period, typename Clock::duration::period>::value), NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<typename Clock::duration, typename Clock::time_point::duration>::value), NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT(Clock::is_monotonic || !Clock::is_monotonic, NOTHING, ());
+ // to be replaced by has static member bool is_monotonic
+}
+
+template <typename Clock>
+void check_clock_now()
+{
+ typename Clock::time_point t1 = Clock::now();
+}
+
+template <typename Clock>
+void check_clock_now_ec()
+{
+ boost::system::error_code ec;
+ typename Clock::time_point t1 = Clock::now(ec);
+ BOOST_TEST(ec.value()==0);
+}
+
+template <typename Clock>
+void check_clock_now_throws()
+{
+ typename Clock::time_point t1 = Clock::now(boost::throws());
+}
+
+template <typename Clock>
+void check_clock_now_err(int err)
+{
+ Clock::set_errno(err);
+ try {
+ typename Clock::time_point t1 = Clock::now();
+ } catch (boost::system::system_error& ex) {
+ BOOST_TEST(ex.code().value()==err);
+// BOOST_TEST(ex.code().category() == BOOST_CHRONO_SYSTEM_CATEGORY);
+// BOOST_TEST(std::string(ex.what()) == std::string("errored_clock"));
+ }
+ Clock::set_errno(0);
+}
+
+template <typename Clock>
+void check_clock_now_ec_err(int err)
+{
+ Clock::set_errno(err);
+ boost::system::error_code ec;
+ typename Clock::time_point t1 = Clock::now(ec);
+ BOOST_TEST(ec.value()==err);
+// BOOST_TEST(ec.category() == BOOST_CHRONO_SYSTEM_CATEGORY);
+ Clock::set_errno(0);
+}
+
+template <typename Clock>
+void check_clock_now_throws_err(int err)
+{
+ Clock::set_errno(err);
+ try {
+ typename Clock::time_point t1 = Clock::now(boost::throws());
+ BOOST_TEST(0&&"exception not thown");
+ } catch (boost::system::system_error& ex) {
+ BOOST_TEST(ex.code().value()==err);
+// BOOST_TEST(ex.code().category() == BOOST_CHRONO_SYSTEM_CATEGORY);
+// BOOST_TEST(std::string(ex.what()) == std::string("errored_clock"));
+ }
+ Clock::set_errno(0);
+}
+
+int main()
+{
+ check_clock_invariants<boost::chrono::high_resolution_clock>();
+ check_clock_now<boost::chrono::high_resolution_clock>();
+ check_clock_now_ec<boost::chrono::high_resolution_clock>();
+ check_clock_now_throws<boost::chrono::high_resolution_clock>();
+
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ check_clock_invariants<boost::chrono::monotonic_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::monotonic_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::monotonic_clock>();
+ check_clock_now_ec<boost::chrono::monotonic_clock>();
+ check_clock_now_throws<boost::chrono::monotonic_clock>();
+#endif
+
+ check_clock_invariants<boost::chrono::system_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::system_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::system_clock>();
+ check_clock_now_ec<boost::chrono::system_clock>();
+ check_clock_now_throws<boost::chrono::system_clock>();
+ {
+ typedef boost::chrono::system_clock C;
+ C::time_point t1 = C::from_time_t(C::to_time_t(C::now()));
+ (void)t1;
+ }
+ {
+ typedef boost::chrono::system_clock C;
+ std::time_t t1 = C::to_time_t(C::now());
+ (void)t1;
+
+ }
+ {
+ BOOST_TEST((boost::chrono::system_clock::duration::min)() <
+ boost::chrono::system_clock::duration::zero());
+
+ }
+
+#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+ check_clock_invariants<boost::chrono::thread_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::thread_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::thread_clock>();
+ check_clock_now_ec<boost::chrono::thread_clock>();
+ check_clock_now_throws<boost::chrono::thread_clock>();
+#endif
+
+ check_clock_invariants<boost::chrono::process_real_cpu_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::process_real_cpu_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::process_real_cpu_clock>();
+ check_clock_now_ec<boost::chrono::process_real_cpu_clock>();
+ check_clock_now_throws<boost::chrono::process_real_cpu_clock>();
+
+ check_clock_invariants<boost::chrono::process_user_cpu_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::process_user_cpu_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::process_user_cpu_clock>();
+ check_clock_now_ec<boost::chrono::process_user_cpu_clock>();
+ check_clock_now_throws<boost::chrono::process_user_cpu_clock>();
+
+ check_clock_invariants<boost::chrono::process_system_cpu_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::process_system_cpu_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::process_system_cpu_clock>();
+ check_clock_now_ec<boost::chrono::process_system_cpu_clock>();
+ check_clock_now_throws<boost::chrono::process_system_cpu_clock>();
+
+ check_clock_invariants<boost::chrono::process_cpu_clock>();
+ BOOST_CHRONO_STATIC_ASSERT(boost::chrono::process_cpu_clock::is_monotonic, NOTHING, ());
+ check_clock_now<boost::chrono::process_cpu_clock>();
+ check_clock_now_ec<boost::chrono::process_cpu_clock>();
+ check_clock_now_throws<boost::chrono::process_cpu_clock>();
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/clock/errored_clock.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/clock/errored_clock.hpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,62 @@
+// errored_clock.hpp --------------------------------------------------------------//
+
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_CHRONO_ERRORED_CLOCKS_HPP
+#define BOOST_CHRONO_ERRORED_CLOCKS_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/chrono/detail/system.hpp>
+
+ class errored_clock
+ {
+ public:
+ typedef boost::chrono::nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<errored_clock> time_point;
+ static const bool is_monotonic = true;
+ static int errno_;
+
+ static void set_errno(int err) {
+ errno_=err;
+ }
+
+ // throws on error
+ static time_point now() {
+ boost::throw_exception(
+ boost::system::system_error(
+ errno_,
+ BOOST_CHRONO_SYSTEM_CATEGORY,
+ "errored_clock"
+ )
+ );
+ return time_point();
+ }
+ // never throws and set ec
+ static time_point now(boost::system::error_code & ec) {
+ if (BOOST_CHRONO_IS_THROWS(ec))
+ {
+ boost::throw_exception(
+ boost::system::system_error(
+ errno_,
+ BOOST_CHRONO_SYSTEM_CATEGORY,
+ "errored_clock"
+ )
+ );
+ }
+ ec.assign( errno_, BOOST_CHRONO_SYSTEM_CATEGORY );
+ return time_point();
+ };
+ };
+ int errored_clock::errno_;
+
+#endif

Added: trunk/libs/chrono/test/duration/arithmetic_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/arithmetic_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,225 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/chrono/typeof/boost/chrono/chrono.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+
+ // UNARY PLUS
+ {
+ const boost::chrono::minutes m(3);
+ boost::chrono::minutes m2 = +m;
+ BOOST_TEST(m.count() == m2.count());
+ }
+
+ // UNARY MINUS
+ {
+ const boost::chrono::minutes m(3);
+ boost::chrono::minutes m2 = -m;
+ BOOST_TEST(m2.count() == -m.count());
+ }
+ // PRE INCREMENT
+ {
+ boost::chrono::hours h(3);
+ boost::chrono::hours& href = ++h;
+ BOOST_TEST(&href == &h);
+ BOOST_TEST(h.count() == 4);
+ }
+ // POST INCREMENT
+ {
+ boost::chrono::hours h(3);
+ boost::chrono::hours h2 = h++;
+ BOOST_TEST(h.count() == 4);
+ BOOST_TEST(h2.count() == 3);
+ }
+ // PRE DECREMENT
+ {
+ boost::chrono::hours h(3);
+ boost::chrono::hours& href = --h;
+ BOOST_TEST(&href == &h);
+ BOOST_TEST(h.count() == 2);
+ }
+ // POST DECREMENT
+ {
+ boost::chrono::hours h(3);
+ boost::chrono::hours h2 = h--;
+ BOOST_TEST(h.count() == 2);
+ BOOST_TEST(h2.count() == 3);
+ }
+ // PLUS ASSIGN
+ {
+ boost::chrono::seconds s(3);
+ s += boost::chrono::seconds(2);
+ BOOST_TEST(s.count() == 5);
+ s += boost::chrono::minutes(2);
+ BOOST_TEST(s.count() == 125);
+ }
+ // MINUS ASSIGN
+ {
+ boost::chrono::seconds s(3);
+ s -= boost::chrono::seconds(2);
+ BOOST_TEST(s.count() == 1);
+ s -= boost::chrono::minutes(2);
+ BOOST_TEST(s.count() == -119);
+ }
+ // TIMES ASSIGN
+ {
+ boost::chrono::nanoseconds ns(3);
+ ns *= 5;
+ BOOST_TEST(ns.count() == 15);
+ }
+ // DIVIDE ASSIGN
+ {
+ boost::chrono::nanoseconds ns(15);
+ ns /= 5;
+ BOOST_TEST(ns.count() == 3);
+ }
+ // MODULUS ASSIGN duration
+ {
+ boost::chrono::microseconds us(11);
+ boost::chrono::microseconds us2(3);
+ us %= us2;
+ BOOST_TEST(us.count() == 2);
+ us %= boost::chrono::milliseconds(3);
+ BOOST_TEST(us.count() == 2);
+ }
+ // MODULUS ASSIGN Rep
+ {
+ boost::chrono::microseconds us(11);
+ us %= 3;
+ BOOST_TEST(us.count() == 2);
+ }
+ // PLUS
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(5);
+ boost::chrono::seconds r = s1 + s2;
+ BOOST_TEST(r.count() == 8);
+ }
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::microseconds s2(5);
+ boost::chrono::microseconds r = s1 + s2;
+ BOOST_TEST(r.count() == 3000005);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(3);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(5);
+ boost::chrono::duration<int, boost::ratio<1, 15> > r = s1 + s2;
+ BOOST_TEST(r.count() == 75);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(3);
+ boost::chrono::duration<double, boost::ratio<3, 5> > s2(5);
+ boost::chrono::duration<double, boost::ratio<1, 15> > r = s1 + s2;
+ BOOST_TEST(r.count() == 75);
+ }
+
+
+ // MINUS
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(5);
+ boost::chrono::seconds r = s1 - s2;
+ BOOST_TEST(r.count() == -2);
+ }
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::microseconds s2(5);
+ boost::chrono::microseconds r = s1 - s2;
+ BOOST_TEST(r.count() == 2999995);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(3);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(5);
+ boost::chrono::duration<int, boost::ratio<1, 15> > r = s1 - s2;
+ BOOST_TEST(r.count() == -15);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(3);
+ boost::chrono::duration<double, boost::ratio<3, 5> > s2(5);
+ boost::chrono::duration<double, boost::ratio<1, 15> > r = s1 - s2;
+ BOOST_TEST(r.count() == -15);
+ }
+
+ // TIMES rep
+ {
+ boost::chrono::nanoseconds ns(3);
+ ns = ns * 5;
+ BOOST_TEST(ns.count() == 15);
+ ns = 6 * ns;
+ BOOST_TEST(ns.count() == 90);
+ }
+
+ // DIVIDE duration
+ {
+ boost::chrono::nanoseconds ns1(15);
+ boost::chrono::nanoseconds ns2(5);
+ BOOST_TEST(ns1 / ns2 == 3);
+ }
+ {
+ boost::chrono::microseconds us1(15);
+ boost::chrono::nanoseconds ns2(5);
+ BOOST_TEST(us1 / ns2 == 3000);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(30);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(5);
+ BOOST_TEST(s1 / s2 == 6);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(30);
+ boost::chrono::duration<double, boost::ratio<3, 5> > s2(5);
+ BOOST_TEST(s1 / s2 == 20./3);
+ }
+ // DIVIDE rep
+ {
+ boost::chrono::nanoseconds ns(15);
+ ns = ns / 5;
+ BOOST_TEST(ns.count() == 3);
+ }
+
+ // MODULUS duration
+
+ {
+ boost::chrono::nanoseconds ns1(15);
+ boost::chrono::nanoseconds ns2(6);
+ boost::chrono::nanoseconds r = ns1 % ns2;
+ BOOST_TEST(r.count() == 3);
+ }
+ {
+ boost::chrono::microseconds us1(15);
+ boost::chrono::nanoseconds ns2(28);
+ boost::chrono::nanoseconds r = us1 % ns2;
+ BOOST_TEST(r.count() == 20);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<3, 5> > s1(6);
+ boost::chrono::duration<int, boost::ratio<2, 3> > s2(3);
+ boost::chrono::duration<int, boost::ratio<1, 15> > r = s1 % s2;
+ BOOST_TEST(r.count() == 24);
+ }
+ // MODULUS rep
+ {
+ boost::chrono::nanoseconds ns(15);
+ ns = ns % 6;
+ BOOST_TEST(ns.count() == 3);
+ }
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/duration/comparisons_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/comparisons_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(3);
+ BOOST_TEST(s1 == s2);
+ BOOST_TEST(!(s1 != s2));
+ }
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(4);
+ BOOST_TEST(!(s1 == s2));
+ BOOST_TEST(s1 != s2);
+ }
+ {
+ boost::chrono::milliseconds s1(3);
+ boost::chrono::microseconds s2(3000);
+ BOOST_TEST(s1 == s2);
+ BOOST_TEST(!(s1 != s2));
+ }
+ {
+ boost::chrono::milliseconds s1(3);
+ boost::chrono::microseconds s2(4000);
+ BOOST_TEST(!(s1 == s2));
+ BOOST_TEST(s1 != s2);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(9);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(10);
+ BOOST_TEST(s1 == s2);
+ BOOST_TEST(!(s1 != s2));
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(10);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(9);
+ BOOST_TEST(!(s1 == s2));
+ BOOST_TEST(s1 != s2);
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(9);
+ boost::chrono::duration<double, boost::ratio<3, 5> > s2(10);
+ BOOST_TEST(s1 == s2);
+ BOOST_TEST(!(s1 != s2));
+ }
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(3);
+ BOOST_TEST(!(s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST( (s1 >= s2));
+ }
+ {
+ boost::chrono::seconds s1(3);
+ boost::chrono::seconds s2(4);
+ BOOST_TEST( (s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST(!(s1 >= s2));
+ }
+ {
+ boost::chrono::milliseconds s1(3);
+ boost::chrono::microseconds s2(3000);
+ BOOST_TEST(!(s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST( (s1 >= s2));
+ }
+ {
+ boost::chrono::milliseconds s1(3);
+ boost::chrono::microseconds s2(4000);
+ BOOST_TEST( (s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST(!(s1 >= s2));
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(9);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(10);
+ BOOST_TEST(!(s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST( (s1 >= s2));
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(10);
+ boost::chrono::duration<int, boost::ratio<3, 5> > s2(9);
+ BOOST_TEST(!(s1 < s2));
+ BOOST_TEST( (s1 > s2));
+ BOOST_TEST(!(s1 <= s2));
+ BOOST_TEST( (s1 >= s2));
+ }
+ {
+ boost::chrono::duration<int, boost::ratio<2, 3> > s1(9);
+ boost::chrono::duration<double, boost::ratio<3, 5> > s2(10);
+ BOOST_TEST(!(s1 < s2));
+ BOOST_TEST(!(s1 > s2));
+ BOOST_TEST( (s1 <= s2));
+ BOOST_TEST( (s1 >= s2));
+ }
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/duration/cons/convert_float_to_int_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/cons/convert_float_to_int_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// conversions from floating point to integral durations disallowed
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ boost::chrono::duration<double> d;
+ boost::chrono::duration<int> i = d;
+}

Added: trunk/libs/chrono/test/duration/cons/convert_inexact_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/cons/convert_inexact_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// inexact conversions disallowed for integral reps
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ boost::chrono::microseconds us(1);
+ boost::chrono::milliseconds ms = us;
+}

Added: trunk/libs/chrono/test/duration/cons/implicit_constructot_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/cons/implicit_constructot_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// test for explicit
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<int> d = 1;
+}

Added: trunk/libs/chrono/test/duration/cons/non_implicit_convertible_rep_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/cons/non_implicit_convertible_rep_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Rep2 shall be implicitly convertible to rep
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<Rep> d(1);
+}

Added: trunk/libs/chrono/test/duration/cons/treat_as_floating_point_Rep2_true_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/cons/treat_as_floating_point_Rep2_true_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// treat_as_floating_point<Rep2>::value must be false
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ boost::chrono::duration<int> d(1.);
+}

Added: trunk/libs/chrono/test/duration/constructor_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/constructor_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#include <libs/chrono/test/rep.h>
+
+template <class D>
+void
+check_default()
+{
+ D d;
+ BOOST_TEST(d.count() == typename D::rep());
+}
+
+template <class D, class R>
+void
+check_from_rep(R r)
+{
+ D d(r);
+ BOOST_TEST(d.count() == r);
+}
+
+int main()
+{
+ // exact conversions allowed for integral reps
+ {
+ boost::chrono::milliseconds ms(1);
+ boost::chrono::microseconds us = ms;
+ BOOST_TEST(us.count() == 1000);
+ }
+ // inexact conversions allowed for floating point reps
+ {
+ boost::chrono::duration<double, boost::micro> us(1);
+ boost::chrono::duration<double, boost::milli> ms = us;
+ BOOST_TEST(ms.count() == 1./1000);
+ }
+ // Convert int to float
+ {
+ boost::chrono::duration<int> i(3);
+ boost::chrono::duration<int> d = i;
+ BOOST_TEST(d.count() == 3);
+ }
+ // default constructor
+ {
+ check_default<boost::chrono::duration<Rep> >();
+ }
+ // constructor from rep
+ {
+ check_from_rep<boost::chrono::duration<int> >(5);
+ check_from_rep<boost::chrono::duration<int, boost::ratio<3, 2> > >(5);
+ check_from_rep<boost::chrono::duration<Rep, boost::ratio<3, 2> > >(Rep(3));
+ check_from_rep<boost::chrono::duration<double, boost::ratio<2, 3> > >(5.5);
+ }
+ // constructor from other rep
+ {
+ boost::chrono::duration<double> d(5);
+ BOOST_TEST(d.count() == 5);
+ return boost::report_errors();
+ }
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/duration/default_ratio_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/default_ratio_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// Test default template arg:
+
+// template <class Rep, class Period = ratio<1>>
+// class duration;
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+BOOST_CHRONO_STATIC_ASSERT((boost::is_same<
+ boost::chrono::duration<int, boost::ratio<1> >,
+ boost::chrono::duration<int>
+>::value), NOTHING, ());

Added: trunk/libs/chrono/test/duration/duration_cast_int_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/duration_cast_int_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// ToDuration must be an instantiation of duration.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ boost::chrono::duration_cast<int>(boost::chrono::milliseconds(3));
+}

Added: trunk/libs/chrono/test/duration/duration_cast_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/duration_cast_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <class ToDuration, class FromDuration>
+void
+test(const FromDuration& f, const ToDuration& d)
+{
+#if defined(BOOST_NO_DECLTYPE)
+ typedef BOOST_TYPEOF_TPL(boost::chrono::duration_cast<ToDuration>(f)) R;
+#else
+ typedef decltype(boost::chrono::duration_cast<ToDuration>(f)) R;
+#endif
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<R, ToDuration>::value), NOTHING, ());
+ BOOST_TEST(boost::chrono::duration_cast<ToDuration>(f) == d);
+}
+
+int main()
+{
+ test(boost::chrono::milliseconds(7265000), boost::chrono::hours(2));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::minutes(121));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::seconds(7265));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::milliseconds(7265000));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::microseconds(7265000000LL));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::nanoseconds(7265000000000LL));
+ test(boost::chrono::milliseconds(7265000),
+ boost::chrono::duration<double, boost::ratio<3600> >(7265./3600));
+ test(boost::chrono::duration<int, boost::ratio<2, 3> >(9),
+ boost::chrono::duration<int, boost::ratio<3, 5> >(10));
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/duration/duration_duration_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/duration_duration_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// If a program instantiates duration with a duration type for the template
+// argument Rep a diagnostic is required.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::duration<boost::chrono::milliseconds> D;
+ D d;
+}

Added: trunk/libs/chrono/test/duration/duration_values_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/duration_values_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <libs/chrono/test/rep.h>
+
+template <class D>
+void check_max()
+{
+ typedef typename D::rep Rep;
+ Rep max_rep = (boost::chrono::duration_values<Rep>::max)();
+ BOOST_TEST((D::max)().count() == max_rep);
+}
+
+template <class D>
+void check_min()
+{
+ typedef typename D::rep Rep;
+ Rep min_rep = (boost::chrono::duration_values<Rep>::min)();
+ BOOST_TEST((D::min)().count() == min_rep);
+}
+
+template <class D>
+void check_zero()
+{
+ typedef typename D::rep Rep;
+ Rep zero_rep = boost::chrono::duration_values<Rep>::zero();
+ BOOST_TEST(D::zero().count() == zero_rep);
+}
+
+
+int main()
+{
+ check_max<boost::chrono::duration<int> >();
+ check_max<boost::chrono::duration<Rep> >();
+ check_min<boost::chrono::duration<int> >();
+ check_min<boost::chrono::duration<Rep> >();
+ check_zero<boost::chrono::duration<int> >();
+ check_zero<boost::chrono::duration<Rep> >();
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/duration/nonmember/divide_rep2_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/nonmember/divide_rep2_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<Rep> d(Rep(15));
+ d = d / 5;
+}

Added: trunk/libs/chrono/test/duration/nonmember/modulus_rep2_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/nonmember/modulus_rep2_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<Rep> d(Rep(15));
+ d = d % 5;
+}

Added: trunk/libs/chrono/test/duration/nonmember/times_rep2_lhs_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/nonmember/times_rep2_lhs_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<Rep> d;
+ d = 5 * d;
+}

Added: trunk/libs/chrono/test/duration/nonmember/times_rep2_rhs_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/nonmember/times_rep2_rhs_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+
+#include "../../rep.h"
+
+void test()
+{
+ boost::chrono::duration<Rep> d;
+ d = d * 5;
+}

Added: trunk/libs/chrono/test/duration/positive_num_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/positive_num_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// Period::num must be positive, diagnostic required.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::duration<int, boost::ratio<5, -1> > D;
+ D d;
+}

Added: trunk/libs/chrono/test/duration/ratio_alias_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/ratio_alias_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// Period shall be a specialization of ratio, diagnostic required.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::duration<int,
+ boost::ratio_add<
+ boost::ratio<1,2>,
+ boost::ratio<1,3>
+ >
+ > D;
+ D d;
+}

Added: trunk/libs/chrono/test/duration/ratio_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/ratio_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// Period shall be a specialization of ratio, diagnostic required.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::duration<int, int > D;
+ D d;
+}

Added: trunk/libs/chrono/test/duration/typedefs_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/typedefs_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#include <limits>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <typename D, int ExpectedDigits, typename ExpectedPeriod>
+void check_duration()
+{
+ typedef typename D::rep Rep;
+ typedef typename D::period Period;
+ BOOST_CHRONO_STATIC_ASSERT(boost::is_signed<Rep>::value, NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT(boost::is_integral<Rep>::value, NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT(std::numeric_limits<Rep>::digits >= ExpectedDigits, NOTHING, ());
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<Period, ExpectedPeriod >::value), NOTHING, ());
+}
+
+void test()
+{
+ check_duration<boost::chrono::hours, 22, boost::ratio<3600> >();
+ check_duration<boost::chrono::minutes, 28, boost::ratio<60> >();
+ check_duration<boost::chrono::seconds, 34, boost::ratio<1> >();
+ check_duration<boost::chrono::milliseconds, 44, boost::milli >();
+ check_duration<boost::chrono::microseconds, 54, boost::micro >();
+ check_duration<boost::chrono::nanoseconds, 63, boost::nano >();
+}

Added: trunk/libs/chrono/test/duration/types_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/duration/types_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// duration
+// Test nested types
+
+// typedef Rep rep;
+// typedef Period period;
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+typedef boost::chrono::duration<long, boost::ratio<3, 2> > D;
+BOOST_CHRONO_STATIC_ASSERT((boost::is_same<D::rep, long>::value), NOTHING, ());
+BOOST_CHRONO_STATIC_ASSERT((boost::is_same<D::period, boost::ratio<3, 2> >::value), NOTHING, ());

Added: trunk/libs/chrono/test/intmax_c.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/intmax_c.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,19 @@
+// intmax_c.cpp --------------------------------------------------------------//
+
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/cstdint.hpp>
+
+#ifdef INTMAX_C
+#define BOOST_INTMAX_C(a) INTMAX_C(a)
+#else
+#define BOOST_INTMAX_C(a) a##LL
+#endif
+
+boost::intmax_t i = BOOST_INTMAX_C(1000000000);
+int main() {
+ return (i);
+}

Added: trunk/libs/chrono/test/rep.h
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/rep.h 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef REP_H
+#define REP_H
+
+class Rep
+{
+public:
+ int data_;
+ Rep() : data_(-1) {}
+ explicit Rep(int i) : data_(i) {}
+
+ bool operator==(int i) const {return data_ == i;}
+ bool operator==(const Rep& r) const {return data_ == r.data_;}
+
+ Rep& operator*=(Rep x) {data_ *= x.data_; return *this;}
+ Rep& operator/=(Rep x) {data_ /= x.data_; return *this;}
+};
+
+#endif // REP_H

Added: trunk/libs/chrono/test/run_timer_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/run_timer_test.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,226 @@
+// boost run_timer_test.cpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2006, 2008
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#include <boost/chrono/process_times.hpp>
+#include <boost/chrono/timer.hpp>
+#include <cstdlib> // for atol()
+#include <iostream>
+#include <sstream>
+#include <locale>
+#include <ctime>
+#include <cmath> // for sqrt(), used to burn time
+
+using boost::chrono::run_timer;
+using boost::system::error_code;
+
+#include <boost/detail/lightweight_test.hpp>
+
+//#define BOOST_TEST(expr) if (!(expr)) std::cout << "*****ERROR*****\n"
+
+#define CHECK_REPORT(Timer,String_Stream,R,U,S,Expected_String) \
+ check_report(Timer, String_Stream, R, U, S, Expected_String, __LINE__)
+
+
+namespace
+{
+ typedef boost::chrono::nanoseconds ns;
+
+ bool check_report( run_timer & tmr, std::stringstream & ss,
+ run_timer::duration r, run_timer::duration u, run_timer::duration s,
+ const std::string & expected, int line )
+ {
+ tmr.test_report(r,u,s);
+ bool result(true);
+ if ( ss.str() != expected )
+ {
+ std::cout << "run_timer_test.cpp(" << line << ") : error: actual output \""
+ << ss.str() << "\" != expected \"" << expected << "\"\n";
+ result = false;
+ }
+ return result;
+ }
+
+ void run_timer_constructor_overload_test()
+ {
+ // exercise each supported combination of constructor arguments
+
+ std::ostream & os = std::cout;
+ const int pl = 9;
+ boost::system::error_code ec;
+
+ run_timer t1;
+ run_timer t2( os );
+ run_timer t3( ec );
+ run_timer t4( os, ec );
+ run_timer t5( pl );
+ run_timer t6( os, pl );
+ run_timer t7( pl, ec );
+ run_timer t8( os, pl, ec );
+ run_timer t9( "t9, default places, r %r, c %c, p %p, u %u, s %s\n" );
+ run_timer t10( os, "t10, default places, r %r, c %c, p %p, u %u, s %s\n" );
+ run_timer t11( "t11, default places, r %r, c %c, p %p, u %u, s %s\n", ec );
+ run_timer t12( os, "t12, default places, r %r, c %c, p %p, u %u, s %s\n", ec );
+ run_timer t13( pl, "t13, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
+ run_timer t14( "t14, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl );
+ run_timer t15( os, pl, "t15, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
+ run_timer t16( os, "t16, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl );
+ run_timer t17( pl, "t17, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec );
+ run_timer t18( "t18, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl, ec );
+ run_timer t19( os, pl, "t19, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec );
+ run_timer t20( os, "t20, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl, ec );
+
+ std::cout << "Burn some time so run_timers have something to report...";
+ boost::chrono::timer<boost::chrono::high_resolution_clock> t;
+ while ( t.elapsed() < boost::chrono::seconds(1) ) {}
+ std::cout << "\n";
+ std::cout << run_timer::default_places() << " default places\n";
+ std::cout << pl << " explicitly coded places\n";
+ }
+
+ // accuracy test
+ void accuracy_test( int argc, char * argv[] )
+ {
+ long timeout_in_secs = 1;
+ if ( argc > 1 ) timeout_in_secs = std::atol( argv[1] );
+ std::cout << "accuracy test for " << timeout_in_secs << " second(s)...";
+
+ std::clock_t timeout_in_clock_t = std::clock();
+ timeout_in_clock_t += (timeout_in_secs * CLOCKS_PER_SEC);
+
+ boost::chrono::system_timer sys;
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ boost::chrono::monotonic_timer mono;
+#endif
+ boost::chrono::high_resolution_timer hires;
+ boost::chrono::process_timer process;
+
+ std::clock_t now;
+ do
+ {
+ now = std::clock();
+ } while ( now < timeout_in_clock_t );
+
+ boost::chrono::system_timer::duration sys_dur = sys.elapsed();
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ boost::chrono::monotonic_timer::duration mono_dur = mono.elapsed();
+#endif
+ boost::chrono::high_resolution_timer::duration hires_dur = hires.elapsed();
+ boost::chrono::process_times times;
+ process.elapsed( times );
+
+ std::cout << std::endl;
+
+ ns timeout_in_nanoseconds( static_cast<long long>(timeout_in_secs) * 1000000000LL );
+
+ // Allow 20% leeway. Particularly on Linux, there seems to be a large discrepancy
+ // between std::clock() and higher resolution clocks.
+ ns maximum_delta ( static_cast<long long>(timeout_in_nanoseconds.count() * 0.20 ) );
+
+ std::cout << timeout_in_nanoseconds.count() << " timeout_in_nanoseconds\n";
+ std::cout << maximum_delta.count() << " maximum_delta\n";
+
+ std::cout << sys_dur.count() << " sys_dur\n";
+
+ BOOST_TEST( sys_dur > timeout_in_nanoseconds - maximum_delta
+ && sys_dur < timeout_in_nanoseconds + maximum_delta );
+
+#ifdef BOOST_CHRONO_HAS_CLOCK_MONOTONIC
+ std::cout << mono_dur.count() << " mono_dur\n";
+
+ BOOST_TEST( mono_dur > timeout_in_nanoseconds - maximum_delta
+ && mono_dur < timeout_in_nanoseconds + maximum_delta );
+#endif
+
+ std::cout << hires_dur.count() << " hires_dur\n";
+
+ BOOST_TEST( hires_dur > timeout_in_nanoseconds - maximum_delta
+ && hires_dur < timeout_in_nanoseconds + maximum_delta );
+
+ std::cout << times.real.count() << " times.real\n";
+
+ BOOST_TEST( times.real > timeout_in_nanoseconds - maximum_delta
+ && times.real < timeout_in_nanoseconds + maximum_delta );
+ }
+
+ // report test
+
+ void report_test()
+ {
+ {
+ std::stringstream ss;
+ run_timer t(ss);
+ BOOST_TEST( CHECK_REPORT(t, ss, ns(0), ns(0), ns(0),
+ "\nreal 0.000s, cpu 0.000s (0.0%), user 0.000s, system 0.000s\n" ) );
+ }
+
+ {
+ std::stringstream ss;
+ run_timer t(ss);
+ BOOST_TEST( CHECK_REPORT(t, ss, ns(3000000000LL), ns(2000000000LL), ns(1000000000LL),
+ "\nreal 3.000s, cpu 3.000s (100.0%), user 2.000s, system 1.000s\n" ) );
+ }
+
+ {
+ std::stringstream ss;
+ run_timer t( ss, "9 places: r %r, c %c, p %p, u %u, s %s", 9 );
+ BOOST_TEST( CHECK_REPORT(t, ss, ns(3000000003LL), ns(2000000002LL), ns(1000000001LL),
+ "9 places: "
+ "r 3.000000003, c 3.000000003, p 100.0, u 2.000000002, s 1.000000001" ) );
+ }
+ }
+
+ // process_timer_test
+
+ void process_timer_test()
+ {
+ std::cout << "process_timer_test..." << std::flush;
+
+ boost::chrono::process_timer t;
+ double res=0; // avoids optimization
+ for (long i = 0; i < 10000000L; ++i)
+ {
+ res+=std::sqrt( static_cast<double>(i) ); // avoids optimization
+ }
+
+ boost::chrono::process_times times;
+ times.real = times.system = times.user = ns(0);
+
+ BOOST_TEST( times.real == ns(0) );
+ BOOST_TEST( times.user == ns(0) );
+ BOOST_TEST( times.system == ns(0) );
+
+ t.elapsed( times );
+ std::cout << "\n";
+
+ std::cout << times.real.count() << " times.real\n";
+ std::cout << times.user.count() << " times.user\n";
+ std::cout << times.system.count() << " times.system\n";
+ std::cout << (times.user+times.system).count() << " times.user+system\n";
+ BOOST_TEST( times.real > ns(1) );
+
+ BOOST_TEST( times.user+times.system > ns(1) );
+
+ std::cout << "complete " << res << std::endl;
+ }
+}
+
+int main( int argc, char * argv[] )
+{
+ std::locale loc( "" ); // test with appropriate locale
+ std::cout.imbue( loc );
+
+ accuracy_test( argc, argv );
+ run_timer_constructor_overload_test();
+ process_timer_test();
+ report_test();
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/chrono/test/time_point/arithmetic_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/arithmetic_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ boost::chrono::time_point<Clock, Duration> t(Duration(3));
+ t += Duration(2);
+ BOOST_TEST(t.time_since_epoch() == Duration(5));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ boost::chrono::time_point<Clock, Duration> t(Duration(3));
+ t -= Duration(2);
+ BOOST_TEST(t.time_since_epoch() == Duration(1));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ boost::chrono::time_point<Clock, Duration1> t1(Duration1(3));
+ boost::chrono::time_point<Clock, Duration2> t2 = t1 - Duration2(5);
+ BOOST_TEST(t2.time_since_epoch() == Duration2(2995));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ boost::chrono::time_point<Clock, Duration1> t1(Duration1(3));
+ boost::chrono::time_point<Clock, Duration2> t2(Duration2(5));
+ BOOST_TEST((t1 - t2) == Duration2(2995));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ boost::chrono::time_point<Clock, Duration1> t1(Duration1(3));
+ boost::chrono::time_point<Clock, Duration2> t2 = t1 + Duration2(5);
+ BOOST_TEST(t2.time_since_epoch() == Duration2(3005));
+ t2 = Duration2(6) + t1;
+ BOOST_TEST(t2.time_since_epoch() == Duration2(3006));
+ }
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/time_point/comparisons/equal_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/comparisons/equal_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// time_points with different clocks should not compare
+
+#include <boost/chrono.hpp>
+
+#include "../../clock.h"
+
+void test()
+{
+ typedef boost::chrono::system_clock Clock1;
+ typedef Clock Clock2;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ typedef boost::chrono::time_point<Clock1, Duration1> T1;
+ typedef boost::chrono::time_point<Clock2, Duration2> T2;
+
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3000));
+ t1 == t2;
+}

Added: trunk/libs/chrono/test/time_point/comparisons/less_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/comparisons/less_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// time_points with different clocks should not compare
+
+#include <boost/chrono.hpp>
+
+#include "../../clock.h"
+
+void test()
+{
+ typedef boost::chrono::system_clock Clock1;
+ typedef Clock Clock2;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ typedef boost::chrono::time_point<Clock1, Duration1> T1;
+ typedef boost::chrono::time_point<Clock2, Duration2> T2;
+
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3000));
+ t1 < t2;
+}

Added: trunk/libs/chrono/test/time_point/comparisons_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/comparisons_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ typedef boost::chrono::time_point<Clock, Duration1> T1;
+ typedef boost::chrono::time_point<Clock, Duration2> T2;
+
+ {
+ T1 t1(Duration1(3));
+ T1 t2(Duration1(3));
+ BOOST_TEST( (t1 == t2));
+ BOOST_TEST(!(t1 != t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T1 t2(Duration1(4));
+ BOOST_TEST(!(t1 == t2));
+ BOOST_TEST( (t1 != t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3000));
+ BOOST_TEST( (t1 == t2));
+ BOOST_TEST(!(t1 != t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3001));
+ BOOST_TEST(!(t1 == t2));
+ BOOST_TEST( (t1 != t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T1 t2(Duration1(3));
+ BOOST_TEST(!(t1 < t2));
+ BOOST_TEST(!(t1 > t2));
+ BOOST_TEST( (t1 <= t2));
+ BOOST_TEST( (t1 >= t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T1 t2(Duration1(4));
+ BOOST_TEST( (t1 < t2));
+ BOOST_TEST(!(t1 > t2));
+ BOOST_TEST( (t1 <= t2));
+ BOOST_TEST(!(t1 >= t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3000));
+ BOOST_TEST(!(t1 < t2));
+ BOOST_TEST(!(t1 > t2));
+ BOOST_TEST( (t1 <= t2));
+ BOOST_TEST( (t1 >= t2));
+ }
+ {
+ T1 t1(Duration1(3));
+ T2 t2(Duration2(3001));
+ BOOST_TEST( (t1 < t2));
+ BOOST_TEST(!(t1 > t2));
+ BOOST_TEST( (t1 <= t2));
+ BOOST_TEST(!(t1 >= t2));
+ }
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/time_point/cons/implicit_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/cons/implicit_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// test for explicit
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ boost::chrono::time_point<Clock, Duration> t = Duration(3);
+}

Added: trunk/libs/chrono/test/time_point/cons/non_implicit_convertible_duration_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/cons/non_implicit_convertible_duration_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Duration2 shall be implicitly convertible to duration.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration1;
+ typedef boost::chrono::microseconds Duration2;
+ {
+ boost::chrono::time_point<Clock, Duration2> t2(Duration2(3));
+ boost::chrono::time_point<Clock, Duration1> t1 = t2;
+ }
+}

Added: trunk/libs/chrono/test/time_point/constructor_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/constructor_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <libs/chrono/test/rep.h>
+
+int main()
+{
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::microseconds Duration1;
+ typedef boost::chrono::milliseconds Duration2;
+ boost::chrono::time_point<Clock, Duration2> t2(Duration2(3));
+ boost::chrono::time_point<Clock, Duration1> t1 = t2;
+ BOOST_TEST(t1.time_since_epoch() == Duration1(3000));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::duration<Rep, boost::milli> Duration;
+ boost::chrono::time_point<Clock, Duration> t;
+ BOOST_TEST(t.time_since_epoch() == Duration::zero());
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ boost::chrono::time_point<Clock, Duration> t(Duration(3));
+ BOOST_TEST(t.time_since_epoch() == Duration(3));
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ boost::chrono::time_point<Clock, Duration> t(boost::chrono::seconds(3));
+ BOOST_TEST(t.time_since_epoch() == Duration(3000));
+ }
+
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/time_point/default_duration.pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/default_duration.pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+void test()
+{
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<boost::chrono::system_clock::duration,
+ boost::chrono::time_point<boost::chrono::system_clock>::duration>::value), NOTHING, ());
+}

Added: trunk/libs/chrono/test/time_point/default_duration_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/default_duration_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+void test()
+{
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<boost::chrono::system_clock::duration,
+ boost::chrono::time_point<boost::chrono::system_clock>::duration>::value), NOTHING, ());
+}

Added: trunk/libs/chrono/test/time_point/duration.fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/duration.fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Duration shall be an instance of duration.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::time_point<boost::chrono::system_clock, int> T;
+ T t;
+}

Added: trunk/libs/chrono/test/time_point/min_max_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/min_max_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds Duration;
+ typedef boost::chrono::time_point<Clock, Duration> TP;
+
+ BOOST_TEST((TP::min)() == TP((Duration::min)()));
+ BOOST_TEST((TP::max)() == TP((Duration::max)()));
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/time_point/not_duration_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/not_duration_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Duration shall be an instance of duration.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::time_point<boost::chrono::system_clock, int> T;
+ T t;
+}

Added: trunk/libs/chrono/test/time_point/time_point_cast_int_fail.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/time_point_cast_int_fail.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// ToDuration shall be an instantiation of duration.
+
+#include <boost/chrono.hpp>
+
+void test()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::time_point<Clock, boost::chrono::milliseconds> FromTimePoint;
+ typedef boost::chrono::time_point<Clock, boost::chrono::minutes> ToTimePoint;
+ boost::chrono::time_point_cast<ToTimePoint>(FromTimePoint(boost::chrono::milliseconds(3)));
+}

Added: trunk/libs/chrono/test/time_point/time_point_cast_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/time_point/time_point_cast_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <class FromDuration, class ToDuration>
+void
+test(const FromDuration& df, const ToDuration& d)
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::time_point<Clock, FromDuration> FromTimePoint;
+ typedef boost::chrono::time_point<Clock, ToDuration> ToTimePoint;
+ FromTimePoint f(df);
+ ToTimePoint t(d);
+#if defined(BOOST_NO_DECLTYPE)
+ typedef BOOST_TYPEOF_TPL(boost::chrono::time_point_cast<ToDuration>(f)) R;
+#else
+ typedef decltype(boost::chrono::time_point_cast<ToDuration>(f)) R;
+#endif
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<R, ToTimePoint>::value), NOTHING, ());
+ BOOST_TEST(boost::chrono::time_point_cast<ToDuration>(f) == t);
+}
+
+int main()
+{
+ test(boost::chrono::milliseconds(7265000), boost::chrono::hours(2));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::minutes(121));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::seconds(7265));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::milliseconds(7265000));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::microseconds(7265000000LL));
+ test(boost::chrono::milliseconds(7265000), boost::chrono::nanoseconds(7265000000000LL));
+ test(boost::chrono::milliseconds(7265000),
+ boost::chrono::duration<double, boost::ratio<3600> >(7265./3600));
+ test(boost::chrono::duration<int, boost::ratio<2, 3> >(9),
+ boost::chrono::duration<int, boost::ratio<3, 5> >(10));
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/traits/common_type_duration_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/traits/common_type_duration_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <class D1, class D2, class De>
+void
+test()
+{
+ typedef typename boost::common_type<D1, D2>::type Dc;
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<Dc, De>::value), NOTHING, ());
+}
+
+void testall()
+{
+ test<boost::chrono::duration<int, boost::ratio<1, 100> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> > >();
+ test<boost::chrono::duration<long, boost::ratio<1, 100> >,
+ boost::chrono::duration<int, boost::ratio<1, 1000> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> > >();
+ test<boost::chrono::duration<char, boost::ratio<1, 30> >,
+ boost::chrono::duration<short, boost::ratio<1, 1000> >,
+ boost::chrono::duration<int, boost::ratio<1, 3000> > >();
+ test<boost::chrono::duration<double, boost::ratio<21, 1> >,
+ boost::chrono::duration<short, boost::ratio<15, 1> >,
+ boost::chrono::duration<double, boost::ratio<3, 1> > >();
+}

Added: trunk/libs/chrono/test/traits/common_type_time_point_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/traits/common_type_time_point_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <class D1, class D2, class De>
+void
+test()
+{
+ typedef boost::chrono::system_clock C;
+ typedef boost::chrono::time_point<C, D1> T1;
+ typedef boost::chrono::time_point<C, D2> T2;
+ typedef boost::chrono::time_point<C, De> Te;
+ typedef typename boost::common_type<T1, T2>::type Tc;
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_same<Tc, Te>::value), NOTHING, ());
+}
+
+void testall()
+{
+ test<boost::chrono::duration<int, boost::ratio<1, 100> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> > >();
+ test<boost::chrono::duration<long, boost::ratio<1, 100> >,
+ boost::chrono::duration<int, boost::ratio<1, 1000> >,
+ boost::chrono::duration<long, boost::ratio<1, 1000> > >();
+ test<boost::chrono::duration<char, boost::ratio<1, 30> >,
+ boost::chrono::duration<short, boost::ratio<1, 1000> >,
+ boost::chrono::duration<int, boost::ratio<1, 3000> > >();
+ test<boost::chrono::duration<double, boost::ratio<21, 1> >,
+ boost::chrono::duration<short, boost::ratio<15, 1> >,
+ boost::chrono::duration<double, boost::ratio<3, 1> > >();
+}

Added: trunk/libs/chrono/test/traits/duration_values_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/traits/duration_values_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+#include <limits>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <libs/chrono/test/rep.h>
+
+int main()
+{
+ BOOST_TEST((boost::chrono::duration_values<int>::min)() ==
+ (std::numeric_limits<int>::min)());
+ BOOST_TEST((boost::chrono::duration_values<double>::min)() ==
+ -(std::numeric_limits<double>::max)());
+ BOOST_TEST((boost::chrono::duration_values<Rep>::min)() ==
+ (std::numeric_limits<Rep>::min)());
+
+ BOOST_TEST((boost::chrono::duration_values<int>::max)() ==
+ (std::numeric_limits<int>::max)());
+ BOOST_TEST((boost::chrono::duration_values<double>::max)() ==
+ (std::numeric_limits<double>::max)());
+ BOOST_TEST((boost::chrono::duration_values<Rep>::max)() ==
+ (std::numeric_limits<Rep>::max)());
+
+ BOOST_TEST(boost::chrono::duration_values<int>::zero() == 0);
+ BOOST_TEST(boost::chrono::duration_values<Rep>::zero() == 0);
+
+ return boost::report_errors();
+}

Added: trunk/libs/chrono/test/traits/treat_as_floating_point_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/traits/treat_as_floating_point_pass.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+// Copyright 2010 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+template <class T>
+void
+test()
+{
+ BOOST_CHRONO_STATIC_ASSERT((boost::is_base_of<boost::is_floating_point<T>,
+ boost::chrono::treat_as_floating_point<T> >::value), NOTHING, ());
+}
+
+struct A {};
+
+void testall()
+{
+ test<int>();
+ test<unsigned>();
+ test<char>();
+ test<bool>();
+ test<float>();
+ test<double>();
+ test<long double>();
+ test<A>();
+}

Added: trunk/libs/chrono/test/win32_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/chrono/test/win32_test.cpp 2011-01-05 19:47:42 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,106 @@
+// boost win32_test.cpp -----------------------------------------------------//
+
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org/libs/chrono for documentation.
+#include <boost/chrono/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined(BOOST_CHRONO_WINDOWS_API)
+
+#include <boost/chrono/detail/static_assert.hpp>
+#if !defined(BOOST_NO_STATIC_ASSERT)
+#define NOTHING ""
+#endif
+
+#include <boost/detail/win/basic_types.hpp>
+#include <boost/detail/win/time.hpp>
+#include <windows.h>
+#include <boost/type_traits.hpp>
+#include <boost/typeof/typeof.hpp>
+
+void test() {
+ {
+ boost::detail::win32::LARGE_INTEGER_ a;
+ LARGE_INTEGER b;
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::LARGE_INTEGER_)==sizeof(LARGE_INTEGER)
+ ), NOTHING, (boost::detail::win32::LARGE_INTEGER_, LARGE_INTEGER));
+ BOOST_TEST((
+ sizeof(a.QuadPart)==sizeof(b.QuadPart)
+ ));
+ BOOST_CHRONO_STATIC_ASSERT((
+ offsetof(boost::detail::win32::LARGE_INTEGER_, QuadPart)==offsetof(LARGE_INTEGER, QuadPart)
+ ), NOTHING, (boost::detail::win32::LARGE_INTEGER_, LARGE_INTEGER));
+ }
+// BOOST_CHRONO_STATIC_ASSERT((
+// boost::is_same<
+// BOOST_TYPEOF(boost::detail::win32::LARGE_INTEGER_::QuadPart),
+// BOOST_TYPEOF(LARGE_INTEGER::QuadPart)
+// >::value
+// ), NOTHING, (boost::detail::win32::LARGE_INTEGER_, LARGE_INTEGER));
+
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::BOOL_)==sizeof(BOOL)
+ ), NOTHING, (boost::detail::win32::BOOL_, BOOL));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::DWORD_)==sizeof(DWORD)
+ ), NOTHING, (boost::detail::win32::DWORD_, DWORD));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::HANDLE_)==sizeof(HANDLE)
+ ), NOTHING, (boost::detail::win32::HANDLE_, HANDLE));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::LONG_)==sizeof(LONG)
+ ), NOTHING, (boost::detail::win32::LONG_, LONG));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::LONGLONG_)==sizeof(LONGLONG)
+ ), NOTHING, (boost::detail::win32::LONGLONG_, LONGLONG));
+ BOOST_CHRONO_STATIC_ASSERT((
+ boost::is_same<boost::detail::win32::LONGLONG_,LONGLONG>::value
+ ), NOTHING, (boost::detail::win32::LONGLONG_, LONGLONG));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::PLARGE_INTEGER_)==sizeof(PLARGE_INTEGER)
+ ), NOTHING, (boost::detail::win32::PLARGE_INTEGER_, PLARGE_INTEGER));
+ {
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::FILETIME_)==sizeof(FILETIME)
+ ), NOTHING, (boost::detail::win32::FILETIME_, FILETIME));
+ BOOST_CHRONO_STATIC_ASSERT((
+ sizeof(boost::detail::win32::PFILETIME_)==sizeof(PFILETIME)
+ ), NOTHING, (boost::detail::win32::PFILETIME_, PFILETIME));
+
+ boost::detail::win32::FILETIME_ a;
+ FILETIME b;
+ BOOST_TEST((
+ sizeof(a.dwLowDateTime)==sizeof(b.dwLowDateTime)
+ ));
+ BOOST_TEST((
+ sizeof(a.dwHighDateTime)==sizeof(b.dwHighDateTime)
+ ));
+ BOOST_CHRONO_STATIC_ASSERT((
+ offsetof(boost::detail::win32::FILETIME_, dwLowDateTime)==offsetof(FILETIME, dwLowDateTime)
+ ), NOTHING, (boost::detail::win32::FILETIME_, FILETIME));
+ BOOST_CHRONO_STATIC_ASSERT((
+ offsetof(boost::detail::win32::FILETIME_, dwHighDateTime)==offsetof(FILETIME, dwHighDateTime)
+ ), NOTHING, (boost::detail::win32::FILETIME_, FILETIME));
+
+ }
+
+// BOOST_CHRONO_STATIC_ASSERT((
+// GetLastError==boost::detail::win32::::GetLastError
+// ), NOTHING, ());
+
+}
+#else
+void test() {
+}
+#endif
+int main( )
+{
+ test();
+
+ return boost::report_errors();
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk