[release] Permission to merge after regression cycle

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';

On 10/23/2013 4:26 PM, Vicente J. Botet Escriba wrote:
Hi,
I have been fixing some bugs on Boost.Chrono <snip>
I would like to merge these changeset to release. Is it time to do it before releasing boost 1.55?
Always check the release schedule at http://www.boost.org/development/index.html when you have these questions. There you'll see that bug fixes are allowed without release manager permission until Monday. So fire when ready (after the tests have cycled and they look good, of course). Thanks, -- Eric Niebler Boost.org http://www.boost.org

On Wed, Oct 23, 2013 at 10:28 PM, Eric Niebler <eniebler@boost.org> wrote:
Always check the release schedule at http://www.boost.org/development/index.html when you have these questions. There you'll see that bug fixes are allowed without release manager permission until Monday. So fire when ready (after the tests have cycled and they look good, of course).
The calender is a little confusing, in that it also says 1.55.0 was closed except by permission on Sept 30.

On 10/23/2013 7:49 PM, Frank Mori Hess wrote:
On Wed, Oct 23, 2013 at 10:28 PM, Eric Niebler <eniebler@boost.org> wrote:
Always check the release schedule at http://www.boost.org/development/index.html when you have these questions. There you'll see that bug fixes are allowed without release manager permission until Monday. So fire when ready (after the tests have cycled and they look good, of course).
The calender is a little confusing, in that it also says 1.55.0 was closed except by permission on Sept 30.
That should read 1.55.0 *beta* was closed on Sept 30 except by permission, but you could infer that by the "1.55.0 Begin beta RC" entry 3 days later. -- Eric Niebler Boost.org http://www.boost.org

Le 24/10/13 04:28, Eric Niebler a écrit :
On 10/23/2013 4:26 PM, Vicente J. Botet Escriba wrote:
Hi,
I have been fixing some bugs on Boost.Chrono <snip>
I would like to merge these changeset to release. Is it time to do it before releasing boost 1.55? Always check the release schedule at http://www.boost.org/development/index.html when you have these questions. There you'll see that bug fixes are allowed without release manager permission until Monday. So fire when ready (after the tests have cycled and they look good, of course).
You are right, I should do it every time :( I have started to see some tester pass OK on darwin, linux and windows since rev 86425. Even if it doesn't fix all the testers it will be better than the current situation. I have just do the merge. Committed revision 86448. Best, Vicente
participants (3)
-
Eric Niebler
-
Frank Mori Hess
-
Vicente J. Botet Escriba