$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [release] Permission to merge after regression cycle
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-10-23 19:26:15
Hi,
I have been fixing some bugs on Boost.Chrono
#9274 <https://svn.boost.org/trac/boost/ticket/9274> 	lost of precission 
on system_clock input <https://svn.boost.org/trac/boost/ticket/9274> 	
        
        
        
        
#9276 <https://svn.boost.org/trac/boost/ticket/9276> 	output from a 
system_clock::time_point get a time_point that is one day later than 
expected <https://svn.boost.org/trac/boost/ticket/9276>
#9265 <https://svn.boost.org/trac/boost/ticket/9265> 
time_point_output_h test crashes regression test 
<https://svn.boost.org/trac/boost/ticket/9265>
#8328 <https://svn.boost.org/trac/boost/ticket/8328> 	chrono crashes 
visual studio 2012 regression tests 
<https://svn.boost.org/trac/boost/ticket/8328>
The concerned change sets are
19:00 Changeset /[86410]/ by viboes 
<https://svn.boost.org/trac/boost/changeset/86410>
    Thread: Try to fix system_clock::time_point output on windows. 
18:01 Changeset /[86384]/ by viboes 
<https://svn.boost.org/trac/boost/changeset/86384>
    Chrono: try to avoid the crash with msvc 11 on chrono_io. 
17:36 Changeset /[86383]/ by viboes 
<https://svn.boost.org/trac/boost/changeset/86383>
    Chrono: set precission to 9 so that there is no lost with the
    hisgest ... 
14:27 Changeset /[86376]/ by viboes 
<https://svn.boost.org/trac/boost/changeset/86376>
    Chrono: fix two important issues with Boost.Chrono IO v2 on windows
    * ... 
14:54 Changeset /[86357]/ by viboes 
<https://svn.boost.org/trac/boost/changeset/86357>
Chrono: don't run test_good_utc_fmt_system_clock on windows as this is ...
I would like to merge these changeset to release. Is it time to do it 
before releasing boost 1.55?
Best,
Vicente
Patch:
  svn diff boost/chrono/detail/inlined/win/chrono.hpp 
boost/chrono/io/time_point_io.hpp 
libs/chrono/test/io/time_point_output.cpp libs/chrono/example/io_ex1.cpp
Index: boost/chrono/detail/inlined/win/chrono.hpp
===================================================================
--- boost/chrono/detail/inlined/win/chrono.hpp    (revision 86326)
+++ boost/chrono/detail/inlined/win/chrono.hpp    (working copy)
@@ -109,8 +109,11 @@
      {
          ec.clear();
      }
-    return time_point(duration(
-      (static_cast<__int64>( ft.dwHighDateTime ) << 32) | 
ft.dwLowDateTime));
+    return system_clock::time_point(
+      system_clock::duration(
+       ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | 
ft.dwLowDateTime)
+       -116444736000000000LL
+       ));
    }
  #endif
Index: boost/chrono/io/time_point_io.hpp
===================================================================
--- boost/chrono/io/time_point_io.hpp    (revision 86326)
+++ boost/chrono/io/time_point_io.hpp    (working copy)
@@ -28,6 +28,7 @@
  #include <boost/chrono/clock_string.hpp>
  #include <boost/chrono/round.hpp>
  #include <boost/chrono/detail/scan_keyword.hpp>
+#include <boost/static_assert.hpp>
  #include <boost/detail/no_exceptions_support.hpp>
  #include <cstring>
  #include <locale>
@@ -46,9 +47,11 @@
  {
    namespace chrono
    {
+    typedef double fractional_seconds;
      namespace detail
      {
+
        template <class CharT, class InputIterator = 
std::istreambuf_iterator<CharT> >
        struct time_get
        {
@@ -758,6 +761,7 @@
          { 0,31,59,90,120,151,181,212,243,273,304,334},
          { 0,31,60,91,121,152,182,213,244,274,305,335}
        };
+
        return days[is_leap(year)][month-1] + day - 1;
      }
@@ -779,7 +783,7 @@
        month++;
        int day = t->tm_mday;
        int day_of_year = days_from_1jan(year,month,day);
-      int days_since_epoch = days_from_1970(year) + day_of_year;
+      int days_since_epoch = days_from_1970(year) + day_of_year ;
        time_t seconds_in_day = 3600 * 24;
        time_t result = seconds_in_day * days_since_epoch + 3600 * 
t->tm_hour + 60 * t->tm_min + t->tm_sec;
@@ -801,11 +805,36 @@
       return y * 365 + y / 4 - y / 100 + y / 400;
     }
+    // Returns year/month/day triple in civil calendar
+    // Preconditions:  z is number of days since 1970-01-01 and is in 
the range:
+    //                   [numeric_limits<Int>::min(), 
numeric_limits<Int>::max()-719468].
+    template <class Int>
+    //constexpr
+    void
+    inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) 
BOOST_NOEXCEPT
+    {
+ BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
+                 "This algorithm has not been ported to a 16 bit 
unsigned integer");
+ BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
+                 "This algorithm has not been ported to a 16 bit signed 
integer");
+        z += 719468;
+        const Int era = (z >= 0 ? z : z - 146096) / 146097;
+        const unsigned doe = static_cast<unsigned>(z - era * 
146097);          // [0, 146096]
+        const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) 
/ 365;  // [0, 399]
+        y = static_cast<Int>(yoe) + era * 400;
+        const unsigned doy = doe - (365*yoe + yoe/4 - 
yoe/100);                // [0, 365]
+        const unsigned mp = (5*doy + 
2)/153;                                   // [0, 11]
+        d = doy - (153*mp+2)/5 + 1;                             // [1, 31]
+        m = mp + (mp < 10 ? 3 : -9); // [1, 12]
+        y += (m <= 2);
+        --m;
+    }
     inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
     {
        if (t==0) return 0;
        if (tm==0) return 0;
+#if 0
        static  const unsigned char
          day_of_year_month[2][366] =
             {
@@ -820,6 +849,7 @@
         { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
         { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
       };
+#endif
       const time_t seconds_in_day = 3600 * 24;
       int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
@@ -829,6 +859,7 @@
         hms = seconds_in_day+hms;
       }
+#if 0
       int32_t x = days_since_epoch;
       int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) 
* 400
             / 146097);
@@ -843,16 +874,23 @@
         //y -= 32767 + 2;
         y += 70;
         tm->tm_year=y;
-       const bool leap = is_leap(y);
+       const int32_t leap = is_leap(y);
         tm->tm_mon = day_of_year_month[leap][doy]-1;
-       tm->tm_mday = doy - 
days_in_year_before[leap][day_of_year_month[leap][doy] - 1];
+       tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
+#else
+       int32_t y;
+       unsigned m, d;
+       civil_from_days(days_since_epoch, y, m, d);
+       tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
+#endif
-
       tm->tm_hour = hms / 3600;
       const int ms = hms % 3600;
       tm->tm_min = ms / 60;
       tm->tm_sec = ms % 60;
+     tm->tm_isdst = -1;
+     (void)mktime(tm);
       return tm;
     }
@@ -907,6 +945,9 @@
                tm = *tmp;
  #else
              if (gmtime_r(&t, &tm) == 0) failed = true;
+            tm.tm_isdst = -1;
+            (void)mktime(&tm);
+
  #endif
            }
@@ -922,7 +963,7 @@
                failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
                if (!failed)
                {
-                duration<double> d = tp - system_clock::from_time_t(t) 
+ seconds(tm.tm_sec);
+                duration<fractional_seconds> d = tp - 
system_clock::from_time_t(t) + seconds(tm.tm_sec);
                  if (d.count() < 10) os << CharT('0');
                  //if (! os.good()) {
                  //  throw "exception";
@@ -932,6 +973,7 @@
                  //if (! os.good()) {
                  //throw "exception";
                  //}
+                os.precision(9);
                  os << d.count();
                  //if (! os.good()) {
                  //throw "exception";
@@ -1058,12 +1100,8 @@
            const std::time_get<CharT>& tg = 
std::use_facet<std::time_get<CharT> >(loc);
            const std::ctype<CharT>& ct = 
std::use_facet<std::ctype<CharT> >(loc);
            tm tm; // {0}
-          tm.tm_year=0;
-          tm.tm_mon=0;
-          tm.tm_mday=0;
-          tm.tm_hour=0;
-          tm.tm_min=0;
-          tm.tm_sec=0;
+          std::memset(&tm, 0, sizeof(std::tm));
+
            typedef std::istreambuf_iterator<CharT, Traits> It;
            if (pb == pe)
            {
@@ -1079,9 +1117,13 @@
              tg.get(is, 0, is, err, &tm, pb, pe);
  #endif
              if (err & std::ios_base::failbit) goto exit;
-            double sec;
+            fractional_seconds sec;
              CharT c = CharT();
+            std::ios::fmtflags flgs = is.flags();
+            is.setf(std::ios::fixed, std::ios::floatfield);
+            is.precision(9);
              is >> sec;
+            is.flags(flgs);
              if (is.fail())
              {
                err |= std::ios_base::failbit;
@@ -1099,13 +1141,14 @@
              if (err & std::ios_base::failbit) goto exit;
              time_t t;
+
  #if BOOST_CHRONO_INTERNAL_TIMEGM
              t = detail::internal_timegm(&tm);
  #else
              t = timegm(&tm);
  #endif
              tp = time_point_cast<Duration>(
-                system_clock::from_time_t(t) - min + 
round<microseconds> (duration<double> (sec))
+                system_clock::from_time_t(t) - min + 
round<system_clock::duration> (duration<fractional_seconds> (sec))
                  );
            }
            else
Index: libs/chrono/test/io/time_point_output.cpp
===================================================================
--- libs/chrono/test/io/time_point_output.cpp    (revision 86326)
+++ libs/chrono/test/io/time_point_output.cpp    (working copy)
@@ -148,68 +148,102 @@
    using namespace boost::chrono;
    using namespace boost;
-  test_good_system_clock("1970-01-01 02:00:00.000000 +0000", hours(2), 
duration_style::prefix);
-  test_good_system_clock("1970-01-01 02:00:00.000000 +0000", hours(2), 
duration_style::symbol);
+  test_good_system_clock("1970-01-01 02:00:00.000000000 +0000", 
hours(2), duration_style::prefix);
+  test_good_system_clock("1970-01-01 02:00:00.000000000 +0000", 
hours(2), duration_style::symbol);
-  test_good_prefix_system_clock("1970-01-01 02:00:00.000000 +0000", 
hours(2));
-  test_good_prefix_system_clock("1970-01-01 00:02:00.000000 +0000", 
minutes(2));
-  test_good_prefix_system_clock("1970-01-01 00:00:02.000000 +0000", 
seconds(2));
-  test_good_prefix_system_clock("1970-01-01 00:00:01.000000 +0000", 
seconds(1));
-  test_good_prefix_system_clock("1969-12-31 23:59:59.000000 +0000", 
seconds(-1));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.000000 +0000", 
seconds(0));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.002000 +0000", 
milliseconds(2));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.000002 +0000", 
microseconds(2));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.000000 +0000", 
nanoseconds(2));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.200000 +0000", 
duration<boost::int_least64_t, deci> (2));
-  test_good_prefix_system_clock("1970-01-01 00:00:00.066667 +0000", 
duration<boost::int_least64_t, ratio<1, 30> > (2));
+  test_good_prefix_system_clock("1970-01-01 02:00:00.000000000 +0000", 
hours(2));
+  test_good_prefix_system_clock("1970-01-01 00:02:00.000000000 +0000", 
minutes(2));
+  test_good_prefix_system_clock("1970-01-01 00:00:02.000000000 +0000", 
seconds(2));
+  test_good_prefix_system_clock("1970-01-01 00:00:01.000000000 +0000", 
seconds(1));
+  test_good_prefix_system_clock("1969-12-31 23:59:59.000000000 +0000", 
seconds(-1));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.000000000 +0000", 
seconds(0));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.002000000 +0000", 
milliseconds(2));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.000002000 +0000", 
microseconds(2));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.000000002 +0000", 
nanoseconds(2));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.200000000 +0000", 
duration<boost::int_least64_t, deci> (2));
+  test_good_prefix_system_clock("1970-01-01 00:00:00.066666667 +0000", 
duration<boost::int_least64_t, ratio<1, 30> > (2));
-  test_good_symbol_system_clock("1970-01-01 02:00:00.000000 +0000", 
hours(2));
-  test_good_symbol_system_clock("1970-01-01 00:02:00.000000 +0000", 
minutes(2));
-  test_good_symbol_system_clock("1970-01-01 00:00:02.000000 +0000", 
seconds(2));
-  test_good_symbol_system_clock("1970-01-01 00:00:00.002000 +0000", 
milliseconds(2));
-  test_good_symbol_system_clock("1970-01-01 00:00:00.000000 +0000", 
nanoseconds(2));
-  test_good_symbol_system_clock("1970-01-01 00:00:00.200000 +0000", 
duration<boost::int_least64_t, deci> (2));
-  test_good_symbol_system_clock("1970-01-01 00:00:00.066667 +0000", 
duration<boost::int_least64_t, ratio<1, 30> > (2));
+  test_good_symbol_system_clock("1970-01-01 02:00:00.000000000 +0000", 
hours(2));
+  test_good_symbol_system_clock("1970-01-01 00:02:00.000000000 +0000", 
minutes(2));
+  test_good_symbol_system_clock("1970-01-01 00:00:02.000000000 +0000", 
seconds(2));
+  test_good_symbol_system_clock("1970-01-01 00:00:00.002000000 +0000", 
milliseconds(2));
+  test_good_symbol_system_clock("1970-01-01 00:00:00.000000002 +0000", 
nanoseconds(2));
+  test_good_symbol_system_clock("1970-01-01 00:00:00.200000000 +0000", 
duration<boost::int_least64_t, deci> (2));
+  test_good_symbol_system_clock("1970-01-01 00:00:00.066666667 +0000", 
duration<boost::int_least64_t, ratio<1, 30> > (2));
    test_good_utc_fmt_system_clock("1970-01-01 02:00:00", "%Y-%m-%d 
%H:%M:%S", hours(2));
    test_good_utc_fmt_system_clock("1970-01-01 02", "%Y-%m-%d %H", 
hours(2));
-
+#if ! defined(BOOST_CHRONO_WINDOWS_API)
    test_good_utc_fmt_system_clock ("1970-01-01 02:00:00", "%Y-%m-%d 
%T", hours(2));
    test_good_utc_fmt_system_clock ("1970-01-01 02:00", "%Y-%m-%d %R", 
hours(2));
    test_good_utc_fmt_system_clock ("% 1970-01-01 02:00", "%% %Y-%m-%d 
%R", hours(2));
    test_good_utc_fmt_system_clock ("1970-01-01 02:00 Thursday January", 
"%Y-%m-%d %R %A %B", hours(2));
-
+#endif
  }
+
+#endif
+#if BOOST_CHRONO_VERSION == 2
  void test_gmtime(std::time_t t)
  {
    std::cout << "t    " << t << std::endl;
+  puts(ctime(&t));
    std::tm tm;
+  std::memset(&tm, 0, sizeof(std::tm));
    if (boost::chrono::detail::internal_gmtime(&t, &tm))
    {
-    std::cout << "year  " << tm.tm_year << std::endl;
-    std::cout << "month " << tm.tm_mon << std::endl;
-    std::cout << "day   " << tm.tm_mday << std::endl;
-    std::cout << "hour  " << tm.tm_hour << std::endl;
-    std::cout << "min   " << tm.tm_min << std::endl;
-    std::cout << "sec   " << tm.tm_sec << std::endl;
+    tm.tm_isdst = -1;
+    (void)mktime(&tm);
+    std::tm tm2;
+    std::memset(&tm2, 0, sizeof(std::tm));
+    if (gmtime_r(&t, &tm2))
+    {
+      tm2.tm_isdst = -1;
+      (void)mktime(&tm2);
+
+      BOOST_TEST_EQ( tm.tm_year , tm2.tm_year );
+      BOOST_TEST_EQ( tm.tm_mon , tm2.tm_mon );
+      BOOST_TEST_EQ( tm.tm_mday , tm2.tm_mday );
+      BOOST_TEST_EQ( tm.tm_hour , tm2.tm_hour);
+      BOOST_TEST_EQ( tm.tm_min , tm2.tm_min );
+      BOOST_TEST_EQ( tm.tm_sec , tm2.tm_sec );
+      BOOST_TEST_EQ( tm.tm_wday , tm2.tm_wday );
+      BOOST_TEST_EQ( tm.tm_yday , tm2.tm_yday );
+      BOOST_TEST_EQ( tm.tm_isdst , tm2.tm_isdst );
+    }
    }
+
  }
  #endif
+
  int main()
  {
-//  test_gmtime(  0 );
-//  test_gmtime( -1  );
-//  test_gmtime( +1  );
-//  test_gmtime(  0 - (3600 * 24) );
-//  test_gmtime( -1 - (3600 * 24) );
-//  test_gmtime( +1 - (3600 * 24) );
-//  test_gmtime(  0 + (3600 * 24) );
-//  test_gmtime( -1 + (3600 * 24) );
-//  test_gmtime( +1 + (3600 * 24) );
+#if BOOST_CHRONO_VERSION == 2
+  test_gmtime(  0 );
+  test_gmtime( -1  );
+  test_gmtime( +1  );
+  test_gmtime(  0 - (3600 * 24) );
+  test_gmtime( -1 - (3600 * 24) );
+  test_gmtime( +1 - (3600 * 24) );
+  test_gmtime(  0 + (3600 * 24) );
+  test_gmtime( -1 + (3600 * 24) );
+  test_gmtime( +1 + (3600 * 24) );
+  test_gmtime(  0 + 365*(3600 * 24) );
+  test_gmtime(  0 + 10LL*365*(3600 * 24) );
+  test_gmtime(  0 + 15LL*365*(3600 * 24) );
+  test_gmtime(  0 + 17LL*365*(3600 * 24) );
+  test_gmtime(  0 + 18LL*365*(3600 * 24) );
+  test_gmtime(  0 + 19LL*365*(3600 * 24) );
+  test_gmtime(  0 + 19LL*365*(3600 * 24)+ (3600 * 24));
+  test_gmtime(  0 + 19LL*365*(3600 * 24)+ 3*(3600 * 24));
+  test_gmtime(  0 + 19LL*365*(3600 * 24)+ 4*(3600 * 24));
+  test_gmtime(  0 + 20LL*365*(3600 * 24) );
+  test_gmtime(  0 + 40LL*365*(3600 * 24) );
+#endif
+
    std::cout << "high_resolution_clock=" << std::endl;
    check_all<boost::chrono::high_resolution_clock> ();
  #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
@@ -239,6 +273,13 @@
    check_all<boost::chrono::process_cpu_clock> ();
  #endif
+#if BOOST_CHRONO_VERSION == 2
+  boost::chrono::system_clock::time_point tp = 
boost::chrono::system_clock::now();
+  std::cout << tp << std::endl;
+  time_t t = boost::chrono::system_clock::to_time_t(tp);
+  test_gmtime(  t );
+#endif
+
    return boost::report_errors();
  }
Index: libs/chrono/example/io_ex1.cpp
===================================================================
--- libs/chrono/example/io_ex1.cpp    (revision 86326)
+++ libs/chrono/example/io_ex1.cpp    (working copy)
@@ -53,10 +53,13 @@
           <<  ClockTick(3) + nanoseconds(10) << '\n';
      cout << "\nsystem_clock::now() = " << system_clock::now() << '\n';
+#if defined _MSC_VER && _MSC_VER == 1700
+#else
  #if BOOST_CHRONO_VERSION==2
      cout << "\nsystem_clock::now() = " << 
time_fmt(chrono::timezone::local) << system_clock::now() << '\n';
      cout << "\nsystem_clock::now() = " << 
time_fmt(chrono::timezone::local,"%Y/%m/%d") << system_clock::now() << '\n';
  #endif
+#endif
  #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
      cout << "steady_clock::now() = " << steady_clock::now() << '\n';