@@ -1401,6 +1401,7 @@ struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
14011401
14021402template <typename FormatContext, typename OutputIt> struct tm_formatter {
14031403 using char_type = typename FormatContext::char_type;
1404+ static constexpr int daysperweek = 7 ;
14041405
14051406 FormatContext& ctx;
14061407 OutputIt out;
@@ -1415,8 +1416,7 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14151416 int upper;
14161417 int lower;
14171418 };
1418- auto tm_split_year () const -> split_year {
1419- auto year = tm_year ();
1419+ auto tm_split_year (int year) const -> split_year {
14201420 auto q = year / 100 ;
14211421 auto r = year % 100 ;
14221422 if (r < 0 ) {
@@ -1429,8 +1429,9 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14291429 auto hour = tm.tm_hour % 12 ;
14301430 return hour == 0 ? 12 : hour;
14311431 }
1432- static constexpr char digits1 (size_t value) {
1433- return detail::digits2 (value)[1 ];
1432+ void write1 (size_t value) { *out++ = detail::digits2 (value)[1 ]; }
1433+ void write2 (size_t value) {
1434+ out = std::copy_n (detail::digits2 (value), 2 , out);
14341435 }
14351436
14361437 explicit tm_formatter (FormatContext& ctx_, OutputIt out_, const std::tm& tm_)
@@ -1470,14 +1471,14 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14701471 void on_full_weekday () { format_localized (' A' ); }
14711472 void on_dec0_weekday (numeric_system ns) {
14721473 if (ns == numeric_system::standard) {
1473- *out++ = digits1 (detail::to_unsigned (tm.tm_wday ));
1474+ write1 (detail::to_unsigned (tm.tm_wday ));
14741475 } else {
14751476 format_localized (' w' , ' O' );
14761477 }
14771478 }
14781479 void on_dec1_weekday (numeric_system ns) {
14791480 if (ns == numeric_system::standard) {
1480- *out++ = digits1 (detail::to_unsigned (tm.tm_wday == 0 ? 7 : tm.tm_wday ));
1481+ write1 (detail::to_unsigned (tm.tm_wday == 0 ? daysperweek : tm.tm_wday ));
14811482 } else {
14821483 format_localized (' u' , ' O' );
14831484 }
@@ -1496,10 +1497,10 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14961497 }
14971498 void on_us_date () {
14981499 char buf[8 ];
1499- detail::write_digit2_separated (buf, detail::to_unsigned (tm. tm_mon + 1 ),
1500- detail::to_unsigned (tm.tm_mday ),
1501- detail::to_unsigned (tm_split_year (). lower ),
1502- ' /' );
1500+ detail::write_digit2_separated (
1501+ buf, detail::to_unsigned (tm.tm_mon + 1 ),
1502+ detail::to_unsigned (tm. tm_mday ),
1503+ detail::to_unsigned ( tm_split_year ( tm_year ()). lower ), ' /' );
15031504 out = std::copy_n (buf, sizeof (buf), out);
15041505 }
15051506 void on_iso_date () {
@@ -1529,19 +1530,17 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15291530 }
15301531 void on_last2_year (numeric_system ns) {
15311532 if (ns == numeric_system::standard) {
1532- out = std::copy_n (
1533- detail::digits2 (detail::to_unsigned (tm_split_year ().lower )), 2 , out);
1533+ write2 (detail::to_unsigned (tm_split_year (tm_year ()).lower ));
15341534 } else {
15351535 format_localized (' y' , ' O' );
15361536 }
15371537 }
15381538 void on_offset_year () { format_localized (' y' , ' E' ); }
15391539 void on_base_year (numeric_system ns) {
15401540 if (ns == numeric_system::standard) {
1541- auto split = tm_split_year ();
1541+ auto split = tm_split_year (tm_year () );
15421542 if (split.upper >= 0 && split.upper < 100 ) {
1543- out = std::copy_n (detail::digits2 (detail::to_unsigned (split.upper )), 2 ,
1544- out);
1543+ write2 (detail::to_unsigned (split.upper ));
15451544 } else {
15461545 out = detail::write<char_type>(out, split.upper );
15471546 }
@@ -1551,31 +1550,32 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15511550 }
15521551 void on_dec_month (numeric_system ns) {
15531552 if (ns == numeric_system::standard) {
1554- out = std::copy_n (detail::digits2 (detail::to_unsigned (tm.tm_mon + 1 )), 2 ,
1555- out);
1553+ write2 (detail::to_unsigned (tm.tm_mon + 1 ));
15561554 } else {
15571555 format_localized (' m' , ' O' );
15581556 }
15591557 }
15601558 void on_dec0_week_of_year (numeric_system ns) {
1561- // TODO: Optimization
15621559 if (ns == numeric_system::standard) {
1563- format_localized (' U' );
1560+ write2 (detail::to_unsigned ((tm.tm_yday + daysperweek - tm.tm_wday ) /
1561+ daysperweek));
15641562 } else {
15651563 format_localized (' U' , ' O' );
15661564 }
15671565 }
15681566 void on_dec1_week_of_year (numeric_system ns) {
1569- // TODO: Optimization
15701567 if (ns == numeric_system::standard) {
1571- format_localized (' W' );
1568+ write2 (detail::to_unsigned (
1569+ (tm.tm_yday + daysperweek -
1570+ (tm.tm_wday == 0 ? (daysperweek - 1 ) : (tm.tm_wday - 1 ))) /
1571+ daysperweek));
15721572 } else {
15731573 format_localized (' W' , ' O' );
15741574 }
15751575 }
15761576 void on_iso_week_of_year (numeric_system ns) {
1577- // TODO: Optimization
15781577 if (ns == numeric_system::standard) {
1578+ // TODO: Optimization
15791579 format_localized (' V' );
15801580 } else {
15811581 format_localized (' V' , ' O' );
@@ -1591,13 +1591,12 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15911591 }
15921592 void on_day_of_year () {
15931593 auto yday = tm.tm_yday + 1 ;
1594- *out++ = digits1 (detail::to_unsigned (yday / 100 ));
1595- out = std::copy_n (detail::digits2 ( detail:: to_unsigned (yday % 100 )), 2 , out );
1594+ write1 (detail::to_unsigned (yday / 100 ));
1595+ write2 (detail::to_unsigned (yday % 100 ));
15961596 }
15971597 void on_day_of_month_zero (numeric_system ns) {
15981598 if (ns == numeric_system::standard) {
1599- out =
1600- std::copy_n (detail::digits2 (detail::to_unsigned (tm.tm_mday )), 2 , out);
1599+ write2 (detail::to_unsigned (tm.tm_mday ));
16011600 } else {
16021601 format_localized (' d' , ' O' );
16031602 }
@@ -1613,41 +1612,37 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
16131612 }
16141613 void on_24_hour (numeric_system ns) {
16151614 if (ns == numeric_system::standard) {
1616- out =
1617- std::copy_n (detail::digits2 (detail::to_unsigned (tm.tm_hour )), 2 , out);
1615+ write2 (detail::to_unsigned (tm.tm_hour ));
16181616 } else {
16191617 format_localized (' H' , ' O' );
16201618 }
16211619 }
16221620 void on_12_hour (numeric_system ns) {
16231621 if (ns == numeric_system::standard) {
1624- out = std::copy_n (detail::digits2 (detail::to_unsigned (tm_hour12 ())), 2 ,
1625- out);
1622+ write2 (detail::to_unsigned (tm_hour12 ()));
16261623 } else {
16271624 format_localized (' I' , ' O' );
16281625 }
16291626 }
16301627 void on_minute (numeric_system ns) {
16311628 if (ns == numeric_system::standard) {
1632- out =
1633- std::copy_n (detail::digits2 (detail::to_unsigned (tm.tm_min )), 2 , out);
1629+ write2 (detail::to_unsigned (tm.tm_min ));
16341630 } else {
16351631 format_localized (' M' , ' O' );
16361632 }
16371633 }
16381634 void on_second (numeric_system ns) {
16391635 if (ns == numeric_system::standard) {
1640- out =
1641- std::copy_n (detail::digits2 (detail::to_unsigned (tm.tm_sec )), 2 , out);
1636+ write2 (detail::to_unsigned (tm.tm_sec ));
16421637 } else {
16431638 format_localized (' S' , ' O' );
16441639 }
16451640 }
16461641 void on_12_hour_time () { format_localized (' r' ); }
16471642 void on_24_hour_time () {
1648- out = std::copy_n (detail::digits2 ( detail:: to_unsigned (tm.tm_hour )), 2 , out );
1643+ write2 (detail::to_unsigned (tm.tm_hour ));
16491644 *out++ = ' :' ;
1650- out = std::copy_n (detail::digits2 ( detail:: to_unsigned (tm.tm_min )), 2 , out );
1645+ write2 (detail::to_unsigned (tm.tm_min ));
16511646 }
16521647 void on_iso_time () {
16531648 char buf[8 ];
0 commit comments