$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r75334 - in trunk: boost/chrono boost/chrono/io boost/chrono/io_v1 libs/chrono/test/io
From: vicente.botet_at_[hidden]
Date: 2011-11-05 23:07:45
Author: viboes
Date: 2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
New Revision: 75334
URL: http://svn.boost.org/trac/boost/changeset/75334
Log:
Chrono: Added time_point units, get and put facets and adapt time_point I/O
Added:
   trunk/boost/chrono/io/time_point_get.hpp   (contents, props changed)
   trunk/boost/chrono/io/time_point_put.hpp   (contents, props changed)
   trunk/boost/chrono/io/time_point_units.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/chrono/config.hpp                   |     5 -                                       
   trunk/boost/chrono/io/time_point_io.hpp         |    96 ++++++++++++++++++++++++++++--          
   trunk/boost/chrono/io_v1/chrono_io.hpp          |     3                                         
   trunk/libs/chrono/test/io/time_point_input.cpp  |   123 ++++++++++++++++++++------------------- 
   trunk/libs/chrono/test/io/time_point_output.cpp |    74 ++++++++++++------------                
   5 files changed, 190 insertions(+), 111 deletions(-)
Modified: trunk/boost/chrono/config.hpp
==============================================================================
--- trunk/boost/chrono/config.hpp	(original)
+++ trunk/boost/chrono/config.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -91,10 +91,7 @@
 // deprecated i/o
 //#define BOOST_CHRONO_DONT_PROVIDE_DEPRECATED_IO_V1
 
-#define BOOST_CHRONO_IO_V1_DONT_PROVIDE_DEPRECATED
-#define BOOST_CHRONO_IO_USE_XALLOC
-#define BOOST_CHRONO_USES_DURATION_PUT
-#define BOOST_CHRONO_USES_DURATION_GET
+// this doesn't works yet in compilers other than clang-3.0
 //#define BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
 
 // unicode support  ------------------------------//
Added: trunk/boost/chrono/io/time_point_get.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/chrono/io/time_point_get.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -0,0 +1,310 @@
+//
+//  (C) Copyright Howard Hinnant
+//  (C) Copyright 2011 Vicente J. Botet Escriba
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_TIME_POINT_GET_HPP
+#define BOOST_CHRONO_IO_TIME_POINT_GET_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/chrono/io/time_point_units.hpp>
+#include <boost/chrono/io/duration_get.hpp>
+#include <boost/assert.hpp>
+#include <locale>
+#include <string>
+
+/**
+ * Duration formatting facet for input.
+ */
+namespace boost
+{
+  namespace chrono
+  {
+
+    /**
+     * @c time_point_get is used to parse a character sequence, extracting
+     * components of a duration into a class duration.
+     * Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
+     * If the sequence being parsed matches the correct format, the
+     * corresponding member of the class duration argument are set to the
+     * value used to produce the sequence;
+     * otherwise either an error is reported or unspecified values are assigned.
+     * In other words, user confirmation is required for reliable parsing of
+     * user-entered durations, but machine-generated formats can be parsed
+     * reliably. This allows parsers to be aggressive about interpreting user
+     * variations on standard formats.
+     *
+     * If the end iterator is reached during parsing of the get() member
+     * function, the member sets std::ios_base::eofbit in err.
+     */
+    template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
+    class time_point_get: public std::locale::facet
+    {
+    public:
+      /**
+       * Type of character the facet is instantiated on.
+       */
+      typedef CharT char_type;
+      /**
+       * Type of iterator used to scan the character buffer.
+       */
+      typedef InputIterator iter_type;
+
+      /**
+       * Construct a @c time_point_get facet.
+       * @param refs
+       * @Effects Construct a @c time_point_get facet.
+       * If the @c refs argument is @c 0 then destruction of the object is
+       * delegated to the @c locale, or locales, containing it. This allows
+       * the user to ignore lifetime management issues. On the other had,
+       * if @c refs is @c 1 then the object must be explicitly deleted;
+       * the @c locale will not do so. In this case, the object can be
+       * maintained across the lifetime of multiple locales.
+       */
+
+      explicit time_point_get(size_t refs = 0) :
+        std::locale::facet(refs)
+      {
+      }
+
+      /**
+       * @param s start input stream iterator
+       * @param end end input stream iterator
+       * @param ios a reference to a ios_base
+       * @param err the ios_base state
+       * @param d the duration
+       * @param pattern begin of the formatting pattern
+       * @param pat_end end of the formatting pattern
+       *
+       * Requires: [pattern,pat_end) shall be a valid range.
+       *
+       * Effects: The function starts by evaluating err = std::ios_base::goodbit.
+       * It then enters a loop, reading zero or more characters from s at
+       * each iteration. Unless otherwise specified below, the loop
+       * terminates when the first of the following conditions holds:
+       * - The expression pattern == pat_end evaluates to true.
+       * - The expression err == std::ios_base::goodbit evaluates to false.
+       * - The expression s == end evaluates to true, in which case the
+       * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
+       * - The next element of pattern is equal to Õ%Õ, followed by a conversion
+       * specifier character, format.
+       * If the number of elements in the range [pattern,pat_end) is not
+       * sufficient to unambiguously determine whether the conversion
+       * specification is complete and valid, the function evaluates
+       * err = std::ios_base::failbit. Otherwise, the function evaluates
+       * s = do_get(s, end, ios, err, d). If err == std::ios_base::goodbit holds after
+       * the evaluation of the expression, the function increments pattern to
+       * point just past the end of the conversion specification and continues
+       * looping.
+       * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
+       * which case the function first increments pattern until
+       * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
+       * then advances s until s == end || !isspace(*s, ios.getloc()) is true,
+       * and finally resumes looping.
+       * - The next character read from s matches the element pointed to by
+       * pattern in a case-insensitive comparison, in which case the function
+       * evaluates ++pattern, ++s and continues looping. Otherwise, the function
+       * evaluates err = std::ios_base::failbit.
+       *
+       * Returns: s
+       */
+      template <class Clock, class Duration>
+      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+          time_point<Clock, Duration> &tp, const char_type *pattern, const char_type *pat_end) const
+      {
+        std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+
+        Duration d;
+        bool duration_found=false, epoch_found=false, loc_found=false;
+
+        const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+        err = std::ios_base::goodbit;
+        while (pattern != pat_end && err == std::ios_base::goodbit)
+        {
+          std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+            if (s == end)
+            {
+                err |= std::ios_base::eofbit;
+                break;
+            }
+            if (ct.narrow(*pattern, 0) == '%')
+            {
+                if (++pattern == pat_end)
+                {
+                    err |= std::ios_base::failbit;
+                    return s;
+                }
+                char cmd = ct.narrow(*pattern, 0);
+                switch (cmd)
+                {
+                case 'd':
+                {
+                  if (duration_found || loc_found) {
+                    err |= std::ios_base::failbit;
+                    return s;
+                  }
+                  duration_found=true;
+                  s = get_duration(s, end, ios, err,  d);
+                  std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+                  if ( err & (std::ios_base::badbit |std::ios_base::failbit) )
+                  {
+                    return s;
+                  }
+                  break;
+                }
+                case 'e':
+                {
+                  if (epoch_found || loc_found) {
+                    err |= std::ios_base::failbit;
+                    return s;
+                  }
+                  epoch_found=true;
+                  s = get_epoch<Clock>(s, end, ios, err);
+                  std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+                  if ( err & (std::ios_base::badbit |std::ios_base::failbit) )
+                  {
+                    return s;
+                  }
+                  break;
+                }
+                case 'x':
+                {
+                  if (duration_found || epoch_found || loc_found) {
+                    err |= std::ios_base::failbit;
+                    return s;
+                  }
+                  loc_found=true;
+                  std::basic_string<CharT> pat = time_point_units<CharT>::imbue_if_has_not(ios).get_pattern();
+                  if (pattern+1 != pat_end)
+                  pat.append(pattern+1, pat_end);
+                  pattern = pat.data();
+                  pat_end = pattern + pat.size();
+                  break;
+                }
+                default:
+                  BOOST_ASSERT(false && "Boost::Chrono internal error.");
+                  break;
+                }
+
+                ++pattern;
+            }
+            else if (ct.is(std::ctype_base::space, *pattern))
+            {
+                for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
+                    ;
+                for (        ;    s != end    && ct.is(std::ctype_base::space, *s);    ++s)
+                    ;
+            }
+            else if (ct.toupper(*s) == ct.toupper(*pattern))
+            {
+                ++s;
+                ++pattern;
+            }
+            else {
+                err |= std::ios_base::failbit;
+            }
+        }
+
+        // Success!  Store it.
+        tp = time_point<Clock, Duration>(d);
+        std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+
+        return s;
+      }
+
+      /**
+       *
+       * @param s an input stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @Effects imbue in @c ios the @c time_point_units_default facet if not already present.
+       * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+       * @code
+       *   return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
+       * @codeend
+       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+       */
+      template <class Clock, class Duration>
+      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+          time_point<Clock, Duration> &tp) const
+      {
+        std::basic_string < CharT > str = time_point_units<CharT>::imbue_if_has_not(ios).get_pattern();
+        return get(s, end, ios, err, tp, str.data(), str.data() + str.size());
+      }
+
+      /**
+       *
+       * @param s an input stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+       */
+      template <typename Rep, typename Period>
+      iter_type get_duration(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, duration<Rep, Period>& d) const
+      {
+        if (!std::has_facet<duration_get<CharT> >(ios.getloc()))
+        {
+          ios.imbue(std::locale(ios.getloc(), new duration_get<CharT>()));
+        }
+        return std::use_facet<duration_get<CharT> >(ios.getloc())
+        .get(s, end, ios, err, d);
+      }
+
+      /**
+       *
+       * @param s an output stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @param pattern
+       * @Effects Calls do_put_unit(s, ios, d).
+       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+       */
+      template <class Clock>
+      iter_type get_epoch(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err) const
+      {
+        time_point_units<CharT> const &facet = time_point_units<CharT>::imbue_if_has_not(is);
+
+        const std::basic_string<CharT> units = facet.get_epoch<Clock>();
+        err = std::ios_base::goodbit;
+        std::ptrdiff_t k =
+            chrono_detail::scan_keyword(i, e, &units, &units + 1,
+            //~ std::use_facet<std::ctype<CharT> >(ios.getloc()),
+            err) - &units;
+        std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+        if (k == 1)
+        {
+          err |= std::ios_base::failbit;
+          return i;
+        }
+        std::cerr << __FILE__ <<":"<< __LINE__ <<  " err "<< err << std::endl;
+        return i;
+      }
+
+      /**
+       * Unique identifier for this type of facet.
+       */
+      static std::locale::id id;
+
+      /**
+       * @Effects Destroy the facet
+       */
+      ~time_point_get()
+      {
+      }
+    };
+
+    /**
+     * Unique identifier for this type of facet.
+     */
+    template <class CharT, class InputIterator>
+    std::locale::id time_point_get<CharT, InputIterator>::id;
+
+  } // chrono
+}
+// boost
+
+#endif  // BOOST_CHRONO_CHRONO_IO_HPP
Modified: trunk/boost/chrono/io/time_point_io.hpp
==============================================================================
--- trunk/boost/chrono/io/time_point_io.hpp	(original)
+++ trunk/boost/chrono/io/time_point_io.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -1,4 +1,4 @@
-//  chrono_io
+//  boost/chrono/io/time_point_io.hpp
 //
 //  (C) Copyright Howard Hinnant
 //  (C) Copyright 2010-2011 Vicente J. Botet Escriba
@@ -12,7 +12,8 @@
 #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
 #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
 
-#include <boost/chrono/io/translate.hpp>
+#include <boost/chrono/io/time_point_put.hpp>
+#include <boost/chrono/io/time_point_get.hpp>
 #include <boost/chrono/io/duration_io.hpp>
 #include <boost/chrono/io/ios_base_state.hpp>
 #include <boost/chrono/io/utility/manip_base.hpp>
@@ -48,8 +49,7 @@
          * Change the timezone_type and time format ios state;
          */
         template <typename out_stream>
-        void operator()(out_stream &ios) const
-        //void operator()(std::ios_base &ios) const
+        void operator()(std::ios_base &ios) const
         {
           set_time_fmt<CharT>(ios, fmt_);
           set_timezone(ios, tz_);
@@ -217,8 +217,55 @@
     operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<Clock,
         Duration>& tp)
     {
-      return os << tp.time_since_epoch() << epoch_translate(clock_string<Clock,
-          CharT>::since());
+
+#if 0
+      return os << tp.time_since_epoch() << clock_string<Clock,
+          CharT>::since();
+#else
+        typedef std::basic_string<CharT, Traits> string_type;
+        bool failed = false;
+        try
+        {
+          std::ios_base::iostate err = std::ios_base::goodbit;
+          try
+          {
+            typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
+            if (opfx)
+            {
+              if (!std::has_facet<time_point_put<CharT> >(os.getloc()))
+              {
+                os.imbue(std::locale(os.getloc(), new time_point_put<CharT> ()));
+              }
+              if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, tp) .failed())
+              {
+                err = std::ios_base::badbit;
+              }
+              os.width(0);
+            }
+          }
+          catch (...)
+          {
+            bool flag = false;
+            try
+            {
+              os.setstate(std::ios_base::failbit);
+            }
+            catch (std::ios_base::failure )
+            {
+              flag = true;
+            }
+            if (flag) throw;
+          }
+          if (err) os.setstate(err);
+          return os;
+        }
+        catch (...)
+        {
+          failed = true;
+        }
+        if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
+        return os;
+#endif
     }
 
     template<class CharT, class Traits, class Clock, class Duration>
@@ -226,12 +273,13 @@
     operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock,
         Duration>& tp)
     {
+#if 0
       Duration d;
       is >> d;
       if (is.good())
       {
-        const std::basic_string<CharT> units = epoch_translate(clock_string<
-            Clock, CharT>::since());
+        const std::basic_string<CharT> units = clock_string<
+            Clock, CharT>::since();
         std::ios_base::iostate err = std::ios_base::goodbit;
         typedef std::istreambuf_iterator<CharT, Traits> in_iterator;
         in_iterator i(is);
@@ -251,6 +299,38 @@
       else
         is.setstate(is.failbit);
       return is;
+#else
+      std::ios_base::iostate err = std::ios_base::goodbit;
+
+      try
+      {
+        typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
+        if(ipfx)
+        {
+          if (!std::has_facet<time_point_get<CharT> >(is.getloc()))
+          {
+            is.imbue(std::locale(is.getloc(), new time_point_get<CharT>()));
+          }
+          std::use_facet<time_point_get<CharT> >(is.getloc())
+          .get(is, std::istreambuf_iterator<CharT,Traits>() ,is, err, tp);
+        }
+      }
+      catch(...)
+      {
+        bool flag = false;
+        try
+        {
+          is.setstate(std::ios_base::failbit);
+        }
+        catch( std::ios_base::failure )
+        {
+          flag= true;
+        }
+        if ( flag ) throw;
+      }
+      if ( err ) is.setstate(err);
+      return is;
+#endif
     }
 
 #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
Added: trunk/boost/chrono/io/time_point_put.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/chrono/io/time_point_put.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -0,0 +1,212 @@
+//
+//  (C) Copyright Howard Hinnant
+//  (C) Copyright 2011 Vicente J. Botet Escriba
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+
+/**
+ * Duration formatting facet for output.
+ */
+#ifndef BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
+#define BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/chrono/io/time_point_units.hpp>
+#include <boost/chrono/io/duration_put.hpp>
+#include <boost/assert.hpp>
+#include <locale>
+
+namespace boost
+{
+  namespace chrono
+  {
+
+    /**
+     * @tparam ChatT a character type
+     * @tparam OutputIterator a model of @c OutputIterator
+     *
+     * The @c time_point_put facet provides facilities for formatted output of duration values.
+     * The member function of @c time_point_put take a duration and translate this into character string representation.
+     *
+     * FIXME As the facet doesn't have any data, I'm wondering if this should functions
+     * shouldn't be at the namespace level or static member functions.
+     * This will leverage the user to need to ensure that the facet is imbued on the ios_base.
+     */
+    template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
+    class time_point_put: public std::locale::facet
+    {
+    public:
+      /**
+       * Type of character the facet is instantiated on.
+       */
+      typedef CharT char_type;
+      /**
+       * Type of iterator used to write in the character buffer.
+       */
+      typedef OutputIterator iter_type;
+
+      /**
+       * Construct a time_point_put facet.
+       * @param refs
+       * @Effects Construct a time_point_put facet.
+       * If the @c refs argument is @c 0 then destruction of the object is
+       * delegated to the @c locale, or locales, containing it. This allows
+       * the user to ignore lifetime management issues. On the other had,
+       * if @c refs is @c 1 then the object must be explicitly deleted;
+       * the @c locale will not do so. In this case, the object can be
+       * maintained across the lifetime of multiple locales.
+       */
+      explicit time_point_put(size_t refs = 0) :
+        std::locale::facet(refs)
+      {
+      }
+
+      /**
+       *
+       * @param s an output stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @param pattern begin of the formatting pattern
+       * @param pat_end end of the formatting pattern
+       *
+       * @Effects Steps through the sequence from @c pattern to @c pat_end,
+       * identifying characters that are part of a pattern sequence. Each character
+       * that is not part of a pattern sequence is written to @c s immediately, and
+       * each pattern sequence, as it is identified, results in a call to
+       * @c put_value or @c put_unit;
+       * thus, pattern elements and other characters are interleaved in the output
+       * in the order in which they appear in the pattern. Pattern sequences are
+       * identified by converting each character @c c to a @c char value as if by
+       * @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
+       * @c ios.getloc(). The first character of each sequence is equal to @c Õ%Õ,
+       * followed by a pattern specifier character @c spec, which can be @c 'v' for
+       * the duration value or @c 'u' for the duration unit. .
+       * For each valid pattern sequence identified, calls
+       * <c>put_value(s, ios, d)</c> or <c>put_unit(s, ios, d)</c>.
+       *
+       * @Returns An iterator pointing immediately after the last character produced.
+       */
+      template <class Clock, class Duration>
+      iter_type put(iter_type s, std::ios_base& ios, time_point<Clock, Duration> const& tp, const CharT* pattern,
+          const CharT* pat_end) const
+      {
+        time_point_units<CharT,OutputIterator> const& units_facet = time_point_units<CharT,OutputIterator>::imbue_if_has_not(ios);
+
+        const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+        for (; pattern != pat_end; ++pattern)
+        {
+            if (ct.narrow(*pattern, 0) == '%')
+            {
+                if (++pattern == pat_end)
+                {
+                    *s++ = pattern[-1];
+                    break;
+                }
+                char fmt = ct.narrow(*pattern, 0);
+                switch (fmt)
+                {
+                case 'd':
+                {
+                  s = put_duration(s, ios, tp.time_since_epoch());
+                  break;
+                }
+                case 'e':
+                {
+                  s = put_epoch<Clock>(s, ios);
+                  break;
+                }
+                case 'x':
+                {
+                  std::basic_string<CharT> pat = units_facet.get_pattern();
+                  pattern = pat.data();
+                  pat_end = pattern + pat.size();
+                  break;
+                }
+                default:
+                  BOOST_ASSERT(false && "Boost::Chrono internal error.");
+                  break;
+                }
+            }
+            else
+                *s++ = *pattern;
+        }
+        return s;
+      }
+
+      /**
+       *
+       * @param s an output stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @Effects imbue in @c ios the @c time_point_units_default facet if not already present.
+       * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+       * @code
+       *   return put(s, ios, d, str.data(), str.data() + str.size());
+       * @codeend
+       * @Returns An iterator pointing immediately after the last character produced.
+       */
+      template <class Clock, class Duration>
+      iter_type put(iter_type s, std::ios_base& ios, time_point<Clock, Duration> const& tp) const
+      {
+        std::basic_string<CharT> str = time_point_units<CharT,OutputIterator>::imbue_if_has_not(ios).get_pattern();
+        return put(s, ios, tp, str.data(), str.data() + str.size());
+      }
+
+      /**
+       *
+       * @param s an output stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @Effects As if std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, ' ', static_cast<long int> (d.count())).
+       * @Returns An iterator pointing immediately after the last character produced.
+       */
+      template <typename Rep, typename Period>
+      iter_type put_duration(iter_type s, std::ios_base& ios, duration<Rep, Period> const& d) const
+      {
+        if (!std::has_facet<duration_put<CharT> >(ios.getloc()))
+        {
+          ios.imbue(std::locale(ios.getloc(), new duration_put<CharT>()));
+        }
+        return std::use_facet<duration_put<CharT> >(ios.getloc())
+        .put(s, ios, d);
+      }
+
+      /**
+       *
+       * @param s an output stream iterator
+       * @param ios a reference to a ios_base
+       * @param d the duration
+       * @param pattern
+       * @Effects imbue in @c ios the @c time_point_units_default facet if not already present.
+       * @Effects Calls std::use_facet<time_point_units<CharT,OutputIterator> >(ios.getloc()).put(s, ios, d).
+       * @Returns An iterator pointing immediately after the last character produced.
+       */
+      template <typename Clock>
+      iter_type put_epoch(iter_type s, std::ios_base& ios) const
+      {
+        return time_point_units<CharT,OutputIterator>::imbue_if_has_not(ios).template put<Clock>(s, ios);
+      }
+
+      /**
+       * Unique identifier for this type of facet.
+       */
+      static std::locale::id id;
+
+      /**
+       * @Effects Destroy the facet
+       */
+      ~time_point_put()
+      {
+      }
+
+    };
+
+    template <class CharT, class OutputIterator>
+    std::locale::id time_point_put<CharT, OutputIterator>::id;
+
+  } // chrono
+} // boost
+
+#endif  // BOOST_CHRONO_CHRONO_IO_HPP
Added: trunk/boost/chrono/io/time_point_units.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/chrono/io/time_point_units.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -0,0 +1,275 @@
+//
+//  (C) Copyright Howard Hinnant
+//  (C) Copyright 2011 Vicente J. Botet Escriba
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
+#define BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP
+
+#include <boost/chrono/config.hpp>
+#include <boost/chrono/process_cpu_clocks.hpp>
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/thread_clock.hpp>
+#include <boost/chrono/io/ios_base_state.hpp>
+#include <string>
+#include <iostream>
+#include <ios>
+#include <locale>
+#include <algorithm>
+
+namespace boost
+{
+  namespace chrono
+  {
+
+    /**
+     * @c time_point_units facet gives useful information about the duration units,
+     * as the number of plural forms, the plural form associated to a duration,
+     * the text associated to a plural form and a duration's period,
+     */
+    template <typename CharT=char, class OutputIterator = std::ostreambuf_iterator<CharT> >
+    class time_point_units: public std::locale::facet
+    {
+      static time_point_units* global_;
+    public:
+      typedef CharT char_type;
+      typedef OutputIterator iter_type;
+
+      static std::locale::id id;
+
+      explicit time_point_units(size_t refs = 0) :
+        std::locale::facet(refs)
+      {
+      }
+
+      /**
+       * @Return Gets the global time_point_units,
+       * used when the stream has no associated time_point_units facet.
+       * @Throws an exception if the global is 0.
+      Ê
+      */
+      static time_point_units* global()
+      {
+        return global_;
+      }
+
+      /**
+      If the facet is not 0, sets the new global time_point_units, after deleting the preceding one. This is used when the stream has no associated time_point_units facet.
+      Otherwise throw an exception.
+      */
+      static void global(time_point_units* ptr)
+      {
+        global_ = ptr;
+      }
+
+      /**
+       * Factory cloning a the global instance.
+       * @return a clone of the global instance.
+       */
+      static time_point_units* make()
+      {
+        return global_->clone();;
+      }
+
+      /**
+       * imbue a clone of this facet in @c ios.
+       * @param ios the ios to imbue.
+       */
+#if defined BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
+      // FIXME: This cause a linker problem on compilers other than clang-3.0 c++03 or c++0x
+      static time_point_units<CharT,OutputIterator> const& imbue_if_has_not(std::ios_base& ios)
+      {
+        if (!std::has_facet<time_point_units<CharT,OutputIterator> >(ios.getloc()))
+          ios.imbue(std::locale(ios.getloc(), make()));
+        return std::use_facet<time_point_units<CharT,OutputIterator> >(ios.getloc());
+      }
+#else
+      static inline time_point_units<CharT,OutputIterator> const& imbue_if_has_not(std::ios_base& ios);
+#endif
+
+      template <typename Clock>
+      iter_type put(iter_type s, std::ios_base& ios) const
+      {
+        return do_put(s, ios, Clock());
+      }
+
+      /**
+       *
+       * @return the pattern to be used by default.
+       */
+      std::basic_string<CharT> get_pattern() const
+      {
+        return do_get_pattern();
+      }
+
+      /**
+       *
+       * @return the pattern to be used by default.
+       */
+      template <typename Clock>
+      std::basic_string<CharT> get_epoch() const
+      {
+        return do_get_epoch(Clock());
+      }
+
+    protected:
+      virtual ~time_point_units() {};
+      virtual time_point_units<CharT, OutputIterator>* clone() const = 0;
+
+      virtual std::basic_string<CharT> do_get_pattern() const=0;
+
+      virtual iter_type
+      do_put(iter_type s, std::ios_base& ios, system_clock) const = 0;
+      virtual std::basic_string<CharT> do_get_epoch(system_clock) const=0;
+
+      virtual iter_type
+      do_put(iter_type s, std::ios_base& ios, steady_clock) const = 0;
+      virtual std::basic_string<CharT> do_get_epoch(steady_clock) const=0;
+
+//#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
+      virtual iter_type do_put(iter_type s, std::ios_base& ios, process_real_cpu_clock c) const =0;
+      virtual std::basic_string<CharT> do_get_epoch(process_real_cpu_clock) const=0;
+      virtual iter_type do_put(iter_type s, std::ios_base& ios, process_user_cpu_clock c) const =0;
+      virtual std::basic_string<CharT> do_get_epoch(process_user_cpu_clock) const=0;
+      virtual iter_type do_put(iter_type s, std::ios_base& ios, process_system_cpu_clock c) const =0;
+      virtual std::basic_string<CharT> do_get_epoch(process_system_cpu_clock) const=0;
+      virtual iter_type do_put(iter_type s, std::ios_base& ios, process_cpu_clock c) const =0;
+      virtual std::basic_string<CharT> do_get_epoch(process_cpu_clock) const=0;
+//#endif
+#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+      virtual iter_type do_put(iter_type s, std::ios_base& ios, thread_clock c) const =0;
+      virtual std::basic_string<CharT> do_get_epoch(thread_clock) const=0;
+#endif
+
+    };
+
+    template <typename CharT, class OutputIterator>
+    std::locale::id time_point_units<CharT, OutputIterator>::id;
+
+
+    // This class is used to define the strings for the default English
+    template <typename CharT=char, class OutputIterator = std::ostreambuf_iterator<CharT> >
+    class time_point_units_default: public time_point_units<CharT, OutputIterator>
+    {
+    public:
+      typedef CharT char_type;
+      typedef OutputIterator iter_type;
+
+      explicit time_point_units_default(size_t refs = 0) :
+        time_point_units<CharT, OutputIterator> (refs)
+      {
+      }
+      ~time_point_units_default() {}
+
+
+    protected:
+      time_point_units<CharT, OutputIterator>* clone() const
+      {
+        return new time_point_units_default<CharT, OutputIterator>();
+      }
+
+      std::basic_string<CharT> do_get_pattern() const
+      {
+        static const CharT t[] =
+        { '%', 'd', '%', 'e' };
+        static const std::basic_string<CharT> pattern(t, t + sizeof (t) / sizeof (t[0]));
+
+        return pattern;
+      }
+
+      iter_type do_put(iter_type s, std::ios_base& , system_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(system_clock ) const
+      {
+        return clock_string<system_clock,CharT>::since();
+      }
+      iter_type do_put(iter_type s, std::ios_base& , steady_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(steady_clock ) const
+      {
+        return clock_string<steady_clock,CharT>::since();
+      }
+
+//#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
+      iter_type do_put(iter_type s, std::ios_base& , process_real_cpu_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(process_real_cpu_clock ) const
+      {
+        return clock_string<process_real_cpu_clock,CharT>::since();
+      }
+      iter_type do_put(iter_type s, std::ios_base& , process_user_cpu_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(process_user_cpu_clock ) const
+      {
+        return clock_string<process_user_cpu_clock,CharT>::since();
+      }
+      iter_type do_put(iter_type s, std::ios_base& , process_system_cpu_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(process_system_cpu_clock ) const
+      {
+        return clock_string<process_system_cpu_clock,CharT>::since();
+      }
+      iter_type do_put(iter_type s, std::ios_base& , process_cpu_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(process_cpu_clock ) const
+      {
+        return clock_string<process_cpu_clock,CharT>::since();
+      }
+
+//#endif
+#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
+      iter_type do_put(iter_type s, std::ios_base& , thread_clock c) const
+      {
+        std::basic_string<CharT> str = do_get_epoch(c);
+        return std::copy(str.begin(), str.end(), s);
+      }
+      std::basic_string<CharT> do_get_epoch(thread_clock ) const
+      {
+        return clock_string<thread_clock,CharT>::since();
+      }
+#endif
+
+    };
+
+    template <typename CharT, class OutputIterator>
+    time_point_units<CharT, OutputIterator>* time_point_units<CharT, OutputIterator>::global_=new time_point_units_default<CharT, OutputIterator>();
+
+#if ! defined BOOST_CHRONO_USES_DURATION_UNITS_GLOBAL
+    template <typename CharT, class OutputIterator>
+    time_point_units<CharT,OutputIterator> const&
+    time_point_units<CharT, OutputIterator>::imbue_if_has_not(std::ios_base& ios)
+    {
+        if (!std::has_facet<time_point_units<CharT,OutputIterator> >(ios.getloc())) ios.imbue(
+            std::locale(ios.getloc(), new time_point_units_default<CharT,OutputIterator>()));
+        return std::use_facet<time_point_units<CharT,OutputIterator> >(ios.getloc());
+    }
+
+#endif
+
+
+  } // chrono
+
+} // boost
+
+#endif  // header
Modified: trunk/boost/chrono/io_v1/chrono_io.hpp
==============================================================================
--- trunk/boost/chrono/io_v1/chrono_io.hpp	(original)
+++ trunk/boost/chrono/io_v1/chrono_io.hpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -576,10 +576,11 @@
                       &units, &units + 1,
                       //~ std::use_facet<std::ctype<CharT> >(is.getloc()),
                       err) - &units;
+        is.setstate(err);
         if (k == 1)
         {
+          is.setstate(err | is.failbit);
             // failed to read epoch string
-            is.setstate(err);
             return is;
         }
         tp = time_point<Clock, Duration>(d);
Modified: trunk/libs/chrono/test/io/time_point_input.cpp
==============================================================================
--- trunk/libs/chrono/test/io/time_point_input.cpp	(original)
+++ trunk/libs/chrono/test/io/time_point_input.cpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -9,94 +9,95 @@
 #include <boost/chrono/thread_clock.hpp>
 #include <boost/chrono/process_cpu_clocks.hpp>
 
-template<typename Clock, typename D>
+template <typename Clock, typename D>
 void test_good(std::string str, D res)
 {
-  std::istringstream in(str+boost::chrono::clock_string<Clock,char>::since());
-  boost::chrono::time_point<Clock,D> tp;
+  std::istringstream in(str + boost::chrono::clock_string<Clock, char>::since());
+  boost::chrono::time_point<Clock, D> tp;
   in >> tp;
-  BOOST_TEST(in.good());
-  BOOST_TEST((tp == boost::chrono::time_point<Clock,D>(res)));
+  BOOST_TEST(in.eof());
+  BOOST_TEST(!in.fail());
+  BOOST_TEST( (tp == boost::chrono::time_point<Clock, D>(res)));
 }
 
-template<typename Clock, typename D>
-void test_fail(const char* str, D )
+template <typename Clock, typename D>
+void test_fail(const char* str, D)
 {
-  std::istringstream in(str+boost::chrono::clock_string<Clock,char>::since());
-  boost::chrono::time_point<Clock,D> tp;
-    in >> tp;
-    BOOST_TEST(in.fail());
-    BOOST_TEST((tp == boost::chrono::time_point<Clock,D>()));
+  std::istringstream in(str + boost::chrono::clock_string<Clock, char>::since());
+  boost::chrono::time_point<Clock, D> tp;
+  in >> tp;
+  BOOST_TEST(in.fail());
+  BOOST_TEST( (tp == boost::chrono::time_point<Clock, D>()));
 }
 
-template<typename Clock, typename D>
+template <typename Clock, typename D>
 void test_fail_no_epoch(const char* str, D r)
 {
   std::istringstream in(str);
-  boost::chrono::time_point<Clock,D> tp;
-    in >> tp;
-    BOOST_TEST(in.fail());
-    BOOST_TEST((tp == boost::chrono::time_point<Clock,D>()));
+  boost::chrono::time_point<Clock, D> tp;
+  in >> tp;
+  BOOST_TEST(in.fail());
+  BOOST_TEST( (tp == boost::chrono::time_point<Clock, D>()));
 }
 
-template<typename Clock, typename D>
+template <typename Clock, typename D>
 void test_fail_epoch(const char* str, D)
 {
   std::istringstream in(str);
-  boost::chrono::time_point<Clock,D> tp;
-    in >> tp;
-    BOOST_TEST(in.fail());
-    BOOST_TEST((tp == boost::chrono::time_point<Clock,D>()));
+  boost::chrono::time_point<Clock, D> tp;
+  in >> tp;
+  BOOST_TEST(in.fail());
+  BOOST_TEST( (tp == boost::chrono::time_point<Clock, D>()));
 }
 
-template<typename Clock>
+template <typename Clock>
 void check_all()
 {
   using namespace boost::chrono;
   using namespace boost;
 
-  test_good<Clock>("5000 hours", hours(5000));
-  test_good<Clock>("5000 minutes", minutes(5000));
-  test_good<Clock>("5000 seconds", seconds(5000));
-  test_good<Clock>("1 seconds", seconds(1));
-  test_good<Clock>("1 second", seconds(1));
-  test_good<Clock>("-1 seconds", seconds(-1));
-  test_good<Clock>("0 second", seconds(0));
-  test_good<Clock>("0 seconds", seconds(0));
-  test_good<Clock>("5000 milliseconds", milliseconds(5000));
-  test_good<Clock>("5000 microseconds", microseconds(5000));
-  test_good<Clock>("5000 nanoseconds", nanoseconds(5000));
-  test_good<Clock>("5000 deciseconds", duration<boost::int_least64_t, deci> (5000));
-  test_good<Clock>("5000 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (5000));
+  test_good<Clock> ("5000 hours", hours(5000));
+  test_good<Clock> ("5000 minutes", minutes(5000));
+  test_good<Clock> ("5000 seconds", seconds(5000));
+  test_good<Clock> ("1 seconds", seconds(1));
+  test_good<Clock> ("1 second", seconds(1));
+  test_good<Clock> ("-1 seconds", seconds(-1));
+  test_good<Clock> ("0 second", seconds(0));
+  test_good<Clock> ("0 seconds", seconds(0));
+  test_good<Clock> ("5000 milliseconds", milliseconds(5000));
+  test_good<Clock> ("5000 microseconds", microseconds(5000));
+  test_good<Clock> ("5000 nanoseconds", nanoseconds(5000));
+  test_good<Clock> ("5000 deciseconds", duration<boost::int_least64_t, deci> (5000));
+  test_good<Clock> ("5000 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (5000));
 
-  test_good<Clock>("5000 h", hours(5000));
+  test_good<Clock> ("5000 h", hours(5000));
 #if defined BOOST_CHRONO_DONT_PROVIDE_DEPRECATED_IO_V1
   test_good<Clock>("5000 min", minutes(5000));
 #else
-  test_good<Clock>("5000 m", minutes(5000));
+  test_good<Clock> ("5000 m", minutes(5000));
 #endif
-  test_good<Clock>("5000 s", seconds(5000));
-  test_good<Clock>("5000 ms", milliseconds(5000));
-  test_good<Clock>("5000 ns", nanoseconds(5000));
-  test_good<Clock>("5000 ds", duration<boost::int_least64_t, deci> (5000));
-  test_good<Clock>("5000 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (5000));
-
-  test_good<Clock>("5000 milliseconds", seconds(5));
-  test_good<Clock>("5 milliseconds", nanoseconds(5000000));
-  test_good<Clock>("4000 ms", seconds(4));
-  test_fail<Clock>("3001 ms", seconds(3));
-  test_fail_epoch<Clock>("3001 ms", seconds(3));
-  test_fail_epoch<Clock>("3001 ms since", seconds(3));
+  test_good<Clock> ("5000 s", seconds(5000));
+  test_good<Clock> ("5000 ms", milliseconds(5000));
+  test_good<Clock> ("5000 ns", nanoseconds(5000));
+  test_good<Clock> ("5000 ds", duration<boost::int_least64_t, deci> (5000));
+  test_good<Clock> ("5000 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (5000));
+
+  test_good<Clock> ("5000 milliseconds", seconds(5));
+  test_good<Clock> ("5 milliseconds", nanoseconds(5000000));
+  test_good<Clock> ("4000 ms", seconds(4));
+  test_fail<Clock> ("3001 ms", seconds(3));
+  test_fail_epoch<Clock> ("3001 ms", seconds(3));
+  test_fail_epoch<Clock> ("3001 ms since", seconds(3));
 
 }
 
 int main()
 {
   std::cout << "high_resolution_clock=" << std::endl;
-  check_all<boost::chrono::high_resolution_clock>();
+  check_all<boost::chrono::high_resolution_clock> ();
 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
-  std::cout << "steady_clock="<< std::endl;
-  check_all<boost::chrono::steady_clock>();
+  std::cout << "steady_clock=" << std::endl;
+  check_all<boost::chrono::steady_clock> ();
 #endif
   //std::cout << "system_clock=";
   //check_all<boost::chrono::system_clock>();
@@ -107,14 +108,14 @@
 #endif
 
 #if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
-  std::cout << "process_real_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_real_cpu_clock>();
-  std::cout << "process_user_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_user_cpu_clock>();
-  std::cout << "process_system_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_system_cpu_clock>();
-  std::cout << "process_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_cpu_clock>();
+  std::cout << "process_real_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_real_cpu_clock> ();
+  std::cout << "process_user_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_user_cpu_clock> ();
+  std::cout << "process_system_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_system_cpu_clock> ();
+  std::cout << "process_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_cpu_clock> ();
 #endif
 
   return boost::report_errors();
Modified: trunk/libs/chrono/test/io/time_point_output.cpp
==============================================================================
--- trunk/libs/chrono/test/io/time_point_output.cpp	(original)
+++ trunk/libs/chrono/test/io/time_point_output.cpp	2011-11-05 23:07:43 EDT (Sat, 05 Nov 2011)
@@ -9,28 +9,28 @@
 #include <boost/chrono/thread_clock.hpp>
 #include <boost/chrono/process_cpu_clocks.hpp>
 
-template<typename Clock, typename D>
+template <typename Clock, typename D>
 void test_good_prefix(const char* str, D d)
 {
   std::ostringstream out;
-  boost::chrono::time_point<Clock,D> tp(d);
+  boost::chrono::time_point<Clock, D> tp(d);
   out << tp;
   BOOST_TEST(out.good());
-  BOOST_TEST((out.str() == std::string(str)+boost::chrono::clock_string<Clock,char>::since()));
+  BOOST_TEST( (out.str() == std::string(str) + boost::chrono::clock_string<Clock, char>::since()));
 }
 
-template<typename Clock, typename D>
+template <typename Clock, typename D>
 void test_good_symbol(const char* str, D d)
 {
   std::ostringstream out;
-  boost::chrono::time_point<Clock,D> tp(d);
+  boost::chrono::time_point<Clock, D> tp(d);
 #if defined BOOST_CHRONO_DONT_PROVIDE_DEPRECATED_IO_V1
   out << boost::chrono::duration_fmt(boost::chrono::duration_style::symbol) << tp;
 #else
   out << boost::chrono::duration_short << tp;
 #endif
   BOOST_TEST(out.good());
-  BOOST_TEST((out.str() == std::string(str)+boost::chrono::clock_string<Clock,char>::since()));
+  BOOST_TEST( (out.str() == std::string(str) + boost::chrono::clock_string<Clock, char>::since()));
 }
 
 #if defined BOOST_CHRONO_DONT_PROVIDE_DEPRECATED_IO_V1
@@ -45,7 +45,7 @@
 }
 #endif
 
-template<typename Clock>
+template <typename Clock>
 void check_all()
 {
   using namespace boost::chrono;
@@ -56,39 +56,39 @@
   test_good<Clock>("2 h", hours(2), duration_style::symbol);
 #endif
 
-  test_good_prefix<Clock>("2 hours", hours(2));
-  test_good_prefix<Clock>("2 minutes", minutes(2));
-  test_good_prefix<Clock>("2 seconds", seconds(2));
-  test_good_prefix<Clock>("1 second", seconds(1));
-  test_good_prefix<Clock>("-1 second", seconds(-1));
-  test_good_prefix<Clock>("0 seconds", seconds(0));
-  test_good_prefix<Clock>("2 milliseconds", milliseconds(2));
-  test_good_prefix<Clock>("2 microseconds", microseconds(2));
-  test_good_prefix<Clock>("2 nanoseconds", nanoseconds(2));
-  test_good_prefix<Clock>("2 deciseconds", duration<boost::int_least64_t, deci> (2));
-  test_good_prefix<Clock>("2 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (2));
+  test_good_prefix<Clock> ("2 hours", hours(2));
+  test_good_prefix<Clock> ("2 minutes", minutes(2));
+  test_good_prefix<Clock> ("2 seconds", seconds(2));
+  test_good_prefix<Clock> ("1 second", seconds(1));
+  test_good_prefix<Clock> ("-1 second", seconds(-1));
+  test_good_prefix<Clock> ("0 seconds", seconds(0));
+  test_good_prefix<Clock> ("2 milliseconds", milliseconds(2));
+  test_good_prefix<Clock> ("2 microseconds", microseconds(2));
+  test_good_prefix<Clock> ("2 nanoseconds", nanoseconds(2));
+  test_good_prefix<Clock> ("2 deciseconds", duration<boost::int_least64_t, deci> (2));
+  test_good_prefix<Clock> ("2 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (2));
 
-  test_good_symbol<Clock>("2 h", hours(2));
+  test_good_symbol<Clock> ("2 h", hours(2));
 #if defined BOOST_CHRONO_DONT_PROVIDE_DEPRECATED_IO_V1
   test_good_symbol<Clock>("2 min", minutes(2));
 #else
-  test_good_symbol<Clock>("2 m", minutes(2));
+  test_good_symbol<Clock> ("2 m", minutes(2));
 #endif
-  test_good_symbol<Clock>("2 s", seconds(2));
-  test_good_symbol<Clock>("2 ms", milliseconds(2));
-  test_good_symbol<Clock>("2 ns", nanoseconds(2));
-  test_good_symbol<Clock>("2 ds", duration<boost::int_least64_t, deci> (2));
-  test_good_symbol<Clock>("2 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (2));
+  test_good_symbol<Clock> ("2 s", seconds(2));
+  test_good_symbol<Clock> ("2 ms", milliseconds(2));
+  test_good_symbol<Clock> ("2 ns", nanoseconds(2));
+  test_good_symbol<Clock> ("2 ds", duration<boost::int_least64_t, deci> (2));
+  test_good_symbol<Clock> ("2 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (2));
 }
 
 int main()
 {
 
-  std::cout << "high_resolution_clock="<< std::endl;
-  check_all<boost::chrono::high_resolution_clock>();
+  std::cout << "high_resolution_clock=" << std::endl;
+  check_all<boost::chrono::high_resolution_clock> ();
 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
-  std::cout << "steady_clock="<< std::endl;
-  check_all<boost::chrono::steady_clock>();
+  std::cout << "steady_clock=" << std::endl;
+  check_all<boost::chrono::steady_clock> ();
 #endif
   //std::cout << "system_clock=";
   //check_all<boost::chrono::system_clock>();
@@ -99,14 +99,14 @@
 #endif
 
 #if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
-  std::cout << "process_real_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_real_cpu_clock>();
-  std::cout << "process_user_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_user_cpu_clock>();
-  std::cout << "process_system_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_system_cpu_clock>();
-  std::cout << "process_cpu_clock="<< std::endl;
-  check_all<boost::chrono::process_cpu_clock>();
+  std::cout << "process_real_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_real_cpu_clock> ();
+  std::cout << "process_user_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_user_cpu_clock> ();
+  std::cout << "process_system_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_system_cpu_clock> ();
+  std::cout << "process_cpu_clock=" << std::endl;
+  check_all<boost::chrono::process_cpu_clock> ();
 #endif
 
   return boost::report_errors();