$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r75202 - in trunk: boost/chrono boost/chrono/io libs/chrono/test/io
From: vicente.botet_at_[hidden]
Date: 2011-10-31 15:04:48
Author: viboes
Date: 2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
New Revision: 75202
URL: http://svn.boost.org/trac/boost/changeset/75202
Log:
Chrono: Added duration_get facade + some needed adaptations
Added:
   trunk/boost/chrono/io/duration_get.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/chrono/config.hpp                  |     1                                         
   trunk/boost/chrono/io/duration_io.hpp          |    32 ++++------------------                  
   trunk/boost/chrono/io/duration_put.hpp         |    57 ++++++++++++++++++++++++++++++++++++--- 
   trunk/boost/chrono/io/duration_unit_string.hpp |     1                                         
   trunk/boost/chrono/io/duration_units.hpp       |     7 ++++                                    
   trunk/boost/chrono/io/ios_base_state.hpp       |     2                                         
   trunk/boost/chrono/io/translate.hpp            |     1                                         
   trunk/libs/chrono/test/io/duration_input.cpp   |     4 +-                                      
   8 files changed, 71 insertions(+), 34 deletions(-)
Modified: trunk/boost/chrono/config.hpp
==============================================================================
--- trunk/boost/chrono/config.hpp	(original)
+++ trunk/boost/chrono/config.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -92,6 +92,7 @@
 #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
 //#define BOOST_CHRONO_IS_LOCALIZABLE_VIRTUAL
 //#define BOOST_CHRONO_IS_LOCALIZABLE_TRANSLATE
 
Added: trunk/boost/chrono/io/duration_get.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/chrono/io/duration_get.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -0,0 +1,640 @@
+//
+//  (C) Copyright 2011 Vicente J. Botet Escriba
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+
+#ifndef BOOST_CHRONO_IO_DURATION_GET_HPP
+#define BOOST_CHRONO_IO_DURATION_GET_HPP
+
+#include <boost/chrono/config.hpp>
+#include <string>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/math/common_factor_rt.hpp>
+#include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/assert.hpp>
+#include <locale>
+
+/**
+ * Duration formatting facet for input.
+ */
+namespace boost
+{
+  namespace chrono
+  {
+
+    namespace detail
+    {
+      template <class Rep, bool = is_scalar<Rep>::value>
+      struct duration_io_intermediate
+      {
+        typedef Rep type;
+      };
+
+      template <class Rep>
+      struct duration_io_intermediate<Rep, true>
+      {
+        typedef typename mpl::if_c<is_floating_point<Rep>::value, long double, typename mpl::if_c<
+            is_signed<Rep>::value, long long, unsigned long long>::type>::type type;
+      };
+
+    }
+
+    /**
+     * @c duration_get is used to parse a character sequence, extracting
+     * components of a duration into a class duration.
+     * Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
+     * If the sequence being parsed matches the correct format, the
+     * corresponding member of the class duration argument are set to the
+     * value used to produce the sequence;
+     * otherwise either an error is reported or unspecified values are assigned.
+     * In other words, user confirmation is required for reliable parsing of
+     * user-entered durations, but machine-generated formats can be parsed
+     * reliably. This allows parsers to be aggressive about interpreting user
+     * variations on standard formats.
+     *
+     * If the end iterator is reached during parsing of the get() member
+     * function, the member sets std::ios_base::eofbit in err.
+     */
+    template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
+    class duration_get: public std::locale::facet
+    {
+    public:
+      /**
+       * Type of character the facet is instantiated on.
+       */
+      typedef CharT char_type;
+      /**
+       * Type of iterator used to scan the character buffer.
+       */
+      typedef InputIterator iter_type;
+
+      /**
+       * Construct a @c duration_get facet.
+       * @param refs
+       * @Effects Construct a @c duration_get facet.
+       * If the @c refs argument is @c 0 then destruction of the object is
+       * delegated to the @c std::locale, or std::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 std::locale will not do so. In this case, the object can be
+       * maintained across the lifetime of multiple std::locales.
+       */
+
+      explicit duration_get(size_t refs = 0) :
+        std::locale::facet(refs)
+      {
+      }
+
+      /**
+       * @param s start input stream iterator
+       * @param end end input stream iterator
+       * @param ios a reference to a ios_base
+       * @param err the ios_base state
+       * @param d the duration
+       * @param pattern begin of the formatting pattern
+       * @param pat_end end of the formatting pattern
+       *
+       * Requires: [pattern,pat_end) shall be a valid range.
+       *
+       * Effects: The function starts by evaluating err = std::ios_base::goodbit.
+       * It then enters a loop, reading zero or more characters from s at
+       * each iteration. Unless otherwise specified below, the loop
+       * terminates when the first of the following conditions holds:
+       * - The expression pattern == pat_end evaluates to true.
+       * - The expression err == std::ios_base::goodbit evaluates to false.
+       * - The expression s == end evaluates to true, in which case the
+       * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
+       * - The next element of pattern is equal to Õ%Õ, followed by a conversion
+       * specifier character, format.
+       * If the number of elements in the range [pattern,pat_end) is not
+       * sufficient to unambiguously determine whether the conversion
+       * specification is complete and valid, the function evaluates
+       * err = std::ios_base::failbit. Otherwise, the function evaluates
+       * s = 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 <typename Rep, typename Period>
+      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+          duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
+      {
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+        if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
+            std::locale(ios.getloc(), new duration_units_default<CharT> ()));
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+        typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
+        intermediate_type r;
+        detail::rt_ratio rt;
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+#if 1
+        const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+        err = std::ios_base::goodbit;
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+        while (pattern != pat_end && err == std::ios_base::goodbit)
+        {
+          std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+            if (s == end)
+            {
+                err |= std::ios_base::failbit;
+                break;
+            }
+            std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+            if (ct.narrow(*pattern, 0) == '%')
+            {
+                if (++pattern == pat_end)
+                {
+                    err |= std::ios_base::failbit;
+                    break;
+                }
+                std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+                char cmd = ct.narrow(*pattern, 0);
+                std::cerr << __FILE__ << ":"<<__LINE__ << ": cmd "<<  cmd << std::endl;
+                switch (cmd)
+                {
+                case 'v':
+                {
+                  std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err)  << "- " << r << std::endl;
+                  s=get_value(s, end, ios, err, r);
+                  std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err)  << "+ " << r << std::endl;
+                  if ((err & std::ios_base::failbit) != 0)
+                  {
+                    return s;
+                  }
+                  break;
+                }
+                case 'u':
+                {
+                  std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << "- ["<<rt.num <<"/" <<rt.den <<"]"<< std::endl;
+                  s = get_unit<Rep>(s, end, ios, err, rt);
+                  std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << "+ ["<<rt.num <<"/" <<rt.den <<"]"<< std::endl;
+                  break;
+                }
+                case 'x':
+                {
+                  std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+                  pattern = pat.data();
+                  pat_end = pattern + pat.size();
+                  break;
+                }
+                default:
+                  BOOST_ASSERT(false && "Boost::Chrono internal error.");
+                  break;
+                }
+
+                ++pattern;
+                std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+            }
+            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)
+                    ;
+                std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+            }
+            else if (ct.toupper(*s) == ct.toupper(*pattern))
+            {
+                ++s;
+                ++pattern;
+                std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+            }
+            else {
+                err |= std::ios_base::failbit;
+            }
+            std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+        }
+        if (s == end)
+            err |= std::ios_base::eofbit;
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+        unsigned long long num = rt.num;
+        unsigned long long den = rt.den;
+
+        // r should be multiplied by (num/den) / Period
+        // Reduce (num/den) / Period to lowest terms
+        unsigned long long gcd_n1_n2 = math::gcd<unsigned long long>(num, Period::num);
+        unsigned long long gcd_d1_d2 = math::gcd<unsigned long long>(den, Period::den);
+        num /= gcd_n1_n2;
+        den /= gcd_d1_d2;
+        unsigned long long n2 = Period::num / gcd_n1_n2;
+        unsigned long long d2 = Period::den / gcd_d1_d2;
+        if (num > (std::numeric_limits<unsigned long long>::max)() / d2 || den > (std::numeric_limits<
+            unsigned long long>::max)() / n2)
+        {
+          // (num/den) / Period overflows
+          err |= std::ios_base::failbit;
+          return s;
+        }
+        num *= d2;
+        den *= n2;
+
+        // num / den is now factor to multiply by r
+        typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
+        if (is_integral<intermediate_type>::value)
+        {
+          // Reduce r * num / den
+          common_type_t t = math::gcd<common_type_t>(r, den);
+          r /= t;
+          den /= t;
+          if (den != 1)
+          {
+            // Conversion to Period is integral and not exact
+            err |= std::ios_base::failbit;
+            return s;
+          }
+        }
+        if (r > ( (duration_values<common_type_t>::max)() / num))
+        {
+          // Conversion to Period overflowed
+          err |= std::ios_base::failbit;
+          return s;
+        }
+        common_type_t t = r * num;
+        t /= den;
+        if (t > 0)
+        {
+          Rep pt = t;
+          if ( (duration_values<Rep>::max)() < pt)
+          {
+            // Conversion to Period overflowed
+            err |= std::ios_base::failbit;
+            return s;
+          }
+        }
+        // Success!  Store it.
+        r = Rep(t);
+        d = duration<Rep, Period> (r);
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+
+        return s;
+
+#else
+
+
+        for (; pattern != pat_end; ++pattern)
+        {
+          // FIXME: Shouldn't "uvx" be a basic_string<CharT> ?????
+          if ( (*pattern != CharT('%')) || ( (pattern + 1) == pat_end) || (!std::strchr("uvx", * (pattern + 1))))
+          {
+            //if (*s++ == *pattern)
+
+          }
+          else
+          {
+            ++pattern;
+            switch (*pattern)
+            {
+            case 'v':
+            {
+              s=get_value(s, end, ios, err, r);
+              if ((err & std::ios_base::failbit) != 0)
+              {
+                return s;
+              }
+              break;
+            }
+            case 'u':
+            {
+              //s = get_unit(s, end, ios, err, d);
+              break;
+            }
+            case 'x':
+            {
+              std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+              pattern = pat.data();
+              pat_end = pattern + pat.size();
+              break;
+            }
+            default:
+              BOOST_ASSERT(false && "Boost::Chrono internal error.");
+              break;
+            }
+          }
+        }
+#endif
+        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 duration_units_default facet if not already present.
+       * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
+       * @code
+       *   return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
+       * @codeend
+       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
+       */
+      template <typename Rep, typename Period>
+      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
+          duration<Rep, Period> & d) const
+      {
+        if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
+            std::locale(ios.getloc(), new duration_units_default<CharT> ()));
+
+        std::basic_string < CharT > str = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+        return get(s, end, ios, err, d, 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>
+      iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const
+      {
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+        return std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+      }
+
+      /**
+       *
+       * @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 <typename Rep>
+      iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
+          detail::rt_ratio &rt) const
+      {
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+        if (!std::has_facet<duration_units<CharT> >(is.getloc())) is.imbue(
+            std::locale(is.getloc(), new duration_units_default<CharT> ()));
+
+        // unit is num / den (yet to be determined)
+        unsigned long long num = 0;
+        unsigned long long den = 0;
+        if (*i == '[')
+        {
+          // parse [N/D]s or [N/D]seconds format
+          ++i;
+          i=std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, num);
+          if ((err & std::ios_base::failbit) != 0)
+          {
+            return i;
+          }
+
+          if (i==e)
+          {
+            err |= std::ios_base::failbit;
+            return i;
+          }
+          CharT x = *i++;
+          if (x != '/')
+          {
+            err |= std::ios_base::failbit;
+            return i;
+          }
+          i=std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, den);
+          if ((err & std::ios_base::failbit) != 0)
+          {
+            return i;
+          }
+          if (i==e)
+          {
+            err |= std::ios_base::failbit;
+            return i;
+          }
+          if (*i != ']')
+          {
+            err |= std::ios_base::failbit;
+            return i;
+          }
+          ++i;
+          if (i==e)
+          {
+            err |= std::ios_base::failbit;
+            return i;
+          }
+          const std::basic_string<CharT> units[] =
+          {
+              std::use_facet<duration_units<CharT> >(is.getloc()).template get_plural_form<ratio<1> >(duration_style::prefix, 1),
+              std::use_facet<duration_units<CharT> >(is.getloc()).template get_plural_form<ratio<1> >(duration_style::symbol, 1)
+          };
+          // FIXME is this necessary?????
+          err = std::ios_base::goodbit;
+          const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, units,
+              units + sizeof (units) / sizeof (units[0]),
+              //~ std::use_facet<std::ctype<CharT> >(loc),
+              err);
+          switch ( (k - units) / 2)
+          {
+          case 0:
+            break;
+          default:
+            err |= std::ios_base::failbit;
+            return i;
+          }
+        }
+        else
+        {
+          // parse SI name, short or long
+
+          const std::basic_string<CharT> units[] =
+          {
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, atto> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, atto> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, atto> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, femto> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, femto> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, femto> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, pico> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, pico> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, pico> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, nano> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, nano> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, nano> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, micro> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, micro> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, micro> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, milli> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, milli> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, milli> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, centi> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, centi> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, centi> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, deci> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, deci> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, deci> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, deca> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, deca> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, deca> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, hecto> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, hecto> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, hecto> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, kilo> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, kilo> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, kilo> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, mega> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, mega> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, mega> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, giga> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, tera> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, giga> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, peta> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, peta> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, peta> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, exa> (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, exa> (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, exa> (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<1> > (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<1> > (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, ratio<1> > (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<60> > (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<60> > (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, ratio<60> > (1)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<3600> > (2)),
+              duration_unit<CharT> (is.getloc(), true, duration<Rep, ratio<3600> > (1)),
+              duration_unit<CharT> (is.getloc(), false, duration<Rep, ratio<3600> > (1)),
+              };
+          std::ios_base::iostate err = std::ios_base::goodbit;
+          const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, units,
+              units + sizeof (units) / sizeof (units[0]),
+              //~ std::use_facet<std::ctype<CharT> >(loc),
+              err);
+          switch ( (k - units) / 3)
+          {
+          case 0:
+            num = 1ULL;
+            den = 1000000000000000000ULL;
+            break;
+          case 1:
+            num = 1ULL;
+            den = 1000000000000000ULL;
+            break;
+          case 2:
+            num = 1ULL;
+            den = 1000000000000ULL;
+            break;
+          case 3:
+            num = 1ULL;
+            den = 1000000000ULL;
+            break;
+          case 4:
+            num = 1ULL;
+            den = 1000000ULL;
+            break;
+          case 5:
+            num = 1ULL;
+            den = 1000ULL;
+            break;
+          case 6:
+            num = 1ULL;
+            den = 100ULL;
+            break;
+          case 7:
+            num = 1ULL;
+            den = 10ULL;
+            break;
+          case 8:
+            num = 10ULL;
+            den = 1ULL;
+            break;
+          case 9:
+            num = 100ULL;
+            den = 1ULL;
+            break;
+          case 10:
+            num = 1000ULL;
+            den = 1ULL;
+            break;
+          case 11:
+            num = 1000000ULL;
+            den = 1ULL;
+            break;
+          case 12:
+            num = 1000000000ULL;
+            den = 1ULL;
+            break;
+          case 13:
+            num = 1000000000000ULL;
+            den = 1ULL;
+            break;
+          case 14:
+            num = 1000000000000000ULL;
+            den = 1ULL;
+            break;
+          case 15:
+            num = 1000000000000000000ULL;
+            den = 1ULL;
+            break;
+          case 16:
+            num = 1;
+            den = 1;
+            break;
+          case 17:
+            num = 60;
+            den = 1;
+            break;
+          case 18:
+            num = 3600;
+            den = 1;
+            break;
+          default:
+            err = std::ios_base::failbit;
+            return i;
+          }
+        }
+        // unit is num/den
+
+        rt = detail::rt_ratio(num,den);
+        std::cerr << __FILE__ << ":"<<__LINE__ << ":"<<  int(err) << std::endl;
+        return i;
+      }
+
+      /**
+       * Unique identifier for this type of facet.
+       */
+      static std::locale::id id;
+
+      /**
+       * @Effects Destroy the facet
+       */
+      ~duration_get()
+      {
+      }
+    };
+
+    /**
+     * Unique identifier for this type of facet.
+     */
+    template <class CharT, class OutputIterator>
+    std::locale::id duration_get<CharT, OutputIterator>::id;
+
+  } // chrono
+}
+// boost
+
+#endif  // BOOST_CHRONO_CHRONO_IO_HPP
Modified: trunk/boost/chrono/io/duration_io.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_io.hpp	(original)
+++ trunk/boost/chrono/io/duration_io.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -15,17 +15,14 @@
 
 #include <boost/chrono/chrono.hpp>
 #include <boost/ratio/ratio_io.hpp>
-#include <boost/type_traits/is_scalar.hpp>
-#include <boost/type_traits/is_signed.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/math/common_factor_rt.hpp>
-#include <boost/chrono/detail/scan_keyword.hpp>
+
 #include <boost/chrono/io/duration_style.hpp>
 #include <boost/chrono/io/duration_unit_string.hpp>
 #include <boost/chrono/io/ios_base_state.hpp>
 //#include <boost/format.hpp>
 #include <locale>
 #include <boost/chrono/io/duration_put.hpp>
+#include <boost/chrono/io/duration_get.hpp>
 namespace boost
 {
   namespace chrono
@@ -562,22 +559,6 @@
       return os;
     }
 
-    namespace chrono_detail
-    {
-      template <class Rep, bool = is_scalar<Rep>::value>
-      struct duration_io_intermediate
-      {
-        typedef Rep type;
-      };
-
-      template <class Rep>
-      struct duration_io_intermediate<Rep, true>
-      {
-        typedef typename mpl::if_c<is_floating_point<Rep>::value, long double, typename mpl::if_c<
-            is_signed<Rep>::value, long long, unsigned long long>::type>::type type;
-      };
-
-    }
 
     /**
      *
@@ -610,21 +591,20 @@
             is.imbue(std::locale(is.getloc(), new duration_get<CharT>()));
           }
           std::use_facet<duration_get<CharT> >(is.getloc())
-          .get(is, std::istreambuf_iterator<CharT,Traits>()
-              ,is, err, d);
+          .get(is, std::istreambuf_iterator<CharT,Traits>() ,is, err, d);
         }
       } // try
 
       catch(...)
       {
-        bool flag = FALSE;
+        bool flag = false;
         try
         {
           is.setstate(std::ios_base::failbit);
         }
         catch( std::ios_base::failure )
         {
-          flag= TRUE;
+          flag= true;
         }
         if ( flag ) throw;
       }
@@ -635,7 +615,7 @@
 #elif defined BOOST_CHRONO_IS_LOCALIZABLE_TRANSLATE2
 #else
 
-      typedef typename chrono_detail::duration_io_intermediate<Rep>::type intermediate_type;
+      typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
       intermediate_type r;
       // read value into r
       is >> r;
Modified: trunk/boost/chrono/io/duration_put.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_put.hpp	(original)
+++ trunk/boost/chrono/io/duration_put.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -1,4 +1,5 @@
 //
+//  (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
@@ -66,7 +67,7 @@
        * @param s an output stream iterator
        * @param ios a reference to a ios_base
        * @param d the duration
-       * @param pattern begin of the formatting patter
+       * @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,
@@ -93,6 +94,47 @@
         if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
             std::locale(ios.getloc(), new duration_units_default<CharT> ()));
 
+#if 1
+        const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
+        for (; pattern != pat_end; ++pattern)
+        {
+            if (ct.narrow(*pattern, 0) == '%')
+            {
+                if (++pattern == pat_end)
+                {
+                    *s++ = pattern[-1];
+                    break;
+                }
+                char fmt = ct.narrow(*pattern, 0);
+                switch (fmt)
+                {
+                case 'v':
+                {
+                  s = put_value(s, ios, d);
+                  break;
+                }
+                case 'u':
+                {
+                  s = put_unit(s, ios, d);
+                  break;
+                }
+                case 'x':
+                {
+                  std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+                  pattern = pat.data();
+                  pat_end = pattern + pat.size();
+                  break;
+                }
+                default:
+                  BOOST_ASSERT(false && "Boost::Chrono internal error.");
+                  break;
+                }
+            }
+            else
+                *s++ = *pattern;
+        }
+
+#else
         for (; pattern != pat_end; ++pattern)
         {
           // FIXME: Shouldn't "uvx" be a basic_string<CharT> ?????
@@ -107,12 +149,12 @@
             {
             case 'v':
             {
-              put_value(s, ios, d);
+              s = put_value(s, ios, d);
               break;
             }
             case 'u':
             {
-              put_unit(s, ios, d);
+              s = put_unit(s, ios, d);
               break;
             }
             case 'x':
@@ -128,6 +170,7 @@
             }
           }
         }
+#endif
         return s;
       }
 
@@ -158,7 +201,7 @@
        * @param s an output stream iterator
        * @param ios a reference to a ios_base
        * @param d the duration
-       * @Effects Calls do_put_value(s, f, d).
+       * @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>
@@ -174,12 +217,16 @@
        * @param ios a reference to a ios_base
        * @param d the duration
        * @param pattern
-       * @Effects Calls do_put_unit(s, f, d).
+       * @Effects imbue in @c ios the @c duration_units_default facet if not already present.
+       * @Effects Calls std::use_facet<duration_units<CharT> >(ios.getloc()).put(s, ios, d).
        * @Returns An iterator pointing immediately after the last character produced.
        */
       template <typename Rep, typename Period>
       iter_type put_unit(iter_type s, std::ios_base& ios, duration<Rep, Period> const& d) const
       {
+        if (!std::has_facet<duration_units<CharT> >(ios.getloc())) ios.imbue(
+            std::locale(ios.getloc(), new duration_units_default<CharT> ()));
+
         return std::use_facet<duration_units<CharT> >(ios.getloc()).put(s, ios, d);
       }
 
Modified: trunk/boost/chrono/io/duration_unit_string.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_unit_string.hpp	(original)
+++ trunk/boost/chrono/io/duration_unit_string.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -1,4 +1,5 @@
 //
+//  (C) Copyright Howard Hinnant
 //  (C) Copyright 2010-2011 Vicente J. Botet Escriba
 //  Use, modification and distribution are subject to the Boost Software License,
 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Modified: trunk/boost/chrono/io/duration_units.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_units.hpp	(original)
+++ trunk/boost/chrono/io/duration_units.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -1,4 +1,5 @@
 //
+//  (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
@@ -112,6 +113,11 @@
         {
         }
 
+        rt_ratio(intmax_t n=0, intmax_t d=0) :
+          num(n), den(d)
+        {
+        }
+
         intmax_t num;
         intmax_t den;
       };
@@ -224,6 +230,7 @@
         return do_get_plural_form(style, Period(), pf);
       }
 
+
       /**
        *
        * @return the pattern to be used by default.
Modified: trunk/boost/chrono/io/ios_base_state.hpp
==============================================================================
--- trunk/boost/chrono/io/ios_base_state.hpp	(original)
+++ trunk/boost/chrono/io/ios_base_state.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -1,4 +1,4 @@
-//  boost/chrono/io/detail/fmt_masks.hpp
+//  boost/chrono/io/ios_base_state.hpp
 //
 //  (C) Copyright 2010-2011 Vicente J. Botet Escriba
 //  Use, modification and distribution are subject to the Boost Software License,
Modified: trunk/boost/chrono/io/translate.hpp
==============================================================================
--- trunk/boost/chrono/io/translate.hpp	(original)
+++ trunk/boost/chrono/io/translate.hpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -1,4 +1,5 @@
 //
+//  (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
Modified: trunk/libs/chrono/test/io/duration_input.cpp
==============================================================================
--- trunk/libs/chrono/test/io/duration_input.cpp	(original)
+++ trunk/libs/chrono/test/io/duration_input.cpp	2011-10-31 15:04:46 EDT (Mon, 31 Oct 2011)
@@ -12,7 +12,7 @@
   std::istringstream in(str);
   D d(0);
   in >> d;
-  BOOST_TEST(in.good());
+  BOOST_TEST(!in.fail());
   BOOST_TEST(d == res);
 }
 
@@ -30,7 +30,7 @@
     std::istringstream in(str);
     DGood d = DGood::zero();
     in >> d;
-    BOOST_TEST(in.good());
+    BOOST_TEST(!in.fail());
     BOOST_TEST(d == res);
   }
 }