1*1b8b02a4SEd Tanous // NOLINTBEGIN 2*1b8b02a4SEd Tanous // clang-format off 3*1b8b02a4SEd Tanous 4*1b8b02a4SEd Tanous /* 5*1b8b02a4SEd Tanous * Originally sourced from 6*1b8b02a4SEd Tanous * https://github.com/HowardHinnant/date/blob/master/include/date/date.h 7*1b8b02a4SEd Tanous */ 8*1b8b02a4SEd Tanous 9*1b8b02a4SEd Tanous #ifndef DATE_H 10*1b8b02a4SEd Tanous #define DATE_H 11*1b8b02a4SEd Tanous 12*1b8b02a4SEd Tanous // The MIT License (MIT) 13*1b8b02a4SEd Tanous // 14*1b8b02a4SEd Tanous // Copyright (c) 2015, 2016, 2017 Howard Hinnant 15*1b8b02a4SEd Tanous // Copyright (c) 2016 Adrian Colomitchi 16*1b8b02a4SEd Tanous // Copyright (c) 2017 Florian Dang 17*1b8b02a4SEd Tanous // Copyright (c) 2017 Paul Thompson 18*1b8b02a4SEd Tanous // Copyright (c) 2018, 2019 Tomasz Kamiński 19*1b8b02a4SEd Tanous // Copyright (c) 2019 Jiangang Zhuang 20*1b8b02a4SEd Tanous // 21*1b8b02a4SEd Tanous // Permission is hereby granted, free of charge, to any person obtaining a copy 22*1b8b02a4SEd Tanous // of this software and associated documentation files (the "Software"), to deal 23*1b8b02a4SEd Tanous // in the Software without restriction, including without limitation the rights 24*1b8b02a4SEd Tanous // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25*1b8b02a4SEd Tanous // copies of the Software, and to permit persons to whom the Software is 26*1b8b02a4SEd Tanous // furnished to do so, subject to the following conditions: 27*1b8b02a4SEd Tanous // 28*1b8b02a4SEd Tanous // The above copyright notice and this permission notice shall be included in all 29*1b8b02a4SEd Tanous // copies or substantial portions of the Software. 30*1b8b02a4SEd Tanous // 31*1b8b02a4SEd Tanous // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32*1b8b02a4SEd Tanous // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33*1b8b02a4SEd Tanous // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34*1b8b02a4SEd Tanous // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35*1b8b02a4SEd Tanous // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36*1b8b02a4SEd Tanous // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37*1b8b02a4SEd Tanous // SOFTWARE. 38*1b8b02a4SEd Tanous // 39*1b8b02a4SEd Tanous // Our apologies. When the previous paragraph was written, lowercase had not yet 40*1b8b02a4SEd Tanous // been invented (that would involve another several millennia of evolution). 41*1b8b02a4SEd Tanous // We did not mean to shout. 42*1b8b02a4SEd Tanous 43*1b8b02a4SEd Tanous #ifndef HAS_STRING_VIEW 44*1b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 45*1b8b02a4SEd Tanous # define HAS_STRING_VIEW 1 46*1b8b02a4SEd Tanous # else 47*1b8b02a4SEd Tanous # define HAS_STRING_VIEW 0 48*1b8b02a4SEd Tanous # endif 49*1b8b02a4SEd Tanous #endif // HAS_STRING_VIEW 50*1b8b02a4SEd Tanous 51*1b8b02a4SEd Tanous #include <cassert> 52*1b8b02a4SEd Tanous #include <algorithm> 53*1b8b02a4SEd Tanous #include <cctype> 54*1b8b02a4SEd Tanous #include <chrono> 55*1b8b02a4SEd Tanous #include <climits> 56*1b8b02a4SEd Tanous #include <cmath> 57*1b8b02a4SEd Tanous #include <cstddef> 58*1b8b02a4SEd Tanous #include <cstdint> 59*1b8b02a4SEd Tanous #include <cstdlib> 60*1b8b02a4SEd Tanous #include <ctime> 61*1b8b02a4SEd Tanous #include <ios> 62*1b8b02a4SEd Tanous #include <istream> 63*1b8b02a4SEd Tanous #include <iterator> 64*1b8b02a4SEd Tanous #include <limits> 65*1b8b02a4SEd Tanous #include <locale> 66*1b8b02a4SEd Tanous #include <memory> 67*1b8b02a4SEd Tanous #include <ostream> 68*1b8b02a4SEd Tanous #include <ratio> 69*1b8b02a4SEd Tanous #include <sstream> 70*1b8b02a4SEd Tanous #include <stdexcept> 71*1b8b02a4SEd Tanous #include <string> 72*1b8b02a4SEd Tanous #if HAS_STRING_VIEW 73*1b8b02a4SEd Tanous # include <string_view> 74*1b8b02a4SEd Tanous #endif 75*1b8b02a4SEd Tanous #include <utility> 76*1b8b02a4SEd Tanous #include <type_traits> 77*1b8b02a4SEd Tanous 78*1b8b02a4SEd Tanous 79*1b8b02a4SEd Tanous #ifdef __GNUC__ 80*1b8b02a4SEd Tanous # pragma GCC diagnostic push 81*1b8b02a4SEd Tanous # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) 82*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wpedantic" 83*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wconversion" 84*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wold-style-cast" 85*1b8b02a4SEd Tanous # endif 86*1b8b02a4SEd Tanous # if __GNUC__ < 5 87*1b8b02a4SEd Tanous // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers 88*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wmissing-field-initializers" 89*1b8b02a4SEd Tanous # endif 90*1b8b02a4SEd Tanous #endif 91*1b8b02a4SEd Tanous 92*1b8b02a4SEd Tanous #ifdef __clang__ 93*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" 94*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 95*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wold-style-cast" 96*1b8b02a4SEd Tanous #endif 97*1b8b02a4SEd Tanous 98*1b8b02a4SEd Tanous #ifdef _MSC_VER 99*1b8b02a4SEd Tanous # pragma warning(push) 100*1b8b02a4SEd Tanous // warning C4127: conditional expression is constant 101*1b8b02a4SEd Tanous # pragma warning(disable : 4127) 102*1b8b02a4SEd Tanous #endif 103*1b8b02a4SEd Tanous 104*1b8b02a4SEd Tanous namespace date 105*1b8b02a4SEd Tanous { 106*1b8b02a4SEd Tanous 107*1b8b02a4SEd Tanous //---------------+ 108*1b8b02a4SEd Tanous // Configuration | 109*1b8b02a4SEd Tanous //---------------+ 110*1b8b02a4SEd Tanous 111*1b8b02a4SEd Tanous #ifndef ONLY_C_LOCALE 112*1b8b02a4SEd Tanous # define ONLY_C_LOCALE 1 113*1b8b02a4SEd Tanous #endif 114*1b8b02a4SEd Tanous 115*1b8b02a4SEd Tanous #if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910)) 116*1b8b02a4SEd Tanous // MSVC 117*1b8b02a4SEd Tanous # ifndef _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 118*1b8b02a4SEd Tanous # define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 119*1b8b02a4SEd Tanous # endif 120*1b8b02a4SEd Tanous # if _MSC_VER < 1910 121*1b8b02a4SEd Tanous // before VS2017 122*1b8b02a4SEd Tanous # define CONSTDATA const 123*1b8b02a4SEd Tanous # define CONSTCD11 124*1b8b02a4SEd Tanous # define CONSTCD14 125*1b8b02a4SEd Tanous # define NOEXCEPT _NOEXCEPT 126*1b8b02a4SEd Tanous # else 127*1b8b02a4SEd Tanous // VS2017 and later 128*1b8b02a4SEd Tanous # define CONSTDATA constexpr const 129*1b8b02a4SEd Tanous # define CONSTCD11 constexpr 130*1b8b02a4SEd Tanous # define CONSTCD14 constexpr 131*1b8b02a4SEd Tanous # define NOEXCEPT noexcept 132*1b8b02a4SEd Tanous # endif 133*1b8b02a4SEd Tanous 134*1b8b02a4SEd Tanous #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 135*1b8b02a4SEd Tanous // Oracle Developer Studio 12.6 and earlier 136*1b8b02a4SEd Tanous # define CONSTDATA constexpr const 137*1b8b02a4SEd Tanous # define CONSTCD11 constexpr 138*1b8b02a4SEd Tanous # define CONSTCD14 139*1b8b02a4SEd Tanous # define NOEXCEPT noexcept 140*1b8b02a4SEd Tanous 141*1b8b02a4SEd Tanous #elif __cplusplus >= 201402 142*1b8b02a4SEd Tanous // C++14 143*1b8b02a4SEd Tanous # define CONSTDATA constexpr const 144*1b8b02a4SEd Tanous # define CONSTCD11 constexpr 145*1b8b02a4SEd Tanous # define CONSTCD14 constexpr 146*1b8b02a4SEd Tanous # define NOEXCEPT noexcept 147*1b8b02a4SEd Tanous #else 148*1b8b02a4SEd Tanous // C++11 149*1b8b02a4SEd Tanous # define CONSTDATA constexpr const 150*1b8b02a4SEd Tanous # define CONSTCD11 constexpr 151*1b8b02a4SEd Tanous # define CONSTCD14 152*1b8b02a4SEd Tanous # define NOEXCEPT noexcept 153*1b8b02a4SEd Tanous #endif 154*1b8b02a4SEd Tanous 155*1b8b02a4SEd Tanous #ifndef HAS_UNCAUGHT_EXCEPTIONS 156*1b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 157*1b8b02a4SEd Tanous # define HAS_UNCAUGHT_EXCEPTIONS 1 158*1b8b02a4SEd Tanous # else 159*1b8b02a4SEd Tanous # define HAS_UNCAUGHT_EXCEPTIONS 0 160*1b8b02a4SEd Tanous # endif 161*1b8b02a4SEd Tanous #endif // HAS_UNCAUGHT_EXCEPTIONS 162*1b8b02a4SEd Tanous 163*1b8b02a4SEd Tanous #ifndef HAS_VOID_T 164*1b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 165*1b8b02a4SEd Tanous # define HAS_VOID_T 1 166*1b8b02a4SEd Tanous # else 167*1b8b02a4SEd Tanous # define HAS_VOID_T 0 168*1b8b02a4SEd Tanous # endif 169*1b8b02a4SEd Tanous #endif // HAS_VOID_T 170*1b8b02a4SEd Tanous 171*1b8b02a4SEd Tanous // Protect from Oracle sun macro 172*1b8b02a4SEd Tanous #ifdef sun 173*1b8b02a4SEd Tanous # undef sun 174*1b8b02a4SEd Tanous #endif 175*1b8b02a4SEd Tanous 176*1b8b02a4SEd Tanous // Work around for a NVCC compiler bug which causes it to fail 177*1b8b02a4SEd Tanous // to compile std::ratio_{multiply,divide} when used directly 178*1b8b02a4SEd Tanous // in the std::chrono::duration template instantiations below 179*1b8b02a4SEd Tanous namespace detail { 180*1b8b02a4SEd Tanous template <typename R1, typename R2> 181*1b8b02a4SEd Tanous using ratio_multiply = decltype(std::ratio_multiply<R1, R2>{}); 182*1b8b02a4SEd Tanous 183*1b8b02a4SEd Tanous template <typename R1, typename R2> 184*1b8b02a4SEd Tanous using ratio_divide = decltype(std::ratio_divide<R1, R2>{}); 185*1b8b02a4SEd Tanous } // namespace detail 186*1b8b02a4SEd Tanous 187*1b8b02a4SEd Tanous //-----------+ 188*1b8b02a4SEd Tanous // Interface | 189*1b8b02a4SEd Tanous //-----------+ 190*1b8b02a4SEd Tanous 191*1b8b02a4SEd Tanous // durations 192*1b8b02a4SEd Tanous 193*1b8b02a4SEd Tanous using days = std::chrono::duration 194*1b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>; 195*1b8b02a4SEd Tanous 196*1b8b02a4SEd Tanous using weeks = std::chrono::duration 197*1b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<7>, days::period>>; 198*1b8b02a4SEd Tanous 199*1b8b02a4SEd Tanous using years = std::chrono::duration 200*1b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<146097, 400>, days::period>>; 201*1b8b02a4SEd Tanous 202*1b8b02a4SEd Tanous using months = std::chrono::duration 203*1b8b02a4SEd Tanous <int, detail::ratio_divide<years::period, std::ratio<12>>>; 204*1b8b02a4SEd Tanous 205*1b8b02a4SEd Tanous // time_point 206*1b8b02a4SEd Tanous 207*1b8b02a4SEd Tanous template <class Duration> 208*1b8b02a4SEd Tanous using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>; 209*1b8b02a4SEd Tanous 210*1b8b02a4SEd Tanous using sys_days = sys_time<days>; 211*1b8b02a4SEd Tanous using sys_seconds = sys_time<std::chrono::seconds>; 212*1b8b02a4SEd Tanous 213*1b8b02a4SEd Tanous struct local_t {}; 214*1b8b02a4SEd Tanous 215*1b8b02a4SEd Tanous template <class Duration> 216*1b8b02a4SEd Tanous using local_time = std::chrono::time_point<local_t, Duration>; 217*1b8b02a4SEd Tanous 218*1b8b02a4SEd Tanous using local_seconds = local_time<std::chrono::seconds>; 219*1b8b02a4SEd Tanous using local_days = local_time<days>; 220*1b8b02a4SEd Tanous 221*1b8b02a4SEd Tanous // types 222*1b8b02a4SEd Tanous 223*1b8b02a4SEd Tanous struct last_spec 224*1b8b02a4SEd Tanous { 225*1b8b02a4SEd Tanous explicit last_spec() = default; 226*1b8b02a4SEd Tanous }; 227*1b8b02a4SEd Tanous 228*1b8b02a4SEd Tanous class day; 229*1b8b02a4SEd Tanous class month; 230*1b8b02a4SEd Tanous class year; 231*1b8b02a4SEd Tanous 232*1b8b02a4SEd Tanous class weekday; 233*1b8b02a4SEd Tanous class weekday_indexed; 234*1b8b02a4SEd Tanous class weekday_last; 235*1b8b02a4SEd Tanous 236*1b8b02a4SEd Tanous class month_day; 237*1b8b02a4SEd Tanous class month_day_last; 238*1b8b02a4SEd Tanous class month_weekday; 239*1b8b02a4SEd Tanous class month_weekday_last; 240*1b8b02a4SEd Tanous 241*1b8b02a4SEd Tanous class year_month; 242*1b8b02a4SEd Tanous 243*1b8b02a4SEd Tanous class year_month_day; 244*1b8b02a4SEd Tanous class year_month_day_last; 245*1b8b02a4SEd Tanous class year_month_weekday; 246*1b8b02a4SEd Tanous class year_month_weekday_last; 247*1b8b02a4SEd Tanous 248*1b8b02a4SEd Tanous // date composition operators 249*1b8b02a4SEd Tanous 250*1b8b02a4SEd Tanous CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; 251*1b8b02a4SEd Tanous CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; 252*1b8b02a4SEd Tanous 253*1b8b02a4SEd Tanous CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; 254*1b8b02a4SEd Tanous CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; 255*1b8b02a4SEd Tanous CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; 256*1b8b02a4SEd Tanous CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; 257*1b8b02a4SEd Tanous CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; 258*1b8b02a4SEd Tanous 259*1b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; 260*1b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; 261*1b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; 262*1b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; 263*1b8b02a4SEd Tanous 264*1b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; 265*1b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; 266*1b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; 267*1b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; 268*1b8b02a4SEd Tanous 269*1b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; 270*1b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; 271*1b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; 272*1b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; 273*1b8b02a4SEd Tanous 274*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; 275*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; 276*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; 277*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; 278*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; 279*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; 280*1b8b02a4SEd Tanous 281*1b8b02a4SEd Tanous CONSTCD11 282*1b8b02a4SEd Tanous year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; 283*1b8b02a4SEd Tanous CONSTCD11 284*1b8b02a4SEd Tanous year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; 285*1b8b02a4SEd Tanous CONSTCD11 286*1b8b02a4SEd Tanous year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; 287*1b8b02a4SEd Tanous CONSTCD11 288*1b8b02a4SEd Tanous year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; 289*1b8b02a4SEd Tanous CONSTCD11 290*1b8b02a4SEd Tanous year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; 291*1b8b02a4SEd Tanous 292*1b8b02a4SEd Tanous CONSTCD11 293*1b8b02a4SEd Tanous year_month_weekday 294*1b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; 295*1b8b02a4SEd Tanous 296*1b8b02a4SEd Tanous CONSTCD11 297*1b8b02a4SEd Tanous year_month_weekday 298*1b8b02a4SEd Tanous operator/(const year& y, const month_weekday& mwd) NOEXCEPT; 299*1b8b02a4SEd Tanous 300*1b8b02a4SEd Tanous CONSTCD11 301*1b8b02a4SEd Tanous year_month_weekday 302*1b8b02a4SEd Tanous operator/(int y, const month_weekday& mwd) NOEXCEPT; 303*1b8b02a4SEd Tanous 304*1b8b02a4SEd Tanous CONSTCD11 305*1b8b02a4SEd Tanous year_month_weekday 306*1b8b02a4SEd Tanous operator/(const month_weekday& mwd, const year& y) NOEXCEPT; 307*1b8b02a4SEd Tanous 308*1b8b02a4SEd Tanous CONSTCD11 309*1b8b02a4SEd Tanous year_month_weekday 310*1b8b02a4SEd Tanous operator/(const month_weekday& mwd, int y) NOEXCEPT; 311*1b8b02a4SEd Tanous 312*1b8b02a4SEd Tanous CONSTCD11 313*1b8b02a4SEd Tanous year_month_weekday_last 314*1b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; 315*1b8b02a4SEd Tanous 316*1b8b02a4SEd Tanous CONSTCD11 317*1b8b02a4SEd Tanous year_month_weekday_last 318*1b8b02a4SEd Tanous operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; 319*1b8b02a4SEd Tanous 320*1b8b02a4SEd Tanous CONSTCD11 321*1b8b02a4SEd Tanous year_month_weekday_last 322*1b8b02a4SEd Tanous operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; 323*1b8b02a4SEd Tanous 324*1b8b02a4SEd Tanous CONSTCD11 325*1b8b02a4SEd Tanous year_month_weekday_last 326*1b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; 327*1b8b02a4SEd Tanous 328*1b8b02a4SEd Tanous CONSTCD11 329*1b8b02a4SEd Tanous year_month_weekday_last 330*1b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; 331*1b8b02a4SEd Tanous 332*1b8b02a4SEd Tanous // Detailed interface 333*1b8b02a4SEd Tanous 334*1b8b02a4SEd Tanous // day 335*1b8b02a4SEd Tanous 336*1b8b02a4SEd Tanous class day 337*1b8b02a4SEd Tanous { 338*1b8b02a4SEd Tanous unsigned char d_; 339*1b8b02a4SEd Tanous 340*1b8b02a4SEd Tanous public: 341*1b8b02a4SEd Tanous day() = default; 342*1b8b02a4SEd Tanous explicit CONSTCD11 day(unsigned d) NOEXCEPT; 343*1b8b02a4SEd Tanous 344*1b8b02a4SEd Tanous CONSTCD14 day& operator++() NOEXCEPT; 345*1b8b02a4SEd Tanous CONSTCD14 day operator++(int) NOEXCEPT; 346*1b8b02a4SEd Tanous CONSTCD14 day& operator--() NOEXCEPT; 347*1b8b02a4SEd Tanous CONSTCD14 day operator--(int) NOEXCEPT; 348*1b8b02a4SEd Tanous 349*1b8b02a4SEd Tanous CONSTCD14 day& operator+=(const days& d) NOEXCEPT; 350*1b8b02a4SEd Tanous CONSTCD14 day& operator-=(const days& d) NOEXCEPT; 351*1b8b02a4SEd Tanous 352*1b8b02a4SEd Tanous CONSTCD11 explicit operator unsigned() const NOEXCEPT; 353*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 354*1b8b02a4SEd Tanous }; 355*1b8b02a4SEd Tanous 356*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; 357*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; 358*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; 359*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; 360*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; 361*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; 362*1b8b02a4SEd Tanous 363*1b8b02a4SEd Tanous CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; 364*1b8b02a4SEd Tanous CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; 365*1b8b02a4SEd Tanous CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; 366*1b8b02a4SEd Tanous CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; 367*1b8b02a4SEd Tanous 368*1b8b02a4SEd Tanous template<class CharT, class Traits> 369*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 370*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const day& d); 371*1b8b02a4SEd Tanous 372*1b8b02a4SEd Tanous // month 373*1b8b02a4SEd Tanous 374*1b8b02a4SEd Tanous class month 375*1b8b02a4SEd Tanous { 376*1b8b02a4SEd Tanous unsigned char m_; 377*1b8b02a4SEd Tanous 378*1b8b02a4SEd Tanous public: 379*1b8b02a4SEd Tanous month() = default; 380*1b8b02a4SEd Tanous explicit CONSTCD11 month(unsigned m) NOEXCEPT; 381*1b8b02a4SEd Tanous 382*1b8b02a4SEd Tanous CONSTCD14 month& operator++() NOEXCEPT; 383*1b8b02a4SEd Tanous CONSTCD14 month operator++(int) NOEXCEPT; 384*1b8b02a4SEd Tanous CONSTCD14 month& operator--() NOEXCEPT; 385*1b8b02a4SEd Tanous CONSTCD14 month operator--(int) NOEXCEPT; 386*1b8b02a4SEd Tanous 387*1b8b02a4SEd Tanous CONSTCD14 month& operator+=(const months& m) NOEXCEPT; 388*1b8b02a4SEd Tanous CONSTCD14 month& operator-=(const months& m) NOEXCEPT; 389*1b8b02a4SEd Tanous 390*1b8b02a4SEd Tanous CONSTCD11 explicit operator unsigned() const NOEXCEPT; 391*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 392*1b8b02a4SEd Tanous }; 393*1b8b02a4SEd Tanous 394*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; 395*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; 396*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; 397*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; 398*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; 399*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; 400*1b8b02a4SEd Tanous 401*1b8b02a4SEd Tanous CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; 402*1b8b02a4SEd Tanous CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; 403*1b8b02a4SEd Tanous CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; 404*1b8b02a4SEd Tanous CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; 405*1b8b02a4SEd Tanous 406*1b8b02a4SEd Tanous template<class CharT, class Traits> 407*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 408*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month& m); 409*1b8b02a4SEd Tanous 410*1b8b02a4SEd Tanous // year 411*1b8b02a4SEd Tanous 412*1b8b02a4SEd Tanous class year 413*1b8b02a4SEd Tanous { 414*1b8b02a4SEd Tanous short y_; 415*1b8b02a4SEd Tanous 416*1b8b02a4SEd Tanous public: 417*1b8b02a4SEd Tanous year() = default; 418*1b8b02a4SEd Tanous explicit CONSTCD11 year(int y) NOEXCEPT; 419*1b8b02a4SEd Tanous 420*1b8b02a4SEd Tanous CONSTCD14 year& operator++() NOEXCEPT; 421*1b8b02a4SEd Tanous CONSTCD14 year operator++(int) NOEXCEPT; 422*1b8b02a4SEd Tanous CONSTCD14 year& operator--() NOEXCEPT; 423*1b8b02a4SEd Tanous CONSTCD14 year operator--(int) NOEXCEPT; 424*1b8b02a4SEd Tanous 425*1b8b02a4SEd Tanous CONSTCD14 year& operator+=(const years& y) NOEXCEPT; 426*1b8b02a4SEd Tanous CONSTCD14 year& operator-=(const years& y) NOEXCEPT; 427*1b8b02a4SEd Tanous 428*1b8b02a4SEd Tanous CONSTCD11 year operator-() const NOEXCEPT; 429*1b8b02a4SEd Tanous CONSTCD11 year operator+() const NOEXCEPT; 430*1b8b02a4SEd Tanous 431*1b8b02a4SEd Tanous CONSTCD11 bool is_leap() const NOEXCEPT; 432*1b8b02a4SEd Tanous 433*1b8b02a4SEd Tanous CONSTCD11 explicit operator int() const NOEXCEPT; 434*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 435*1b8b02a4SEd Tanous 436*1b8b02a4SEd Tanous static CONSTCD11 year min() NOEXCEPT { return year{-32767}; } 437*1b8b02a4SEd Tanous static CONSTCD11 year max() NOEXCEPT { return year{32767}; } 438*1b8b02a4SEd Tanous }; 439*1b8b02a4SEd Tanous 440*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; 441*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; 442*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; 443*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; 444*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; 445*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; 446*1b8b02a4SEd Tanous 447*1b8b02a4SEd Tanous CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; 448*1b8b02a4SEd Tanous CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; 449*1b8b02a4SEd Tanous CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; 450*1b8b02a4SEd Tanous CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; 451*1b8b02a4SEd Tanous 452*1b8b02a4SEd Tanous template<class CharT, class Traits> 453*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 454*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year& y); 455*1b8b02a4SEd Tanous 456*1b8b02a4SEd Tanous // weekday 457*1b8b02a4SEd Tanous 458*1b8b02a4SEd Tanous class weekday 459*1b8b02a4SEd Tanous { 460*1b8b02a4SEd Tanous unsigned char wd_; 461*1b8b02a4SEd Tanous public: 462*1b8b02a4SEd Tanous weekday() = default; 463*1b8b02a4SEd Tanous explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; 464*1b8b02a4SEd Tanous CONSTCD14 weekday(const sys_days& dp) NOEXCEPT; 465*1b8b02a4SEd Tanous CONSTCD14 explicit weekday(const local_days& dp) NOEXCEPT; 466*1b8b02a4SEd Tanous 467*1b8b02a4SEd Tanous CONSTCD14 weekday& operator++() NOEXCEPT; 468*1b8b02a4SEd Tanous CONSTCD14 weekday operator++(int) NOEXCEPT; 469*1b8b02a4SEd Tanous CONSTCD14 weekday& operator--() NOEXCEPT; 470*1b8b02a4SEd Tanous CONSTCD14 weekday operator--(int) NOEXCEPT; 471*1b8b02a4SEd Tanous 472*1b8b02a4SEd Tanous CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; 473*1b8b02a4SEd Tanous CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; 474*1b8b02a4SEd Tanous 475*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 476*1b8b02a4SEd Tanous 477*1b8b02a4SEd Tanous CONSTCD11 unsigned c_encoding() const NOEXCEPT; 478*1b8b02a4SEd Tanous CONSTCD11 unsigned iso_encoding() const NOEXCEPT; 479*1b8b02a4SEd Tanous 480*1b8b02a4SEd Tanous CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; 481*1b8b02a4SEd Tanous CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; 482*1b8b02a4SEd Tanous 483*1b8b02a4SEd Tanous private: 484*1b8b02a4SEd Tanous static CONSTCD14 unsigned char weekday_from_days(int z) NOEXCEPT; 485*1b8b02a4SEd Tanous 486*1b8b02a4SEd Tanous friend CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; 487*1b8b02a4SEd Tanous friend CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; 488*1b8b02a4SEd Tanous friend CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; 489*1b8b02a4SEd Tanous template<class CharT, class Traits> 490*1b8b02a4SEd Tanous friend std::basic_ostream<CharT, Traits>& 491*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd); 492*1b8b02a4SEd Tanous friend class weekday_indexed; 493*1b8b02a4SEd Tanous }; 494*1b8b02a4SEd Tanous 495*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; 496*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; 497*1b8b02a4SEd Tanous 498*1b8b02a4SEd Tanous CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; 499*1b8b02a4SEd Tanous CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; 500*1b8b02a4SEd Tanous CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; 501*1b8b02a4SEd Tanous CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; 502*1b8b02a4SEd Tanous 503*1b8b02a4SEd Tanous template<class CharT, class Traits> 504*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 505*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd); 506*1b8b02a4SEd Tanous 507*1b8b02a4SEd Tanous // weekday_indexed 508*1b8b02a4SEd Tanous 509*1b8b02a4SEd Tanous class weekday_indexed 510*1b8b02a4SEd Tanous { 511*1b8b02a4SEd Tanous unsigned char wd_ : 4; 512*1b8b02a4SEd Tanous unsigned char index_ : 4; 513*1b8b02a4SEd Tanous 514*1b8b02a4SEd Tanous public: 515*1b8b02a4SEd Tanous weekday_indexed() = default; 516*1b8b02a4SEd Tanous CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT; 517*1b8b02a4SEd Tanous 518*1b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 519*1b8b02a4SEd Tanous CONSTCD11 unsigned index() const NOEXCEPT; 520*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 521*1b8b02a4SEd Tanous }; 522*1b8b02a4SEd Tanous 523*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; 524*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; 525*1b8b02a4SEd Tanous 526*1b8b02a4SEd Tanous template<class CharT, class Traits> 527*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 528*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi); 529*1b8b02a4SEd Tanous 530*1b8b02a4SEd Tanous // weekday_last 531*1b8b02a4SEd Tanous 532*1b8b02a4SEd Tanous class weekday_last 533*1b8b02a4SEd Tanous { 534*1b8b02a4SEd Tanous date::weekday wd_; 535*1b8b02a4SEd Tanous 536*1b8b02a4SEd Tanous public: 537*1b8b02a4SEd Tanous explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT; 538*1b8b02a4SEd Tanous 539*1b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 540*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 541*1b8b02a4SEd Tanous }; 542*1b8b02a4SEd Tanous 543*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; 544*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; 545*1b8b02a4SEd Tanous 546*1b8b02a4SEd Tanous template<class CharT, class Traits> 547*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 548*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl); 549*1b8b02a4SEd Tanous 550*1b8b02a4SEd Tanous namespace detail 551*1b8b02a4SEd Tanous { 552*1b8b02a4SEd Tanous 553*1b8b02a4SEd Tanous struct unspecified_month_disambiguator {}; 554*1b8b02a4SEd Tanous 555*1b8b02a4SEd Tanous } // namespace detail 556*1b8b02a4SEd Tanous 557*1b8b02a4SEd Tanous // year_month 558*1b8b02a4SEd Tanous 559*1b8b02a4SEd Tanous class year_month 560*1b8b02a4SEd Tanous { 561*1b8b02a4SEd Tanous date::year y_; 562*1b8b02a4SEd Tanous date::month m_; 563*1b8b02a4SEd Tanous 564*1b8b02a4SEd Tanous public: 565*1b8b02a4SEd Tanous year_month() = default; 566*1b8b02a4SEd Tanous CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT; 567*1b8b02a4SEd Tanous 568*1b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 569*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 570*1b8b02a4SEd Tanous 571*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 572*1b8b02a4SEd Tanous CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; 573*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 574*1b8b02a4SEd Tanous CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; 575*1b8b02a4SEd Tanous CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; 576*1b8b02a4SEd Tanous CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; 577*1b8b02a4SEd Tanous 578*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 579*1b8b02a4SEd Tanous }; 580*1b8b02a4SEd Tanous 581*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; 582*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; 583*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; 584*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; 585*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; 586*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; 587*1b8b02a4SEd Tanous 588*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 589*1b8b02a4SEd Tanous CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; 590*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 591*1b8b02a4SEd Tanous CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; 592*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 593*1b8b02a4SEd Tanous CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; 594*1b8b02a4SEd Tanous 595*1b8b02a4SEd Tanous CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; 596*1b8b02a4SEd Tanous CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; 597*1b8b02a4SEd Tanous CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; 598*1b8b02a4SEd Tanous CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; 599*1b8b02a4SEd Tanous 600*1b8b02a4SEd Tanous template<class CharT, class Traits> 601*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 602*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym); 603*1b8b02a4SEd Tanous 604*1b8b02a4SEd Tanous // month_day 605*1b8b02a4SEd Tanous 606*1b8b02a4SEd Tanous class month_day 607*1b8b02a4SEd Tanous { 608*1b8b02a4SEd Tanous date::month m_; 609*1b8b02a4SEd Tanous date::day d_; 610*1b8b02a4SEd Tanous 611*1b8b02a4SEd Tanous public: 612*1b8b02a4SEd Tanous month_day() = default; 613*1b8b02a4SEd Tanous CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT; 614*1b8b02a4SEd Tanous 615*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 616*1b8b02a4SEd Tanous CONSTCD11 date::day day() const NOEXCEPT; 617*1b8b02a4SEd Tanous 618*1b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 619*1b8b02a4SEd Tanous }; 620*1b8b02a4SEd Tanous 621*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; 622*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; 623*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; 624*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; 625*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; 626*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; 627*1b8b02a4SEd Tanous 628*1b8b02a4SEd Tanous template<class CharT, class Traits> 629*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 630*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md); 631*1b8b02a4SEd Tanous 632*1b8b02a4SEd Tanous // month_day_last 633*1b8b02a4SEd Tanous 634*1b8b02a4SEd Tanous class month_day_last 635*1b8b02a4SEd Tanous { 636*1b8b02a4SEd Tanous date::month m_; 637*1b8b02a4SEd Tanous 638*1b8b02a4SEd Tanous public: 639*1b8b02a4SEd Tanous CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT; 640*1b8b02a4SEd Tanous 641*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 642*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 643*1b8b02a4SEd Tanous }; 644*1b8b02a4SEd Tanous 645*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; 646*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 647*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; 648*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; 649*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 650*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 651*1b8b02a4SEd Tanous 652*1b8b02a4SEd Tanous template<class CharT, class Traits> 653*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 654*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl); 655*1b8b02a4SEd Tanous 656*1b8b02a4SEd Tanous // month_weekday 657*1b8b02a4SEd Tanous 658*1b8b02a4SEd Tanous class month_weekday 659*1b8b02a4SEd Tanous { 660*1b8b02a4SEd Tanous date::month m_; 661*1b8b02a4SEd Tanous date::weekday_indexed wdi_; 662*1b8b02a4SEd Tanous public: 663*1b8b02a4SEd Tanous CONSTCD11 month_weekday(const date::month& m, 664*1b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT; 665*1b8b02a4SEd Tanous 666*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 667*1b8b02a4SEd Tanous CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; 668*1b8b02a4SEd Tanous 669*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 670*1b8b02a4SEd Tanous }; 671*1b8b02a4SEd Tanous 672*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; 673*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; 674*1b8b02a4SEd Tanous 675*1b8b02a4SEd Tanous template<class CharT, class Traits> 676*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 677*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd); 678*1b8b02a4SEd Tanous 679*1b8b02a4SEd Tanous // month_weekday_last 680*1b8b02a4SEd Tanous 681*1b8b02a4SEd Tanous class month_weekday_last 682*1b8b02a4SEd Tanous { 683*1b8b02a4SEd Tanous date::month m_; 684*1b8b02a4SEd Tanous date::weekday_last wdl_; 685*1b8b02a4SEd Tanous 686*1b8b02a4SEd Tanous public: 687*1b8b02a4SEd Tanous CONSTCD11 month_weekday_last(const date::month& m, 688*1b8b02a4SEd Tanous const date::weekday_last& wd) NOEXCEPT; 689*1b8b02a4SEd Tanous 690*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 691*1b8b02a4SEd Tanous CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; 692*1b8b02a4SEd Tanous 693*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 694*1b8b02a4SEd Tanous }; 695*1b8b02a4SEd Tanous 696*1b8b02a4SEd Tanous CONSTCD11 697*1b8b02a4SEd Tanous bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; 698*1b8b02a4SEd Tanous CONSTCD11 699*1b8b02a4SEd Tanous bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; 700*1b8b02a4SEd Tanous 701*1b8b02a4SEd Tanous template<class CharT, class Traits> 702*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 703*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl); 704*1b8b02a4SEd Tanous 705*1b8b02a4SEd Tanous // class year_month_day 706*1b8b02a4SEd Tanous 707*1b8b02a4SEd Tanous class year_month_day 708*1b8b02a4SEd Tanous { 709*1b8b02a4SEd Tanous date::year y_; 710*1b8b02a4SEd Tanous date::month m_; 711*1b8b02a4SEd Tanous date::day d_; 712*1b8b02a4SEd Tanous 713*1b8b02a4SEd Tanous public: 714*1b8b02a4SEd Tanous year_month_day() = default; 715*1b8b02a4SEd Tanous CONSTCD11 year_month_day(const date::year& y, const date::month& m, 716*1b8b02a4SEd Tanous const date::day& d) NOEXCEPT; 717*1b8b02a4SEd Tanous CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; 718*1b8b02a4SEd Tanous 719*1b8b02a4SEd Tanous CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; 720*1b8b02a4SEd Tanous CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; 721*1b8b02a4SEd Tanous 722*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 723*1b8b02a4SEd Tanous CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; 724*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 725*1b8b02a4SEd Tanous CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; 726*1b8b02a4SEd Tanous CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; 727*1b8b02a4SEd Tanous CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; 728*1b8b02a4SEd Tanous 729*1b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 730*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 731*1b8b02a4SEd Tanous CONSTCD11 date::day day() const NOEXCEPT; 732*1b8b02a4SEd Tanous 733*1b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 734*1b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 735*1b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 736*1b8b02a4SEd Tanous 737*1b8b02a4SEd Tanous private: 738*1b8b02a4SEd Tanous static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; 739*1b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 740*1b8b02a4SEd Tanous }; 741*1b8b02a4SEd Tanous 742*1b8b02a4SEd Tanous CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; 743*1b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 744*1b8b02a4SEd Tanous CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; 745*1b8b02a4SEd Tanous CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; 746*1b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 747*1b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 748*1b8b02a4SEd Tanous 749*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 750*1b8b02a4SEd Tanous CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; 751*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 752*1b8b02a4SEd Tanous CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; 753*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 754*1b8b02a4SEd Tanous CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; 755*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; 756*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; 757*1b8b02a4SEd Tanous CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; 758*1b8b02a4SEd Tanous 759*1b8b02a4SEd Tanous template<class CharT, class Traits> 760*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 761*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd); 762*1b8b02a4SEd Tanous 763*1b8b02a4SEd Tanous // year_month_day_last 764*1b8b02a4SEd Tanous 765*1b8b02a4SEd Tanous class year_month_day_last 766*1b8b02a4SEd Tanous { 767*1b8b02a4SEd Tanous date::year y_; 768*1b8b02a4SEd Tanous date::month_day_last mdl_; 769*1b8b02a4SEd Tanous 770*1b8b02a4SEd Tanous public: 771*1b8b02a4SEd Tanous CONSTCD11 year_month_day_last(const date::year& y, 772*1b8b02a4SEd Tanous const date::month_day_last& mdl) NOEXCEPT; 773*1b8b02a4SEd Tanous 774*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 775*1b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; 776*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 777*1b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; 778*1b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; 779*1b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; 780*1b8b02a4SEd Tanous 781*1b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 782*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 783*1b8b02a4SEd Tanous CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; 784*1b8b02a4SEd Tanous CONSTCD14 date::day day() const NOEXCEPT; 785*1b8b02a4SEd Tanous 786*1b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 787*1b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 788*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 789*1b8b02a4SEd Tanous }; 790*1b8b02a4SEd Tanous 791*1b8b02a4SEd Tanous CONSTCD11 792*1b8b02a4SEd Tanous bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 793*1b8b02a4SEd Tanous CONSTCD11 794*1b8b02a4SEd Tanous bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 795*1b8b02a4SEd Tanous CONSTCD11 796*1b8b02a4SEd Tanous bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 797*1b8b02a4SEd Tanous CONSTCD11 798*1b8b02a4SEd Tanous bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 799*1b8b02a4SEd Tanous CONSTCD11 800*1b8b02a4SEd Tanous bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 801*1b8b02a4SEd Tanous CONSTCD11 802*1b8b02a4SEd Tanous bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 803*1b8b02a4SEd Tanous 804*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 805*1b8b02a4SEd Tanous CONSTCD14 806*1b8b02a4SEd Tanous year_month_day_last 807*1b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; 808*1b8b02a4SEd Tanous 809*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 810*1b8b02a4SEd Tanous CONSTCD14 811*1b8b02a4SEd Tanous year_month_day_last 812*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; 813*1b8b02a4SEd Tanous 814*1b8b02a4SEd Tanous CONSTCD11 815*1b8b02a4SEd Tanous year_month_day_last 816*1b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; 817*1b8b02a4SEd Tanous 818*1b8b02a4SEd Tanous CONSTCD11 819*1b8b02a4SEd Tanous year_month_day_last 820*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; 821*1b8b02a4SEd Tanous 822*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 823*1b8b02a4SEd Tanous CONSTCD14 824*1b8b02a4SEd Tanous year_month_day_last 825*1b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; 826*1b8b02a4SEd Tanous 827*1b8b02a4SEd Tanous CONSTCD11 828*1b8b02a4SEd Tanous year_month_day_last 829*1b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; 830*1b8b02a4SEd Tanous 831*1b8b02a4SEd Tanous template<class CharT, class Traits> 832*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 833*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl); 834*1b8b02a4SEd Tanous 835*1b8b02a4SEd Tanous // year_month_weekday 836*1b8b02a4SEd Tanous 837*1b8b02a4SEd Tanous class year_month_weekday 838*1b8b02a4SEd Tanous { 839*1b8b02a4SEd Tanous date::year y_; 840*1b8b02a4SEd Tanous date::month m_; 841*1b8b02a4SEd Tanous date::weekday_indexed wdi_; 842*1b8b02a4SEd Tanous 843*1b8b02a4SEd Tanous public: 844*1b8b02a4SEd Tanous year_month_weekday() = default; 845*1b8b02a4SEd Tanous CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, 846*1b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT; 847*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; 848*1b8b02a4SEd Tanous CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; 849*1b8b02a4SEd Tanous 850*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 851*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; 852*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 853*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; 854*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; 855*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; 856*1b8b02a4SEd Tanous 857*1b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 858*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 859*1b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 860*1b8b02a4SEd Tanous CONSTCD11 unsigned index() const NOEXCEPT; 861*1b8b02a4SEd Tanous CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; 862*1b8b02a4SEd Tanous 863*1b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 864*1b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 865*1b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 866*1b8b02a4SEd Tanous 867*1b8b02a4SEd Tanous private: 868*1b8b02a4SEd Tanous static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; 869*1b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 870*1b8b02a4SEd Tanous }; 871*1b8b02a4SEd Tanous 872*1b8b02a4SEd Tanous CONSTCD11 873*1b8b02a4SEd Tanous bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; 874*1b8b02a4SEd Tanous CONSTCD11 875*1b8b02a4SEd Tanous bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; 876*1b8b02a4SEd Tanous 877*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 878*1b8b02a4SEd Tanous CONSTCD14 879*1b8b02a4SEd Tanous year_month_weekday 880*1b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; 881*1b8b02a4SEd Tanous 882*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 883*1b8b02a4SEd Tanous CONSTCD14 884*1b8b02a4SEd Tanous year_month_weekday 885*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; 886*1b8b02a4SEd Tanous 887*1b8b02a4SEd Tanous CONSTCD11 888*1b8b02a4SEd Tanous year_month_weekday 889*1b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; 890*1b8b02a4SEd Tanous 891*1b8b02a4SEd Tanous CONSTCD11 892*1b8b02a4SEd Tanous year_month_weekday 893*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; 894*1b8b02a4SEd Tanous 895*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 896*1b8b02a4SEd Tanous CONSTCD14 897*1b8b02a4SEd Tanous year_month_weekday 898*1b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; 899*1b8b02a4SEd Tanous 900*1b8b02a4SEd Tanous CONSTCD11 901*1b8b02a4SEd Tanous year_month_weekday 902*1b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; 903*1b8b02a4SEd Tanous 904*1b8b02a4SEd Tanous template<class CharT, class Traits> 905*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 906*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi); 907*1b8b02a4SEd Tanous 908*1b8b02a4SEd Tanous // year_month_weekday_last 909*1b8b02a4SEd Tanous 910*1b8b02a4SEd Tanous class year_month_weekday_last 911*1b8b02a4SEd Tanous { 912*1b8b02a4SEd Tanous date::year y_; 913*1b8b02a4SEd Tanous date::month m_; 914*1b8b02a4SEd Tanous date::weekday_last wdl_; 915*1b8b02a4SEd Tanous 916*1b8b02a4SEd Tanous public: 917*1b8b02a4SEd Tanous CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, 918*1b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT; 919*1b8b02a4SEd Tanous 920*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 921*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; 922*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 923*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; 924*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; 925*1b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; 926*1b8b02a4SEd Tanous 927*1b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 928*1b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 929*1b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 930*1b8b02a4SEd Tanous CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; 931*1b8b02a4SEd Tanous 932*1b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 933*1b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 934*1b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 935*1b8b02a4SEd Tanous 936*1b8b02a4SEd Tanous private: 937*1b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 938*1b8b02a4SEd Tanous }; 939*1b8b02a4SEd Tanous 940*1b8b02a4SEd Tanous CONSTCD11 941*1b8b02a4SEd Tanous bool 942*1b8b02a4SEd Tanous operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; 943*1b8b02a4SEd Tanous 944*1b8b02a4SEd Tanous CONSTCD11 945*1b8b02a4SEd Tanous bool 946*1b8b02a4SEd Tanous operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; 947*1b8b02a4SEd Tanous 948*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 949*1b8b02a4SEd Tanous CONSTCD14 950*1b8b02a4SEd Tanous year_month_weekday_last 951*1b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; 952*1b8b02a4SEd Tanous 953*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 954*1b8b02a4SEd Tanous CONSTCD14 955*1b8b02a4SEd Tanous year_month_weekday_last 956*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; 957*1b8b02a4SEd Tanous 958*1b8b02a4SEd Tanous CONSTCD11 959*1b8b02a4SEd Tanous year_month_weekday_last 960*1b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; 961*1b8b02a4SEd Tanous 962*1b8b02a4SEd Tanous CONSTCD11 963*1b8b02a4SEd Tanous year_month_weekday_last 964*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; 965*1b8b02a4SEd Tanous 966*1b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 967*1b8b02a4SEd Tanous CONSTCD14 968*1b8b02a4SEd Tanous year_month_weekday_last 969*1b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; 970*1b8b02a4SEd Tanous 971*1b8b02a4SEd Tanous CONSTCD11 972*1b8b02a4SEd Tanous year_month_weekday_last 973*1b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; 974*1b8b02a4SEd Tanous 975*1b8b02a4SEd Tanous template<class CharT, class Traits> 976*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 977*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl); 978*1b8b02a4SEd Tanous 979*1b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 980*1b8b02a4SEd Tanous inline namespace literals 981*1b8b02a4SEd Tanous { 982*1b8b02a4SEd Tanous 983*1b8b02a4SEd Tanous CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT; 984*1b8b02a4SEd Tanous CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT; 985*1b8b02a4SEd Tanous 986*1b8b02a4SEd Tanous } // inline namespace literals 987*1b8b02a4SEd Tanous #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) 988*1b8b02a4SEd Tanous 989*1b8b02a4SEd Tanous // CONSTDATA date::month January{1}; 990*1b8b02a4SEd Tanous // CONSTDATA date::month February{2}; 991*1b8b02a4SEd Tanous // CONSTDATA date::month March{3}; 992*1b8b02a4SEd Tanous // CONSTDATA date::month April{4}; 993*1b8b02a4SEd Tanous // CONSTDATA date::month May{5}; 994*1b8b02a4SEd Tanous // CONSTDATA date::month June{6}; 995*1b8b02a4SEd Tanous // CONSTDATA date::month July{7}; 996*1b8b02a4SEd Tanous // CONSTDATA date::month August{8}; 997*1b8b02a4SEd Tanous // CONSTDATA date::month September{9}; 998*1b8b02a4SEd Tanous // CONSTDATA date::month October{10}; 999*1b8b02a4SEd Tanous // CONSTDATA date::month November{11}; 1000*1b8b02a4SEd Tanous // CONSTDATA date::month December{12}; 1001*1b8b02a4SEd Tanous // 1002*1b8b02a4SEd Tanous // CONSTDATA date::weekday Sunday{0u}; 1003*1b8b02a4SEd Tanous // CONSTDATA date::weekday Monday{1u}; 1004*1b8b02a4SEd Tanous // CONSTDATA date::weekday Tuesday{2u}; 1005*1b8b02a4SEd Tanous // CONSTDATA date::weekday Wednesday{3u}; 1006*1b8b02a4SEd Tanous // CONSTDATA date::weekday Thursday{4u}; 1007*1b8b02a4SEd Tanous // CONSTDATA date::weekday Friday{5u}; 1008*1b8b02a4SEd Tanous // CONSTDATA date::weekday Saturday{6u}; 1009*1b8b02a4SEd Tanous 1010*1b8b02a4SEd Tanous #if HAS_VOID_T 1011*1b8b02a4SEd Tanous 1012*1b8b02a4SEd Tanous template <class T, class = std::void_t<>> 1013*1b8b02a4SEd Tanous struct is_clock 1014*1b8b02a4SEd Tanous : std::false_type 1015*1b8b02a4SEd Tanous {}; 1016*1b8b02a4SEd Tanous 1017*1b8b02a4SEd Tanous template <class T> 1018*1b8b02a4SEd Tanous struct is_clock<T, std::void_t<decltype(T::now()), typename T::rep, typename T::period, 1019*1b8b02a4SEd Tanous typename T::duration, typename T::time_point, 1020*1b8b02a4SEd Tanous decltype(T::is_steady)>> 1021*1b8b02a4SEd Tanous : std::true_type 1022*1b8b02a4SEd Tanous {}; 1023*1b8b02a4SEd Tanous 1024*1b8b02a4SEd Tanous template<class T> inline constexpr bool is_clock_v = is_clock<T>::value; 1025*1b8b02a4SEd Tanous 1026*1b8b02a4SEd Tanous #endif // HAS_VOID_T 1027*1b8b02a4SEd Tanous 1028*1b8b02a4SEd Tanous //----------------+ 1029*1b8b02a4SEd Tanous // Implementation | 1030*1b8b02a4SEd Tanous //----------------+ 1031*1b8b02a4SEd Tanous 1032*1b8b02a4SEd Tanous // utilities 1033*1b8b02a4SEd Tanous namespace detail { 1034*1b8b02a4SEd Tanous 1035*1b8b02a4SEd Tanous template<class CharT, class Traits = std::char_traits<CharT>> 1036*1b8b02a4SEd Tanous class save_istream 1037*1b8b02a4SEd Tanous { 1038*1b8b02a4SEd Tanous protected: 1039*1b8b02a4SEd Tanous std::basic_ios<CharT, Traits>& is_; 1040*1b8b02a4SEd Tanous CharT fill_; 1041*1b8b02a4SEd Tanous std::ios::fmtflags flags_; 1042*1b8b02a4SEd Tanous std::streamsize precision_; 1043*1b8b02a4SEd Tanous std::streamsize width_; 1044*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>* tie_; 1045*1b8b02a4SEd Tanous std::locale loc_; 1046*1b8b02a4SEd Tanous 1047*1b8b02a4SEd Tanous public: 1048*1b8b02a4SEd Tanous ~save_istream() 1049*1b8b02a4SEd Tanous { 1050*1b8b02a4SEd Tanous is_.fill(fill_); 1051*1b8b02a4SEd Tanous is_.flags(flags_); 1052*1b8b02a4SEd Tanous is_.precision(precision_); 1053*1b8b02a4SEd Tanous is_.width(width_); 1054*1b8b02a4SEd Tanous is_.imbue(loc_); 1055*1b8b02a4SEd Tanous is_.tie(tie_); 1056*1b8b02a4SEd Tanous } 1057*1b8b02a4SEd Tanous 1058*1b8b02a4SEd Tanous save_istream(const save_istream&) = delete; 1059*1b8b02a4SEd Tanous save_istream& operator=(const save_istream&) = delete; 1060*1b8b02a4SEd Tanous 1061*1b8b02a4SEd Tanous explicit save_istream(std::basic_ios<CharT, Traits>& is) 1062*1b8b02a4SEd Tanous : is_(is) 1063*1b8b02a4SEd Tanous , fill_(is.fill()) 1064*1b8b02a4SEd Tanous , flags_(is.flags()) 1065*1b8b02a4SEd Tanous , precision_(is.precision()) 1066*1b8b02a4SEd Tanous , width_(is.width(0)) 1067*1b8b02a4SEd Tanous , tie_(is.tie(nullptr)) 1068*1b8b02a4SEd Tanous , loc_(is.getloc()) 1069*1b8b02a4SEd Tanous { 1070*1b8b02a4SEd Tanous if (tie_ != nullptr) 1071*1b8b02a4SEd Tanous tie_->flush(); 1072*1b8b02a4SEd Tanous } 1073*1b8b02a4SEd Tanous }; 1074*1b8b02a4SEd Tanous 1075*1b8b02a4SEd Tanous template<class CharT, class Traits = std::char_traits<CharT>> 1076*1b8b02a4SEd Tanous class save_ostream 1077*1b8b02a4SEd Tanous : private save_istream<CharT, Traits> 1078*1b8b02a4SEd Tanous { 1079*1b8b02a4SEd Tanous public: 1080*1b8b02a4SEd Tanous ~save_ostream() 1081*1b8b02a4SEd Tanous { 1082*1b8b02a4SEd Tanous if ((this->flags_ & std::ios::unitbuf) && 1083*1b8b02a4SEd Tanous #if HAS_UNCAUGHT_EXCEPTIONS 1084*1b8b02a4SEd Tanous std::uncaught_exceptions() == 0 && 1085*1b8b02a4SEd Tanous #else 1086*1b8b02a4SEd Tanous !std::uncaught_exception() && 1087*1b8b02a4SEd Tanous #endif 1088*1b8b02a4SEd Tanous this->is_.good()) 1089*1b8b02a4SEd Tanous this->is_.rdbuf()->pubsync(); 1090*1b8b02a4SEd Tanous } 1091*1b8b02a4SEd Tanous 1092*1b8b02a4SEd Tanous save_ostream(const save_ostream&) = delete; 1093*1b8b02a4SEd Tanous save_ostream& operator=(const save_ostream&) = delete; 1094*1b8b02a4SEd Tanous 1095*1b8b02a4SEd Tanous explicit save_ostream(std::basic_ios<CharT, Traits>& os) 1096*1b8b02a4SEd Tanous : save_istream<CharT, Traits>(os) 1097*1b8b02a4SEd Tanous { 1098*1b8b02a4SEd Tanous } 1099*1b8b02a4SEd Tanous }; 1100*1b8b02a4SEd Tanous 1101*1b8b02a4SEd Tanous template <class T> 1102*1b8b02a4SEd Tanous struct choose_trunc_type 1103*1b8b02a4SEd Tanous { 1104*1b8b02a4SEd Tanous static const int digits = std::numeric_limits<T>::digits; 1105*1b8b02a4SEd Tanous using type = typename std::conditional 1106*1b8b02a4SEd Tanous < 1107*1b8b02a4SEd Tanous digits < 32, 1108*1b8b02a4SEd Tanous std::int32_t, 1109*1b8b02a4SEd Tanous typename std::conditional 1110*1b8b02a4SEd Tanous < 1111*1b8b02a4SEd Tanous digits < 64, 1112*1b8b02a4SEd Tanous std::int64_t, 1113*1b8b02a4SEd Tanous #ifdef __SIZEOF_INT128__ 1114*1b8b02a4SEd Tanous __int128 1115*1b8b02a4SEd Tanous #else 1116*1b8b02a4SEd Tanous std::int64_t 1117*1b8b02a4SEd Tanous #endif 1118*1b8b02a4SEd Tanous >::type 1119*1b8b02a4SEd Tanous >::type; 1120*1b8b02a4SEd Tanous }; 1121*1b8b02a4SEd Tanous 1122*1b8b02a4SEd Tanous template <class T> 1123*1b8b02a4SEd Tanous CONSTCD11 1124*1b8b02a4SEd Tanous inline 1125*1b8b02a4SEd Tanous typename std::enable_if 1126*1b8b02a4SEd Tanous < 1127*1b8b02a4SEd Tanous !std::chrono::treat_as_floating_point<T>::value, 1128*1b8b02a4SEd Tanous T 1129*1b8b02a4SEd Tanous >::type 1130*1b8b02a4SEd Tanous trunc(T t) NOEXCEPT 1131*1b8b02a4SEd Tanous { 1132*1b8b02a4SEd Tanous return t; 1133*1b8b02a4SEd Tanous } 1134*1b8b02a4SEd Tanous 1135*1b8b02a4SEd Tanous template <class T> 1136*1b8b02a4SEd Tanous CONSTCD14 1137*1b8b02a4SEd Tanous inline 1138*1b8b02a4SEd Tanous typename std::enable_if 1139*1b8b02a4SEd Tanous < 1140*1b8b02a4SEd Tanous std::chrono::treat_as_floating_point<T>::value, 1141*1b8b02a4SEd Tanous T 1142*1b8b02a4SEd Tanous >::type 1143*1b8b02a4SEd Tanous trunc(T t) NOEXCEPT 1144*1b8b02a4SEd Tanous { 1145*1b8b02a4SEd Tanous using std::numeric_limits; 1146*1b8b02a4SEd Tanous using I = typename choose_trunc_type<T>::type; 1147*1b8b02a4SEd Tanous CONSTDATA auto digits = numeric_limits<T>::digits; 1148*1b8b02a4SEd Tanous static_assert(digits < numeric_limits<I>::digits, ""); 1149*1b8b02a4SEd Tanous CONSTDATA auto max = I{1} << (digits-1); 1150*1b8b02a4SEd Tanous CONSTDATA auto min = -max; 1151*1b8b02a4SEd Tanous const auto negative = t < T{0}; 1152*1b8b02a4SEd Tanous if (min <= t && t <= max && t != 0 && t == t) 1153*1b8b02a4SEd Tanous { 1154*1b8b02a4SEd Tanous t = static_cast<T>(static_cast<I>(t)); 1155*1b8b02a4SEd Tanous if (t == 0 && negative) 1156*1b8b02a4SEd Tanous t = -t; 1157*1b8b02a4SEd Tanous } 1158*1b8b02a4SEd Tanous return t; 1159*1b8b02a4SEd Tanous } 1160*1b8b02a4SEd Tanous 1161*1b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp> 1162*1b8b02a4SEd Tanous struct static_gcd 1163*1b8b02a4SEd Tanous { 1164*1b8b02a4SEd Tanous static const std::intmax_t value = static_gcd<Yp, Xp % Yp>::value; 1165*1b8b02a4SEd Tanous }; 1166*1b8b02a4SEd Tanous 1167*1b8b02a4SEd Tanous template <std::intmax_t Xp> 1168*1b8b02a4SEd Tanous struct static_gcd<Xp, 0> 1169*1b8b02a4SEd Tanous { 1170*1b8b02a4SEd Tanous static const std::intmax_t value = Xp; 1171*1b8b02a4SEd Tanous }; 1172*1b8b02a4SEd Tanous 1173*1b8b02a4SEd Tanous template <> 1174*1b8b02a4SEd Tanous struct static_gcd<0, 0> 1175*1b8b02a4SEd Tanous { 1176*1b8b02a4SEd Tanous static const std::intmax_t value = 1; 1177*1b8b02a4SEd Tanous }; 1178*1b8b02a4SEd Tanous 1179*1b8b02a4SEd Tanous template <class R1, class R2> 1180*1b8b02a4SEd Tanous struct no_overflow 1181*1b8b02a4SEd Tanous { 1182*1b8b02a4SEd Tanous private: 1183*1b8b02a4SEd Tanous static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value; 1184*1b8b02a4SEd Tanous static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value; 1185*1b8b02a4SEd Tanous static const std::intmax_t n1 = R1::num / gcd_n1_n2; 1186*1b8b02a4SEd Tanous static const std::intmax_t d1 = R1::den / gcd_d1_d2; 1187*1b8b02a4SEd Tanous static const std::intmax_t n2 = R2::num / gcd_n1_n2; 1188*1b8b02a4SEd Tanous static const std::intmax_t d2 = R2::den / gcd_d1_d2; 1189*1b8b02a4SEd Tanous #ifdef __cpp_constexpr 1190*1b8b02a4SEd Tanous static const std::intmax_t max = std::numeric_limits<std::intmax_t>::max(); 1191*1b8b02a4SEd Tanous #else 1192*1b8b02a4SEd Tanous static const std::intmax_t max = LLONG_MAX; 1193*1b8b02a4SEd Tanous #endif 1194*1b8b02a4SEd Tanous 1195*1b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp, bool overflow> 1196*1b8b02a4SEd Tanous struct mul // overflow == false 1197*1b8b02a4SEd Tanous { 1198*1b8b02a4SEd Tanous static const std::intmax_t value = Xp * Yp; 1199*1b8b02a4SEd Tanous }; 1200*1b8b02a4SEd Tanous 1201*1b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp> 1202*1b8b02a4SEd Tanous struct mul<Xp, Yp, true> 1203*1b8b02a4SEd Tanous { 1204*1b8b02a4SEd Tanous static const std::intmax_t value = 1; 1205*1b8b02a4SEd Tanous }; 1206*1b8b02a4SEd Tanous 1207*1b8b02a4SEd Tanous public: 1208*1b8b02a4SEd Tanous static const bool value = (n1 <= max / d2) && (n2 <= max / d1); 1209*1b8b02a4SEd Tanous typedef std::ratio<mul<n1, d2, !value>::value, 1210*1b8b02a4SEd Tanous mul<n2, d1, !value>::value> type; 1211*1b8b02a4SEd Tanous }; 1212*1b8b02a4SEd Tanous 1213*1b8b02a4SEd Tanous } // detail 1214*1b8b02a4SEd Tanous 1215*1b8b02a4SEd Tanous // trunc towards zero 1216*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1217*1b8b02a4SEd Tanous CONSTCD11 1218*1b8b02a4SEd Tanous inline 1219*1b8b02a4SEd Tanous typename std::enable_if 1220*1b8b02a4SEd Tanous < 1221*1b8b02a4SEd Tanous detail::no_overflow<Period, typename To::period>::value, 1222*1b8b02a4SEd Tanous To 1223*1b8b02a4SEd Tanous >::type 1224*1b8b02a4SEd Tanous trunc(const std::chrono::duration<Rep, Period>& d) 1225*1b8b02a4SEd Tanous { 1226*1b8b02a4SEd Tanous return To{detail::trunc(std::chrono::duration_cast<To>(d).count())}; 1227*1b8b02a4SEd Tanous } 1228*1b8b02a4SEd Tanous 1229*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1230*1b8b02a4SEd Tanous CONSTCD11 1231*1b8b02a4SEd Tanous inline 1232*1b8b02a4SEd Tanous typename std::enable_if 1233*1b8b02a4SEd Tanous < 1234*1b8b02a4SEd Tanous !detail::no_overflow<Period, typename To::period>::value, 1235*1b8b02a4SEd Tanous To 1236*1b8b02a4SEd Tanous >::type 1237*1b8b02a4SEd Tanous trunc(const std::chrono::duration<Rep, Period>& d) 1238*1b8b02a4SEd Tanous { 1239*1b8b02a4SEd Tanous using std::chrono::duration_cast; 1240*1b8b02a4SEd Tanous using std::chrono::duration; 1241*1b8b02a4SEd Tanous using rep = typename std::common_type<Rep, typename To::rep>::type; 1242*1b8b02a4SEd Tanous return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())}; 1243*1b8b02a4SEd Tanous } 1244*1b8b02a4SEd Tanous 1245*1b8b02a4SEd Tanous #ifndef HAS_CHRONO_ROUNDING 1246*1b8b02a4SEd Tanous # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__))) 1247*1b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 1248*1b8b02a4SEd Tanous # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510 1249*1b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 1250*1b8b02a4SEd Tanous # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800 1251*1b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 1252*1b8b02a4SEd Tanous # else 1253*1b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 0 1254*1b8b02a4SEd Tanous # endif 1255*1b8b02a4SEd Tanous #endif // HAS_CHRONO_ROUNDING 1256*1b8b02a4SEd Tanous 1257*1b8b02a4SEd Tanous #if HAS_CHRONO_ROUNDING == 0 1258*1b8b02a4SEd Tanous 1259*1b8b02a4SEd Tanous // round down 1260*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1261*1b8b02a4SEd Tanous CONSTCD14 1262*1b8b02a4SEd Tanous inline 1263*1b8b02a4SEd Tanous typename std::enable_if 1264*1b8b02a4SEd Tanous < 1265*1b8b02a4SEd Tanous detail::no_overflow<Period, typename To::period>::value, 1266*1b8b02a4SEd Tanous To 1267*1b8b02a4SEd Tanous >::type 1268*1b8b02a4SEd Tanous floor(const std::chrono::duration<Rep, Period>& d) 1269*1b8b02a4SEd Tanous { 1270*1b8b02a4SEd Tanous auto t = trunc<To>(d); 1271*1b8b02a4SEd Tanous if (t > d) 1272*1b8b02a4SEd Tanous return t - To{1}; 1273*1b8b02a4SEd Tanous return t; 1274*1b8b02a4SEd Tanous } 1275*1b8b02a4SEd Tanous 1276*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1277*1b8b02a4SEd Tanous CONSTCD14 1278*1b8b02a4SEd Tanous inline 1279*1b8b02a4SEd Tanous typename std::enable_if 1280*1b8b02a4SEd Tanous < 1281*1b8b02a4SEd Tanous !detail::no_overflow<Period, typename To::period>::value, 1282*1b8b02a4SEd Tanous To 1283*1b8b02a4SEd Tanous >::type 1284*1b8b02a4SEd Tanous floor(const std::chrono::duration<Rep, Period>& d) 1285*1b8b02a4SEd Tanous { 1286*1b8b02a4SEd Tanous using rep = typename std::common_type<Rep, typename To::rep>::type; 1287*1b8b02a4SEd Tanous return floor<To>(floor<std::chrono::duration<rep>>(d)); 1288*1b8b02a4SEd Tanous } 1289*1b8b02a4SEd Tanous 1290*1b8b02a4SEd Tanous // round to nearest, to even on tie 1291*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1292*1b8b02a4SEd Tanous CONSTCD14 1293*1b8b02a4SEd Tanous inline 1294*1b8b02a4SEd Tanous To 1295*1b8b02a4SEd Tanous round(const std::chrono::duration<Rep, Period>& d) 1296*1b8b02a4SEd Tanous { 1297*1b8b02a4SEd Tanous auto t0 = floor<To>(d); 1298*1b8b02a4SEd Tanous auto t1 = t0 + To{1}; 1299*1b8b02a4SEd Tanous if (t1 == To{0} && t0 < To{0}) 1300*1b8b02a4SEd Tanous t1 = -t1; 1301*1b8b02a4SEd Tanous auto diff0 = d - t0; 1302*1b8b02a4SEd Tanous auto diff1 = t1 - d; 1303*1b8b02a4SEd Tanous if (diff0 == diff1) 1304*1b8b02a4SEd Tanous { 1305*1b8b02a4SEd Tanous if (t0 - trunc<To>(t0/2)*2 == To{0}) 1306*1b8b02a4SEd Tanous return t0; 1307*1b8b02a4SEd Tanous return t1; 1308*1b8b02a4SEd Tanous } 1309*1b8b02a4SEd Tanous if (diff0 < diff1) 1310*1b8b02a4SEd Tanous return t0; 1311*1b8b02a4SEd Tanous return t1; 1312*1b8b02a4SEd Tanous } 1313*1b8b02a4SEd Tanous 1314*1b8b02a4SEd Tanous // round up 1315*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1316*1b8b02a4SEd Tanous CONSTCD14 1317*1b8b02a4SEd Tanous inline 1318*1b8b02a4SEd Tanous To 1319*1b8b02a4SEd Tanous ceil(const std::chrono::duration<Rep, Period>& d) 1320*1b8b02a4SEd Tanous { 1321*1b8b02a4SEd Tanous auto t = trunc<To>(d); 1322*1b8b02a4SEd Tanous if (t < d) 1323*1b8b02a4SEd Tanous return t + To{1}; 1324*1b8b02a4SEd Tanous return t; 1325*1b8b02a4SEd Tanous } 1326*1b8b02a4SEd Tanous 1327*1b8b02a4SEd Tanous template <class Rep, class Period, 1328*1b8b02a4SEd Tanous class = typename std::enable_if 1329*1b8b02a4SEd Tanous < 1330*1b8b02a4SEd Tanous std::numeric_limits<Rep>::is_signed 1331*1b8b02a4SEd Tanous >::type> 1332*1b8b02a4SEd Tanous CONSTCD11 1333*1b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 1334*1b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 1335*1b8b02a4SEd Tanous { 1336*1b8b02a4SEd Tanous return d >= d.zero() ? d : static_cast<decltype(d)>(-d); 1337*1b8b02a4SEd Tanous } 1338*1b8b02a4SEd Tanous 1339*1b8b02a4SEd Tanous // round down 1340*1b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 1341*1b8b02a4SEd Tanous CONSTCD11 1342*1b8b02a4SEd Tanous inline 1343*1b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 1344*1b8b02a4SEd Tanous floor(const std::chrono::time_point<Clock, FromDuration>& tp) 1345*1b8b02a4SEd Tanous { 1346*1b8b02a4SEd Tanous using std::chrono::time_point; 1347*1b8b02a4SEd Tanous return time_point<Clock, To>{date::floor<To>(tp.time_since_epoch())}; 1348*1b8b02a4SEd Tanous } 1349*1b8b02a4SEd Tanous 1350*1b8b02a4SEd Tanous // round to nearest, to even on tie 1351*1b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 1352*1b8b02a4SEd Tanous CONSTCD11 1353*1b8b02a4SEd Tanous inline 1354*1b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 1355*1b8b02a4SEd Tanous round(const std::chrono::time_point<Clock, FromDuration>& tp) 1356*1b8b02a4SEd Tanous { 1357*1b8b02a4SEd Tanous using std::chrono::time_point; 1358*1b8b02a4SEd Tanous return time_point<Clock, To>{round<To>(tp.time_since_epoch())}; 1359*1b8b02a4SEd Tanous } 1360*1b8b02a4SEd Tanous 1361*1b8b02a4SEd Tanous // round up 1362*1b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 1363*1b8b02a4SEd Tanous CONSTCD11 1364*1b8b02a4SEd Tanous inline 1365*1b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 1366*1b8b02a4SEd Tanous ceil(const std::chrono::time_point<Clock, FromDuration>& tp) 1367*1b8b02a4SEd Tanous { 1368*1b8b02a4SEd Tanous using std::chrono::time_point; 1369*1b8b02a4SEd Tanous return time_point<Clock, To>{ceil<To>(tp.time_since_epoch())}; 1370*1b8b02a4SEd Tanous } 1371*1b8b02a4SEd Tanous 1372*1b8b02a4SEd Tanous #else // HAS_CHRONO_ROUNDING == 1 1373*1b8b02a4SEd Tanous 1374*1b8b02a4SEd Tanous using std::chrono::floor; 1375*1b8b02a4SEd Tanous using std::chrono::ceil; 1376*1b8b02a4SEd Tanous using std::chrono::round; 1377*1b8b02a4SEd Tanous using std::chrono::abs; 1378*1b8b02a4SEd Tanous 1379*1b8b02a4SEd Tanous #endif // HAS_CHRONO_ROUNDING 1380*1b8b02a4SEd Tanous 1381*1b8b02a4SEd Tanous namespace detail 1382*1b8b02a4SEd Tanous { 1383*1b8b02a4SEd Tanous 1384*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1385*1b8b02a4SEd Tanous CONSTCD14 1386*1b8b02a4SEd Tanous inline 1387*1b8b02a4SEd Tanous typename std::enable_if 1388*1b8b02a4SEd Tanous < 1389*1b8b02a4SEd Tanous !std::chrono::treat_as_floating_point<typename To::rep>::value, 1390*1b8b02a4SEd Tanous To 1391*1b8b02a4SEd Tanous >::type 1392*1b8b02a4SEd Tanous round_i(const std::chrono::duration<Rep, Period>& d) 1393*1b8b02a4SEd Tanous { 1394*1b8b02a4SEd Tanous return round<To>(d); 1395*1b8b02a4SEd Tanous } 1396*1b8b02a4SEd Tanous 1397*1b8b02a4SEd Tanous template <class To, class Rep, class Period> 1398*1b8b02a4SEd Tanous CONSTCD14 1399*1b8b02a4SEd Tanous inline 1400*1b8b02a4SEd Tanous typename std::enable_if 1401*1b8b02a4SEd Tanous < 1402*1b8b02a4SEd Tanous std::chrono::treat_as_floating_point<typename To::rep>::value, 1403*1b8b02a4SEd Tanous To 1404*1b8b02a4SEd Tanous >::type 1405*1b8b02a4SEd Tanous round_i(const std::chrono::duration<Rep, Period>& d) 1406*1b8b02a4SEd Tanous { 1407*1b8b02a4SEd Tanous return d; 1408*1b8b02a4SEd Tanous } 1409*1b8b02a4SEd Tanous 1410*1b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 1411*1b8b02a4SEd Tanous CONSTCD11 1412*1b8b02a4SEd Tanous inline 1413*1b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 1414*1b8b02a4SEd Tanous round_i(const std::chrono::time_point<Clock, FromDuration>& tp) 1415*1b8b02a4SEd Tanous { 1416*1b8b02a4SEd Tanous using std::chrono::time_point; 1417*1b8b02a4SEd Tanous return time_point<Clock, To>{round_i<To>(tp.time_since_epoch())}; 1418*1b8b02a4SEd Tanous } 1419*1b8b02a4SEd Tanous 1420*1b8b02a4SEd Tanous } // detail 1421*1b8b02a4SEd Tanous 1422*1b8b02a4SEd Tanous // trunc towards zero 1423*1b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 1424*1b8b02a4SEd Tanous CONSTCD11 1425*1b8b02a4SEd Tanous inline 1426*1b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 1427*1b8b02a4SEd Tanous trunc(const std::chrono::time_point<Clock, FromDuration>& tp) 1428*1b8b02a4SEd Tanous { 1429*1b8b02a4SEd Tanous using std::chrono::time_point; 1430*1b8b02a4SEd Tanous return time_point<Clock, To>{trunc<To>(tp.time_since_epoch())}; 1431*1b8b02a4SEd Tanous } 1432*1b8b02a4SEd Tanous 1433*1b8b02a4SEd Tanous // day 1434*1b8b02a4SEd Tanous 1435*1b8b02a4SEd Tanous CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast<decltype(d_)>(d)) {} 1436*1b8b02a4SEd Tanous CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} 1437*1b8b02a4SEd Tanous CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 1438*1b8b02a4SEd Tanous CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} 1439*1b8b02a4SEd Tanous CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 1440*1b8b02a4SEd Tanous CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} 1441*1b8b02a4SEd Tanous CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} 1442*1b8b02a4SEd Tanous CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} 1443*1b8b02a4SEd Tanous CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} 1444*1b8b02a4SEd Tanous 1445*1b8b02a4SEd Tanous CONSTCD11 1446*1b8b02a4SEd Tanous inline 1447*1b8b02a4SEd Tanous bool 1448*1b8b02a4SEd Tanous operator==(const day& x, const day& y) NOEXCEPT 1449*1b8b02a4SEd Tanous { 1450*1b8b02a4SEd Tanous return static_cast<unsigned>(x) == static_cast<unsigned>(y); 1451*1b8b02a4SEd Tanous } 1452*1b8b02a4SEd Tanous 1453*1b8b02a4SEd Tanous CONSTCD11 1454*1b8b02a4SEd Tanous inline 1455*1b8b02a4SEd Tanous bool 1456*1b8b02a4SEd Tanous operator!=(const day& x, const day& y) NOEXCEPT 1457*1b8b02a4SEd Tanous { 1458*1b8b02a4SEd Tanous return !(x == y); 1459*1b8b02a4SEd Tanous } 1460*1b8b02a4SEd Tanous 1461*1b8b02a4SEd Tanous CONSTCD11 1462*1b8b02a4SEd Tanous inline 1463*1b8b02a4SEd Tanous bool 1464*1b8b02a4SEd Tanous operator<(const day& x, const day& y) NOEXCEPT 1465*1b8b02a4SEd Tanous { 1466*1b8b02a4SEd Tanous return static_cast<unsigned>(x) < static_cast<unsigned>(y); 1467*1b8b02a4SEd Tanous } 1468*1b8b02a4SEd Tanous 1469*1b8b02a4SEd Tanous CONSTCD11 1470*1b8b02a4SEd Tanous inline 1471*1b8b02a4SEd Tanous bool 1472*1b8b02a4SEd Tanous operator>(const day& x, const day& y) NOEXCEPT 1473*1b8b02a4SEd Tanous { 1474*1b8b02a4SEd Tanous return y < x; 1475*1b8b02a4SEd Tanous } 1476*1b8b02a4SEd Tanous 1477*1b8b02a4SEd Tanous CONSTCD11 1478*1b8b02a4SEd Tanous inline 1479*1b8b02a4SEd Tanous bool 1480*1b8b02a4SEd Tanous operator<=(const day& x, const day& y) NOEXCEPT 1481*1b8b02a4SEd Tanous { 1482*1b8b02a4SEd Tanous return !(y < x); 1483*1b8b02a4SEd Tanous } 1484*1b8b02a4SEd Tanous 1485*1b8b02a4SEd Tanous CONSTCD11 1486*1b8b02a4SEd Tanous inline 1487*1b8b02a4SEd Tanous bool 1488*1b8b02a4SEd Tanous operator>=(const day& x, const day& y) NOEXCEPT 1489*1b8b02a4SEd Tanous { 1490*1b8b02a4SEd Tanous return !(x < y); 1491*1b8b02a4SEd Tanous } 1492*1b8b02a4SEd Tanous 1493*1b8b02a4SEd Tanous CONSTCD11 1494*1b8b02a4SEd Tanous inline 1495*1b8b02a4SEd Tanous days 1496*1b8b02a4SEd Tanous operator-(const day& x, const day& y) NOEXCEPT 1497*1b8b02a4SEd Tanous { 1498*1b8b02a4SEd Tanous return days{static_cast<days::rep>(static_cast<unsigned>(x) 1499*1b8b02a4SEd Tanous - static_cast<unsigned>(y))}; 1500*1b8b02a4SEd Tanous } 1501*1b8b02a4SEd Tanous 1502*1b8b02a4SEd Tanous CONSTCD11 1503*1b8b02a4SEd Tanous inline 1504*1b8b02a4SEd Tanous day 1505*1b8b02a4SEd Tanous operator+(const day& x, const days& y) NOEXCEPT 1506*1b8b02a4SEd Tanous { 1507*1b8b02a4SEd Tanous return day{static_cast<unsigned>(x) + static_cast<unsigned>(y.count())}; 1508*1b8b02a4SEd Tanous } 1509*1b8b02a4SEd Tanous 1510*1b8b02a4SEd Tanous CONSTCD11 1511*1b8b02a4SEd Tanous inline 1512*1b8b02a4SEd Tanous day 1513*1b8b02a4SEd Tanous operator+(const days& x, const day& y) NOEXCEPT 1514*1b8b02a4SEd Tanous { 1515*1b8b02a4SEd Tanous return y + x; 1516*1b8b02a4SEd Tanous } 1517*1b8b02a4SEd Tanous 1518*1b8b02a4SEd Tanous CONSTCD11 1519*1b8b02a4SEd Tanous inline 1520*1b8b02a4SEd Tanous day 1521*1b8b02a4SEd Tanous operator-(const day& x, const days& y) NOEXCEPT 1522*1b8b02a4SEd Tanous { 1523*1b8b02a4SEd Tanous return x + -y; 1524*1b8b02a4SEd Tanous } 1525*1b8b02a4SEd Tanous 1526*1b8b02a4SEd Tanous namespace detail 1527*1b8b02a4SEd Tanous { 1528*1b8b02a4SEd Tanous 1529*1b8b02a4SEd Tanous template<class CharT, class Traits> 1530*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1531*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const day& d) 1532*1b8b02a4SEd Tanous { 1533*1b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 1534*1b8b02a4SEd Tanous os.fill('0'); 1535*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 1536*1b8b02a4SEd Tanous os.width(2); 1537*1b8b02a4SEd Tanous os << static_cast<unsigned>(d); 1538*1b8b02a4SEd Tanous return os; 1539*1b8b02a4SEd Tanous } 1540*1b8b02a4SEd Tanous 1541*1b8b02a4SEd Tanous } // namespace detail 1542*1b8b02a4SEd Tanous 1543*1b8b02a4SEd Tanous template<class CharT, class Traits> 1544*1b8b02a4SEd Tanous inline 1545*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1546*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const day& d) 1547*1b8b02a4SEd Tanous { 1548*1b8b02a4SEd Tanous detail::low_level_fmt(os, d); 1549*1b8b02a4SEd Tanous if (!d.ok()) 1550*1b8b02a4SEd Tanous os << " is not a valid day"; 1551*1b8b02a4SEd Tanous return os; 1552*1b8b02a4SEd Tanous } 1553*1b8b02a4SEd Tanous 1554*1b8b02a4SEd Tanous // month 1555*1b8b02a4SEd Tanous 1556*1b8b02a4SEd Tanous CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast<decltype(m_)>(m)) {} 1557*1b8b02a4SEd Tanous CONSTCD14 inline month& month::operator++() NOEXCEPT {*this += months{1}; return *this;} 1558*1b8b02a4SEd Tanous CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 1559*1b8b02a4SEd Tanous CONSTCD14 inline month& month::operator--() NOEXCEPT {*this -= months{1}; return *this;} 1560*1b8b02a4SEd Tanous CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 1561*1b8b02a4SEd Tanous 1562*1b8b02a4SEd Tanous CONSTCD14 1563*1b8b02a4SEd Tanous inline 1564*1b8b02a4SEd Tanous month& 1565*1b8b02a4SEd Tanous month::operator+=(const months& m) NOEXCEPT 1566*1b8b02a4SEd Tanous { 1567*1b8b02a4SEd Tanous *this = *this + m; 1568*1b8b02a4SEd Tanous return *this; 1569*1b8b02a4SEd Tanous } 1570*1b8b02a4SEd Tanous 1571*1b8b02a4SEd Tanous CONSTCD14 1572*1b8b02a4SEd Tanous inline 1573*1b8b02a4SEd Tanous month& 1574*1b8b02a4SEd Tanous month::operator-=(const months& m) NOEXCEPT 1575*1b8b02a4SEd Tanous { 1576*1b8b02a4SEd Tanous *this = *this - m; 1577*1b8b02a4SEd Tanous return *this; 1578*1b8b02a4SEd Tanous } 1579*1b8b02a4SEd Tanous 1580*1b8b02a4SEd Tanous CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} 1581*1b8b02a4SEd Tanous CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} 1582*1b8b02a4SEd Tanous 1583*1b8b02a4SEd Tanous CONSTCD11 1584*1b8b02a4SEd Tanous inline 1585*1b8b02a4SEd Tanous bool 1586*1b8b02a4SEd Tanous operator==(const month& x, const month& y) NOEXCEPT 1587*1b8b02a4SEd Tanous { 1588*1b8b02a4SEd Tanous return static_cast<unsigned>(x) == static_cast<unsigned>(y); 1589*1b8b02a4SEd Tanous } 1590*1b8b02a4SEd Tanous 1591*1b8b02a4SEd Tanous CONSTCD11 1592*1b8b02a4SEd Tanous inline 1593*1b8b02a4SEd Tanous bool 1594*1b8b02a4SEd Tanous operator!=(const month& x, const month& y) NOEXCEPT 1595*1b8b02a4SEd Tanous { 1596*1b8b02a4SEd Tanous return !(x == y); 1597*1b8b02a4SEd Tanous } 1598*1b8b02a4SEd Tanous 1599*1b8b02a4SEd Tanous CONSTCD11 1600*1b8b02a4SEd Tanous inline 1601*1b8b02a4SEd Tanous bool 1602*1b8b02a4SEd Tanous operator<(const month& x, const month& y) NOEXCEPT 1603*1b8b02a4SEd Tanous { 1604*1b8b02a4SEd Tanous return static_cast<unsigned>(x) < static_cast<unsigned>(y); 1605*1b8b02a4SEd Tanous } 1606*1b8b02a4SEd Tanous 1607*1b8b02a4SEd Tanous CONSTCD11 1608*1b8b02a4SEd Tanous inline 1609*1b8b02a4SEd Tanous bool 1610*1b8b02a4SEd Tanous operator>(const month& x, const month& y) NOEXCEPT 1611*1b8b02a4SEd Tanous { 1612*1b8b02a4SEd Tanous return y < x; 1613*1b8b02a4SEd Tanous } 1614*1b8b02a4SEd Tanous 1615*1b8b02a4SEd Tanous CONSTCD11 1616*1b8b02a4SEd Tanous inline 1617*1b8b02a4SEd Tanous bool 1618*1b8b02a4SEd Tanous operator<=(const month& x, const month& y) NOEXCEPT 1619*1b8b02a4SEd Tanous { 1620*1b8b02a4SEd Tanous return !(y < x); 1621*1b8b02a4SEd Tanous } 1622*1b8b02a4SEd Tanous 1623*1b8b02a4SEd Tanous CONSTCD11 1624*1b8b02a4SEd Tanous inline 1625*1b8b02a4SEd Tanous bool 1626*1b8b02a4SEd Tanous operator>=(const month& x, const month& y) NOEXCEPT 1627*1b8b02a4SEd Tanous { 1628*1b8b02a4SEd Tanous return !(x < y); 1629*1b8b02a4SEd Tanous } 1630*1b8b02a4SEd Tanous 1631*1b8b02a4SEd Tanous CONSTCD14 1632*1b8b02a4SEd Tanous inline 1633*1b8b02a4SEd Tanous months 1634*1b8b02a4SEd Tanous operator-(const month& x, const month& y) NOEXCEPT 1635*1b8b02a4SEd Tanous { 1636*1b8b02a4SEd Tanous auto const d = static_cast<unsigned>(x) - static_cast<unsigned>(y); 1637*1b8b02a4SEd Tanous return months(d <= 11 ? d : d + 12); 1638*1b8b02a4SEd Tanous } 1639*1b8b02a4SEd Tanous 1640*1b8b02a4SEd Tanous CONSTCD14 1641*1b8b02a4SEd Tanous inline 1642*1b8b02a4SEd Tanous month 1643*1b8b02a4SEd Tanous operator+(const month& x, const months& y) NOEXCEPT 1644*1b8b02a4SEd Tanous { 1645*1b8b02a4SEd Tanous auto const mu = static_cast<long long>(static_cast<unsigned>(x)) + y.count() - 1; 1646*1b8b02a4SEd Tanous auto const yr = (mu >= 0 ? mu : mu-11) / 12; 1647*1b8b02a4SEd Tanous return month{static_cast<unsigned>(mu - yr * 12 + 1)}; 1648*1b8b02a4SEd Tanous } 1649*1b8b02a4SEd Tanous 1650*1b8b02a4SEd Tanous CONSTCD14 1651*1b8b02a4SEd Tanous inline 1652*1b8b02a4SEd Tanous month 1653*1b8b02a4SEd Tanous operator+(const months& x, const month& y) NOEXCEPT 1654*1b8b02a4SEd Tanous { 1655*1b8b02a4SEd Tanous return y + x; 1656*1b8b02a4SEd Tanous } 1657*1b8b02a4SEd Tanous 1658*1b8b02a4SEd Tanous CONSTCD14 1659*1b8b02a4SEd Tanous inline 1660*1b8b02a4SEd Tanous month 1661*1b8b02a4SEd Tanous operator-(const month& x, const months& y) NOEXCEPT 1662*1b8b02a4SEd Tanous { 1663*1b8b02a4SEd Tanous return x + -y; 1664*1b8b02a4SEd Tanous } 1665*1b8b02a4SEd Tanous 1666*1b8b02a4SEd Tanous namespace detail 1667*1b8b02a4SEd Tanous { 1668*1b8b02a4SEd Tanous 1669*1b8b02a4SEd Tanous template<class CharT, class Traits> 1670*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1671*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month& m) 1672*1b8b02a4SEd Tanous { 1673*1b8b02a4SEd Tanous if (m.ok()) 1674*1b8b02a4SEd Tanous { 1675*1b8b02a4SEd Tanous CharT fmt[] = {'%', 'b', 0}; 1676*1b8b02a4SEd Tanous os << format(os.getloc(), fmt, m); 1677*1b8b02a4SEd Tanous } 1678*1b8b02a4SEd Tanous else 1679*1b8b02a4SEd Tanous os << static_cast<unsigned>(m); 1680*1b8b02a4SEd Tanous return os; 1681*1b8b02a4SEd Tanous } 1682*1b8b02a4SEd Tanous 1683*1b8b02a4SEd Tanous } // namespace detail 1684*1b8b02a4SEd Tanous 1685*1b8b02a4SEd Tanous template<class CharT, class Traits> 1686*1b8b02a4SEd Tanous inline 1687*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1688*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month& m) 1689*1b8b02a4SEd Tanous { 1690*1b8b02a4SEd Tanous detail::low_level_fmt(os, m); 1691*1b8b02a4SEd Tanous if (!m.ok()) 1692*1b8b02a4SEd Tanous os << " is not a valid month"; 1693*1b8b02a4SEd Tanous return os; 1694*1b8b02a4SEd Tanous } 1695*1b8b02a4SEd Tanous 1696*1b8b02a4SEd Tanous // year 1697*1b8b02a4SEd Tanous 1698*1b8b02a4SEd Tanous CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast<decltype(y_)>(y)) {} 1699*1b8b02a4SEd Tanous CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} 1700*1b8b02a4SEd Tanous CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 1701*1b8b02a4SEd Tanous CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} 1702*1b8b02a4SEd Tanous CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 1703*1b8b02a4SEd Tanous CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} 1704*1b8b02a4SEd Tanous CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} 1705*1b8b02a4SEd Tanous CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};} 1706*1b8b02a4SEd Tanous CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;} 1707*1b8b02a4SEd Tanous 1708*1b8b02a4SEd Tanous CONSTCD11 1709*1b8b02a4SEd Tanous inline 1710*1b8b02a4SEd Tanous bool 1711*1b8b02a4SEd Tanous year::is_leap() const NOEXCEPT 1712*1b8b02a4SEd Tanous { 1713*1b8b02a4SEd Tanous return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0); 1714*1b8b02a4SEd Tanous } 1715*1b8b02a4SEd Tanous 1716*1b8b02a4SEd Tanous CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} 1717*1b8b02a4SEd Tanous 1718*1b8b02a4SEd Tanous CONSTCD11 1719*1b8b02a4SEd Tanous inline 1720*1b8b02a4SEd Tanous bool 1721*1b8b02a4SEd Tanous year::ok() const NOEXCEPT 1722*1b8b02a4SEd Tanous { 1723*1b8b02a4SEd Tanous return y_ != std::numeric_limits<short>::min(); 1724*1b8b02a4SEd Tanous } 1725*1b8b02a4SEd Tanous 1726*1b8b02a4SEd Tanous CONSTCD11 1727*1b8b02a4SEd Tanous inline 1728*1b8b02a4SEd Tanous bool 1729*1b8b02a4SEd Tanous operator==(const year& x, const year& y) NOEXCEPT 1730*1b8b02a4SEd Tanous { 1731*1b8b02a4SEd Tanous return static_cast<int>(x) == static_cast<int>(y); 1732*1b8b02a4SEd Tanous } 1733*1b8b02a4SEd Tanous 1734*1b8b02a4SEd Tanous CONSTCD11 1735*1b8b02a4SEd Tanous inline 1736*1b8b02a4SEd Tanous bool 1737*1b8b02a4SEd Tanous operator!=(const year& x, const year& y) NOEXCEPT 1738*1b8b02a4SEd Tanous { 1739*1b8b02a4SEd Tanous return !(x == y); 1740*1b8b02a4SEd Tanous } 1741*1b8b02a4SEd Tanous 1742*1b8b02a4SEd Tanous CONSTCD11 1743*1b8b02a4SEd Tanous inline 1744*1b8b02a4SEd Tanous bool 1745*1b8b02a4SEd Tanous operator<(const year& x, const year& y) NOEXCEPT 1746*1b8b02a4SEd Tanous { 1747*1b8b02a4SEd Tanous return static_cast<int>(x) < static_cast<int>(y); 1748*1b8b02a4SEd Tanous } 1749*1b8b02a4SEd Tanous 1750*1b8b02a4SEd Tanous CONSTCD11 1751*1b8b02a4SEd Tanous inline 1752*1b8b02a4SEd Tanous bool 1753*1b8b02a4SEd Tanous operator>(const year& x, const year& y) NOEXCEPT 1754*1b8b02a4SEd Tanous { 1755*1b8b02a4SEd Tanous return y < x; 1756*1b8b02a4SEd Tanous } 1757*1b8b02a4SEd Tanous 1758*1b8b02a4SEd Tanous CONSTCD11 1759*1b8b02a4SEd Tanous inline 1760*1b8b02a4SEd Tanous bool 1761*1b8b02a4SEd Tanous operator<=(const year& x, const year& y) NOEXCEPT 1762*1b8b02a4SEd Tanous { 1763*1b8b02a4SEd Tanous return !(y < x); 1764*1b8b02a4SEd Tanous } 1765*1b8b02a4SEd Tanous 1766*1b8b02a4SEd Tanous CONSTCD11 1767*1b8b02a4SEd Tanous inline 1768*1b8b02a4SEd Tanous bool 1769*1b8b02a4SEd Tanous operator>=(const year& x, const year& y) NOEXCEPT 1770*1b8b02a4SEd Tanous { 1771*1b8b02a4SEd Tanous return !(x < y); 1772*1b8b02a4SEd Tanous } 1773*1b8b02a4SEd Tanous 1774*1b8b02a4SEd Tanous CONSTCD11 1775*1b8b02a4SEd Tanous inline 1776*1b8b02a4SEd Tanous years 1777*1b8b02a4SEd Tanous operator-(const year& x, const year& y) NOEXCEPT 1778*1b8b02a4SEd Tanous { 1779*1b8b02a4SEd Tanous return years{static_cast<int>(x) - static_cast<int>(y)}; 1780*1b8b02a4SEd Tanous } 1781*1b8b02a4SEd Tanous 1782*1b8b02a4SEd Tanous CONSTCD11 1783*1b8b02a4SEd Tanous inline 1784*1b8b02a4SEd Tanous year 1785*1b8b02a4SEd Tanous operator+(const year& x, const years& y) NOEXCEPT 1786*1b8b02a4SEd Tanous { 1787*1b8b02a4SEd Tanous return year{static_cast<int>(x) + y.count()}; 1788*1b8b02a4SEd Tanous } 1789*1b8b02a4SEd Tanous 1790*1b8b02a4SEd Tanous CONSTCD11 1791*1b8b02a4SEd Tanous inline 1792*1b8b02a4SEd Tanous year 1793*1b8b02a4SEd Tanous operator+(const years& x, const year& y) NOEXCEPT 1794*1b8b02a4SEd Tanous { 1795*1b8b02a4SEd Tanous return y + x; 1796*1b8b02a4SEd Tanous } 1797*1b8b02a4SEd Tanous 1798*1b8b02a4SEd Tanous CONSTCD11 1799*1b8b02a4SEd Tanous inline 1800*1b8b02a4SEd Tanous year 1801*1b8b02a4SEd Tanous operator-(const year& x, const years& y) NOEXCEPT 1802*1b8b02a4SEd Tanous { 1803*1b8b02a4SEd Tanous return year{static_cast<int>(x) - y.count()}; 1804*1b8b02a4SEd Tanous } 1805*1b8b02a4SEd Tanous 1806*1b8b02a4SEd Tanous namespace detail 1807*1b8b02a4SEd Tanous { 1808*1b8b02a4SEd Tanous 1809*1b8b02a4SEd Tanous template<class CharT, class Traits> 1810*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1811*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year& y) 1812*1b8b02a4SEd Tanous { 1813*1b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 1814*1b8b02a4SEd Tanous os.fill('0'); 1815*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::internal); 1816*1b8b02a4SEd Tanous os.width(4 + (y < year{0})); 1817*1b8b02a4SEd Tanous os.imbue(std::locale::classic()); 1818*1b8b02a4SEd Tanous os << static_cast<int>(y); 1819*1b8b02a4SEd Tanous return os; 1820*1b8b02a4SEd Tanous } 1821*1b8b02a4SEd Tanous 1822*1b8b02a4SEd Tanous } // namespace detail 1823*1b8b02a4SEd Tanous 1824*1b8b02a4SEd Tanous template<class CharT, class Traits> 1825*1b8b02a4SEd Tanous inline 1826*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1827*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year& y) 1828*1b8b02a4SEd Tanous { 1829*1b8b02a4SEd Tanous detail::low_level_fmt(os, y); 1830*1b8b02a4SEd Tanous if (!y.ok()) 1831*1b8b02a4SEd Tanous os << " is not a valid year"; 1832*1b8b02a4SEd Tanous return os; 1833*1b8b02a4SEd Tanous } 1834*1b8b02a4SEd Tanous 1835*1b8b02a4SEd Tanous // weekday 1836*1b8b02a4SEd Tanous 1837*1b8b02a4SEd Tanous CONSTCD14 1838*1b8b02a4SEd Tanous inline 1839*1b8b02a4SEd Tanous unsigned char 1840*1b8b02a4SEd Tanous weekday::weekday_from_days(int z) NOEXCEPT 1841*1b8b02a4SEd Tanous { 1842*1b8b02a4SEd Tanous auto u = static_cast<unsigned>(z); 1843*1b8b02a4SEd Tanous return static_cast<unsigned char>(z >= -4 ? (u+4) % 7 : u % 7); 1844*1b8b02a4SEd Tanous } 1845*1b8b02a4SEd Tanous 1846*1b8b02a4SEd Tanous CONSTCD11 1847*1b8b02a4SEd Tanous inline 1848*1b8b02a4SEd Tanous weekday::weekday(unsigned wd) NOEXCEPT 1849*1b8b02a4SEd Tanous : wd_(static_cast<decltype(wd_)>(wd != 7 ? wd : 0)) 1850*1b8b02a4SEd Tanous {} 1851*1b8b02a4SEd Tanous 1852*1b8b02a4SEd Tanous CONSTCD14 1853*1b8b02a4SEd Tanous inline 1854*1b8b02a4SEd Tanous weekday::weekday(const sys_days& dp) NOEXCEPT 1855*1b8b02a4SEd Tanous : wd_(weekday_from_days(dp.time_since_epoch().count())) 1856*1b8b02a4SEd Tanous {} 1857*1b8b02a4SEd Tanous 1858*1b8b02a4SEd Tanous CONSTCD14 1859*1b8b02a4SEd Tanous inline 1860*1b8b02a4SEd Tanous weekday::weekday(const local_days& dp) NOEXCEPT 1861*1b8b02a4SEd Tanous : wd_(weekday_from_days(dp.time_since_epoch().count())) 1862*1b8b02a4SEd Tanous {} 1863*1b8b02a4SEd Tanous 1864*1b8b02a4SEd Tanous CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {*this += days{1}; return *this;} 1865*1b8b02a4SEd Tanous CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 1866*1b8b02a4SEd Tanous CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {*this -= days{1}; return *this;} 1867*1b8b02a4SEd Tanous CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 1868*1b8b02a4SEd Tanous 1869*1b8b02a4SEd Tanous CONSTCD14 1870*1b8b02a4SEd Tanous inline 1871*1b8b02a4SEd Tanous weekday& 1872*1b8b02a4SEd Tanous weekday::operator+=(const days& d) NOEXCEPT 1873*1b8b02a4SEd Tanous { 1874*1b8b02a4SEd Tanous *this = *this + d; 1875*1b8b02a4SEd Tanous return *this; 1876*1b8b02a4SEd Tanous } 1877*1b8b02a4SEd Tanous 1878*1b8b02a4SEd Tanous CONSTCD14 1879*1b8b02a4SEd Tanous inline 1880*1b8b02a4SEd Tanous weekday& 1881*1b8b02a4SEd Tanous weekday::operator-=(const days& d) NOEXCEPT 1882*1b8b02a4SEd Tanous { 1883*1b8b02a4SEd Tanous *this = *this - d; 1884*1b8b02a4SEd Tanous return *this; 1885*1b8b02a4SEd Tanous } 1886*1b8b02a4SEd Tanous 1887*1b8b02a4SEd Tanous CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} 1888*1b8b02a4SEd Tanous 1889*1b8b02a4SEd Tanous CONSTCD11 1890*1b8b02a4SEd Tanous inline 1891*1b8b02a4SEd Tanous unsigned weekday::c_encoding() const NOEXCEPT 1892*1b8b02a4SEd Tanous { 1893*1b8b02a4SEd Tanous return unsigned{wd_}; 1894*1b8b02a4SEd Tanous } 1895*1b8b02a4SEd Tanous 1896*1b8b02a4SEd Tanous CONSTCD11 1897*1b8b02a4SEd Tanous inline 1898*1b8b02a4SEd Tanous unsigned weekday::iso_encoding() const NOEXCEPT 1899*1b8b02a4SEd Tanous { 1900*1b8b02a4SEd Tanous return unsigned{((wd_ == 0u) ? 7u : wd_)}; 1901*1b8b02a4SEd Tanous } 1902*1b8b02a4SEd Tanous 1903*1b8b02a4SEd Tanous CONSTCD11 1904*1b8b02a4SEd Tanous inline 1905*1b8b02a4SEd Tanous bool 1906*1b8b02a4SEd Tanous operator==(const weekday& x, const weekday& y) NOEXCEPT 1907*1b8b02a4SEd Tanous { 1908*1b8b02a4SEd Tanous return x.wd_ == y.wd_; 1909*1b8b02a4SEd Tanous } 1910*1b8b02a4SEd Tanous 1911*1b8b02a4SEd Tanous CONSTCD11 1912*1b8b02a4SEd Tanous inline 1913*1b8b02a4SEd Tanous bool 1914*1b8b02a4SEd Tanous operator!=(const weekday& x, const weekday& y) NOEXCEPT 1915*1b8b02a4SEd Tanous { 1916*1b8b02a4SEd Tanous return !(x == y); 1917*1b8b02a4SEd Tanous } 1918*1b8b02a4SEd Tanous 1919*1b8b02a4SEd Tanous CONSTCD14 1920*1b8b02a4SEd Tanous inline 1921*1b8b02a4SEd Tanous days 1922*1b8b02a4SEd Tanous operator-(const weekday& x, const weekday& y) NOEXCEPT 1923*1b8b02a4SEd Tanous { 1924*1b8b02a4SEd Tanous auto const wdu = x.wd_ - y.wd_; 1925*1b8b02a4SEd Tanous auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; 1926*1b8b02a4SEd Tanous return days{wdu - wk * 7}; 1927*1b8b02a4SEd Tanous } 1928*1b8b02a4SEd Tanous 1929*1b8b02a4SEd Tanous CONSTCD14 1930*1b8b02a4SEd Tanous inline 1931*1b8b02a4SEd Tanous weekday 1932*1b8b02a4SEd Tanous operator+(const weekday& x, const days& y) NOEXCEPT 1933*1b8b02a4SEd Tanous { 1934*1b8b02a4SEd Tanous auto const wdu = static_cast<long long>(static_cast<unsigned>(x.wd_)) + y.count(); 1935*1b8b02a4SEd Tanous auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; 1936*1b8b02a4SEd Tanous return weekday{static_cast<unsigned>(wdu - wk * 7)}; 1937*1b8b02a4SEd Tanous } 1938*1b8b02a4SEd Tanous 1939*1b8b02a4SEd Tanous CONSTCD14 1940*1b8b02a4SEd Tanous inline 1941*1b8b02a4SEd Tanous weekday 1942*1b8b02a4SEd Tanous operator+(const days& x, const weekday& y) NOEXCEPT 1943*1b8b02a4SEd Tanous { 1944*1b8b02a4SEd Tanous return y + x; 1945*1b8b02a4SEd Tanous } 1946*1b8b02a4SEd Tanous 1947*1b8b02a4SEd Tanous CONSTCD14 1948*1b8b02a4SEd Tanous inline 1949*1b8b02a4SEd Tanous weekday 1950*1b8b02a4SEd Tanous operator-(const weekday& x, const days& y) NOEXCEPT 1951*1b8b02a4SEd Tanous { 1952*1b8b02a4SEd Tanous return x + -y; 1953*1b8b02a4SEd Tanous } 1954*1b8b02a4SEd Tanous 1955*1b8b02a4SEd Tanous namespace detail 1956*1b8b02a4SEd Tanous { 1957*1b8b02a4SEd Tanous 1958*1b8b02a4SEd Tanous template<class CharT, class Traits> 1959*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1960*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday& wd) 1961*1b8b02a4SEd Tanous { 1962*1b8b02a4SEd Tanous if (wd.ok()) 1963*1b8b02a4SEd Tanous { 1964*1b8b02a4SEd Tanous CharT fmt[] = {'%', 'a', 0}; 1965*1b8b02a4SEd Tanous os << format(fmt, wd); 1966*1b8b02a4SEd Tanous } 1967*1b8b02a4SEd Tanous else 1968*1b8b02a4SEd Tanous os << wd.c_encoding(); 1969*1b8b02a4SEd Tanous return os; 1970*1b8b02a4SEd Tanous } 1971*1b8b02a4SEd Tanous 1972*1b8b02a4SEd Tanous } // namespace detail 1973*1b8b02a4SEd Tanous 1974*1b8b02a4SEd Tanous template<class CharT, class Traits> 1975*1b8b02a4SEd Tanous inline 1976*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 1977*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd) 1978*1b8b02a4SEd Tanous { 1979*1b8b02a4SEd Tanous detail::low_level_fmt(os, wd); 1980*1b8b02a4SEd Tanous if (!wd.ok()) 1981*1b8b02a4SEd Tanous os << " is not a valid weekday"; 1982*1b8b02a4SEd Tanous return os; 1983*1b8b02a4SEd Tanous } 1984*1b8b02a4SEd Tanous 1985*1b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 1986*1b8b02a4SEd Tanous inline namespace literals 1987*1b8b02a4SEd Tanous { 1988*1b8b02a4SEd Tanous 1989*1b8b02a4SEd Tanous CONSTCD11 1990*1b8b02a4SEd Tanous inline 1991*1b8b02a4SEd Tanous date::day 1992*1b8b02a4SEd Tanous operator "" _d(unsigned long long d) NOEXCEPT 1993*1b8b02a4SEd Tanous { 1994*1b8b02a4SEd Tanous return date::day{static_cast<unsigned>(d)}; 1995*1b8b02a4SEd Tanous } 1996*1b8b02a4SEd Tanous 1997*1b8b02a4SEd Tanous CONSTCD11 1998*1b8b02a4SEd Tanous inline 1999*1b8b02a4SEd Tanous date::year 2000*1b8b02a4SEd Tanous operator "" _y(unsigned long long y) NOEXCEPT 2001*1b8b02a4SEd Tanous { 2002*1b8b02a4SEd Tanous return date::year(static_cast<int>(y)); 2003*1b8b02a4SEd Tanous } 2004*1b8b02a4SEd Tanous #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) 2005*1b8b02a4SEd Tanous 2006*1b8b02a4SEd Tanous CONSTDATA date::last_spec last{}; 2007*1b8b02a4SEd Tanous 2008*1b8b02a4SEd Tanous CONSTDATA date::month jan{1}; 2009*1b8b02a4SEd Tanous CONSTDATA date::month feb{2}; 2010*1b8b02a4SEd Tanous CONSTDATA date::month mar{3}; 2011*1b8b02a4SEd Tanous CONSTDATA date::month apr{4}; 2012*1b8b02a4SEd Tanous CONSTDATA date::month may{5}; 2013*1b8b02a4SEd Tanous CONSTDATA date::month jun{6}; 2014*1b8b02a4SEd Tanous CONSTDATA date::month jul{7}; 2015*1b8b02a4SEd Tanous CONSTDATA date::month aug{8}; 2016*1b8b02a4SEd Tanous CONSTDATA date::month sep{9}; 2017*1b8b02a4SEd Tanous CONSTDATA date::month oct{10}; 2018*1b8b02a4SEd Tanous CONSTDATA date::month nov{11}; 2019*1b8b02a4SEd Tanous CONSTDATA date::month dec{12}; 2020*1b8b02a4SEd Tanous 2021*1b8b02a4SEd Tanous CONSTDATA date::weekday sun{0u}; 2022*1b8b02a4SEd Tanous CONSTDATA date::weekday mon{1u}; 2023*1b8b02a4SEd Tanous CONSTDATA date::weekday tue{2u}; 2024*1b8b02a4SEd Tanous CONSTDATA date::weekday wed{3u}; 2025*1b8b02a4SEd Tanous CONSTDATA date::weekday thu{4u}; 2026*1b8b02a4SEd Tanous CONSTDATA date::weekday fri{5u}; 2027*1b8b02a4SEd Tanous CONSTDATA date::weekday sat{6u}; 2028*1b8b02a4SEd Tanous 2029*1b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 2030*1b8b02a4SEd Tanous } // inline namespace literals 2031*1b8b02a4SEd Tanous #endif 2032*1b8b02a4SEd Tanous 2033*1b8b02a4SEd Tanous CONSTDATA date::month January{1}; 2034*1b8b02a4SEd Tanous CONSTDATA date::month February{2}; 2035*1b8b02a4SEd Tanous CONSTDATA date::month March{3}; 2036*1b8b02a4SEd Tanous CONSTDATA date::month April{4}; 2037*1b8b02a4SEd Tanous CONSTDATA date::month May{5}; 2038*1b8b02a4SEd Tanous CONSTDATA date::month June{6}; 2039*1b8b02a4SEd Tanous CONSTDATA date::month July{7}; 2040*1b8b02a4SEd Tanous CONSTDATA date::month August{8}; 2041*1b8b02a4SEd Tanous CONSTDATA date::month September{9}; 2042*1b8b02a4SEd Tanous CONSTDATA date::month October{10}; 2043*1b8b02a4SEd Tanous CONSTDATA date::month November{11}; 2044*1b8b02a4SEd Tanous CONSTDATA date::month December{12}; 2045*1b8b02a4SEd Tanous 2046*1b8b02a4SEd Tanous CONSTDATA date::weekday Monday{1}; 2047*1b8b02a4SEd Tanous CONSTDATA date::weekday Tuesday{2}; 2048*1b8b02a4SEd Tanous CONSTDATA date::weekday Wednesday{3}; 2049*1b8b02a4SEd Tanous CONSTDATA date::weekday Thursday{4}; 2050*1b8b02a4SEd Tanous CONSTDATA date::weekday Friday{5}; 2051*1b8b02a4SEd Tanous CONSTDATA date::weekday Saturday{6}; 2052*1b8b02a4SEd Tanous CONSTDATA date::weekday Sunday{7}; 2053*1b8b02a4SEd Tanous 2054*1b8b02a4SEd Tanous // weekday_indexed 2055*1b8b02a4SEd Tanous 2056*1b8b02a4SEd Tanous CONSTCD11 2057*1b8b02a4SEd Tanous inline 2058*1b8b02a4SEd Tanous weekday 2059*1b8b02a4SEd Tanous weekday_indexed::weekday() const NOEXCEPT 2060*1b8b02a4SEd Tanous { 2061*1b8b02a4SEd Tanous return date::weekday{static_cast<unsigned>(wd_)}; 2062*1b8b02a4SEd Tanous } 2063*1b8b02a4SEd Tanous 2064*1b8b02a4SEd Tanous CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} 2065*1b8b02a4SEd Tanous 2066*1b8b02a4SEd Tanous CONSTCD11 2067*1b8b02a4SEd Tanous inline 2068*1b8b02a4SEd Tanous bool 2069*1b8b02a4SEd Tanous weekday_indexed::ok() const NOEXCEPT 2070*1b8b02a4SEd Tanous { 2071*1b8b02a4SEd Tanous return weekday().ok() && 1 <= index_ && index_ <= 5; 2072*1b8b02a4SEd Tanous } 2073*1b8b02a4SEd Tanous 2074*1b8b02a4SEd Tanous #ifdef __GNUC__ 2075*1b8b02a4SEd Tanous # pragma GCC diagnostic push 2076*1b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wconversion" 2077*1b8b02a4SEd Tanous #endif // __GNUC__ 2078*1b8b02a4SEd Tanous 2079*1b8b02a4SEd Tanous CONSTCD11 2080*1b8b02a4SEd Tanous inline 2081*1b8b02a4SEd Tanous weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT 2082*1b8b02a4SEd Tanous : wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd.wd_))) 2083*1b8b02a4SEd Tanous , index_(static_cast<decltype(index_)>(index)) 2084*1b8b02a4SEd Tanous {} 2085*1b8b02a4SEd Tanous 2086*1b8b02a4SEd Tanous #ifdef __GNUC__ 2087*1b8b02a4SEd Tanous # pragma GCC diagnostic pop 2088*1b8b02a4SEd Tanous #endif // __GNUC__ 2089*1b8b02a4SEd Tanous 2090*1b8b02a4SEd Tanous namespace detail 2091*1b8b02a4SEd Tanous { 2092*1b8b02a4SEd Tanous 2093*1b8b02a4SEd Tanous template<class CharT, class Traits> 2094*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2095*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi) 2096*1b8b02a4SEd Tanous { 2097*1b8b02a4SEd Tanous return low_level_fmt(os, wdi.weekday()) << '[' << wdi.index() << ']'; 2098*1b8b02a4SEd Tanous } 2099*1b8b02a4SEd Tanous 2100*1b8b02a4SEd Tanous } // namespace detail 2101*1b8b02a4SEd Tanous 2102*1b8b02a4SEd Tanous template<class CharT, class Traits> 2103*1b8b02a4SEd Tanous inline 2104*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2105*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi) 2106*1b8b02a4SEd Tanous { 2107*1b8b02a4SEd Tanous detail::low_level_fmt(os, wdi); 2108*1b8b02a4SEd Tanous if (!wdi.ok()) 2109*1b8b02a4SEd Tanous os << " is not a valid weekday_indexed"; 2110*1b8b02a4SEd Tanous return os; 2111*1b8b02a4SEd Tanous } 2112*1b8b02a4SEd Tanous 2113*1b8b02a4SEd Tanous CONSTCD11 2114*1b8b02a4SEd Tanous inline 2115*1b8b02a4SEd Tanous weekday_indexed 2116*1b8b02a4SEd Tanous weekday::operator[](unsigned index) const NOEXCEPT 2117*1b8b02a4SEd Tanous { 2118*1b8b02a4SEd Tanous return {*this, index}; 2119*1b8b02a4SEd Tanous } 2120*1b8b02a4SEd Tanous 2121*1b8b02a4SEd Tanous CONSTCD11 2122*1b8b02a4SEd Tanous inline 2123*1b8b02a4SEd Tanous bool 2124*1b8b02a4SEd Tanous operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT 2125*1b8b02a4SEd Tanous { 2126*1b8b02a4SEd Tanous return x.weekday() == y.weekday() && x.index() == y.index(); 2127*1b8b02a4SEd Tanous } 2128*1b8b02a4SEd Tanous 2129*1b8b02a4SEd Tanous CONSTCD11 2130*1b8b02a4SEd Tanous inline 2131*1b8b02a4SEd Tanous bool 2132*1b8b02a4SEd Tanous operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT 2133*1b8b02a4SEd Tanous { 2134*1b8b02a4SEd Tanous return !(x == y); 2135*1b8b02a4SEd Tanous } 2136*1b8b02a4SEd Tanous 2137*1b8b02a4SEd Tanous // weekday_last 2138*1b8b02a4SEd Tanous 2139*1b8b02a4SEd Tanous CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} 2140*1b8b02a4SEd Tanous CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} 2141*1b8b02a4SEd Tanous CONSTCD11 inline weekday_last::weekday_last(const date::weekday& wd) NOEXCEPT : wd_(wd) {} 2142*1b8b02a4SEd Tanous 2143*1b8b02a4SEd Tanous CONSTCD11 2144*1b8b02a4SEd Tanous inline 2145*1b8b02a4SEd Tanous bool 2146*1b8b02a4SEd Tanous operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT 2147*1b8b02a4SEd Tanous { 2148*1b8b02a4SEd Tanous return x.weekday() == y.weekday(); 2149*1b8b02a4SEd Tanous } 2150*1b8b02a4SEd Tanous 2151*1b8b02a4SEd Tanous CONSTCD11 2152*1b8b02a4SEd Tanous inline 2153*1b8b02a4SEd Tanous bool 2154*1b8b02a4SEd Tanous operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT 2155*1b8b02a4SEd Tanous { 2156*1b8b02a4SEd Tanous return !(x == y); 2157*1b8b02a4SEd Tanous } 2158*1b8b02a4SEd Tanous 2159*1b8b02a4SEd Tanous namespace detail 2160*1b8b02a4SEd Tanous { 2161*1b8b02a4SEd Tanous 2162*1b8b02a4SEd Tanous template<class CharT, class Traits> 2163*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2164*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl) 2165*1b8b02a4SEd Tanous { 2166*1b8b02a4SEd Tanous return low_level_fmt(os, wdl.weekday()) << "[last]"; 2167*1b8b02a4SEd Tanous } 2168*1b8b02a4SEd Tanous 2169*1b8b02a4SEd Tanous } // namespace detail 2170*1b8b02a4SEd Tanous 2171*1b8b02a4SEd Tanous template<class CharT, class Traits> 2172*1b8b02a4SEd Tanous inline 2173*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2174*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl) 2175*1b8b02a4SEd Tanous { 2176*1b8b02a4SEd Tanous detail::low_level_fmt(os, wdl); 2177*1b8b02a4SEd Tanous if (!wdl.ok()) 2178*1b8b02a4SEd Tanous os << " is not a valid weekday_last"; 2179*1b8b02a4SEd Tanous return os; 2180*1b8b02a4SEd Tanous } 2181*1b8b02a4SEd Tanous 2182*1b8b02a4SEd Tanous CONSTCD11 2183*1b8b02a4SEd Tanous inline 2184*1b8b02a4SEd Tanous weekday_last 2185*1b8b02a4SEd Tanous weekday::operator[](last_spec) const NOEXCEPT 2186*1b8b02a4SEd Tanous { 2187*1b8b02a4SEd Tanous return weekday_last{*this}; 2188*1b8b02a4SEd Tanous } 2189*1b8b02a4SEd Tanous 2190*1b8b02a4SEd Tanous // year_month 2191*1b8b02a4SEd Tanous 2192*1b8b02a4SEd Tanous CONSTCD11 2193*1b8b02a4SEd Tanous inline 2194*1b8b02a4SEd Tanous year_month::year_month(const date::year& y, const date::month& m) NOEXCEPT 2195*1b8b02a4SEd Tanous : y_(y) 2196*1b8b02a4SEd Tanous , m_(m) 2197*1b8b02a4SEd Tanous {} 2198*1b8b02a4SEd Tanous 2199*1b8b02a4SEd Tanous CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} 2200*1b8b02a4SEd Tanous CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} 2201*1b8b02a4SEd Tanous CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} 2202*1b8b02a4SEd Tanous 2203*1b8b02a4SEd Tanous template<class> 2204*1b8b02a4SEd Tanous CONSTCD14 2205*1b8b02a4SEd Tanous inline 2206*1b8b02a4SEd Tanous year_month& 2207*1b8b02a4SEd Tanous year_month::operator+=(const months& dm) NOEXCEPT 2208*1b8b02a4SEd Tanous { 2209*1b8b02a4SEd Tanous *this = *this + dm; 2210*1b8b02a4SEd Tanous return *this; 2211*1b8b02a4SEd Tanous } 2212*1b8b02a4SEd Tanous 2213*1b8b02a4SEd Tanous template<class> 2214*1b8b02a4SEd Tanous CONSTCD14 2215*1b8b02a4SEd Tanous inline 2216*1b8b02a4SEd Tanous year_month& 2217*1b8b02a4SEd Tanous year_month::operator-=(const months& dm) NOEXCEPT 2218*1b8b02a4SEd Tanous { 2219*1b8b02a4SEd Tanous *this = *this - dm; 2220*1b8b02a4SEd Tanous return *this; 2221*1b8b02a4SEd Tanous } 2222*1b8b02a4SEd Tanous 2223*1b8b02a4SEd Tanous CONSTCD14 2224*1b8b02a4SEd Tanous inline 2225*1b8b02a4SEd Tanous year_month& 2226*1b8b02a4SEd Tanous year_month::operator+=(const years& dy) NOEXCEPT 2227*1b8b02a4SEd Tanous { 2228*1b8b02a4SEd Tanous *this = *this + dy; 2229*1b8b02a4SEd Tanous return *this; 2230*1b8b02a4SEd Tanous } 2231*1b8b02a4SEd Tanous 2232*1b8b02a4SEd Tanous CONSTCD14 2233*1b8b02a4SEd Tanous inline 2234*1b8b02a4SEd Tanous year_month& 2235*1b8b02a4SEd Tanous year_month::operator-=(const years& dy) NOEXCEPT 2236*1b8b02a4SEd Tanous { 2237*1b8b02a4SEd Tanous *this = *this - dy; 2238*1b8b02a4SEd Tanous return *this; 2239*1b8b02a4SEd Tanous } 2240*1b8b02a4SEd Tanous 2241*1b8b02a4SEd Tanous CONSTCD11 2242*1b8b02a4SEd Tanous inline 2243*1b8b02a4SEd Tanous bool 2244*1b8b02a4SEd Tanous operator==(const year_month& x, const year_month& y) NOEXCEPT 2245*1b8b02a4SEd Tanous { 2246*1b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month(); 2247*1b8b02a4SEd Tanous } 2248*1b8b02a4SEd Tanous 2249*1b8b02a4SEd Tanous CONSTCD11 2250*1b8b02a4SEd Tanous inline 2251*1b8b02a4SEd Tanous bool 2252*1b8b02a4SEd Tanous operator!=(const year_month& x, const year_month& y) NOEXCEPT 2253*1b8b02a4SEd Tanous { 2254*1b8b02a4SEd Tanous return !(x == y); 2255*1b8b02a4SEd Tanous } 2256*1b8b02a4SEd Tanous 2257*1b8b02a4SEd Tanous CONSTCD11 2258*1b8b02a4SEd Tanous inline 2259*1b8b02a4SEd Tanous bool 2260*1b8b02a4SEd Tanous operator<(const year_month& x, const year_month& y) NOEXCEPT 2261*1b8b02a4SEd Tanous { 2262*1b8b02a4SEd Tanous return x.year() < y.year() ? true 2263*1b8b02a4SEd Tanous : (x.year() > y.year() ? false 2264*1b8b02a4SEd Tanous : (x.month() < y.month())); 2265*1b8b02a4SEd Tanous } 2266*1b8b02a4SEd Tanous 2267*1b8b02a4SEd Tanous CONSTCD11 2268*1b8b02a4SEd Tanous inline 2269*1b8b02a4SEd Tanous bool 2270*1b8b02a4SEd Tanous operator>(const year_month& x, const year_month& y) NOEXCEPT 2271*1b8b02a4SEd Tanous { 2272*1b8b02a4SEd Tanous return y < x; 2273*1b8b02a4SEd Tanous } 2274*1b8b02a4SEd Tanous 2275*1b8b02a4SEd Tanous CONSTCD11 2276*1b8b02a4SEd Tanous inline 2277*1b8b02a4SEd Tanous bool 2278*1b8b02a4SEd Tanous operator<=(const year_month& x, const year_month& y) NOEXCEPT 2279*1b8b02a4SEd Tanous { 2280*1b8b02a4SEd Tanous return !(y < x); 2281*1b8b02a4SEd Tanous } 2282*1b8b02a4SEd Tanous 2283*1b8b02a4SEd Tanous CONSTCD11 2284*1b8b02a4SEd Tanous inline 2285*1b8b02a4SEd Tanous bool 2286*1b8b02a4SEd Tanous operator>=(const year_month& x, const year_month& y) NOEXCEPT 2287*1b8b02a4SEd Tanous { 2288*1b8b02a4SEd Tanous return !(x < y); 2289*1b8b02a4SEd Tanous } 2290*1b8b02a4SEd Tanous 2291*1b8b02a4SEd Tanous template<class> 2292*1b8b02a4SEd Tanous CONSTCD14 2293*1b8b02a4SEd Tanous inline 2294*1b8b02a4SEd Tanous year_month 2295*1b8b02a4SEd Tanous operator+(const year_month& ym, const months& dm) NOEXCEPT 2296*1b8b02a4SEd Tanous { 2297*1b8b02a4SEd Tanous auto dmi = static_cast<int>(static_cast<unsigned>(ym.month())) - 1 + dm.count(); 2298*1b8b02a4SEd Tanous auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; 2299*1b8b02a4SEd Tanous dmi = dmi - dy * 12 + 1; 2300*1b8b02a4SEd Tanous return (ym.year() + years(dy)) / month(static_cast<unsigned>(dmi)); 2301*1b8b02a4SEd Tanous } 2302*1b8b02a4SEd Tanous 2303*1b8b02a4SEd Tanous template<class> 2304*1b8b02a4SEd Tanous CONSTCD14 2305*1b8b02a4SEd Tanous inline 2306*1b8b02a4SEd Tanous year_month 2307*1b8b02a4SEd Tanous operator+(const months& dm, const year_month& ym) NOEXCEPT 2308*1b8b02a4SEd Tanous { 2309*1b8b02a4SEd Tanous return ym + dm; 2310*1b8b02a4SEd Tanous } 2311*1b8b02a4SEd Tanous 2312*1b8b02a4SEd Tanous template<class> 2313*1b8b02a4SEd Tanous CONSTCD14 2314*1b8b02a4SEd Tanous inline 2315*1b8b02a4SEd Tanous year_month 2316*1b8b02a4SEd Tanous operator-(const year_month& ym, const months& dm) NOEXCEPT 2317*1b8b02a4SEd Tanous { 2318*1b8b02a4SEd Tanous return ym + -dm; 2319*1b8b02a4SEd Tanous } 2320*1b8b02a4SEd Tanous 2321*1b8b02a4SEd Tanous CONSTCD11 2322*1b8b02a4SEd Tanous inline 2323*1b8b02a4SEd Tanous months 2324*1b8b02a4SEd Tanous operator-(const year_month& x, const year_month& y) NOEXCEPT 2325*1b8b02a4SEd Tanous { 2326*1b8b02a4SEd Tanous return (x.year() - y.year()) + 2327*1b8b02a4SEd Tanous months(static_cast<unsigned>(x.month()) - static_cast<unsigned>(y.month())); 2328*1b8b02a4SEd Tanous } 2329*1b8b02a4SEd Tanous 2330*1b8b02a4SEd Tanous CONSTCD11 2331*1b8b02a4SEd Tanous inline 2332*1b8b02a4SEd Tanous year_month 2333*1b8b02a4SEd Tanous operator+(const year_month& ym, const years& dy) NOEXCEPT 2334*1b8b02a4SEd Tanous { 2335*1b8b02a4SEd Tanous return (ym.year() + dy) / ym.month(); 2336*1b8b02a4SEd Tanous } 2337*1b8b02a4SEd Tanous 2338*1b8b02a4SEd Tanous CONSTCD11 2339*1b8b02a4SEd Tanous inline 2340*1b8b02a4SEd Tanous year_month 2341*1b8b02a4SEd Tanous operator+(const years& dy, const year_month& ym) NOEXCEPT 2342*1b8b02a4SEd Tanous { 2343*1b8b02a4SEd Tanous return ym + dy; 2344*1b8b02a4SEd Tanous } 2345*1b8b02a4SEd Tanous 2346*1b8b02a4SEd Tanous CONSTCD11 2347*1b8b02a4SEd Tanous inline 2348*1b8b02a4SEd Tanous year_month 2349*1b8b02a4SEd Tanous operator-(const year_month& ym, const years& dy) NOEXCEPT 2350*1b8b02a4SEd Tanous { 2351*1b8b02a4SEd Tanous return ym + -dy; 2352*1b8b02a4SEd Tanous } 2353*1b8b02a4SEd Tanous 2354*1b8b02a4SEd Tanous namespace detail 2355*1b8b02a4SEd Tanous { 2356*1b8b02a4SEd Tanous 2357*1b8b02a4SEd Tanous template<class CharT, class Traits> 2358*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2359*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year_month& ym) 2360*1b8b02a4SEd Tanous { 2361*1b8b02a4SEd Tanous low_level_fmt(os, ym.year()) << '/'; 2362*1b8b02a4SEd Tanous return low_level_fmt(os, ym.month()); 2363*1b8b02a4SEd Tanous } 2364*1b8b02a4SEd Tanous 2365*1b8b02a4SEd Tanous } // namespace detail 2366*1b8b02a4SEd Tanous 2367*1b8b02a4SEd Tanous template<class CharT, class Traits> 2368*1b8b02a4SEd Tanous inline 2369*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2370*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym) 2371*1b8b02a4SEd Tanous { 2372*1b8b02a4SEd Tanous detail::low_level_fmt(os, ym); 2373*1b8b02a4SEd Tanous if (!ym.ok()) 2374*1b8b02a4SEd Tanous os << " is not a valid year_month"; 2375*1b8b02a4SEd Tanous return os; 2376*1b8b02a4SEd Tanous } 2377*1b8b02a4SEd Tanous 2378*1b8b02a4SEd Tanous // month_day 2379*1b8b02a4SEd Tanous 2380*1b8b02a4SEd Tanous CONSTCD11 2381*1b8b02a4SEd Tanous inline 2382*1b8b02a4SEd Tanous month_day::month_day(const date::month& m, const date::day& d) NOEXCEPT 2383*1b8b02a4SEd Tanous : m_(m) 2384*1b8b02a4SEd Tanous , d_(d) 2385*1b8b02a4SEd Tanous {} 2386*1b8b02a4SEd Tanous 2387*1b8b02a4SEd Tanous CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;} 2388*1b8b02a4SEd Tanous CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;} 2389*1b8b02a4SEd Tanous 2390*1b8b02a4SEd Tanous CONSTCD14 2391*1b8b02a4SEd Tanous inline 2392*1b8b02a4SEd Tanous bool 2393*1b8b02a4SEd Tanous month_day::ok() const NOEXCEPT 2394*1b8b02a4SEd Tanous { 2395*1b8b02a4SEd Tanous CONSTDATA date::day d[] = 2396*1b8b02a4SEd Tanous { 2397*1b8b02a4SEd Tanous date::day(31), date::day(29), date::day(31), 2398*1b8b02a4SEd Tanous date::day(30), date::day(31), date::day(30), 2399*1b8b02a4SEd Tanous date::day(31), date::day(31), date::day(30), 2400*1b8b02a4SEd Tanous date::day(31), date::day(30), date::day(31) 2401*1b8b02a4SEd Tanous }; 2402*1b8b02a4SEd Tanous return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast<unsigned>(m_)-1]; 2403*1b8b02a4SEd Tanous } 2404*1b8b02a4SEd Tanous 2405*1b8b02a4SEd Tanous CONSTCD11 2406*1b8b02a4SEd Tanous inline 2407*1b8b02a4SEd Tanous bool 2408*1b8b02a4SEd Tanous operator==(const month_day& x, const month_day& y) NOEXCEPT 2409*1b8b02a4SEd Tanous { 2410*1b8b02a4SEd Tanous return x.month() == y.month() && x.day() == y.day(); 2411*1b8b02a4SEd Tanous } 2412*1b8b02a4SEd Tanous 2413*1b8b02a4SEd Tanous CONSTCD11 2414*1b8b02a4SEd Tanous inline 2415*1b8b02a4SEd Tanous bool 2416*1b8b02a4SEd Tanous operator!=(const month_day& x, const month_day& y) NOEXCEPT 2417*1b8b02a4SEd Tanous { 2418*1b8b02a4SEd Tanous return !(x == y); 2419*1b8b02a4SEd Tanous } 2420*1b8b02a4SEd Tanous 2421*1b8b02a4SEd Tanous CONSTCD11 2422*1b8b02a4SEd Tanous inline 2423*1b8b02a4SEd Tanous bool 2424*1b8b02a4SEd Tanous operator<(const month_day& x, const month_day& y) NOEXCEPT 2425*1b8b02a4SEd Tanous { 2426*1b8b02a4SEd Tanous return x.month() < y.month() ? true 2427*1b8b02a4SEd Tanous : (x.month() > y.month() ? false 2428*1b8b02a4SEd Tanous : (x.day() < y.day())); 2429*1b8b02a4SEd Tanous } 2430*1b8b02a4SEd Tanous 2431*1b8b02a4SEd Tanous CONSTCD11 2432*1b8b02a4SEd Tanous inline 2433*1b8b02a4SEd Tanous bool 2434*1b8b02a4SEd Tanous operator>(const month_day& x, const month_day& y) NOEXCEPT 2435*1b8b02a4SEd Tanous { 2436*1b8b02a4SEd Tanous return y < x; 2437*1b8b02a4SEd Tanous } 2438*1b8b02a4SEd Tanous 2439*1b8b02a4SEd Tanous CONSTCD11 2440*1b8b02a4SEd Tanous inline 2441*1b8b02a4SEd Tanous bool 2442*1b8b02a4SEd Tanous operator<=(const month_day& x, const month_day& y) NOEXCEPT 2443*1b8b02a4SEd Tanous { 2444*1b8b02a4SEd Tanous return !(y < x); 2445*1b8b02a4SEd Tanous } 2446*1b8b02a4SEd Tanous 2447*1b8b02a4SEd Tanous CONSTCD11 2448*1b8b02a4SEd Tanous inline 2449*1b8b02a4SEd Tanous bool 2450*1b8b02a4SEd Tanous operator>=(const month_day& x, const month_day& y) NOEXCEPT 2451*1b8b02a4SEd Tanous { 2452*1b8b02a4SEd Tanous return !(x < y); 2453*1b8b02a4SEd Tanous } 2454*1b8b02a4SEd Tanous 2455*1b8b02a4SEd Tanous namespace detail 2456*1b8b02a4SEd Tanous { 2457*1b8b02a4SEd Tanous 2458*1b8b02a4SEd Tanous template<class CharT, class Traits> 2459*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2460*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_day& md) 2461*1b8b02a4SEd Tanous { 2462*1b8b02a4SEd Tanous low_level_fmt(os, md.month()) << '/'; 2463*1b8b02a4SEd Tanous return low_level_fmt(os, md.day()); 2464*1b8b02a4SEd Tanous } 2465*1b8b02a4SEd Tanous 2466*1b8b02a4SEd Tanous } // namespace detail 2467*1b8b02a4SEd Tanous 2468*1b8b02a4SEd Tanous template<class CharT, class Traits> 2469*1b8b02a4SEd Tanous inline 2470*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2471*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md) 2472*1b8b02a4SEd Tanous { 2473*1b8b02a4SEd Tanous detail::low_level_fmt(os, md); 2474*1b8b02a4SEd Tanous if (!md.ok()) 2475*1b8b02a4SEd Tanous os << " is not a valid month_day"; 2476*1b8b02a4SEd Tanous return os; 2477*1b8b02a4SEd Tanous } 2478*1b8b02a4SEd Tanous 2479*1b8b02a4SEd Tanous // month_day_last 2480*1b8b02a4SEd Tanous 2481*1b8b02a4SEd Tanous CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} 2482*1b8b02a4SEd Tanous CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} 2483*1b8b02a4SEd Tanous CONSTCD11 inline month_day_last::month_day_last(const date::month& m) NOEXCEPT : m_(m) {} 2484*1b8b02a4SEd Tanous 2485*1b8b02a4SEd Tanous CONSTCD11 2486*1b8b02a4SEd Tanous inline 2487*1b8b02a4SEd Tanous bool 2488*1b8b02a4SEd Tanous operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT 2489*1b8b02a4SEd Tanous { 2490*1b8b02a4SEd Tanous return x.month() == y.month(); 2491*1b8b02a4SEd Tanous } 2492*1b8b02a4SEd Tanous 2493*1b8b02a4SEd Tanous CONSTCD11 2494*1b8b02a4SEd Tanous inline 2495*1b8b02a4SEd Tanous bool 2496*1b8b02a4SEd Tanous operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT 2497*1b8b02a4SEd Tanous { 2498*1b8b02a4SEd Tanous return !(x == y); 2499*1b8b02a4SEd Tanous } 2500*1b8b02a4SEd Tanous 2501*1b8b02a4SEd Tanous CONSTCD11 2502*1b8b02a4SEd Tanous inline 2503*1b8b02a4SEd Tanous bool 2504*1b8b02a4SEd Tanous operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT 2505*1b8b02a4SEd Tanous { 2506*1b8b02a4SEd Tanous return x.month() < y.month(); 2507*1b8b02a4SEd Tanous } 2508*1b8b02a4SEd Tanous 2509*1b8b02a4SEd Tanous CONSTCD11 2510*1b8b02a4SEd Tanous inline 2511*1b8b02a4SEd Tanous bool 2512*1b8b02a4SEd Tanous operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT 2513*1b8b02a4SEd Tanous { 2514*1b8b02a4SEd Tanous return y < x; 2515*1b8b02a4SEd Tanous } 2516*1b8b02a4SEd Tanous 2517*1b8b02a4SEd Tanous CONSTCD11 2518*1b8b02a4SEd Tanous inline 2519*1b8b02a4SEd Tanous bool 2520*1b8b02a4SEd Tanous operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT 2521*1b8b02a4SEd Tanous { 2522*1b8b02a4SEd Tanous return !(y < x); 2523*1b8b02a4SEd Tanous } 2524*1b8b02a4SEd Tanous 2525*1b8b02a4SEd Tanous CONSTCD11 2526*1b8b02a4SEd Tanous inline 2527*1b8b02a4SEd Tanous bool 2528*1b8b02a4SEd Tanous operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT 2529*1b8b02a4SEd Tanous { 2530*1b8b02a4SEd Tanous return !(x < y); 2531*1b8b02a4SEd Tanous } 2532*1b8b02a4SEd Tanous 2533*1b8b02a4SEd Tanous namespace detail 2534*1b8b02a4SEd Tanous { 2535*1b8b02a4SEd Tanous 2536*1b8b02a4SEd Tanous template<class CharT, class Traits> 2537*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2538*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl) 2539*1b8b02a4SEd Tanous { 2540*1b8b02a4SEd Tanous return low_level_fmt(os, mdl.month()) << "/last"; 2541*1b8b02a4SEd Tanous } 2542*1b8b02a4SEd Tanous 2543*1b8b02a4SEd Tanous } // namespace detail 2544*1b8b02a4SEd Tanous 2545*1b8b02a4SEd Tanous template<class CharT, class Traits> 2546*1b8b02a4SEd Tanous inline 2547*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2548*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl) 2549*1b8b02a4SEd Tanous { 2550*1b8b02a4SEd Tanous detail::low_level_fmt(os, mdl); 2551*1b8b02a4SEd Tanous if (!mdl.ok()) 2552*1b8b02a4SEd Tanous os << " is not a valid month_day_last"; 2553*1b8b02a4SEd Tanous return os; 2554*1b8b02a4SEd Tanous } 2555*1b8b02a4SEd Tanous 2556*1b8b02a4SEd Tanous // month_weekday 2557*1b8b02a4SEd Tanous 2558*1b8b02a4SEd Tanous CONSTCD11 2559*1b8b02a4SEd Tanous inline 2560*1b8b02a4SEd Tanous month_weekday::month_weekday(const date::month& m, 2561*1b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT 2562*1b8b02a4SEd Tanous : m_(m) 2563*1b8b02a4SEd Tanous , wdi_(wdi) 2564*1b8b02a4SEd Tanous {} 2565*1b8b02a4SEd Tanous 2566*1b8b02a4SEd Tanous CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} 2567*1b8b02a4SEd Tanous 2568*1b8b02a4SEd Tanous CONSTCD11 2569*1b8b02a4SEd Tanous inline 2570*1b8b02a4SEd Tanous weekday_indexed 2571*1b8b02a4SEd Tanous month_weekday::weekday_indexed() const NOEXCEPT 2572*1b8b02a4SEd Tanous { 2573*1b8b02a4SEd Tanous return wdi_; 2574*1b8b02a4SEd Tanous } 2575*1b8b02a4SEd Tanous 2576*1b8b02a4SEd Tanous CONSTCD11 2577*1b8b02a4SEd Tanous inline 2578*1b8b02a4SEd Tanous bool 2579*1b8b02a4SEd Tanous month_weekday::ok() const NOEXCEPT 2580*1b8b02a4SEd Tanous { 2581*1b8b02a4SEd Tanous return m_.ok() && wdi_.ok(); 2582*1b8b02a4SEd Tanous } 2583*1b8b02a4SEd Tanous 2584*1b8b02a4SEd Tanous CONSTCD11 2585*1b8b02a4SEd Tanous inline 2586*1b8b02a4SEd Tanous bool 2587*1b8b02a4SEd Tanous operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT 2588*1b8b02a4SEd Tanous { 2589*1b8b02a4SEd Tanous return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); 2590*1b8b02a4SEd Tanous } 2591*1b8b02a4SEd Tanous 2592*1b8b02a4SEd Tanous CONSTCD11 2593*1b8b02a4SEd Tanous inline 2594*1b8b02a4SEd Tanous bool 2595*1b8b02a4SEd Tanous operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT 2596*1b8b02a4SEd Tanous { 2597*1b8b02a4SEd Tanous return !(x == y); 2598*1b8b02a4SEd Tanous } 2599*1b8b02a4SEd Tanous 2600*1b8b02a4SEd Tanous namespace detail 2601*1b8b02a4SEd Tanous { 2602*1b8b02a4SEd Tanous 2603*1b8b02a4SEd Tanous template<class CharT, class Traits> 2604*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2605*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd) 2606*1b8b02a4SEd Tanous { 2607*1b8b02a4SEd Tanous low_level_fmt(os, mwd.month()) << '/'; 2608*1b8b02a4SEd Tanous return low_level_fmt(os, mwd.weekday_indexed()); 2609*1b8b02a4SEd Tanous } 2610*1b8b02a4SEd Tanous 2611*1b8b02a4SEd Tanous } // namespace detail 2612*1b8b02a4SEd Tanous 2613*1b8b02a4SEd Tanous template<class CharT, class Traits> 2614*1b8b02a4SEd Tanous inline 2615*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2616*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd) 2617*1b8b02a4SEd Tanous { 2618*1b8b02a4SEd Tanous detail::low_level_fmt(os, mwd); 2619*1b8b02a4SEd Tanous if (!mwd.ok()) 2620*1b8b02a4SEd Tanous os << " is not a valid month_weekday"; 2621*1b8b02a4SEd Tanous return os; 2622*1b8b02a4SEd Tanous } 2623*1b8b02a4SEd Tanous 2624*1b8b02a4SEd Tanous // month_weekday_last 2625*1b8b02a4SEd Tanous 2626*1b8b02a4SEd Tanous CONSTCD11 2627*1b8b02a4SEd Tanous inline 2628*1b8b02a4SEd Tanous month_weekday_last::month_weekday_last(const date::month& m, 2629*1b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT 2630*1b8b02a4SEd Tanous : m_(m) 2631*1b8b02a4SEd Tanous , wdl_(wdl) 2632*1b8b02a4SEd Tanous {} 2633*1b8b02a4SEd Tanous 2634*1b8b02a4SEd Tanous CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} 2635*1b8b02a4SEd Tanous 2636*1b8b02a4SEd Tanous CONSTCD11 2637*1b8b02a4SEd Tanous inline 2638*1b8b02a4SEd Tanous weekday_last 2639*1b8b02a4SEd Tanous month_weekday_last::weekday_last() const NOEXCEPT 2640*1b8b02a4SEd Tanous { 2641*1b8b02a4SEd Tanous return wdl_; 2642*1b8b02a4SEd Tanous } 2643*1b8b02a4SEd Tanous 2644*1b8b02a4SEd Tanous CONSTCD11 2645*1b8b02a4SEd Tanous inline 2646*1b8b02a4SEd Tanous bool 2647*1b8b02a4SEd Tanous month_weekday_last::ok() const NOEXCEPT 2648*1b8b02a4SEd Tanous { 2649*1b8b02a4SEd Tanous return m_.ok() && wdl_.ok(); 2650*1b8b02a4SEd Tanous } 2651*1b8b02a4SEd Tanous 2652*1b8b02a4SEd Tanous CONSTCD11 2653*1b8b02a4SEd Tanous inline 2654*1b8b02a4SEd Tanous bool 2655*1b8b02a4SEd Tanous operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT 2656*1b8b02a4SEd Tanous { 2657*1b8b02a4SEd Tanous return x.month() == y.month() && x.weekday_last() == y.weekday_last(); 2658*1b8b02a4SEd Tanous } 2659*1b8b02a4SEd Tanous 2660*1b8b02a4SEd Tanous CONSTCD11 2661*1b8b02a4SEd Tanous inline 2662*1b8b02a4SEd Tanous bool 2663*1b8b02a4SEd Tanous operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT 2664*1b8b02a4SEd Tanous { 2665*1b8b02a4SEd Tanous return !(x == y); 2666*1b8b02a4SEd Tanous } 2667*1b8b02a4SEd Tanous 2668*1b8b02a4SEd Tanous namespace detail 2669*1b8b02a4SEd Tanous { 2670*1b8b02a4SEd Tanous 2671*1b8b02a4SEd Tanous template<class CharT, class Traits> 2672*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2673*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl) 2674*1b8b02a4SEd Tanous { 2675*1b8b02a4SEd Tanous low_level_fmt(os, mwdl.month()) << '/'; 2676*1b8b02a4SEd Tanous return low_level_fmt(os, mwdl.weekday_last()); 2677*1b8b02a4SEd Tanous } 2678*1b8b02a4SEd Tanous 2679*1b8b02a4SEd Tanous } // namespace detail 2680*1b8b02a4SEd Tanous 2681*1b8b02a4SEd Tanous template<class CharT, class Traits> 2682*1b8b02a4SEd Tanous inline 2683*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2684*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl) 2685*1b8b02a4SEd Tanous { 2686*1b8b02a4SEd Tanous detail::low_level_fmt(os, mwdl); 2687*1b8b02a4SEd Tanous if (!mwdl.ok()) 2688*1b8b02a4SEd Tanous os << " is not a valid month_weekday_last"; 2689*1b8b02a4SEd Tanous return os; 2690*1b8b02a4SEd Tanous } 2691*1b8b02a4SEd Tanous 2692*1b8b02a4SEd Tanous // year_month_day_last 2693*1b8b02a4SEd Tanous 2694*1b8b02a4SEd Tanous CONSTCD11 2695*1b8b02a4SEd Tanous inline 2696*1b8b02a4SEd Tanous year_month_day_last::year_month_day_last(const date::year& y, 2697*1b8b02a4SEd Tanous const date::month_day_last& mdl) NOEXCEPT 2698*1b8b02a4SEd Tanous : y_(y) 2699*1b8b02a4SEd Tanous , mdl_(mdl) 2700*1b8b02a4SEd Tanous {} 2701*1b8b02a4SEd Tanous 2702*1b8b02a4SEd Tanous template<class> 2703*1b8b02a4SEd Tanous CONSTCD14 2704*1b8b02a4SEd Tanous inline 2705*1b8b02a4SEd Tanous year_month_day_last& 2706*1b8b02a4SEd Tanous year_month_day_last::operator+=(const months& m) NOEXCEPT 2707*1b8b02a4SEd Tanous { 2708*1b8b02a4SEd Tanous *this = *this + m; 2709*1b8b02a4SEd Tanous return *this; 2710*1b8b02a4SEd Tanous } 2711*1b8b02a4SEd Tanous 2712*1b8b02a4SEd Tanous template<class> 2713*1b8b02a4SEd Tanous CONSTCD14 2714*1b8b02a4SEd Tanous inline 2715*1b8b02a4SEd Tanous year_month_day_last& 2716*1b8b02a4SEd Tanous year_month_day_last::operator-=(const months& m) NOEXCEPT 2717*1b8b02a4SEd Tanous { 2718*1b8b02a4SEd Tanous *this = *this - m; 2719*1b8b02a4SEd Tanous return *this; 2720*1b8b02a4SEd Tanous } 2721*1b8b02a4SEd Tanous 2722*1b8b02a4SEd Tanous CONSTCD14 2723*1b8b02a4SEd Tanous inline 2724*1b8b02a4SEd Tanous year_month_day_last& 2725*1b8b02a4SEd Tanous year_month_day_last::operator+=(const years& y) NOEXCEPT 2726*1b8b02a4SEd Tanous { 2727*1b8b02a4SEd Tanous *this = *this + y; 2728*1b8b02a4SEd Tanous return *this; 2729*1b8b02a4SEd Tanous } 2730*1b8b02a4SEd Tanous 2731*1b8b02a4SEd Tanous CONSTCD14 2732*1b8b02a4SEd Tanous inline 2733*1b8b02a4SEd Tanous year_month_day_last& 2734*1b8b02a4SEd Tanous year_month_day_last::operator-=(const years& y) NOEXCEPT 2735*1b8b02a4SEd Tanous { 2736*1b8b02a4SEd Tanous *this = *this - y; 2737*1b8b02a4SEd Tanous return *this; 2738*1b8b02a4SEd Tanous } 2739*1b8b02a4SEd Tanous 2740*1b8b02a4SEd Tanous CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} 2741*1b8b02a4SEd Tanous CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} 2742*1b8b02a4SEd Tanous 2743*1b8b02a4SEd Tanous CONSTCD11 2744*1b8b02a4SEd Tanous inline 2745*1b8b02a4SEd Tanous month_day_last 2746*1b8b02a4SEd Tanous year_month_day_last::month_day_last() const NOEXCEPT 2747*1b8b02a4SEd Tanous { 2748*1b8b02a4SEd Tanous return mdl_; 2749*1b8b02a4SEd Tanous } 2750*1b8b02a4SEd Tanous 2751*1b8b02a4SEd Tanous CONSTCD14 2752*1b8b02a4SEd Tanous inline 2753*1b8b02a4SEd Tanous day 2754*1b8b02a4SEd Tanous year_month_day_last::day() const NOEXCEPT 2755*1b8b02a4SEd Tanous { 2756*1b8b02a4SEd Tanous CONSTDATA date::day d[] = 2757*1b8b02a4SEd Tanous { 2758*1b8b02a4SEd Tanous date::day(31), date::day(28), date::day(31), 2759*1b8b02a4SEd Tanous date::day(30), date::day(31), date::day(30), 2760*1b8b02a4SEd Tanous date::day(31), date::day(31), date::day(30), 2761*1b8b02a4SEd Tanous date::day(31), date::day(30), date::day(31) 2762*1b8b02a4SEd Tanous }; 2763*1b8b02a4SEd Tanous return (month() != February || !y_.is_leap()) && mdl_.ok() ? 2764*1b8b02a4SEd Tanous d[static_cast<unsigned>(month()) - 1] : date::day{29}; 2765*1b8b02a4SEd Tanous } 2766*1b8b02a4SEd Tanous 2767*1b8b02a4SEd Tanous CONSTCD14 2768*1b8b02a4SEd Tanous inline 2769*1b8b02a4SEd Tanous year_month_day_last::operator sys_days() const NOEXCEPT 2770*1b8b02a4SEd Tanous { 2771*1b8b02a4SEd Tanous return sys_days(year()/month()/day()); 2772*1b8b02a4SEd Tanous } 2773*1b8b02a4SEd Tanous 2774*1b8b02a4SEd Tanous CONSTCD14 2775*1b8b02a4SEd Tanous inline 2776*1b8b02a4SEd Tanous year_month_day_last::operator local_days() const NOEXCEPT 2777*1b8b02a4SEd Tanous { 2778*1b8b02a4SEd Tanous return local_days(year()/month()/day()); 2779*1b8b02a4SEd Tanous } 2780*1b8b02a4SEd Tanous 2781*1b8b02a4SEd Tanous CONSTCD11 2782*1b8b02a4SEd Tanous inline 2783*1b8b02a4SEd Tanous bool 2784*1b8b02a4SEd Tanous year_month_day_last::ok() const NOEXCEPT 2785*1b8b02a4SEd Tanous { 2786*1b8b02a4SEd Tanous return y_.ok() && mdl_.ok(); 2787*1b8b02a4SEd Tanous } 2788*1b8b02a4SEd Tanous 2789*1b8b02a4SEd Tanous CONSTCD11 2790*1b8b02a4SEd Tanous inline 2791*1b8b02a4SEd Tanous bool 2792*1b8b02a4SEd Tanous operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2793*1b8b02a4SEd Tanous { 2794*1b8b02a4SEd Tanous return x.year() == y.year() && x.month_day_last() == y.month_day_last(); 2795*1b8b02a4SEd Tanous } 2796*1b8b02a4SEd Tanous 2797*1b8b02a4SEd Tanous CONSTCD11 2798*1b8b02a4SEd Tanous inline 2799*1b8b02a4SEd Tanous bool 2800*1b8b02a4SEd Tanous operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2801*1b8b02a4SEd Tanous { 2802*1b8b02a4SEd Tanous return !(x == y); 2803*1b8b02a4SEd Tanous } 2804*1b8b02a4SEd Tanous 2805*1b8b02a4SEd Tanous CONSTCD11 2806*1b8b02a4SEd Tanous inline 2807*1b8b02a4SEd Tanous bool 2808*1b8b02a4SEd Tanous operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2809*1b8b02a4SEd Tanous { 2810*1b8b02a4SEd Tanous return x.year() < y.year() ? true 2811*1b8b02a4SEd Tanous : (x.year() > y.year() ? false 2812*1b8b02a4SEd Tanous : (x.month_day_last() < y.month_day_last())); 2813*1b8b02a4SEd Tanous } 2814*1b8b02a4SEd Tanous 2815*1b8b02a4SEd Tanous CONSTCD11 2816*1b8b02a4SEd Tanous inline 2817*1b8b02a4SEd Tanous bool 2818*1b8b02a4SEd Tanous operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2819*1b8b02a4SEd Tanous { 2820*1b8b02a4SEd Tanous return y < x; 2821*1b8b02a4SEd Tanous } 2822*1b8b02a4SEd Tanous 2823*1b8b02a4SEd Tanous CONSTCD11 2824*1b8b02a4SEd Tanous inline 2825*1b8b02a4SEd Tanous bool 2826*1b8b02a4SEd Tanous operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2827*1b8b02a4SEd Tanous { 2828*1b8b02a4SEd Tanous return !(y < x); 2829*1b8b02a4SEd Tanous } 2830*1b8b02a4SEd Tanous 2831*1b8b02a4SEd Tanous CONSTCD11 2832*1b8b02a4SEd Tanous inline 2833*1b8b02a4SEd Tanous bool 2834*1b8b02a4SEd Tanous operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 2835*1b8b02a4SEd Tanous { 2836*1b8b02a4SEd Tanous return !(x < y); 2837*1b8b02a4SEd Tanous } 2838*1b8b02a4SEd Tanous 2839*1b8b02a4SEd Tanous namespace detail 2840*1b8b02a4SEd Tanous { 2841*1b8b02a4SEd Tanous 2842*1b8b02a4SEd Tanous template<class CharT, class Traits> 2843*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2844*1b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl) 2845*1b8b02a4SEd Tanous { 2846*1b8b02a4SEd Tanous low_level_fmt(os, ymdl.year()) << '/'; 2847*1b8b02a4SEd Tanous return low_level_fmt(os, ymdl.month_day_last()); 2848*1b8b02a4SEd Tanous } 2849*1b8b02a4SEd Tanous 2850*1b8b02a4SEd Tanous } // namespace detail 2851*1b8b02a4SEd Tanous 2852*1b8b02a4SEd Tanous template<class CharT, class Traits> 2853*1b8b02a4SEd Tanous inline 2854*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 2855*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl) 2856*1b8b02a4SEd Tanous { 2857*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymdl); 2858*1b8b02a4SEd Tanous if (!ymdl.ok()) 2859*1b8b02a4SEd Tanous os << " is not a valid year_month_day_last"; 2860*1b8b02a4SEd Tanous return os; 2861*1b8b02a4SEd Tanous } 2862*1b8b02a4SEd Tanous 2863*1b8b02a4SEd Tanous template<class> 2864*1b8b02a4SEd Tanous CONSTCD14 2865*1b8b02a4SEd Tanous inline 2866*1b8b02a4SEd Tanous year_month_day_last 2867*1b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT 2868*1b8b02a4SEd Tanous { 2869*1b8b02a4SEd Tanous return (ymdl.year() / ymdl.month() + dm) / last; 2870*1b8b02a4SEd Tanous } 2871*1b8b02a4SEd Tanous 2872*1b8b02a4SEd Tanous template<class> 2873*1b8b02a4SEd Tanous CONSTCD14 2874*1b8b02a4SEd Tanous inline 2875*1b8b02a4SEd Tanous year_month_day_last 2876*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT 2877*1b8b02a4SEd Tanous { 2878*1b8b02a4SEd Tanous return ymdl + dm; 2879*1b8b02a4SEd Tanous } 2880*1b8b02a4SEd Tanous 2881*1b8b02a4SEd Tanous template<class> 2882*1b8b02a4SEd Tanous CONSTCD14 2883*1b8b02a4SEd Tanous inline 2884*1b8b02a4SEd Tanous year_month_day_last 2885*1b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT 2886*1b8b02a4SEd Tanous { 2887*1b8b02a4SEd Tanous return ymdl + (-dm); 2888*1b8b02a4SEd Tanous } 2889*1b8b02a4SEd Tanous 2890*1b8b02a4SEd Tanous CONSTCD11 2891*1b8b02a4SEd Tanous inline 2892*1b8b02a4SEd Tanous year_month_day_last 2893*1b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT 2894*1b8b02a4SEd Tanous { 2895*1b8b02a4SEd Tanous return {ymdl.year()+dy, ymdl.month_day_last()}; 2896*1b8b02a4SEd Tanous } 2897*1b8b02a4SEd Tanous 2898*1b8b02a4SEd Tanous CONSTCD11 2899*1b8b02a4SEd Tanous inline 2900*1b8b02a4SEd Tanous year_month_day_last 2901*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT 2902*1b8b02a4SEd Tanous { 2903*1b8b02a4SEd Tanous return ymdl + dy; 2904*1b8b02a4SEd Tanous } 2905*1b8b02a4SEd Tanous 2906*1b8b02a4SEd Tanous CONSTCD11 2907*1b8b02a4SEd Tanous inline 2908*1b8b02a4SEd Tanous year_month_day_last 2909*1b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT 2910*1b8b02a4SEd Tanous { 2911*1b8b02a4SEd Tanous return ymdl + (-dy); 2912*1b8b02a4SEd Tanous } 2913*1b8b02a4SEd Tanous 2914*1b8b02a4SEd Tanous // year_month_day 2915*1b8b02a4SEd Tanous 2916*1b8b02a4SEd Tanous CONSTCD11 2917*1b8b02a4SEd Tanous inline 2918*1b8b02a4SEd Tanous year_month_day::year_month_day(const date::year& y, const date::month& m, 2919*1b8b02a4SEd Tanous const date::day& d) NOEXCEPT 2920*1b8b02a4SEd Tanous : y_(y) 2921*1b8b02a4SEd Tanous , m_(m) 2922*1b8b02a4SEd Tanous , d_(d) 2923*1b8b02a4SEd Tanous {} 2924*1b8b02a4SEd Tanous 2925*1b8b02a4SEd Tanous CONSTCD14 2926*1b8b02a4SEd Tanous inline 2927*1b8b02a4SEd Tanous year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT 2928*1b8b02a4SEd Tanous : y_(ymdl.year()) 2929*1b8b02a4SEd Tanous , m_(ymdl.month()) 2930*1b8b02a4SEd Tanous , d_(ymdl.day()) 2931*1b8b02a4SEd Tanous {} 2932*1b8b02a4SEd Tanous 2933*1b8b02a4SEd Tanous CONSTCD14 2934*1b8b02a4SEd Tanous inline 2935*1b8b02a4SEd Tanous year_month_day::year_month_day(sys_days dp) NOEXCEPT 2936*1b8b02a4SEd Tanous : year_month_day(from_days(dp.time_since_epoch())) 2937*1b8b02a4SEd Tanous {} 2938*1b8b02a4SEd Tanous 2939*1b8b02a4SEd Tanous CONSTCD14 2940*1b8b02a4SEd Tanous inline 2941*1b8b02a4SEd Tanous year_month_day::year_month_day(local_days dp) NOEXCEPT 2942*1b8b02a4SEd Tanous : year_month_day(from_days(dp.time_since_epoch())) 2943*1b8b02a4SEd Tanous {} 2944*1b8b02a4SEd Tanous 2945*1b8b02a4SEd Tanous CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} 2946*1b8b02a4SEd Tanous CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} 2947*1b8b02a4SEd Tanous CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} 2948*1b8b02a4SEd Tanous 2949*1b8b02a4SEd Tanous template<class> 2950*1b8b02a4SEd Tanous CONSTCD14 2951*1b8b02a4SEd Tanous inline 2952*1b8b02a4SEd Tanous year_month_day& 2953*1b8b02a4SEd Tanous year_month_day::operator+=(const months& m) NOEXCEPT 2954*1b8b02a4SEd Tanous { 2955*1b8b02a4SEd Tanous *this = *this + m; 2956*1b8b02a4SEd Tanous return *this; 2957*1b8b02a4SEd Tanous } 2958*1b8b02a4SEd Tanous 2959*1b8b02a4SEd Tanous template<class> 2960*1b8b02a4SEd Tanous CONSTCD14 2961*1b8b02a4SEd Tanous inline 2962*1b8b02a4SEd Tanous year_month_day& 2963*1b8b02a4SEd Tanous year_month_day::operator-=(const months& m) NOEXCEPT 2964*1b8b02a4SEd Tanous { 2965*1b8b02a4SEd Tanous *this = *this - m; 2966*1b8b02a4SEd Tanous return *this; 2967*1b8b02a4SEd Tanous } 2968*1b8b02a4SEd Tanous 2969*1b8b02a4SEd Tanous CONSTCD14 2970*1b8b02a4SEd Tanous inline 2971*1b8b02a4SEd Tanous year_month_day& 2972*1b8b02a4SEd Tanous year_month_day::operator+=(const years& y) NOEXCEPT 2973*1b8b02a4SEd Tanous { 2974*1b8b02a4SEd Tanous *this = *this + y; 2975*1b8b02a4SEd Tanous return *this; 2976*1b8b02a4SEd Tanous } 2977*1b8b02a4SEd Tanous 2978*1b8b02a4SEd Tanous CONSTCD14 2979*1b8b02a4SEd Tanous inline 2980*1b8b02a4SEd Tanous year_month_day& 2981*1b8b02a4SEd Tanous year_month_day::operator-=(const years& y) NOEXCEPT 2982*1b8b02a4SEd Tanous { 2983*1b8b02a4SEd Tanous *this = *this - y; 2984*1b8b02a4SEd Tanous return *this; 2985*1b8b02a4SEd Tanous } 2986*1b8b02a4SEd Tanous 2987*1b8b02a4SEd Tanous CONSTCD14 2988*1b8b02a4SEd Tanous inline 2989*1b8b02a4SEd Tanous days 2990*1b8b02a4SEd Tanous year_month_day::to_days() const NOEXCEPT 2991*1b8b02a4SEd Tanous { 2992*1b8b02a4SEd Tanous static_assert(std::numeric_limits<unsigned>::digits >= 18, 2993*1b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit unsigned integer"); 2994*1b8b02a4SEd Tanous static_assert(std::numeric_limits<int>::digits >= 20, 2995*1b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit signed integer"); 2996*1b8b02a4SEd Tanous auto const y = static_cast<int>(y_) - (m_ <= February); 2997*1b8b02a4SEd Tanous auto const m = static_cast<unsigned>(m_); 2998*1b8b02a4SEd Tanous auto const d = static_cast<unsigned>(d_); 2999*1b8b02a4SEd Tanous auto const era = (y >= 0 ? y : y-399) / 400; 3000*1b8b02a4SEd Tanous auto const yoe = static_cast<unsigned>(y - era * 400); // [0, 399] 3001*1b8b02a4SEd Tanous auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] 3002*1b8b02a4SEd Tanous auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] 3003*1b8b02a4SEd Tanous return days{era * 146097 + static_cast<int>(doe) - 719468}; 3004*1b8b02a4SEd Tanous } 3005*1b8b02a4SEd Tanous 3006*1b8b02a4SEd Tanous CONSTCD14 3007*1b8b02a4SEd Tanous inline 3008*1b8b02a4SEd Tanous year_month_day::operator sys_days() const NOEXCEPT 3009*1b8b02a4SEd Tanous { 3010*1b8b02a4SEd Tanous return sys_days{to_days()}; 3011*1b8b02a4SEd Tanous } 3012*1b8b02a4SEd Tanous 3013*1b8b02a4SEd Tanous CONSTCD14 3014*1b8b02a4SEd Tanous inline 3015*1b8b02a4SEd Tanous year_month_day::operator local_days() const NOEXCEPT 3016*1b8b02a4SEd Tanous { 3017*1b8b02a4SEd Tanous return local_days{to_days()}; 3018*1b8b02a4SEd Tanous } 3019*1b8b02a4SEd Tanous 3020*1b8b02a4SEd Tanous CONSTCD14 3021*1b8b02a4SEd Tanous inline 3022*1b8b02a4SEd Tanous bool 3023*1b8b02a4SEd Tanous year_month_day::ok() const NOEXCEPT 3024*1b8b02a4SEd Tanous { 3025*1b8b02a4SEd Tanous if (!(y_.ok() && m_.ok())) 3026*1b8b02a4SEd Tanous return false; 3027*1b8b02a4SEd Tanous return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); 3028*1b8b02a4SEd Tanous } 3029*1b8b02a4SEd Tanous 3030*1b8b02a4SEd Tanous CONSTCD11 3031*1b8b02a4SEd Tanous inline 3032*1b8b02a4SEd Tanous bool 3033*1b8b02a4SEd Tanous operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT 3034*1b8b02a4SEd Tanous { 3035*1b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); 3036*1b8b02a4SEd Tanous } 3037*1b8b02a4SEd Tanous 3038*1b8b02a4SEd Tanous CONSTCD11 3039*1b8b02a4SEd Tanous inline 3040*1b8b02a4SEd Tanous bool 3041*1b8b02a4SEd Tanous operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT 3042*1b8b02a4SEd Tanous { 3043*1b8b02a4SEd Tanous return !(x == y); 3044*1b8b02a4SEd Tanous } 3045*1b8b02a4SEd Tanous 3046*1b8b02a4SEd Tanous CONSTCD11 3047*1b8b02a4SEd Tanous inline 3048*1b8b02a4SEd Tanous bool 3049*1b8b02a4SEd Tanous operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT 3050*1b8b02a4SEd Tanous { 3051*1b8b02a4SEd Tanous return x.year() < y.year() ? true 3052*1b8b02a4SEd Tanous : (x.year() > y.year() ? false 3053*1b8b02a4SEd Tanous : (x.month() < y.month() ? true 3054*1b8b02a4SEd Tanous : (x.month() > y.month() ? false 3055*1b8b02a4SEd Tanous : (x.day() < y.day())))); 3056*1b8b02a4SEd Tanous } 3057*1b8b02a4SEd Tanous 3058*1b8b02a4SEd Tanous CONSTCD11 3059*1b8b02a4SEd Tanous inline 3060*1b8b02a4SEd Tanous bool 3061*1b8b02a4SEd Tanous operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT 3062*1b8b02a4SEd Tanous { 3063*1b8b02a4SEd Tanous return y < x; 3064*1b8b02a4SEd Tanous } 3065*1b8b02a4SEd Tanous 3066*1b8b02a4SEd Tanous CONSTCD11 3067*1b8b02a4SEd Tanous inline 3068*1b8b02a4SEd Tanous bool 3069*1b8b02a4SEd Tanous operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT 3070*1b8b02a4SEd Tanous { 3071*1b8b02a4SEd Tanous return !(y < x); 3072*1b8b02a4SEd Tanous } 3073*1b8b02a4SEd Tanous 3074*1b8b02a4SEd Tanous CONSTCD11 3075*1b8b02a4SEd Tanous inline 3076*1b8b02a4SEd Tanous bool 3077*1b8b02a4SEd Tanous operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT 3078*1b8b02a4SEd Tanous { 3079*1b8b02a4SEd Tanous return !(x < y); 3080*1b8b02a4SEd Tanous } 3081*1b8b02a4SEd Tanous 3082*1b8b02a4SEd Tanous template<class CharT, class Traits> 3083*1b8b02a4SEd Tanous inline 3084*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 3085*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd) 3086*1b8b02a4SEd Tanous { 3087*1b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 3088*1b8b02a4SEd Tanous os.fill('0'); 3089*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 3090*1b8b02a4SEd Tanous os.imbue(std::locale::classic()); 3091*1b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) << '-'; 3092*1b8b02a4SEd Tanous os.width(2); 3093*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << '-'; 3094*1b8b02a4SEd Tanous os.width(2); 3095*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()); 3096*1b8b02a4SEd Tanous if (!ymd.ok()) 3097*1b8b02a4SEd Tanous os << " is not a valid year_month_day"; 3098*1b8b02a4SEd Tanous return os; 3099*1b8b02a4SEd Tanous } 3100*1b8b02a4SEd Tanous 3101*1b8b02a4SEd Tanous CONSTCD14 3102*1b8b02a4SEd Tanous inline 3103*1b8b02a4SEd Tanous year_month_day 3104*1b8b02a4SEd Tanous year_month_day::from_days(days dp) NOEXCEPT 3105*1b8b02a4SEd Tanous { 3106*1b8b02a4SEd Tanous static_assert(std::numeric_limits<unsigned>::digits >= 18, 3107*1b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit unsigned integer"); 3108*1b8b02a4SEd Tanous static_assert(std::numeric_limits<int>::digits >= 20, 3109*1b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit signed integer"); 3110*1b8b02a4SEd Tanous auto const z = dp.count() + 719468; 3111*1b8b02a4SEd Tanous auto const era = (z >= 0 ? z : z - 146096) / 146097; 3112*1b8b02a4SEd Tanous auto const doe = static_cast<unsigned>(z - era * 146097); // [0, 146096] 3113*1b8b02a4SEd Tanous auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] 3114*1b8b02a4SEd Tanous auto const y = static_cast<days::rep>(yoe) + era * 400; 3115*1b8b02a4SEd Tanous auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] 3116*1b8b02a4SEd Tanous auto const mp = (5*doy + 2)/153; // [0, 11] 3117*1b8b02a4SEd Tanous auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] 3118*1b8b02a4SEd Tanous auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] 3119*1b8b02a4SEd Tanous return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; 3120*1b8b02a4SEd Tanous } 3121*1b8b02a4SEd Tanous 3122*1b8b02a4SEd Tanous template<class> 3123*1b8b02a4SEd Tanous CONSTCD14 3124*1b8b02a4SEd Tanous inline 3125*1b8b02a4SEd Tanous year_month_day 3126*1b8b02a4SEd Tanous operator+(const year_month_day& ymd, const months& dm) NOEXCEPT 3127*1b8b02a4SEd Tanous { 3128*1b8b02a4SEd Tanous return (ymd.year() / ymd.month() + dm) / ymd.day(); 3129*1b8b02a4SEd Tanous } 3130*1b8b02a4SEd Tanous 3131*1b8b02a4SEd Tanous template<class> 3132*1b8b02a4SEd Tanous CONSTCD14 3133*1b8b02a4SEd Tanous inline 3134*1b8b02a4SEd Tanous year_month_day 3135*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_day& ymd) NOEXCEPT 3136*1b8b02a4SEd Tanous { 3137*1b8b02a4SEd Tanous return ymd + dm; 3138*1b8b02a4SEd Tanous } 3139*1b8b02a4SEd Tanous 3140*1b8b02a4SEd Tanous template<class> 3141*1b8b02a4SEd Tanous CONSTCD14 3142*1b8b02a4SEd Tanous inline 3143*1b8b02a4SEd Tanous year_month_day 3144*1b8b02a4SEd Tanous operator-(const year_month_day& ymd, const months& dm) NOEXCEPT 3145*1b8b02a4SEd Tanous { 3146*1b8b02a4SEd Tanous return ymd + (-dm); 3147*1b8b02a4SEd Tanous } 3148*1b8b02a4SEd Tanous 3149*1b8b02a4SEd Tanous CONSTCD11 3150*1b8b02a4SEd Tanous inline 3151*1b8b02a4SEd Tanous year_month_day 3152*1b8b02a4SEd Tanous operator+(const year_month_day& ymd, const years& dy) NOEXCEPT 3153*1b8b02a4SEd Tanous { 3154*1b8b02a4SEd Tanous return (ymd.year() + dy) / ymd.month() / ymd.day(); 3155*1b8b02a4SEd Tanous } 3156*1b8b02a4SEd Tanous 3157*1b8b02a4SEd Tanous CONSTCD11 3158*1b8b02a4SEd Tanous inline 3159*1b8b02a4SEd Tanous year_month_day 3160*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_day& ymd) NOEXCEPT 3161*1b8b02a4SEd Tanous { 3162*1b8b02a4SEd Tanous return ymd + dy; 3163*1b8b02a4SEd Tanous } 3164*1b8b02a4SEd Tanous 3165*1b8b02a4SEd Tanous CONSTCD11 3166*1b8b02a4SEd Tanous inline 3167*1b8b02a4SEd Tanous year_month_day 3168*1b8b02a4SEd Tanous operator-(const year_month_day& ymd, const years& dy) NOEXCEPT 3169*1b8b02a4SEd Tanous { 3170*1b8b02a4SEd Tanous return ymd + (-dy); 3171*1b8b02a4SEd Tanous } 3172*1b8b02a4SEd Tanous 3173*1b8b02a4SEd Tanous // year_month_weekday 3174*1b8b02a4SEd Tanous 3175*1b8b02a4SEd Tanous CONSTCD11 3176*1b8b02a4SEd Tanous inline 3177*1b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const date::year& y, const date::month& m, 3178*1b8b02a4SEd Tanous const date::weekday_indexed& wdi) 3179*1b8b02a4SEd Tanous NOEXCEPT 3180*1b8b02a4SEd Tanous : y_(y) 3181*1b8b02a4SEd Tanous , m_(m) 3182*1b8b02a4SEd Tanous , wdi_(wdi) 3183*1b8b02a4SEd Tanous {} 3184*1b8b02a4SEd Tanous 3185*1b8b02a4SEd Tanous CONSTCD14 3186*1b8b02a4SEd Tanous inline 3187*1b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT 3188*1b8b02a4SEd Tanous : year_month_weekday(from_days(dp.time_since_epoch())) 3189*1b8b02a4SEd Tanous {} 3190*1b8b02a4SEd Tanous 3191*1b8b02a4SEd Tanous CONSTCD14 3192*1b8b02a4SEd Tanous inline 3193*1b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT 3194*1b8b02a4SEd Tanous : year_month_weekday(from_days(dp.time_since_epoch())) 3195*1b8b02a4SEd Tanous {} 3196*1b8b02a4SEd Tanous 3197*1b8b02a4SEd Tanous template<class> 3198*1b8b02a4SEd Tanous CONSTCD14 3199*1b8b02a4SEd Tanous inline 3200*1b8b02a4SEd Tanous year_month_weekday& 3201*1b8b02a4SEd Tanous year_month_weekday::operator+=(const months& m) NOEXCEPT 3202*1b8b02a4SEd Tanous { 3203*1b8b02a4SEd Tanous *this = *this + m; 3204*1b8b02a4SEd Tanous return *this; 3205*1b8b02a4SEd Tanous } 3206*1b8b02a4SEd Tanous 3207*1b8b02a4SEd Tanous template<class> 3208*1b8b02a4SEd Tanous CONSTCD14 3209*1b8b02a4SEd Tanous inline 3210*1b8b02a4SEd Tanous year_month_weekday& 3211*1b8b02a4SEd Tanous year_month_weekday::operator-=(const months& m) NOEXCEPT 3212*1b8b02a4SEd Tanous { 3213*1b8b02a4SEd Tanous *this = *this - m; 3214*1b8b02a4SEd Tanous return *this; 3215*1b8b02a4SEd Tanous } 3216*1b8b02a4SEd Tanous 3217*1b8b02a4SEd Tanous CONSTCD14 3218*1b8b02a4SEd Tanous inline 3219*1b8b02a4SEd Tanous year_month_weekday& 3220*1b8b02a4SEd Tanous year_month_weekday::operator+=(const years& y) NOEXCEPT 3221*1b8b02a4SEd Tanous { 3222*1b8b02a4SEd Tanous *this = *this + y; 3223*1b8b02a4SEd Tanous return *this; 3224*1b8b02a4SEd Tanous } 3225*1b8b02a4SEd Tanous 3226*1b8b02a4SEd Tanous CONSTCD14 3227*1b8b02a4SEd Tanous inline 3228*1b8b02a4SEd Tanous year_month_weekday& 3229*1b8b02a4SEd Tanous year_month_weekday::operator-=(const years& y) NOEXCEPT 3230*1b8b02a4SEd Tanous { 3231*1b8b02a4SEd Tanous *this = *this - y; 3232*1b8b02a4SEd Tanous return *this; 3233*1b8b02a4SEd Tanous } 3234*1b8b02a4SEd Tanous 3235*1b8b02a4SEd Tanous CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} 3236*1b8b02a4SEd Tanous CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} 3237*1b8b02a4SEd Tanous 3238*1b8b02a4SEd Tanous CONSTCD11 3239*1b8b02a4SEd Tanous inline 3240*1b8b02a4SEd Tanous weekday 3241*1b8b02a4SEd Tanous year_month_weekday::weekday() const NOEXCEPT 3242*1b8b02a4SEd Tanous { 3243*1b8b02a4SEd Tanous return wdi_.weekday(); 3244*1b8b02a4SEd Tanous } 3245*1b8b02a4SEd Tanous 3246*1b8b02a4SEd Tanous CONSTCD11 3247*1b8b02a4SEd Tanous inline 3248*1b8b02a4SEd Tanous unsigned 3249*1b8b02a4SEd Tanous year_month_weekday::index() const NOEXCEPT 3250*1b8b02a4SEd Tanous { 3251*1b8b02a4SEd Tanous return wdi_.index(); 3252*1b8b02a4SEd Tanous } 3253*1b8b02a4SEd Tanous 3254*1b8b02a4SEd Tanous CONSTCD11 3255*1b8b02a4SEd Tanous inline 3256*1b8b02a4SEd Tanous weekday_indexed 3257*1b8b02a4SEd Tanous year_month_weekday::weekday_indexed() const NOEXCEPT 3258*1b8b02a4SEd Tanous { 3259*1b8b02a4SEd Tanous return wdi_; 3260*1b8b02a4SEd Tanous } 3261*1b8b02a4SEd Tanous 3262*1b8b02a4SEd Tanous CONSTCD14 3263*1b8b02a4SEd Tanous inline 3264*1b8b02a4SEd Tanous year_month_weekday::operator sys_days() const NOEXCEPT 3265*1b8b02a4SEd Tanous { 3266*1b8b02a4SEd Tanous return sys_days{to_days()}; 3267*1b8b02a4SEd Tanous } 3268*1b8b02a4SEd Tanous 3269*1b8b02a4SEd Tanous CONSTCD14 3270*1b8b02a4SEd Tanous inline 3271*1b8b02a4SEd Tanous year_month_weekday::operator local_days() const NOEXCEPT 3272*1b8b02a4SEd Tanous { 3273*1b8b02a4SEd Tanous return local_days{to_days()}; 3274*1b8b02a4SEd Tanous } 3275*1b8b02a4SEd Tanous 3276*1b8b02a4SEd Tanous CONSTCD14 3277*1b8b02a4SEd Tanous inline 3278*1b8b02a4SEd Tanous bool 3279*1b8b02a4SEd Tanous year_month_weekday::ok() const NOEXCEPT 3280*1b8b02a4SEd Tanous { 3281*1b8b02a4SEd Tanous if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) 3282*1b8b02a4SEd Tanous return false; 3283*1b8b02a4SEd Tanous if (wdi_.index() <= 4) 3284*1b8b02a4SEd Tanous return true; 3285*1b8b02a4SEd Tanous auto d2 = wdi_.weekday() - date::weekday(static_cast<sys_days>(y_/m_/1)) + 3286*1b8b02a4SEd Tanous days((wdi_.index()-1)*7 + 1); 3287*1b8b02a4SEd Tanous return static_cast<unsigned>(d2.count()) <= static_cast<unsigned>((y_/m_/last).day()); 3288*1b8b02a4SEd Tanous } 3289*1b8b02a4SEd Tanous 3290*1b8b02a4SEd Tanous CONSTCD14 3291*1b8b02a4SEd Tanous inline 3292*1b8b02a4SEd Tanous year_month_weekday 3293*1b8b02a4SEd Tanous year_month_weekday::from_days(days d) NOEXCEPT 3294*1b8b02a4SEd Tanous { 3295*1b8b02a4SEd Tanous sys_days dp{d}; 3296*1b8b02a4SEd Tanous auto const wd = date::weekday(dp); 3297*1b8b02a4SEd Tanous auto const ymd = year_month_day(dp); 3298*1b8b02a4SEd Tanous return {ymd.year(), ymd.month(), wd[(static_cast<unsigned>(ymd.day())-1)/7+1]}; 3299*1b8b02a4SEd Tanous } 3300*1b8b02a4SEd Tanous 3301*1b8b02a4SEd Tanous CONSTCD14 3302*1b8b02a4SEd Tanous inline 3303*1b8b02a4SEd Tanous days 3304*1b8b02a4SEd Tanous year_month_weekday::to_days() const NOEXCEPT 3305*1b8b02a4SEd Tanous { 3306*1b8b02a4SEd Tanous auto d = sys_days(y_/m_/1); 3307*1b8b02a4SEd Tanous return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) 3308*1b8b02a4SEd Tanous ).time_since_epoch(); 3309*1b8b02a4SEd Tanous } 3310*1b8b02a4SEd Tanous 3311*1b8b02a4SEd Tanous CONSTCD11 3312*1b8b02a4SEd Tanous inline 3313*1b8b02a4SEd Tanous bool 3314*1b8b02a4SEd Tanous operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT 3315*1b8b02a4SEd Tanous { 3316*1b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && 3317*1b8b02a4SEd Tanous x.weekday_indexed() == y.weekday_indexed(); 3318*1b8b02a4SEd Tanous } 3319*1b8b02a4SEd Tanous 3320*1b8b02a4SEd Tanous CONSTCD11 3321*1b8b02a4SEd Tanous inline 3322*1b8b02a4SEd Tanous bool 3323*1b8b02a4SEd Tanous operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT 3324*1b8b02a4SEd Tanous { 3325*1b8b02a4SEd Tanous return !(x == y); 3326*1b8b02a4SEd Tanous } 3327*1b8b02a4SEd Tanous 3328*1b8b02a4SEd Tanous template<class CharT, class Traits> 3329*1b8b02a4SEd Tanous inline 3330*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 3331*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi) 3332*1b8b02a4SEd Tanous { 3333*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.year()) << '/'; 3334*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.month()) << '/'; 3335*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.weekday_indexed()); 3336*1b8b02a4SEd Tanous if (!ymwdi.ok()) 3337*1b8b02a4SEd Tanous os << " is not a valid year_month_weekday"; 3338*1b8b02a4SEd Tanous return os; 3339*1b8b02a4SEd Tanous } 3340*1b8b02a4SEd Tanous 3341*1b8b02a4SEd Tanous template<class> 3342*1b8b02a4SEd Tanous CONSTCD14 3343*1b8b02a4SEd Tanous inline 3344*1b8b02a4SEd Tanous year_month_weekday 3345*1b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT 3346*1b8b02a4SEd Tanous { 3347*1b8b02a4SEd Tanous return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); 3348*1b8b02a4SEd Tanous } 3349*1b8b02a4SEd Tanous 3350*1b8b02a4SEd Tanous template<class> 3351*1b8b02a4SEd Tanous CONSTCD14 3352*1b8b02a4SEd Tanous inline 3353*1b8b02a4SEd Tanous year_month_weekday 3354*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT 3355*1b8b02a4SEd Tanous { 3356*1b8b02a4SEd Tanous return ymwd + dm; 3357*1b8b02a4SEd Tanous } 3358*1b8b02a4SEd Tanous 3359*1b8b02a4SEd Tanous template<class> 3360*1b8b02a4SEd Tanous CONSTCD14 3361*1b8b02a4SEd Tanous inline 3362*1b8b02a4SEd Tanous year_month_weekday 3363*1b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT 3364*1b8b02a4SEd Tanous { 3365*1b8b02a4SEd Tanous return ymwd + (-dm); 3366*1b8b02a4SEd Tanous } 3367*1b8b02a4SEd Tanous 3368*1b8b02a4SEd Tanous CONSTCD11 3369*1b8b02a4SEd Tanous inline 3370*1b8b02a4SEd Tanous year_month_weekday 3371*1b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT 3372*1b8b02a4SEd Tanous { 3373*1b8b02a4SEd Tanous return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; 3374*1b8b02a4SEd Tanous } 3375*1b8b02a4SEd Tanous 3376*1b8b02a4SEd Tanous CONSTCD11 3377*1b8b02a4SEd Tanous inline 3378*1b8b02a4SEd Tanous year_month_weekday 3379*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT 3380*1b8b02a4SEd Tanous { 3381*1b8b02a4SEd Tanous return ymwd + dy; 3382*1b8b02a4SEd Tanous } 3383*1b8b02a4SEd Tanous 3384*1b8b02a4SEd Tanous CONSTCD11 3385*1b8b02a4SEd Tanous inline 3386*1b8b02a4SEd Tanous year_month_weekday 3387*1b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT 3388*1b8b02a4SEd Tanous { 3389*1b8b02a4SEd Tanous return ymwd + (-dy); 3390*1b8b02a4SEd Tanous } 3391*1b8b02a4SEd Tanous 3392*1b8b02a4SEd Tanous // year_month_weekday_last 3393*1b8b02a4SEd Tanous 3394*1b8b02a4SEd Tanous CONSTCD11 3395*1b8b02a4SEd Tanous inline 3396*1b8b02a4SEd Tanous year_month_weekday_last::year_month_weekday_last(const date::year& y, 3397*1b8b02a4SEd Tanous const date::month& m, 3398*1b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT 3399*1b8b02a4SEd Tanous : y_(y) 3400*1b8b02a4SEd Tanous , m_(m) 3401*1b8b02a4SEd Tanous , wdl_(wdl) 3402*1b8b02a4SEd Tanous {} 3403*1b8b02a4SEd Tanous 3404*1b8b02a4SEd Tanous template<class> 3405*1b8b02a4SEd Tanous CONSTCD14 3406*1b8b02a4SEd Tanous inline 3407*1b8b02a4SEd Tanous year_month_weekday_last& 3408*1b8b02a4SEd Tanous year_month_weekday_last::operator+=(const months& m) NOEXCEPT 3409*1b8b02a4SEd Tanous { 3410*1b8b02a4SEd Tanous *this = *this + m; 3411*1b8b02a4SEd Tanous return *this; 3412*1b8b02a4SEd Tanous } 3413*1b8b02a4SEd Tanous 3414*1b8b02a4SEd Tanous template<class> 3415*1b8b02a4SEd Tanous CONSTCD14 3416*1b8b02a4SEd Tanous inline 3417*1b8b02a4SEd Tanous year_month_weekday_last& 3418*1b8b02a4SEd Tanous year_month_weekday_last::operator-=(const months& m) NOEXCEPT 3419*1b8b02a4SEd Tanous { 3420*1b8b02a4SEd Tanous *this = *this - m; 3421*1b8b02a4SEd Tanous return *this; 3422*1b8b02a4SEd Tanous } 3423*1b8b02a4SEd Tanous 3424*1b8b02a4SEd Tanous CONSTCD14 3425*1b8b02a4SEd Tanous inline 3426*1b8b02a4SEd Tanous year_month_weekday_last& 3427*1b8b02a4SEd Tanous year_month_weekday_last::operator+=(const years& y) NOEXCEPT 3428*1b8b02a4SEd Tanous { 3429*1b8b02a4SEd Tanous *this = *this + y; 3430*1b8b02a4SEd Tanous return *this; 3431*1b8b02a4SEd Tanous } 3432*1b8b02a4SEd Tanous 3433*1b8b02a4SEd Tanous CONSTCD14 3434*1b8b02a4SEd Tanous inline 3435*1b8b02a4SEd Tanous year_month_weekday_last& 3436*1b8b02a4SEd Tanous year_month_weekday_last::operator-=(const years& y) NOEXCEPT 3437*1b8b02a4SEd Tanous { 3438*1b8b02a4SEd Tanous *this = *this - y; 3439*1b8b02a4SEd Tanous return *this; 3440*1b8b02a4SEd Tanous } 3441*1b8b02a4SEd Tanous 3442*1b8b02a4SEd Tanous CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} 3443*1b8b02a4SEd Tanous CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} 3444*1b8b02a4SEd Tanous 3445*1b8b02a4SEd Tanous CONSTCD11 3446*1b8b02a4SEd Tanous inline 3447*1b8b02a4SEd Tanous weekday 3448*1b8b02a4SEd Tanous year_month_weekday_last::weekday() const NOEXCEPT 3449*1b8b02a4SEd Tanous { 3450*1b8b02a4SEd Tanous return wdl_.weekday(); 3451*1b8b02a4SEd Tanous } 3452*1b8b02a4SEd Tanous 3453*1b8b02a4SEd Tanous CONSTCD11 3454*1b8b02a4SEd Tanous inline 3455*1b8b02a4SEd Tanous weekday_last 3456*1b8b02a4SEd Tanous year_month_weekday_last::weekday_last() const NOEXCEPT 3457*1b8b02a4SEd Tanous { 3458*1b8b02a4SEd Tanous return wdl_; 3459*1b8b02a4SEd Tanous } 3460*1b8b02a4SEd Tanous 3461*1b8b02a4SEd Tanous CONSTCD14 3462*1b8b02a4SEd Tanous inline 3463*1b8b02a4SEd Tanous year_month_weekday_last::operator sys_days() const NOEXCEPT 3464*1b8b02a4SEd Tanous { 3465*1b8b02a4SEd Tanous return sys_days{to_days()}; 3466*1b8b02a4SEd Tanous } 3467*1b8b02a4SEd Tanous 3468*1b8b02a4SEd Tanous CONSTCD14 3469*1b8b02a4SEd Tanous inline 3470*1b8b02a4SEd Tanous year_month_weekday_last::operator local_days() const NOEXCEPT 3471*1b8b02a4SEd Tanous { 3472*1b8b02a4SEd Tanous return local_days{to_days()}; 3473*1b8b02a4SEd Tanous } 3474*1b8b02a4SEd Tanous 3475*1b8b02a4SEd Tanous CONSTCD11 3476*1b8b02a4SEd Tanous inline 3477*1b8b02a4SEd Tanous bool 3478*1b8b02a4SEd Tanous year_month_weekday_last::ok() const NOEXCEPT 3479*1b8b02a4SEd Tanous { 3480*1b8b02a4SEd Tanous return y_.ok() && m_.ok() && wdl_.ok(); 3481*1b8b02a4SEd Tanous } 3482*1b8b02a4SEd Tanous 3483*1b8b02a4SEd Tanous CONSTCD14 3484*1b8b02a4SEd Tanous inline 3485*1b8b02a4SEd Tanous days 3486*1b8b02a4SEd Tanous year_month_weekday_last::to_days() const NOEXCEPT 3487*1b8b02a4SEd Tanous { 3488*1b8b02a4SEd Tanous auto const d = sys_days(y_/m_/last); 3489*1b8b02a4SEd Tanous return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); 3490*1b8b02a4SEd Tanous } 3491*1b8b02a4SEd Tanous 3492*1b8b02a4SEd Tanous CONSTCD11 3493*1b8b02a4SEd Tanous inline 3494*1b8b02a4SEd Tanous bool 3495*1b8b02a4SEd Tanous operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT 3496*1b8b02a4SEd Tanous { 3497*1b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && 3498*1b8b02a4SEd Tanous x.weekday_last() == y.weekday_last(); 3499*1b8b02a4SEd Tanous } 3500*1b8b02a4SEd Tanous 3501*1b8b02a4SEd Tanous CONSTCD11 3502*1b8b02a4SEd Tanous inline 3503*1b8b02a4SEd Tanous bool 3504*1b8b02a4SEd Tanous operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT 3505*1b8b02a4SEd Tanous { 3506*1b8b02a4SEd Tanous return !(x == y); 3507*1b8b02a4SEd Tanous } 3508*1b8b02a4SEd Tanous 3509*1b8b02a4SEd Tanous template<class CharT, class Traits> 3510*1b8b02a4SEd Tanous inline 3511*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 3512*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl) 3513*1b8b02a4SEd Tanous { 3514*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.year()) << '/'; 3515*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.month()) << '/'; 3516*1b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.weekday_last()); 3517*1b8b02a4SEd Tanous if (!ymwdl.ok()) 3518*1b8b02a4SEd Tanous os << " is not a valid year_month_weekday_last"; 3519*1b8b02a4SEd Tanous return os; 3520*1b8b02a4SEd Tanous } 3521*1b8b02a4SEd Tanous 3522*1b8b02a4SEd Tanous template<class> 3523*1b8b02a4SEd Tanous CONSTCD14 3524*1b8b02a4SEd Tanous inline 3525*1b8b02a4SEd Tanous year_month_weekday_last 3526*1b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT 3527*1b8b02a4SEd Tanous { 3528*1b8b02a4SEd Tanous return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); 3529*1b8b02a4SEd Tanous } 3530*1b8b02a4SEd Tanous 3531*1b8b02a4SEd Tanous template<class> 3532*1b8b02a4SEd Tanous CONSTCD14 3533*1b8b02a4SEd Tanous inline 3534*1b8b02a4SEd Tanous year_month_weekday_last 3535*1b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT 3536*1b8b02a4SEd Tanous { 3537*1b8b02a4SEd Tanous return ymwdl + dm; 3538*1b8b02a4SEd Tanous } 3539*1b8b02a4SEd Tanous 3540*1b8b02a4SEd Tanous template<class> 3541*1b8b02a4SEd Tanous CONSTCD14 3542*1b8b02a4SEd Tanous inline 3543*1b8b02a4SEd Tanous year_month_weekday_last 3544*1b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT 3545*1b8b02a4SEd Tanous { 3546*1b8b02a4SEd Tanous return ymwdl + (-dm); 3547*1b8b02a4SEd Tanous } 3548*1b8b02a4SEd Tanous 3549*1b8b02a4SEd Tanous CONSTCD11 3550*1b8b02a4SEd Tanous inline 3551*1b8b02a4SEd Tanous year_month_weekday_last 3552*1b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT 3553*1b8b02a4SEd Tanous { 3554*1b8b02a4SEd Tanous return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; 3555*1b8b02a4SEd Tanous } 3556*1b8b02a4SEd Tanous 3557*1b8b02a4SEd Tanous CONSTCD11 3558*1b8b02a4SEd Tanous inline 3559*1b8b02a4SEd Tanous year_month_weekday_last 3560*1b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT 3561*1b8b02a4SEd Tanous { 3562*1b8b02a4SEd Tanous return ymwdl + dy; 3563*1b8b02a4SEd Tanous } 3564*1b8b02a4SEd Tanous 3565*1b8b02a4SEd Tanous CONSTCD11 3566*1b8b02a4SEd Tanous inline 3567*1b8b02a4SEd Tanous year_month_weekday_last 3568*1b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT 3569*1b8b02a4SEd Tanous { 3570*1b8b02a4SEd Tanous return ymwdl + (-dy); 3571*1b8b02a4SEd Tanous } 3572*1b8b02a4SEd Tanous 3573*1b8b02a4SEd Tanous // year_month from operator/() 3574*1b8b02a4SEd Tanous 3575*1b8b02a4SEd Tanous CONSTCD11 3576*1b8b02a4SEd Tanous inline 3577*1b8b02a4SEd Tanous year_month 3578*1b8b02a4SEd Tanous operator/(const year& y, const month& m) NOEXCEPT 3579*1b8b02a4SEd Tanous { 3580*1b8b02a4SEd Tanous return {y, m}; 3581*1b8b02a4SEd Tanous } 3582*1b8b02a4SEd Tanous 3583*1b8b02a4SEd Tanous CONSTCD11 3584*1b8b02a4SEd Tanous inline 3585*1b8b02a4SEd Tanous year_month 3586*1b8b02a4SEd Tanous operator/(const year& y, int m) NOEXCEPT 3587*1b8b02a4SEd Tanous { 3588*1b8b02a4SEd Tanous return y / month(static_cast<unsigned>(m)); 3589*1b8b02a4SEd Tanous } 3590*1b8b02a4SEd Tanous 3591*1b8b02a4SEd Tanous // month_day from operator/() 3592*1b8b02a4SEd Tanous 3593*1b8b02a4SEd Tanous CONSTCD11 3594*1b8b02a4SEd Tanous inline 3595*1b8b02a4SEd Tanous month_day 3596*1b8b02a4SEd Tanous operator/(const month& m, const day& d) NOEXCEPT 3597*1b8b02a4SEd Tanous { 3598*1b8b02a4SEd Tanous return {m, d}; 3599*1b8b02a4SEd Tanous } 3600*1b8b02a4SEd Tanous 3601*1b8b02a4SEd Tanous CONSTCD11 3602*1b8b02a4SEd Tanous inline 3603*1b8b02a4SEd Tanous month_day 3604*1b8b02a4SEd Tanous operator/(const day& d, const month& m) NOEXCEPT 3605*1b8b02a4SEd Tanous { 3606*1b8b02a4SEd Tanous return m / d; 3607*1b8b02a4SEd Tanous } 3608*1b8b02a4SEd Tanous 3609*1b8b02a4SEd Tanous CONSTCD11 3610*1b8b02a4SEd Tanous inline 3611*1b8b02a4SEd Tanous month_day 3612*1b8b02a4SEd Tanous operator/(const month& m, int d) NOEXCEPT 3613*1b8b02a4SEd Tanous { 3614*1b8b02a4SEd Tanous return m / day(static_cast<unsigned>(d)); 3615*1b8b02a4SEd Tanous } 3616*1b8b02a4SEd Tanous 3617*1b8b02a4SEd Tanous CONSTCD11 3618*1b8b02a4SEd Tanous inline 3619*1b8b02a4SEd Tanous month_day 3620*1b8b02a4SEd Tanous operator/(int m, const day& d) NOEXCEPT 3621*1b8b02a4SEd Tanous { 3622*1b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / d; 3623*1b8b02a4SEd Tanous } 3624*1b8b02a4SEd Tanous 3625*1b8b02a4SEd Tanous CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} 3626*1b8b02a4SEd Tanous 3627*1b8b02a4SEd Tanous // month_day_last from operator/() 3628*1b8b02a4SEd Tanous 3629*1b8b02a4SEd Tanous CONSTCD11 3630*1b8b02a4SEd Tanous inline 3631*1b8b02a4SEd Tanous month_day_last 3632*1b8b02a4SEd Tanous operator/(const month& m, last_spec) NOEXCEPT 3633*1b8b02a4SEd Tanous { 3634*1b8b02a4SEd Tanous return month_day_last{m}; 3635*1b8b02a4SEd Tanous } 3636*1b8b02a4SEd Tanous 3637*1b8b02a4SEd Tanous CONSTCD11 3638*1b8b02a4SEd Tanous inline 3639*1b8b02a4SEd Tanous month_day_last 3640*1b8b02a4SEd Tanous operator/(last_spec, const month& m) NOEXCEPT 3641*1b8b02a4SEd Tanous { 3642*1b8b02a4SEd Tanous return m/last; 3643*1b8b02a4SEd Tanous } 3644*1b8b02a4SEd Tanous 3645*1b8b02a4SEd Tanous CONSTCD11 3646*1b8b02a4SEd Tanous inline 3647*1b8b02a4SEd Tanous month_day_last 3648*1b8b02a4SEd Tanous operator/(int m, last_spec) NOEXCEPT 3649*1b8b02a4SEd Tanous { 3650*1b8b02a4SEd Tanous return month(static_cast<unsigned>(m))/last; 3651*1b8b02a4SEd Tanous } 3652*1b8b02a4SEd Tanous 3653*1b8b02a4SEd Tanous CONSTCD11 3654*1b8b02a4SEd Tanous inline 3655*1b8b02a4SEd Tanous month_day_last 3656*1b8b02a4SEd Tanous operator/(last_spec, int m) NOEXCEPT 3657*1b8b02a4SEd Tanous { 3658*1b8b02a4SEd Tanous return m/last; 3659*1b8b02a4SEd Tanous } 3660*1b8b02a4SEd Tanous 3661*1b8b02a4SEd Tanous // month_weekday from operator/() 3662*1b8b02a4SEd Tanous 3663*1b8b02a4SEd Tanous CONSTCD11 3664*1b8b02a4SEd Tanous inline 3665*1b8b02a4SEd Tanous month_weekday 3666*1b8b02a4SEd Tanous operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT 3667*1b8b02a4SEd Tanous { 3668*1b8b02a4SEd Tanous return {m, wdi}; 3669*1b8b02a4SEd Tanous } 3670*1b8b02a4SEd Tanous 3671*1b8b02a4SEd Tanous CONSTCD11 3672*1b8b02a4SEd Tanous inline 3673*1b8b02a4SEd Tanous month_weekday 3674*1b8b02a4SEd Tanous operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT 3675*1b8b02a4SEd Tanous { 3676*1b8b02a4SEd Tanous return m / wdi; 3677*1b8b02a4SEd Tanous } 3678*1b8b02a4SEd Tanous 3679*1b8b02a4SEd Tanous CONSTCD11 3680*1b8b02a4SEd Tanous inline 3681*1b8b02a4SEd Tanous month_weekday 3682*1b8b02a4SEd Tanous operator/(int m, const weekday_indexed& wdi) NOEXCEPT 3683*1b8b02a4SEd Tanous { 3684*1b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / wdi; 3685*1b8b02a4SEd Tanous } 3686*1b8b02a4SEd Tanous 3687*1b8b02a4SEd Tanous CONSTCD11 3688*1b8b02a4SEd Tanous inline 3689*1b8b02a4SEd Tanous month_weekday 3690*1b8b02a4SEd Tanous operator/(const weekday_indexed& wdi, int m) NOEXCEPT 3691*1b8b02a4SEd Tanous { 3692*1b8b02a4SEd Tanous return m / wdi; 3693*1b8b02a4SEd Tanous } 3694*1b8b02a4SEd Tanous 3695*1b8b02a4SEd Tanous // month_weekday_last from operator/() 3696*1b8b02a4SEd Tanous 3697*1b8b02a4SEd Tanous CONSTCD11 3698*1b8b02a4SEd Tanous inline 3699*1b8b02a4SEd Tanous month_weekday_last 3700*1b8b02a4SEd Tanous operator/(const month& m, const weekday_last& wdl) NOEXCEPT 3701*1b8b02a4SEd Tanous { 3702*1b8b02a4SEd Tanous return {m, wdl}; 3703*1b8b02a4SEd Tanous } 3704*1b8b02a4SEd Tanous 3705*1b8b02a4SEd Tanous CONSTCD11 3706*1b8b02a4SEd Tanous inline 3707*1b8b02a4SEd Tanous month_weekday_last 3708*1b8b02a4SEd Tanous operator/(const weekday_last& wdl, const month& m) NOEXCEPT 3709*1b8b02a4SEd Tanous { 3710*1b8b02a4SEd Tanous return m / wdl; 3711*1b8b02a4SEd Tanous } 3712*1b8b02a4SEd Tanous 3713*1b8b02a4SEd Tanous CONSTCD11 3714*1b8b02a4SEd Tanous inline 3715*1b8b02a4SEd Tanous month_weekday_last 3716*1b8b02a4SEd Tanous operator/(int m, const weekday_last& wdl) NOEXCEPT 3717*1b8b02a4SEd Tanous { 3718*1b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / wdl; 3719*1b8b02a4SEd Tanous } 3720*1b8b02a4SEd Tanous 3721*1b8b02a4SEd Tanous CONSTCD11 3722*1b8b02a4SEd Tanous inline 3723*1b8b02a4SEd Tanous month_weekday_last 3724*1b8b02a4SEd Tanous operator/(const weekday_last& wdl, int m) NOEXCEPT 3725*1b8b02a4SEd Tanous { 3726*1b8b02a4SEd Tanous return m / wdl; 3727*1b8b02a4SEd Tanous } 3728*1b8b02a4SEd Tanous 3729*1b8b02a4SEd Tanous // year_month_day from operator/() 3730*1b8b02a4SEd Tanous 3731*1b8b02a4SEd Tanous CONSTCD11 3732*1b8b02a4SEd Tanous inline 3733*1b8b02a4SEd Tanous year_month_day 3734*1b8b02a4SEd Tanous operator/(const year_month& ym, const day& d) NOEXCEPT 3735*1b8b02a4SEd Tanous { 3736*1b8b02a4SEd Tanous return {ym.year(), ym.month(), d}; 3737*1b8b02a4SEd Tanous } 3738*1b8b02a4SEd Tanous 3739*1b8b02a4SEd Tanous CONSTCD11 3740*1b8b02a4SEd Tanous inline 3741*1b8b02a4SEd Tanous year_month_day 3742*1b8b02a4SEd Tanous operator/(const year_month& ym, int d) NOEXCEPT 3743*1b8b02a4SEd Tanous { 3744*1b8b02a4SEd Tanous return ym / day(static_cast<unsigned>(d)); 3745*1b8b02a4SEd Tanous } 3746*1b8b02a4SEd Tanous 3747*1b8b02a4SEd Tanous CONSTCD11 3748*1b8b02a4SEd Tanous inline 3749*1b8b02a4SEd Tanous year_month_day 3750*1b8b02a4SEd Tanous operator/(const year& y, const month_day& md) NOEXCEPT 3751*1b8b02a4SEd Tanous { 3752*1b8b02a4SEd Tanous return y / md.month() / md.day(); 3753*1b8b02a4SEd Tanous } 3754*1b8b02a4SEd Tanous 3755*1b8b02a4SEd Tanous CONSTCD11 3756*1b8b02a4SEd Tanous inline 3757*1b8b02a4SEd Tanous year_month_day 3758*1b8b02a4SEd Tanous operator/(int y, const month_day& md) NOEXCEPT 3759*1b8b02a4SEd Tanous { 3760*1b8b02a4SEd Tanous return year(y) / md; 3761*1b8b02a4SEd Tanous } 3762*1b8b02a4SEd Tanous 3763*1b8b02a4SEd Tanous CONSTCD11 3764*1b8b02a4SEd Tanous inline 3765*1b8b02a4SEd Tanous year_month_day 3766*1b8b02a4SEd Tanous operator/(const month_day& md, const year& y) NOEXCEPT 3767*1b8b02a4SEd Tanous { 3768*1b8b02a4SEd Tanous return y / md; 3769*1b8b02a4SEd Tanous } 3770*1b8b02a4SEd Tanous 3771*1b8b02a4SEd Tanous CONSTCD11 3772*1b8b02a4SEd Tanous inline 3773*1b8b02a4SEd Tanous year_month_day 3774*1b8b02a4SEd Tanous operator/(const month_day& md, int y) NOEXCEPT 3775*1b8b02a4SEd Tanous { 3776*1b8b02a4SEd Tanous return year(y) / md; 3777*1b8b02a4SEd Tanous } 3778*1b8b02a4SEd Tanous 3779*1b8b02a4SEd Tanous // year_month_day_last from operator/() 3780*1b8b02a4SEd Tanous 3781*1b8b02a4SEd Tanous CONSTCD11 3782*1b8b02a4SEd Tanous inline 3783*1b8b02a4SEd Tanous year_month_day_last 3784*1b8b02a4SEd Tanous operator/(const year_month& ym, last_spec) NOEXCEPT 3785*1b8b02a4SEd Tanous { 3786*1b8b02a4SEd Tanous return {ym.year(), month_day_last{ym.month()}}; 3787*1b8b02a4SEd Tanous } 3788*1b8b02a4SEd Tanous 3789*1b8b02a4SEd Tanous CONSTCD11 3790*1b8b02a4SEd Tanous inline 3791*1b8b02a4SEd Tanous year_month_day_last 3792*1b8b02a4SEd Tanous operator/(const year& y, const month_day_last& mdl) NOEXCEPT 3793*1b8b02a4SEd Tanous { 3794*1b8b02a4SEd Tanous return {y, mdl}; 3795*1b8b02a4SEd Tanous } 3796*1b8b02a4SEd Tanous 3797*1b8b02a4SEd Tanous CONSTCD11 3798*1b8b02a4SEd Tanous inline 3799*1b8b02a4SEd Tanous year_month_day_last 3800*1b8b02a4SEd Tanous operator/(int y, const month_day_last& mdl) NOEXCEPT 3801*1b8b02a4SEd Tanous { 3802*1b8b02a4SEd Tanous return year(y) / mdl; 3803*1b8b02a4SEd Tanous } 3804*1b8b02a4SEd Tanous 3805*1b8b02a4SEd Tanous CONSTCD11 3806*1b8b02a4SEd Tanous inline 3807*1b8b02a4SEd Tanous year_month_day_last 3808*1b8b02a4SEd Tanous operator/(const month_day_last& mdl, const year& y) NOEXCEPT 3809*1b8b02a4SEd Tanous { 3810*1b8b02a4SEd Tanous return y / mdl; 3811*1b8b02a4SEd Tanous } 3812*1b8b02a4SEd Tanous 3813*1b8b02a4SEd Tanous CONSTCD11 3814*1b8b02a4SEd Tanous inline 3815*1b8b02a4SEd Tanous year_month_day_last 3816*1b8b02a4SEd Tanous operator/(const month_day_last& mdl, int y) NOEXCEPT 3817*1b8b02a4SEd Tanous { 3818*1b8b02a4SEd Tanous return year(y) / mdl; 3819*1b8b02a4SEd Tanous } 3820*1b8b02a4SEd Tanous 3821*1b8b02a4SEd Tanous // year_month_weekday from operator/() 3822*1b8b02a4SEd Tanous 3823*1b8b02a4SEd Tanous CONSTCD11 3824*1b8b02a4SEd Tanous inline 3825*1b8b02a4SEd Tanous year_month_weekday 3826*1b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT 3827*1b8b02a4SEd Tanous { 3828*1b8b02a4SEd Tanous return {ym.year(), ym.month(), wdi}; 3829*1b8b02a4SEd Tanous } 3830*1b8b02a4SEd Tanous 3831*1b8b02a4SEd Tanous CONSTCD11 3832*1b8b02a4SEd Tanous inline 3833*1b8b02a4SEd Tanous year_month_weekday 3834*1b8b02a4SEd Tanous operator/(const year& y, const month_weekday& mwd) NOEXCEPT 3835*1b8b02a4SEd Tanous { 3836*1b8b02a4SEd Tanous return {y, mwd.month(), mwd.weekday_indexed()}; 3837*1b8b02a4SEd Tanous } 3838*1b8b02a4SEd Tanous 3839*1b8b02a4SEd Tanous CONSTCD11 3840*1b8b02a4SEd Tanous inline 3841*1b8b02a4SEd Tanous year_month_weekday 3842*1b8b02a4SEd Tanous operator/(int y, const month_weekday& mwd) NOEXCEPT 3843*1b8b02a4SEd Tanous { 3844*1b8b02a4SEd Tanous return year(y) / mwd; 3845*1b8b02a4SEd Tanous } 3846*1b8b02a4SEd Tanous 3847*1b8b02a4SEd Tanous CONSTCD11 3848*1b8b02a4SEd Tanous inline 3849*1b8b02a4SEd Tanous year_month_weekday 3850*1b8b02a4SEd Tanous operator/(const month_weekday& mwd, const year& y) NOEXCEPT 3851*1b8b02a4SEd Tanous { 3852*1b8b02a4SEd Tanous return y / mwd; 3853*1b8b02a4SEd Tanous } 3854*1b8b02a4SEd Tanous 3855*1b8b02a4SEd Tanous CONSTCD11 3856*1b8b02a4SEd Tanous inline 3857*1b8b02a4SEd Tanous year_month_weekday 3858*1b8b02a4SEd Tanous operator/(const month_weekday& mwd, int y) NOEXCEPT 3859*1b8b02a4SEd Tanous { 3860*1b8b02a4SEd Tanous return year(y) / mwd; 3861*1b8b02a4SEd Tanous } 3862*1b8b02a4SEd Tanous 3863*1b8b02a4SEd Tanous // year_month_weekday_last from operator/() 3864*1b8b02a4SEd Tanous 3865*1b8b02a4SEd Tanous CONSTCD11 3866*1b8b02a4SEd Tanous inline 3867*1b8b02a4SEd Tanous year_month_weekday_last 3868*1b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT 3869*1b8b02a4SEd Tanous { 3870*1b8b02a4SEd Tanous return {ym.year(), ym.month(), wdl}; 3871*1b8b02a4SEd Tanous } 3872*1b8b02a4SEd Tanous 3873*1b8b02a4SEd Tanous CONSTCD11 3874*1b8b02a4SEd Tanous inline 3875*1b8b02a4SEd Tanous year_month_weekday_last 3876*1b8b02a4SEd Tanous operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT 3877*1b8b02a4SEd Tanous { 3878*1b8b02a4SEd Tanous return {y, mwdl.month(), mwdl.weekday_last()}; 3879*1b8b02a4SEd Tanous } 3880*1b8b02a4SEd Tanous 3881*1b8b02a4SEd Tanous CONSTCD11 3882*1b8b02a4SEd Tanous inline 3883*1b8b02a4SEd Tanous year_month_weekday_last 3884*1b8b02a4SEd Tanous operator/(int y, const month_weekday_last& mwdl) NOEXCEPT 3885*1b8b02a4SEd Tanous { 3886*1b8b02a4SEd Tanous return year(y) / mwdl; 3887*1b8b02a4SEd Tanous } 3888*1b8b02a4SEd Tanous 3889*1b8b02a4SEd Tanous CONSTCD11 3890*1b8b02a4SEd Tanous inline 3891*1b8b02a4SEd Tanous year_month_weekday_last 3892*1b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT 3893*1b8b02a4SEd Tanous { 3894*1b8b02a4SEd Tanous return y / mwdl; 3895*1b8b02a4SEd Tanous } 3896*1b8b02a4SEd Tanous 3897*1b8b02a4SEd Tanous CONSTCD11 3898*1b8b02a4SEd Tanous inline 3899*1b8b02a4SEd Tanous year_month_weekday_last 3900*1b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, int y) NOEXCEPT 3901*1b8b02a4SEd Tanous { 3902*1b8b02a4SEd Tanous return year(y) / mwdl; 3903*1b8b02a4SEd Tanous } 3904*1b8b02a4SEd Tanous 3905*1b8b02a4SEd Tanous template <class Duration> 3906*1b8b02a4SEd Tanous struct fields; 3907*1b8b02a4SEd Tanous 3908*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 3909*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 3910*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 3911*1b8b02a4SEd Tanous const fields<Duration>& fds, const std::string* abbrev = nullptr, 3912*1b8b02a4SEd Tanous const std::chrono::seconds* offset_sec = nullptr); 3913*1b8b02a4SEd Tanous 3914*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration, class Alloc> 3915*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 3916*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 3917*1b8b02a4SEd Tanous fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 3918*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr); 3919*1b8b02a4SEd Tanous 3920*1b8b02a4SEd Tanous // hh_mm_ss 3921*1b8b02a4SEd Tanous 3922*1b8b02a4SEd Tanous namespace detail 3923*1b8b02a4SEd Tanous { 3924*1b8b02a4SEd Tanous 3925*1b8b02a4SEd Tanous struct undocumented {explicit undocumented() = default;}; 3926*1b8b02a4SEd Tanous 3927*1b8b02a4SEd Tanous // width<n>::value is the number of fractional decimal digits in 1/n 3928*1b8b02a4SEd Tanous // width<0>::value and width<1>::value are defined to be 0 3929*1b8b02a4SEd Tanous // If 1/n takes more than 18 fractional decimal digits, 3930*1b8b02a4SEd Tanous // the result is truncated to 19. 3931*1b8b02a4SEd Tanous // Example: width<2>::value == 1 3932*1b8b02a4SEd Tanous // Example: width<3>::value == 19 3933*1b8b02a4SEd Tanous // Example: width<4>::value == 2 3934*1b8b02a4SEd Tanous // Example: width<10>::value == 1 3935*1b8b02a4SEd Tanous // Example: width<1000>::value == 3 3936*1b8b02a4SEd Tanous template <std::uint64_t n, std::uint64_t d, unsigned w = 0, 3937*1b8b02a4SEd Tanous bool should_continue = n%d != 0 && (w < 19)> 3938*1b8b02a4SEd Tanous struct width 3939*1b8b02a4SEd Tanous { 3940*1b8b02a4SEd Tanous static_assert(d > 0, "width called with zero denominator"); 3941*1b8b02a4SEd Tanous static CONSTDATA unsigned value = 1 + width<n%d*10, d, w+1>::value; 3942*1b8b02a4SEd Tanous }; 3943*1b8b02a4SEd Tanous 3944*1b8b02a4SEd Tanous template <std::uint64_t n, std::uint64_t d, unsigned w> 3945*1b8b02a4SEd Tanous struct width<n, d, w, false> 3946*1b8b02a4SEd Tanous { 3947*1b8b02a4SEd Tanous static CONSTDATA unsigned value = 0; 3948*1b8b02a4SEd Tanous }; 3949*1b8b02a4SEd Tanous 3950*1b8b02a4SEd Tanous template <unsigned exp> 3951*1b8b02a4SEd Tanous struct static_pow10 3952*1b8b02a4SEd Tanous { 3953*1b8b02a4SEd Tanous private: 3954*1b8b02a4SEd Tanous static CONSTDATA std::uint64_t h = static_pow10<exp/2>::value; 3955*1b8b02a4SEd Tanous public: 3956*1b8b02a4SEd Tanous static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1); 3957*1b8b02a4SEd Tanous }; 3958*1b8b02a4SEd Tanous 3959*1b8b02a4SEd Tanous template <> 3960*1b8b02a4SEd Tanous struct static_pow10<0> 3961*1b8b02a4SEd Tanous { 3962*1b8b02a4SEd Tanous static CONSTDATA std::uint64_t value = 1; 3963*1b8b02a4SEd Tanous }; 3964*1b8b02a4SEd Tanous 3965*1b8b02a4SEd Tanous template <class Duration> 3966*1b8b02a4SEd Tanous class decimal_format_seconds 3967*1b8b02a4SEd Tanous { 3968*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 3969*1b8b02a4SEd Tanous using rep = typename CT::rep; 3970*1b8b02a4SEd Tanous static unsigned CONSTDATA trial_width = 3971*1b8b02a4SEd Tanous detail::width<CT::period::num, CT::period::den>::value; 3972*1b8b02a4SEd Tanous public: 3973*1b8b02a4SEd Tanous static unsigned CONSTDATA width = trial_width < 19 ? trial_width : 6u; 3974*1b8b02a4SEd Tanous using precision = std::chrono::duration<rep, 3975*1b8b02a4SEd Tanous std::ratio<1, static_pow10<width>::value>>; 3976*1b8b02a4SEd Tanous 3977*1b8b02a4SEd Tanous private: 3978*1b8b02a4SEd Tanous std::chrono::seconds s_; 3979*1b8b02a4SEd Tanous precision sub_s_; 3980*1b8b02a4SEd Tanous 3981*1b8b02a4SEd Tanous public: 3982*1b8b02a4SEd Tanous CONSTCD11 decimal_format_seconds() 3983*1b8b02a4SEd Tanous : s_() 3984*1b8b02a4SEd Tanous , sub_s_() 3985*1b8b02a4SEd Tanous {} 3986*1b8b02a4SEd Tanous 3987*1b8b02a4SEd Tanous CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT 3988*1b8b02a4SEd Tanous : s_(std::chrono::duration_cast<std::chrono::seconds>(d)) 3989*1b8b02a4SEd Tanous , sub_s_(std::chrono::duration_cast<precision>(d - s_)) 3990*1b8b02a4SEd Tanous {} 3991*1b8b02a4SEd Tanous 3992*1b8b02a4SEd Tanous CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} 3993*1b8b02a4SEd Tanous CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} 3994*1b8b02a4SEd Tanous CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} 3995*1b8b02a4SEd Tanous 3996*1b8b02a4SEd Tanous CONSTCD14 precision to_duration() const NOEXCEPT 3997*1b8b02a4SEd Tanous { 3998*1b8b02a4SEd Tanous return s_ + sub_s_; 3999*1b8b02a4SEd Tanous } 4000*1b8b02a4SEd Tanous 4001*1b8b02a4SEd Tanous CONSTCD11 bool in_conventional_range() const NOEXCEPT 4002*1b8b02a4SEd Tanous { 4003*1b8b02a4SEd Tanous return sub_s_ < std::chrono::seconds{1} && s_ < std::chrono::minutes{1}; 4004*1b8b02a4SEd Tanous } 4005*1b8b02a4SEd Tanous 4006*1b8b02a4SEd Tanous template <class CharT, class Traits> 4007*1b8b02a4SEd Tanous friend 4008*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4009*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x) 4010*1b8b02a4SEd Tanous { 4011*1b8b02a4SEd Tanous return x.print(os, std::chrono::treat_as_floating_point<rep>{}); 4012*1b8b02a4SEd Tanous } 4013*1b8b02a4SEd Tanous 4014*1b8b02a4SEd Tanous template <class CharT, class Traits> 4015*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4016*1b8b02a4SEd Tanous print(std::basic_ostream<CharT, Traits>& os, std::true_type) const 4017*1b8b02a4SEd Tanous { 4018*1b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _(os); 4019*1b8b02a4SEd Tanous std::chrono::duration<rep> d = s_ + sub_s_; 4020*1b8b02a4SEd Tanous if (d < std::chrono::seconds{10}) 4021*1b8b02a4SEd Tanous os << '0'; 4022*1b8b02a4SEd Tanous os.precision(width+6); 4023*1b8b02a4SEd Tanous os << std::fixed << d.count(); 4024*1b8b02a4SEd Tanous return os; 4025*1b8b02a4SEd Tanous } 4026*1b8b02a4SEd Tanous 4027*1b8b02a4SEd Tanous template <class CharT, class Traits> 4028*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4029*1b8b02a4SEd Tanous print(std::basic_ostream<CharT, Traits>& os, std::false_type) const 4030*1b8b02a4SEd Tanous { 4031*1b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _(os); 4032*1b8b02a4SEd Tanous os.fill('0'); 4033*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 4034*1b8b02a4SEd Tanous os.width(2); 4035*1b8b02a4SEd Tanous os << s_.count(); 4036*1b8b02a4SEd Tanous if (width > 0) 4037*1b8b02a4SEd Tanous { 4038*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 4039*1b8b02a4SEd Tanous os << std::use_facet<std::numpunct<CharT>>(os.getloc()).decimal_point(); 4040*1b8b02a4SEd Tanous #else 4041*1b8b02a4SEd Tanous os << '.'; 4042*1b8b02a4SEd Tanous #endif 4043*1b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _s(os); 4044*1b8b02a4SEd Tanous os.imbue(std::locale::classic()); 4045*1b8b02a4SEd Tanous os.width(width); 4046*1b8b02a4SEd Tanous os << sub_s_.count(); 4047*1b8b02a4SEd Tanous } 4048*1b8b02a4SEd Tanous return os; 4049*1b8b02a4SEd Tanous } 4050*1b8b02a4SEd Tanous }; 4051*1b8b02a4SEd Tanous 4052*1b8b02a4SEd Tanous template <class Rep, class Period> 4053*1b8b02a4SEd Tanous inline 4054*1b8b02a4SEd Tanous CONSTCD11 4055*1b8b02a4SEd Tanous typename std::enable_if 4056*1b8b02a4SEd Tanous < 4057*1b8b02a4SEd Tanous std::numeric_limits<Rep>::is_signed, 4058*1b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 4059*1b8b02a4SEd Tanous >::type 4060*1b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 4061*1b8b02a4SEd Tanous { 4062*1b8b02a4SEd Tanous return d >= d.zero() ? +d : -d; 4063*1b8b02a4SEd Tanous } 4064*1b8b02a4SEd Tanous 4065*1b8b02a4SEd Tanous template <class Rep, class Period> 4066*1b8b02a4SEd Tanous inline 4067*1b8b02a4SEd Tanous CONSTCD11 4068*1b8b02a4SEd Tanous typename std::enable_if 4069*1b8b02a4SEd Tanous < 4070*1b8b02a4SEd Tanous !std::numeric_limits<Rep>::is_signed, 4071*1b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 4072*1b8b02a4SEd Tanous >::type 4073*1b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 4074*1b8b02a4SEd Tanous { 4075*1b8b02a4SEd Tanous return d; 4076*1b8b02a4SEd Tanous } 4077*1b8b02a4SEd Tanous 4078*1b8b02a4SEd Tanous } // namespace detail 4079*1b8b02a4SEd Tanous 4080*1b8b02a4SEd Tanous template <class Duration> 4081*1b8b02a4SEd Tanous class hh_mm_ss 4082*1b8b02a4SEd Tanous { 4083*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<typename std::common_type<Duration, 4084*1b8b02a4SEd Tanous std::chrono::seconds>::type>; 4085*1b8b02a4SEd Tanous 4086*1b8b02a4SEd Tanous std::chrono::hours h_; 4087*1b8b02a4SEd Tanous std::chrono::minutes m_; 4088*1b8b02a4SEd Tanous dfs s_; 4089*1b8b02a4SEd Tanous bool neg_; 4090*1b8b02a4SEd Tanous 4091*1b8b02a4SEd Tanous public: 4092*1b8b02a4SEd Tanous static unsigned CONSTDATA fractional_width = dfs::width; 4093*1b8b02a4SEd Tanous using precision = typename dfs::precision; 4094*1b8b02a4SEd Tanous 4095*1b8b02a4SEd Tanous CONSTCD11 hh_mm_ss() NOEXCEPT 4096*1b8b02a4SEd Tanous : hh_mm_ss(Duration::zero()) 4097*1b8b02a4SEd Tanous {} 4098*1b8b02a4SEd Tanous 4099*1b8b02a4SEd Tanous CONSTCD11 explicit hh_mm_ss(Duration d) NOEXCEPT 4100*1b8b02a4SEd Tanous : h_(std::chrono::duration_cast<std::chrono::hours>(detail::abs(d))) 4101*1b8b02a4SEd Tanous , m_(std::chrono::duration_cast<std::chrono::minutes>(detail::abs(d)) - h_) 4102*1b8b02a4SEd Tanous , s_(detail::abs(d) - h_ - m_) 4103*1b8b02a4SEd Tanous , neg_(d < Duration::zero()) 4104*1b8b02a4SEd Tanous {} 4105*1b8b02a4SEd Tanous 4106*1b8b02a4SEd Tanous CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} 4107*1b8b02a4SEd Tanous CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} 4108*1b8b02a4SEd Tanous CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} 4109*1b8b02a4SEd Tanous CONSTCD14 std::chrono::seconds& 4110*1b8b02a4SEd Tanous seconds(detail::undocumented) NOEXCEPT {return s_.seconds();} 4111*1b8b02a4SEd Tanous CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();} 4112*1b8b02a4SEd Tanous CONSTCD11 bool is_negative() const NOEXCEPT {return neg_;} 4113*1b8b02a4SEd Tanous 4114*1b8b02a4SEd Tanous CONSTCD11 explicit operator precision() const NOEXCEPT {return to_duration();} 4115*1b8b02a4SEd Tanous CONSTCD11 precision to_duration() const NOEXCEPT 4116*1b8b02a4SEd Tanous {return (s_.to_duration() + m_ + h_) * (1-2*neg_);} 4117*1b8b02a4SEd Tanous 4118*1b8b02a4SEd Tanous CONSTCD11 bool in_conventional_range() const NOEXCEPT 4119*1b8b02a4SEd Tanous { 4120*1b8b02a4SEd Tanous return !neg_ && h_ < days{1} && m_ < std::chrono::hours{1} && 4121*1b8b02a4SEd Tanous s_.in_conventional_range(); 4122*1b8b02a4SEd Tanous } 4123*1b8b02a4SEd Tanous 4124*1b8b02a4SEd Tanous private: 4125*1b8b02a4SEd Tanous 4126*1b8b02a4SEd Tanous template <class charT, class traits> 4127*1b8b02a4SEd Tanous friend 4128*1b8b02a4SEd Tanous std::basic_ostream<charT, traits>& 4129*1b8b02a4SEd Tanous operator<<(std::basic_ostream<charT, traits>& os, hh_mm_ss const& tod) 4130*1b8b02a4SEd Tanous { 4131*1b8b02a4SEd Tanous if (tod.is_negative()) 4132*1b8b02a4SEd Tanous os << '-'; 4133*1b8b02a4SEd Tanous if (tod.h_ < std::chrono::hours{10}) 4134*1b8b02a4SEd Tanous os << '0'; 4135*1b8b02a4SEd Tanous os << tod.h_.count() << ':'; 4136*1b8b02a4SEd Tanous if (tod.m_ < std::chrono::minutes{10}) 4137*1b8b02a4SEd Tanous os << '0'; 4138*1b8b02a4SEd Tanous os << tod.m_.count() << ':' << tod.s_; 4139*1b8b02a4SEd Tanous return os; 4140*1b8b02a4SEd Tanous } 4141*1b8b02a4SEd Tanous 4142*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration2> 4143*1b8b02a4SEd Tanous friend 4144*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4145*1b8b02a4SEd Tanous date::to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 4146*1b8b02a4SEd Tanous const fields<Duration2>& fds, const std::string* abbrev, 4147*1b8b02a4SEd Tanous const std::chrono::seconds* offset_sec); 4148*1b8b02a4SEd Tanous 4149*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration2, class Alloc> 4150*1b8b02a4SEd Tanous friend 4151*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 4152*1b8b02a4SEd Tanous date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 4153*1b8b02a4SEd Tanous fields<Duration2>& fds, 4154*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev, std::chrono::minutes* offset); 4155*1b8b02a4SEd Tanous }; 4156*1b8b02a4SEd Tanous 4157*1b8b02a4SEd Tanous inline 4158*1b8b02a4SEd Tanous CONSTCD14 4159*1b8b02a4SEd Tanous bool 4160*1b8b02a4SEd Tanous is_am(std::chrono::hours const& h) NOEXCEPT 4161*1b8b02a4SEd Tanous { 4162*1b8b02a4SEd Tanous using std::chrono::hours; 4163*1b8b02a4SEd Tanous return hours{0} <= h && h < hours{12}; 4164*1b8b02a4SEd Tanous } 4165*1b8b02a4SEd Tanous 4166*1b8b02a4SEd Tanous inline 4167*1b8b02a4SEd Tanous CONSTCD14 4168*1b8b02a4SEd Tanous bool 4169*1b8b02a4SEd Tanous is_pm(std::chrono::hours const& h) NOEXCEPT 4170*1b8b02a4SEd Tanous { 4171*1b8b02a4SEd Tanous using std::chrono::hours; 4172*1b8b02a4SEd Tanous return hours{12} <= h && h < hours{24}; 4173*1b8b02a4SEd Tanous } 4174*1b8b02a4SEd Tanous 4175*1b8b02a4SEd Tanous inline 4176*1b8b02a4SEd Tanous CONSTCD14 4177*1b8b02a4SEd Tanous std::chrono::hours 4178*1b8b02a4SEd Tanous make12(std::chrono::hours h) NOEXCEPT 4179*1b8b02a4SEd Tanous { 4180*1b8b02a4SEd Tanous using std::chrono::hours; 4181*1b8b02a4SEd Tanous if (h < hours{12}) 4182*1b8b02a4SEd Tanous { 4183*1b8b02a4SEd Tanous if (h == hours{0}) 4184*1b8b02a4SEd Tanous h = hours{12}; 4185*1b8b02a4SEd Tanous } 4186*1b8b02a4SEd Tanous else 4187*1b8b02a4SEd Tanous { 4188*1b8b02a4SEd Tanous if (h != hours{12}) 4189*1b8b02a4SEd Tanous h = h - hours{12}; 4190*1b8b02a4SEd Tanous } 4191*1b8b02a4SEd Tanous return h; 4192*1b8b02a4SEd Tanous } 4193*1b8b02a4SEd Tanous 4194*1b8b02a4SEd Tanous inline 4195*1b8b02a4SEd Tanous CONSTCD14 4196*1b8b02a4SEd Tanous std::chrono::hours 4197*1b8b02a4SEd Tanous make24(std::chrono::hours h, bool is_pm) NOEXCEPT 4198*1b8b02a4SEd Tanous { 4199*1b8b02a4SEd Tanous using std::chrono::hours; 4200*1b8b02a4SEd Tanous if (is_pm) 4201*1b8b02a4SEd Tanous { 4202*1b8b02a4SEd Tanous if (h != hours{12}) 4203*1b8b02a4SEd Tanous h = h + hours{12}; 4204*1b8b02a4SEd Tanous } 4205*1b8b02a4SEd Tanous else if (h == hours{12}) 4206*1b8b02a4SEd Tanous h = hours{0}; 4207*1b8b02a4SEd Tanous return h; 4208*1b8b02a4SEd Tanous } 4209*1b8b02a4SEd Tanous 4210*1b8b02a4SEd Tanous template <class Duration> 4211*1b8b02a4SEd Tanous using time_of_day = hh_mm_ss<Duration>; 4212*1b8b02a4SEd Tanous 4213*1b8b02a4SEd Tanous template <class Rep, class Period> 4214*1b8b02a4SEd Tanous CONSTCD11 4215*1b8b02a4SEd Tanous inline 4216*1b8b02a4SEd Tanous hh_mm_ss<std::chrono::duration<Rep, Period>> 4217*1b8b02a4SEd Tanous make_time(const std::chrono::duration<Rep, Period>& d) 4218*1b8b02a4SEd Tanous { 4219*1b8b02a4SEd Tanous return hh_mm_ss<std::chrono::duration<Rep, Period>>(d); 4220*1b8b02a4SEd Tanous } 4221*1b8b02a4SEd Tanous 4222*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 4223*1b8b02a4SEd Tanous inline 4224*1b8b02a4SEd Tanous typename std::enable_if 4225*1b8b02a4SEd Tanous < 4226*1b8b02a4SEd Tanous !std::is_convertible<Duration, days>::value, 4227*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4228*1b8b02a4SEd Tanous >::type 4229*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const sys_time<Duration>& tp) 4230*1b8b02a4SEd Tanous { 4231*1b8b02a4SEd Tanous auto const dp = date::floor<days>(tp); 4232*1b8b02a4SEd Tanous return os << year_month_day(dp) << ' ' << make_time(tp-dp); 4233*1b8b02a4SEd Tanous } 4234*1b8b02a4SEd Tanous 4235*1b8b02a4SEd Tanous template <class CharT, class Traits> 4236*1b8b02a4SEd Tanous inline 4237*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4238*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const sys_days& dp) 4239*1b8b02a4SEd Tanous { 4240*1b8b02a4SEd Tanous return os << year_month_day(dp); 4241*1b8b02a4SEd Tanous } 4242*1b8b02a4SEd Tanous 4243*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 4244*1b8b02a4SEd Tanous inline 4245*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4246*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const local_time<Duration>& ut) 4247*1b8b02a4SEd Tanous { 4248*1b8b02a4SEd Tanous return (os << sys_time<Duration>{ut.time_since_epoch()}); 4249*1b8b02a4SEd Tanous } 4250*1b8b02a4SEd Tanous 4251*1b8b02a4SEd Tanous namespace detail 4252*1b8b02a4SEd Tanous { 4253*1b8b02a4SEd Tanous 4254*1b8b02a4SEd Tanous template <class CharT, std::size_t N> 4255*1b8b02a4SEd Tanous class string_literal; 4256*1b8b02a4SEd Tanous 4257*1b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 4258*1b8b02a4SEd Tanous inline 4259*1b8b02a4SEd Tanous CONSTCD14 4260*1b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 4261*1b8b02a4SEd Tanous N1 + N2 - 1> 4262*1b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT; 4263*1b8b02a4SEd Tanous 4264*1b8b02a4SEd Tanous template <class CharT, std::size_t N> 4265*1b8b02a4SEd Tanous class string_literal 4266*1b8b02a4SEd Tanous { 4267*1b8b02a4SEd Tanous CharT p_[N]; 4268*1b8b02a4SEd Tanous 4269*1b8b02a4SEd Tanous CONSTCD11 string_literal() NOEXCEPT 4270*1b8b02a4SEd Tanous : p_{} 4271*1b8b02a4SEd Tanous {} 4272*1b8b02a4SEd Tanous 4273*1b8b02a4SEd Tanous public: 4274*1b8b02a4SEd Tanous using const_iterator = const CharT*; 4275*1b8b02a4SEd Tanous 4276*1b8b02a4SEd Tanous string_literal(string_literal const&) = default; 4277*1b8b02a4SEd Tanous string_literal& operator=(string_literal const&) = delete; 4278*1b8b02a4SEd Tanous 4279*1b8b02a4SEd Tanous template <std::size_t N1 = 2, 4280*1b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 4281*1b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c) NOEXCEPT 4282*1b8b02a4SEd Tanous : p_{c} 4283*1b8b02a4SEd Tanous { 4284*1b8b02a4SEd Tanous } 4285*1b8b02a4SEd Tanous 4286*1b8b02a4SEd Tanous template <std::size_t N1 = 3, 4287*1b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 4288*1b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c1, CharT c2) NOEXCEPT 4289*1b8b02a4SEd Tanous : p_{c1, c2} 4290*1b8b02a4SEd Tanous { 4291*1b8b02a4SEd Tanous } 4292*1b8b02a4SEd Tanous 4293*1b8b02a4SEd Tanous template <std::size_t N1 = 4, 4294*1b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 4295*1b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c1, CharT c2, CharT c3) NOEXCEPT 4296*1b8b02a4SEd Tanous : p_{c1, c2, c3} 4297*1b8b02a4SEd Tanous { 4298*1b8b02a4SEd Tanous } 4299*1b8b02a4SEd Tanous 4300*1b8b02a4SEd Tanous CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT 4301*1b8b02a4SEd Tanous : p_{} 4302*1b8b02a4SEd Tanous { 4303*1b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 4304*1b8b02a4SEd Tanous p_[i] = a[i]; 4305*1b8b02a4SEd Tanous } 4306*1b8b02a4SEd Tanous 4307*1b8b02a4SEd Tanous template <class U = CharT, 4308*1b8b02a4SEd Tanous class = typename std::enable_if<(1 < sizeof(U))>::type> 4309*1b8b02a4SEd Tanous CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT 4310*1b8b02a4SEd Tanous : p_{} 4311*1b8b02a4SEd Tanous { 4312*1b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 4313*1b8b02a4SEd Tanous p_[i] = a[i]; 4314*1b8b02a4SEd Tanous } 4315*1b8b02a4SEd Tanous 4316*1b8b02a4SEd Tanous template <class CharT2, 4317*1b8b02a4SEd Tanous class = typename std::enable_if<!std::is_same<CharT2, CharT>::value>::type> 4318*1b8b02a4SEd Tanous CONSTCD14 string_literal(string_literal<CharT2, N> const& a) NOEXCEPT 4319*1b8b02a4SEd Tanous : p_{} 4320*1b8b02a4SEd Tanous { 4321*1b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 4322*1b8b02a4SEd Tanous p_[i] = a[i]; 4323*1b8b02a4SEd Tanous } 4324*1b8b02a4SEd Tanous 4325*1b8b02a4SEd Tanous CONSTCD11 const CharT* data() const NOEXCEPT {return p_;} 4326*1b8b02a4SEd Tanous CONSTCD11 std::size_t size() const NOEXCEPT {return N-1;} 4327*1b8b02a4SEd Tanous 4328*1b8b02a4SEd Tanous CONSTCD11 const_iterator begin() const NOEXCEPT {return p_;} 4329*1b8b02a4SEd Tanous CONSTCD11 const_iterator end() const NOEXCEPT {return p_ + N-1;} 4330*1b8b02a4SEd Tanous 4331*1b8b02a4SEd Tanous CONSTCD11 CharT const& operator[](std::size_t n) const NOEXCEPT 4332*1b8b02a4SEd Tanous { 4333*1b8b02a4SEd Tanous return p_[n]; 4334*1b8b02a4SEd Tanous } 4335*1b8b02a4SEd Tanous 4336*1b8b02a4SEd Tanous template <class Traits> 4337*1b8b02a4SEd Tanous friend 4338*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4339*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s) 4340*1b8b02a4SEd Tanous { 4341*1b8b02a4SEd Tanous return os << s.p_; 4342*1b8b02a4SEd Tanous } 4343*1b8b02a4SEd Tanous 4344*1b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 4345*1b8b02a4SEd Tanous friend 4346*1b8b02a4SEd Tanous CONSTCD14 4347*1b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 4348*1b8b02a4SEd Tanous N1 + N2 - 1> 4349*1b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT; 4350*1b8b02a4SEd Tanous }; 4351*1b8b02a4SEd Tanous 4352*1b8b02a4SEd Tanous template <class CharT> 4353*1b8b02a4SEd Tanous CONSTCD11 4354*1b8b02a4SEd Tanous inline 4355*1b8b02a4SEd Tanous string_literal<CharT, 3> 4356*1b8b02a4SEd Tanous operator+(const string_literal<CharT, 2>& x, const string_literal<CharT, 2>& y) NOEXCEPT 4357*1b8b02a4SEd Tanous { 4358*1b8b02a4SEd Tanous return string_literal<CharT, 3>(x[0], y[0]); 4359*1b8b02a4SEd Tanous } 4360*1b8b02a4SEd Tanous 4361*1b8b02a4SEd Tanous template <class CharT> 4362*1b8b02a4SEd Tanous CONSTCD11 4363*1b8b02a4SEd Tanous inline 4364*1b8b02a4SEd Tanous string_literal<CharT, 4> 4365*1b8b02a4SEd Tanous operator+(const string_literal<CharT, 3>& x, const string_literal<CharT, 2>& y) NOEXCEPT 4366*1b8b02a4SEd Tanous { 4367*1b8b02a4SEd Tanous return string_literal<CharT, 4>(x[0], x[1], y[0]); 4368*1b8b02a4SEd Tanous } 4369*1b8b02a4SEd Tanous 4370*1b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 4371*1b8b02a4SEd Tanous CONSTCD14 4372*1b8b02a4SEd Tanous inline 4373*1b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 4374*1b8b02a4SEd Tanous N1 + N2 - 1> 4375*1b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT 4376*1b8b02a4SEd Tanous { 4377*1b8b02a4SEd Tanous using CT = typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type; 4378*1b8b02a4SEd Tanous 4379*1b8b02a4SEd Tanous string_literal<CT, N1 + N2 - 1> r; 4380*1b8b02a4SEd Tanous std::size_t i = 0; 4381*1b8b02a4SEd Tanous for (; i < N1-1; ++i) 4382*1b8b02a4SEd Tanous r.p_[i] = CT(x.p_[i]); 4383*1b8b02a4SEd Tanous for (std::size_t j = 0; j < N2; ++j, ++i) 4384*1b8b02a4SEd Tanous r.p_[i] = CT(y.p_[j]); 4385*1b8b02a4SEd Tanous 4386*1b8b02a4SEd Tanous return r; 4387*1b8b02a4SEd Tanous } 4388*1b8b02a4SEd Tanous 4389*1b8b02a4SEd Tanous 4390*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, std::size_t N> 4391*1b8b02a4SEd Tanous inline 4392*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> 4393*1b8b02a4SEd Tanous operator+(std::basic_string<CharT, Traits, Alloc> x, const string_literal<CharT, N>& y) 4394*1b8b02a4SEd Tanous { 4395*1b8b02a4SEd Tanous x.append(y.data(), y.size()); 4396*1b8b02a4SEd Tanous return x; 4397*1b8b02a4SEd Tanous } 4398*1b8b02a4SEd Tanous 4399*1b8b02a4SEd Tanous #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \ 4400*1b8b02a4SEd Tanous && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150) 4401*1b8b02a4SEd Tanous 4402*1b8b02a4SEd Tanous template <class CharT, 4403*1b8b02a4SEd Tanous class = std::enable_if_t<std::is_same<CharT, char>::value || 4404*1b8b02a4SEd Tanous std::is_same<CharT, wchar_t>::value || 4405*1b8b02a4SEd Tanous std::is_same<CharT, char16_t>::value || 4406*1b8b02a4SEd Tanous std::is_same<CharT, char32_t>::value>> 4407*1b8b02a4SEd Tanous CONSTCD14 4408*1b8b02a4SEd Tanous inline 4409*1b8b02a4SEd Tanous string_literal<CharT, 2> 4410*1b8b02a4SEd Tanous msl(CharT c) NOEXCEPT 4411*1b8b02a4SEd Tanous { 4412*1b8b02a4SEd Tanous return string_literal<CharT, 2>{c}; 4413*1b8b02a4SEd Tanous } 4414*1b8b02a4SEd Tanous 4415*1b8b02a4SEd Tanous CONSTCD14 4416*1b8b02a4SEd Tanous inline 4417*1b8b02a4SEd Tanous std::size_t 4418*1b8b02a4SEd Tanous to_string_len(std::intmax_t i) 4419*1b8b02a4SEd Tanous { 4420*1b8b02a4SEd Tanous std::size_t r = 0; 4421*1b8b02a4SEd Tanous do 4422*1b8b02a4SEd Tanous { 4423*1b8b02a4SEd Tanous i /= 10; 4424*1b8b02a4SEd Tanous ++r; 4425*1b8b02a4SEd Tanous } while (i > 0); 4426*1b8b02a4SEd Tanous return r; 4427*1b8b02a4SEd Tanous } 4428*1b8b02a4SEd Tanous 4429*1b8b02a4SEd Tanous template <std::intmax_t N> 4430*1b8b02a4SEd Tanous CONSTCD14 4431*1b8b02a4SEd Tanous inline 4432*1b8b02a4SEd Tanous std::enable_if_t 4433*1b8b02a4SEd Tanous < 4434*1b8b02a4SEd Tanous N < 10, 4435*1b8b02a4SEd Tanous string_literal<char, to_string_len(N)+1> 4436*1b8b02a4SEd Tanous > 4437*1b8b02a4SEd Tanous msl() NOEXCEPT 4438*1b8b02a4SEd Tanous { 4439*1b8b02a4SEd Tanous return msl(char(N % 10 + '0')); 4440*1b8b02a4SEd Tanous } 4441*1b8b02a4SEd Tanous 4442*1b8b02a4SEd Tanous template <std::intmax_t N> 4443*1b8b02a4SEd Tanous CONSTCD14 4444*1b8b02a4SEd Tanous inline 4445*1b8b02a4SEd Tanous std::enable_if_t 4446*1b8b02a4SEd Tanous < 4447*1b8b02a4SEd Tanous 10 <= N, 4448*1b8b02a4SEd Tanous string_literal<char, to_string_len(N)+1> 4449*1b8b02a4SEd Tanous > 4450*1b8b02a4SEd Tanous msl() NOEXCEPT 4451*1b8b02a4SEd Tanous { 4452*1b8b02a4SEd Tanous return msl<N/10>() + msl(char(N % 10 + '0')); 4453*1b8b02a4SEd Tanous } 4454*1b8b02a4SEd Tanous 4455*1b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 4456*1b8b02a4SEd Tanous CONSTCD14 4457*1b8b02a4SEd Tanous inline 4458*1b8b02a4SEd Tanous std::enable_if_t 4459*1b8b02a4SEd Tanous < 4460*1b8b02a4SEd Tanous std::ratio<N, D>::type::den != 1, 4461*1b8b02a4SEd Tanous string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 4462*1b8b02a4SEd Tanous to_string_len(std::ratio<N, D>::type::den) + 4> 4463*1b8b02a4SEd Tanous > 4464*1b8b02a4SEd Tanous msl(std::ratio<N, D>) NOEXCEPT 4465*1b8b02a4SEd Tanous { 4466*1b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 4467*1b8b02a4SEd Tanous return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) + 4468*1b8b02a4SEd Tanous msl<R::den>() + msl(CharT{']'}); 4469*1b8b02a4SEd Tanous } 4470*1b8b02a4SEd Tanous 4471*1b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 4472*1b8b02a4SEd Tanous CONSTCD14 4473*1b8b02a4SEd Tanous inline 4474*1b8b02a4SEd Tanous std::enable_if_t 4475*1b8b02a4SEd Tanous < 4476*1b8b02a4SEd Tanous std::ratio<N, D>::type::den == 1, 4477*1b8b02a4SEd Tanous string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3> 4478*1b8b02a4SEd Tanous > 4479*1b8b02a4SEd Tanous msl(std::ratio<N, D>) NOEXCEPT 4480*1b8b02a4SEd Tanous { 4481*1b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 4482*1b8b02a4SEd Tanous return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'}); 4483*1b8b02a4SEd Tanous } 4484*1b8b02a4SEd Tanous 4485*1b8b02a4SEd Tanous 4486*1b8b02a4SEd Tanous #else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) 4487*1b8b02a4SEd Tanous 4488*1b8b02a4SEd Tanous inline 4489*1b8b02a4SEd Tanous std::string 4490*1b8b02a4SEd Tanous to_string(std::uint64_t x) 4491*1b8b02a4SEd Tanous { 4492*1b8b02a4SEd Tanous return std::to_string(x); 4493*1b8b02a4SEd Tanous } 4494*1b8b02a4SEd Tanous 4495*1b8b02a4SEd Tanous template <class CharT> 4496*1b8b02a4SEd Tanous inline 4497*1b8b02a4SEd Tanous std::basic_string<CharT> 4498*1b8b02a4SEd Tanous to_string(std::uint64_t x) 4499*1b8b02a4SEd Tanous { 4500*1b8b02a4SEd Tanous auto y = std::to_string(x); 4501*1b8b02a4SEd Tanous return std::basic_string<CharT>(y.begin(), y.end()); 4502*1b8b02a4SEd Tanous } 4503*1b8b02a4SEd Tanous 4504*1b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 4505*1b8b02a4SEd Tanous inline 4506*1b8b02a4SEd Tanous typename std::enable_if 4507*1b8b02a4SEd Tanous < 4508*1b8b02a4SEd Tanous std::ratio<N, D>::type::den != 1, 4509*1b8b02a4SEd Tanous std::basic_string<CharT> 4510*1b8b02a4SEd Tanous >::type 4511*1b8b02a4SEd Tanous msl(std::ratio<N, D>) 4512*1b8b02a4SEd Tanous { 4513*1b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 4514*1b8b02a4SEd Tanous return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} + 4515*1b8b02a4SEd Tanous to_string<CharT>(R::den) + CharT{']'}; 4516*1b8b02a4SEd Tanous } 4517*1b8b02a4SEd Tanous 4518*1b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 4519*1b8b02a4SEd Tanous inline 4520*1b8b02a4SEd Tanous typename std::enable_if 4521*1b8b02a4SEd Tanous < 4522*1b8b02a4SEd Tanous std::ratio<N, D>::type::den == 1, 4523*1b8b02a4SEd Tanous std::basic_string<CharT> 4524*1b8b02a4SEd Tanous >::type 4525*1b8b02a4SEd Tanous msl(std::ratio<N, D>) 4526*1b8b02a4SEd Tanous { 4527*1b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 4528*1b8b02a4SEd Tanous return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'}; 4529*1b8b02a4SEd Tanous } 4530*1b8b02a4SEd Tanous 4531*1b8b02a4SEd Tanous #endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) 4532*1b8b02a4SEd Tanous 4533*1b8b02a4SEd Tanous template <class CharT> 4534*1b8b02a4SEd Tanous CONSTCD11 4535*1b8b02a4SEd Tanous inline 4536*1b8b02a4SEd Tanous string_literal<CharT, 2> 4537*1b8b02a4SEd Tanous msl(std::atto) NOEXCEPT 4538*1b8b02a4SEd Tanous { 4539*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'a'}; 4540*1b8b02a4SEd Tanous } 4541*1b8b02a4SEd Tanous 4542*1b8b02a4SEd Tanous template <class CharT> 4543*1b8b02a4SEd Tanous CONSTCD11 4544*1b8b02a4SEd Tanous inline 4545*1b8b02a4SEd Tanous string_literal<CharT, 2> 4546*1b8b02a4SEd Tanous msl(std::femto) NOEXCEPT 4547*1b8b02a4SEd Tanous { 4548*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'f'}; 4549*1b8b02a4SEd Tanous } 4550*1b8b02a4SEd Tanous 4551*1b8b02a4SEd Tanous template <class CharT> 4552*1b8b02a4SEd Tanous CONSTCD11 4553*1b8b02a4SEd Tanous inline 4554*1b8b02a4SEd Tanous string_literal<CharT, 2> 4555*1b8b02a4SEd Tanous msl(std::pico) NOEXCEPT 4556*1b8b02a4SEd Tanous { 4557*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'p'}; 4558*1b8b02a4SEd Tanous } 4559*1b8b02a4SEd Tanous 4560*1b8b02a4SEd Tanous template <class CharT> 4561*1b8b02a4SEd Tanous CONSTCD11 4562*1b8b02a4SEd Tanous inline 4563*1b8b02a4SEd Tanous string_literal<CharT, 2> 4564*1b8b02a4SEd Tanous msl(std::nano) NOEXCEPT 4565*1b8b02a4SEd Tanous { 4566*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'n'}; 4567*1b8b02a4SEd Tanous } 4568*1b8b02a4SEd Tanous 4569*1b8b02a4SEd Tanous template <class CharT> 4570*1b8b02a4SEd Tanous CONSTCD11 4571*1b8b02a4SEd Tanous inline 4572*1b8b02a4SEd Tanous typename std::enable_if 4573*1b8b02a4SEd Tanous < 4574*1b8b02a4SEd Tanous std::is_same<CharT, char>::value, 4575*1b8b02a4SEd Tanous string_literal<char, 3> 4576*1b8b02a4SEd Tanous >::type 4577*1b8b02a4SEd Tanous msl(std::micro) NOEXCEPT 4578*1b8b02a4SEd Tanous { 4579*1b8b02a4SEd Tanous return string_literal<char, 3>{'\xC2', '\xB5'}; 4580*1b8b02a4SEd Tanous } 4581*1b8b02a4SEd Tanous 4582*1b8b02a4SEd Tanous template <class CharT> 4583*1b8b02a4SEd Tanous CONSTCD11 4584*1b8b02a4SEd Tanous inline 4585*1b8b02a4SEd Tanous typename std::enable_if 4586*1b8b02a4SEd Tanous < 4587*1b8b02a4SEd Tanous !std::is_same<CharT, char>::value, 4588*1b8b02a4SEd Tanous string_literal<CharT, 2> 4589*1b8b02a4SEd Tanous >::type 4590*1b8b02a4SEd Tanous msl(std::micro) NOEXCEPT 4591*1b8b02a4SEd Tanous { 4592*1b8b02a4SEd Tanous return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}}; 4593*1b8b02a4SEd Tanous } 4594*1b8b02a4SEd Tanous 4595*1b8b02a4SEd Tanous template <class CharT> 4596*1b8b02a4SEd Tanous CONSTCD11 4597*1b8b02a4SEd Tanous inline 4598*1b8b02a4SEd Tanous string_literal<CharT, 2> 4599*1b8b02a4SEd Tanous msl(std::milli) NOEXCEPT 4600*1b8b02a4SEd Tanous { 4601*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'m'}; 4602*1b8b02a4SEd Tanous } 4603*1b8b02a4SEd Tanous 4604*1b8b02a4SEd Tanous template <class CharT> 4605*1b8b02a4SEd Tanous CONSTCD11 4606*1b8b02a4SEd Tanous inline 4607*1b8b02a4SEd Tanous string_literal<CharT, 2> 4608*1b8b02a4SEd Tanous msl(std::centi) NOEXCEPT 4609*1b8b02a4SEd Tanous { 4610*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'c'}; 4611*1b8b02a4SEd Tanous } 4612*1b8b02a4SEd Tanous 4613*1b8b02a4SEd Tanous template <class CharT> 4614*1b8b02a4SEd Tanous CONSTCD11 4615*1b8b02a4SEd Tanous inline 4616*1b8b02a4SEd Tanous string_literal<CharT, 3> 4617*1b8b02a4SEd Tanous msl(std::deca) NOEXCEPT 4618*1b8b02a4SEd Tanous { 4619*1b8b02a4SEd Tanous return string_literal<CharT, 3>{'d', 'a'}; 4620*1b8b02a4SEd Tanous } 4621*1b8b02a4SEd Tanous 4622*1b8b02a4SEd Tanous template <class CharT> 4623*1b8b02a4SEd Tanous CONSTCD11 4624*1b8b02a4SEd Tanous inline 4625*1b8b02a4SEd Tanous string_literal<CharT, 2> 4626*1b8b02a4SEd Tanous msl(std::deci) NOEXCEPT 4627*1b8b02a4SEd Tanous { 4628*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'d'}; 4629*1b8b02a4SEd Tanous } 4630*1b8b02a4SEd Tanous 4631*1b8b02a4SEd Tanous template <class CharT> 4632*1b8b02a4SEd Tanous CONSTCD11 4633*1b8b02a4SEd Tanous inline 4634*1b8b02a4SEd Tanous string_literal<CharT, 2> 4635*1b8b02a4SEd Tanous msl(std::hecto) NOEXCEPT 4636*1b8b02a4SEd Tanous { 4637*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'h'}; 4638*1b8b02a4SEd Tanous } 4639*1b8b02a4SEd Tanous 4640*1b8b02a4SEd Tanous template <class CharT> 4641*1b8b02a4SEd Tanous CONSTCD11 4642*1b8b02a4SEd Tanous inline 4643*1b8b02a4SEd Tanous string_literal<CharT, 2> 4644*1b8b02a4SEd Tanous msl(std::kilo) NOEXCEPT 4645*1b8b02a4SEd Tanous { 4646*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'k'}; 4647*1b8b02a4SEd Tanous } 4648*1b8b02a4SEd Tanous 4649*1b8b02a4SEd Tanous template <class CharT> 4650*1b8b02a4SEd Tanous CONSTCD11 4651*1b8b02a4SEd Tanous inline 4652*1b8b02a4SEd Tanous string_literal<CharT, 2> 4653*1b8b02a4SEd Tanous msl(std::mega) NOEXCEPT 4654*1b8b02a4SEd Tanous { 4655*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'M'}; 4656*1b8b02a4SEd Tanous } 4657*1b8b02a4SEd Tanous 4658*1b8b02a4SEd Tanous template <class CharT> 4659*1b8b02a4SEd Tanous CONSTCD11 4660*1b8b02a4SEd Tanous inline 4661*1b8b02a4SEd Tanous string_literal<CharT, 2> 4662*1b8b02a4SEd Tanous msl(std::giga) NOEXCEPT 4663*1b8b02a4SEd Tanous { 4664*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'G'}; 4665*1b8b02a4SEd Tanous } 4666*1b8b02a4SEd Tanous 4667*1b8b02a4SEd Tanous template <class CharT> 4668*1b8b02a4SEd Tanous CONSTCD11 4669*1b8b02a4SEd Tanous inline 4670*1b8b02a4SEd Tanous string_literal<CharT, 2> 4671*1b8b02a4SEd Tanous msl(std::tera) NOEXCEPT 4672*1b8b02a4SEd Tanous { 4673*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'T'}; 4674*1b8b02a4SEd Tanous } 4675*1b8b02a4SEd Tanous 4676*1b8b02a4SEd Tanous template <class CharT> 4677*1b8b02a4SEd Tanous CONSTCD11 4678*1b8b02a4SEd Tanous inline 4679*1b8b02a4SEd Tanous string_literal<CharT, 2> 4680*1b8b02a4SEd Tanous msl(std::peta) NOEXCEPT 4681*1b8b02a4SEd Tanous { 4682*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'P'}; 4683*1b8b02a4SEd Tanous } 4684*1b8b02a4SEd Tanous 4685*1b8b02a4SEd Tanous template <class CharT> 4686*1b8b02a4SEd Tanous CONSTCD11 4687*1b8b02a4SEd Tanous inline 4688*1b8b02a4SEd Tanous string_literal<CharT, 2> 4689*1b8b02a4SEd Tanous msl(std::exa) NOEXCEPT 4690*1b8b02a4SEd Tanous { 4691*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'E'}; 4692*1b8b02a4SEd Tanous } 4693*1b8b02a4SEd Tanous 4694*1b8b02a4SEd Tanous template <class CharT, class Period> 4695*1b8b02a4SEd Tanous CONSTCD11 4696*1b8b02a4SEd Tanous inline 4697*1b8b02a4SEd Tanous auto 4698*1b8b02a4SEd Tanous get_units(Period p) 4699*1b8b02a4SEd Tanous -> decltype(msl<CharT>(p) + string_literal<CharT, 2>{'s'}) 4700*1b8b02a4SEd Tanous { 4701*1b8b02a4SEd Tanous return msl<CharT>(p) + string_literal<CharT, 2>{'s'}; 4702*1b8b02a4SEd Tanous } 4703*1b8b02a4SEd Tanous 4704*1b8b02a4SEd Tanous template <class CharT> 4705*1b8b02a4SEd Tanous CONSTCD11 4706*1b8b02a4SEd Tanous inline 4707*1b8b02a4SEd Tanous string_literal<CharT, 2> 4708*1b8b02a4SEd Tanous get_units(std::ratio<1>) 4709*1b8b02a4SEd Tanous { 4710*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'s'}; 4711*1b8b02a4SEd Tanous } 4712*1b8b02a4SEd Tanous 4713*1b8b02a4SEd Tanous template <class CharT> 4714*1b8b02a4SEd Tanous CONSTCD11 4715*1b8b02a4SEd Tanous inline 4716*1b8b02a4SEd Tanous string_literal<CharT, 2> 4717*1b8b02a4SEd Tanous get_units(std::ratio<3600>) 4718*1b8b02a4SEd Tanous { 4719*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'h'}; 4720*1b8b02a4SEd Tanous } 4721*1b8b02a4SEd Tanous 4722*1b8b02a4SEd Tanous template <class CharT> 4723*1b8b02a4SEd Tanous CONSTCD11 4724*1b8b02a4SEd Tanous inline 4725*1b8b02a4SEd Tanous string_literal<CharT, 4> 4726*1b8b02a4SEd Tanous get_units(std::ratio<60>) 4727*1b8b02a4SEd Tanous { 4728*1b8b02a4SEd Tanous return string_literal<CharT, 4>{'m', 'i', 'n'}; 4729*1b8b02a4SEd Tanous } 4730*1b8b02a4SEd Tanous 4731*1b8b02a4SEd Tanous template <class CharT> 4732*1b8b02a4SEd Tanous CONSTCD11 4733*1b8b02a4SEd Tanous inline 4734*1b8b02a4SEd Tanous string_literal<CharT, 2> 4735*1b8b02a4SEd Tanous get_units(std::ratio<86400>) 4736*1b8b02a4SEd Tanous { 4737*1b8b02a4SEd Tanous return string_literal<CharT, 2>{'d'}; 4738*1b8b02a4SEd Tanous } 4739*1b8b02a4SEd Tanous 4740*1b8b02a4SEd Tanous template <class CharT, class Traits = std::char_traits<CharT>> 4741*1b8b02a4SEd Tanous struct make_string; 4742*1b8b02a4SEd Tanous 4743*1b8b02a4SEd Tanous template <> 4744*1b8b02a4SEd Tanous struct make_string<char> 4745*1b8b02a4SEd Tanous { 4746*1b8b02a4SEd Tanous template <class Rep> 4747*1b8b02a4SEd Tanous static 4748*1b8b02a4SEd Tanous std::string 4749*1b8b02a4SEd Tanous from(Rep n) 4750*1b8b02a4SEd Tanous { 4751*1b8b02a4SEd Tanous return std::to_string(n); 4752*1b8b02a4SEd Tanous } 4753*1b8b02a4SEd Tanous }; 4754*1b8b02a4SEd Tanous 4755*1b8b02a4SEd Tanous template <class Traits> 4756*1b8b02a4SEd Tanous struct make_string<char, Traits> 4757*1b8b02a4SEd Tanous { 4758*1b8b02a4SEd Tanous template <class Rep> 4759*1b8b02a4SEd Tanous static 4760*1b8b02a4SEd Tanous std::basic_string<char, Traits> 4761*1b8b02a4SEd Tanous from(Rep n) 4762*1b8b02a4SEd Tanous { 4763*1b8b02a4SEd Tanous auto s = std::to_string(n); 4764*1b8b02a4SEd Tanous return std::basic_string<char, Traits>(s.begin(), s.end()); 4765*1b8b02a4SEd Tanous } 4766*1b8b02a4SEd Tanous }; 4767*1b8b02a4SEd Tanous 4768*1b8b02a4SEd Tanous template <> 4769*1b8b02a4SEd Tanous struct make_string<wchar_t> 4770*1b8b02a4SEd Tanous { 4771*1b8b02a4SEd Tanous template <class Rep> 4772*1b8b02a4SEd Tanous static 4773*1b8b02a4SEd Tanous std::wstring 4774*1b8b02a4SEd Tanous from(Rep n) 4775*1b8b02a4SEd Tanous { 4776*1b8b02a4SEd Tanous return std::to_wstring(n); 4777*1b8b02a4SEd Tanous } 4778*1b8b02a4SEd Tanous }; 4779*1b8b02a4SEd Tanous 4780*1b8b02a4SEd Tanous template <class Traits> 4781*1b8b02a4SEd Tanous struct make_string<wchar_t, Traits> 4782*1b8b02a4SEd Tanous { 4783*1b8b02a4SEd Tanous template <class Rep> 4784*1b8b02a4SEd Tanous static 4785*1b8b02a4SEd Tanous std::basic_string<wchar_t, Traits> 4786*1b8b02a4SEd Tanous from(Rep n) 4787*1b8b02a4SEd Tanous { 4788*1b8b02a4SEd Tanous auto s = std::to_wstring(n); 4789*1b8b02a4SEd Tanous return std::basic_string<wchar_t, Traits>(s.begin(), s.end()); 4790*1b8b02a4SEd Tanous } 4791*1b8b02a4SEd Tanous }; 4792*1b8b02a4SEd Tanous 4793*1b8b02a4SEd Tanous } // namespace detail 4794*1b8b02a4SEd Tanous 4795*1b8b02a4SEd Tanous // to_stream 4796*1b8b02a4SEd Tanous 4797*1b8b02a4SEd Tanous CONSTDATA year nanyear{-32768}; 4798*1b8b02a4SEd Tanous 4799*1b8b02a4SEd Tanous template <class Duration> 4800*1b8b02a4SEd Tanous struct fields 4801*1b8b02a4SEd Tanous { 4802*1b8b02a4SEd Tanous year_month_day ymd{nanyear/0/0}; 4803*1b8b02a4SEd Tanous weekday wd{8u}; 4804*1b8b02a4SEd Tanous hh_mm_ss<Duration> tod{}; 4805*1b8b02a4SEd Tanous bool has_tod = false; 4806*1b8b02a4SEd Tanous 4807*1b8b02a4SEd Tanous #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ <= 409) 4808*1b8b02a4SEd Tanous fields() : ymd{nanyear/0/0}, wd{8u}, tod{}, has_tod{false} {} 4809*1b8b02a4SEd Tanous #else 4810*1b8b02a4SEd Tanous fields() = default; 4811*1b8b02a4SEd Tanous #endif 4812*1b8b02a4SEd Tanous 4813*1b8b02a4SEd Tanous fields(year_month_day ymd_) : ymd(ymd_) {} 4814*1b8b02a4SEd Tanous fields(weekday wd_) : wd(wd_) {} 4815*1b8b02a4SEd Tanous fields(hh_mm_ss<Duration> tod_) : tod(tod_), has_tod(true) {} 4816*1b8b02a4SEd Tanous 4817*1b8b02a4SEd Tanous fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {} 4818*1b8b02a4SEd Tanous fields(year_month_day ymd_, hh_mm_ss<Duration> tod_) : ymd(ymd_), tod(tod_), 4819*1b8b02a4SEd Tanous has_tod(true) {} 4820*1b8b02a4SEd Tanous 4821*1b8b02a4SEd Tanous fields(weekday wd_, hh_mm_ss<Duration> tod_) : wd(wd_), tod(tod_), has_tod(true) {} 4822*1b8b02a4SEd Tanous 4823*1b8b02a4SEd Tanous fields(year_month_day ymd_, weekday wd_, hh_mm_ss<Duration> tod_) 4824*1b8b02a4SEd Tanous : ymd(ymd_) 4825*1b8b02a4SEd Tanous , wd(wd_) 4826*1b8b02a4SEd Tanous , tod(tod_) 4827*1b8b02a4SEd Tanous , has_tod(true) 4828*1b8b02a4SEd Tanous {} 4829*1b8b02a4SEd Tanous }; 4830*1b8b02a4SEd Tanous 4831*1b8b02a4SEd Tanous namespace detail 4832*1b8b02a4SEd Tanous { 4833*1b8b02a4SEd Tanous 4834*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 4835*1b8b02a4SEd Tanous unsigned 4836*1b8b02a4SEd Tanous extract_weekday(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds) 4837*1b8b02a4SEd Tanous { 4838*1b8b02a4SEd Tanous if (!fds.ymd.ok() && !fds.wd.ok()) 4839*1b8b02a4SEd Tanous { 4840*1b8b02a4SEd Tanous // fds does not contain a valid weekday 4841*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 4842*1b8b02a4SEd Tanous return 8; 4843*1b8b02a4SEd Tanous } 4844*1b8b02a4SEd Tanous weekday wd; 4845*1b8b02a4SEd Tanous if (fds.ymd.ok()) 4846*1b8b02a4SEd Tanous { 4847*1b8b02a4SEd Tanous wd = weekday{sys_days(fds.ymd)}; 4848*1b8b02a4SEd Tanous if (fds.wd.ok() && wd != fds.wd) 4849*1b8b02a4SEd Tanous { 4850*1b8b02a4SEd Tanous // fds.ymd and fds.wd are inconsistent 4851*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 4852*1b8b02a4SEd Tanous return 8; 4853*1b8b02a4SEd Tanous } 4854*1b8b02a4SEd Tanous } 4855*1b8b02a4SEd Tanous else 4856*1b8b02a4SEd Tanous wd = fds.wd; 4857*1b8b02a4SEd Tanous return static_cast<unsigned>((wd - Sunday).count()); 4858*1b8b02a4SEd Tanous } 4859*1b8b02a4SEd Tanous 4860*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 4861*1b8b02a4SEd Tanous unsigned 4862*1b8b02a4SEd Tanous extract_month(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds) 4863*1b8b02a4SEd Tanous { 4864*1b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 4865*1b8b02a4SEd Tanous { 4866*1b8b02a4SEd Tanous // fds does not contain a valid month 4867*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 4868*1b8b02a4SEd Tanous return 0; 4869*1b8b02a4SEd Tanous } 4870*1b8b02a4SEd Tanous return static_cast<unsigned>(fds.ymd.month()); 4871*1b8b02a4SEd Tanous } 4872*1b8b02a4SEd Tanous 4873*1b8b02a4SEd Tanous } // namespace detail 4874*1b8b02a4SEd Tanous 4875*1b8b02a4SEd Tanous #if ONLY_C_LOCALE 4876*1b8b02a4SEd Tanous 4877*1b8b02a4SEd Tanous namespace detail 4878*1b8b02a4SEd Tanous { 4879*1b8b02a4SEd Tanous 4880*1b8b02a4SEd Tanous inline 4881*1b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 4882*1b8b02a4SEd Tanous weekday_names() 4883*1b8b02a4SEd Tanous { 4884*1b8b02a4SEd Tanous static const std::string nm[] = 4885*1b8b02a4SEd Tanous { 4886*1b8b02a4SEd Tanous "Sunday", 4887*1b8b02a4SEd Tanous "Monday", 4888*1b8b02a4SEd Tanous "Tuesday", 4889*1b8b02a4SEd Tanous "Wednesday", 4890*1b8b02a4SEd Tanous "Thursday", 4891*1b8b02a4SEd Tanous "Friday", 4892*1b8b02a4SEd Tanous "Saturday", 4893*1b8b02a4SEd Tanous "Sun", 4894*1b8b02a4SEd Tanous "Mon", 4895*1b8b02a4SEd Tanous "Tue", 4896*1b8b02a4SEd Tanous "Wed", 4897*1b8b02a4SEd Tanous "Thu", 4898*1b8b02a4SEd Tanous "Fri", 4899*1b8b02a4SEd Tanous "Sat" 4900*1b8b02a4SEd Tanous }; 4901*1b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 4902*1b8b02a4SEd Tanous } 4903*1b8b02a4SEd Tanous 4904*1b8b02a4SEd Tanous inline 4905*1b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 4906*1b8b02a4SEd Tanous month_names() 4907*1b8b02a4SEd Tanous { 4908*1b8b02a4SEd Tanous static const std::string nm[] = 4909*1b8b02a4SEd Tanous { 4910*1b8b02a4SEd Tanous "January", 4911*1b8b02a4SEd Tanous "February", 4912*1b8b02a4SEd Tanous "March", 4913*1b8b02a4SEd Tanous "April", 4914*1b8b02a4SEd Tanous "May", 4915*1b8b02a4SEd Tanous "June", 4916*1b8b02a4SEd Tanous "July", 4917*1b8b02a4SEd Tanous "August", 4918*1b8b02a4SEd Tanous "September", 4919*1b8b02a4SEd Tanous "October", 4920*1b8b02a4SEd Tanous "November", 4921*1b8b02a4SEd Tanous "December", 4922*1b8b02a4SEd Tanous "Jan", 4923*1b8b02a4SEd Tanous "Feb", 4924*1b8b02a4SEd Tanous "Mar", 4925*1b8b02a4SEd Tanous "Apr", 4926*1b8b02a4SEd Tanous "May", 4927*1b8b02a4SEd Tanous "Jun", 4928*1b8b02a4SEd Tanous "Jul", 4929*1b8b02a4SEd Tanous "Aug", 4930*1b8b02a4SEd Tanous "Sep", 4931*1b8b02a4SEd Tanous "Oct", 4932*1b8b02a4SEd Tanous "Nov", 4933*1b8b02a4SEd Tanous "Dec" 4934*1b8b02a4SEd Tanous }; 4935*1b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 4936*1b8b02a4SEd Tanous } 4937*1b8b02a4SEd Tanous 4938*1b8b02a4SEd Tanous inline 4939*1b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 4940*1b8b02a4SEd Tanous ampm_names() 4941*1b8b02a4SEd Tanous { 4942*1b8b02a4SEd Tanous static const std::string nm[] = 4943*1b8b02a4SEd Tanous { 4944*1b8b02a4SEd Tanous "AM", 4945*1b8b02a4SEd Tanous "PM" 4946*1b8b02a4SEd Tanous }; 4947*1b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 4948*1b8b02a4SEd Tanous } 4949*1b8b02a4SEd Tanous 4950*1b8b02a4SEd Tanous template <class CharT, class Traits, class FwdIter> 4951*1b8b02a4SEd Tanous FwdIter 4952*1b8b02a4SEd Tanous scan_keyword(std::basic_istream<CharT, Traits>& is, FwdIter kb, FwdIter ke) 4953*1b8b02a4SEd Tanous { 4954*1b8b02a4SEd Tanous size_t nkw = static_cast<size_t>(std::distance(kb, ke)); 4955*1b8b02a4SEd Tanous const unsigned char doesnt_match = '\0'; 4956*1b8b02a4SEd Tanous const unsigned char might_match = '\1'; 4957*1b8b02a4SEd Tanous const unsigned char does_match = '\2'; 4958*1b8b02a4SEd Tanous unsigned char statbuf[100]; 4959*1b8b02a4SEd Tanous unsigned char* status = statbuf; 4960*1b8b02a4SEd Tanous std::unique_ptr<unsigned char, void(*)(void*)> stat_hold(0, free); 4961*1b8b02a4SEd Tanous if (nkw > sizeof(statbuf)) 4962*1b8b02a4SEd Tanous { 4963*1b8b02a4SEd Tanous status = (unsigned char*)std::malloc(nkw); 4964*1b8b02a4SEd Tanous if (status == nullptr) 4965*1b8b02a4SEd Tanous std::terminate(); 4966*1b8b02a4SEd Tanous stat_hold.reset(status); 4967*1b8b02a4SEd Tanous } 4968*1b8b02a4SEd Tanous size_t n_might_match = nkw; // At this point, any keyword might match 4969*1b8b02a4SEd Tanous size_t n_does_match = 0; // but none of them definitely do 4970*1b8b02a4SEd Tanous // Initialize all statuses to might_match, except for "" keywords are does_match 4971*1b8b02a4SEd Tanous unsigned char* st = status; 4972*1b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 4973*1b8b02a4SEd Tanous { 4974*1b8b02a4SEd Tanous if (!ky->empty()) 4975*1b8b02a4SEd Tanous *st = might_match; 4976*1b8b02a4SEd Tanous else 4977*1b8b02a4SEd Tanous { 4978*1b8b02a4SEd Tanous *st = does_match; 4979*1b8b02a4SEd Tanous --n_might_match; 4980*1b8b02a4SEd Tanous ++n_does_match; 4981*1b8b02a4SEd Tanous } 4982*1b8b02a4SEd Tanous } 4983*1b8b02a4SEd Tanous // While there might be a match, test keywords against the next CharT 4984*1b8b02a4SEd Tanous for (size_t indx = 0; is && n_might_match > 0; ++indx) 4985*1b8b02a4SEd Tanous { 4986*1b8b02a4SEd Tanous // Peek at the next CharT but don't consume it 4987*1b8b02a4SEd Tanous auto ic = is.peek(); 4988*1b8b02a4SEd Tanous if (ic == EOF) 4989*1b8b02a4SEd Tanous { 4990*1b8b02a4SEd Tanous is.setstate(std::ios::eofbit); 4991*1b8b02a4SEd Tanous break; 4992*1b8b02a4SEd Tanous } 4993*1b8b02a4SEd Tanous auto c = static_cast<char>(toupper(static_cast<unsigned char>(ic))); 4994*1b8b02a4SEd Tanous bool consume = false; 4995*1b8b02a4SEd Tanous // For each keyword which might match, see if the indx character is c 4996*1b8b02a4SEd Tanous // If a match if found, consume c 4997*1b8b02a4SEd Tanous // If a match is found, and that is the last character in the keyword, 4998*1b8b02a4SEd Tanous // then that keyword matches. 4999*1b8b02a4SEd Tanous // If the keyword doesn't match this character, then change the keyword 5000*1b8b02a4SEd Tanous // to doesn't match 5001*1b8b02a4SEd Tanous st = status; 5002*1b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 5003*1b8b02a4SEd Tanous { 5004*1b8b02a4SEd Tanous if (*st == might_match) 5005*1b8b02a4SEd Tanous { 5006*1b8b02a4SEd Tanous if (c == static_cast<char>(toupper(static_cast<unsigned char>((*ky)[indx])))) 5007*1b8b02a4SEd Tanous { 5008*1b8b02a4SEd Tanous consume = true; 5009*1b8b02a4SEd Tanous if (ky->size() == indx+1) 5010*1b8b02a4SEd Tanous { 5011*1b8b02a4SEd Tanous *st = does_match; 5012*1b8b02a4SEd Tanous --n_might_match; 5013*1b8b02a4SEd Tanous ++n_does_match; 5014*1b8b02a4SEd Tanous } 5015*1b8b02a4SEd Tanous } 5016*1b8b02a4SEd Tanous else 5017*1b8b02a4SEd Tanous { 5018*1b8b02a4SEd Tanous *st = doesnt_match; 5019*1b8b02a4SEd Tanous --n_might_match; 5020*1b8b02a4SEd Tanous } 5021*1b8b02a4SEd Tanous } 5022*1b8b02a4SEd Tanous } 5023*1b8b02a4SEd Tanous // consume if we matched a character 5024*1b8b02a4SEd Tanous if (consume) 5025*1b8b02a4SEd Tanous { 5026*1b8b02a4SEd Tanous (void)is.get(); 5027*1b8b02a4SEd Tanous // If we consumed a character and there might be a matched keyword that 5028*1b8b02a4SEd Tanous // was marked matched on a previous iteration, then such keywords 5029*1b8b02a4SEd Tanous // are now marked as not matching. 5030*1b8b02a4SEd Tanous if (n_might_match + n_does_match > 1) 5031*1b8b02a4SEd Tanous { 5032*1b8b02a4SEd Tanous st = status; 5033*1b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 5034*1b8b02a4SEd Tanous { 5035*1b8b02a4SEd Tanous if (*st == does_match && ky->size() != indx+1) 5036*1b8b02a4SEd Tanous { 5037*1b8b02a4SEd Tanous *st = doesnt_match; 5038*1b8b02a4SEd Tanous --n_does_match; 5039*1b8b02a4SEd Tanous } 5040*1b8b02a4SEd Tanous } 5041*1b8b02a4SEd Tanous } 5042*1b8b02a4SEd Tanous } 5043*1b8b02a4SEd Tanous } 5044*1b8b02a4SEd Tanous // We've exited the loop because we hit eof and/or we have no more "might matches". 5045*1b8b02a4SEd Tanous // Return the first matching result 5046*1b8b02a4SEd Tanous for (st = status; kb != ke; ++kb, ++st) 5047*1b8b02a4SEd Tanous if (*st == does_match) 5048*1b8b02a4SEd Tanous break; 5049*1b8b02a4SEd Tanous if (kb == ke) 5050*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 5051*1b8b02a4SEd Tanous return kb; 5052*1b8b02a4SEd Tanous } 5053*1b8b02a4SEd Tanous 5054*1b8b02a4SEd Tanous } // namespace detail 5055*1b8b02a4SEd Tanous 5056*1b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 5057*1b8b02a4SEd Tanous 5058*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 5059*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 5060*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 5061*1b8b02a4SEd Tanous const fields<Duration>& fds, const std::string* abbrev, 5062*1b8b02a4SEd Tanous const std::chrono::seconds* offset_sec) 5063*1b8b02a4SEd Tanous { 5064*1b8b02a4SEd Tanous #if ONLY_C_LOCALE 5065*1b8b02a4SEd Tanous using detail::weekday_names; 5066*1b8b02a4SEd Tanous using detail::month_names; 5067*1b8b02a4SEd Tanous using detail::ampm_names; 5068*1b8b02a4SEd Tanous #endif 5069*1b8b02a4SEd Tanous using detail::save_ostream; 5070*1b8b02a4SEd Tanous using detail::get_units; 5071*1b8b02a4SEd Tanous using detail::extract_weekday; 5072*1b8b02a4SEd Tanous using detail::extract_month; 5073*1b8b02a4SEd Tanous using std::ios; 5074*1b8b02a4SEd Tanous using std::chrono::duration_cast; 5075*1b8b02a4SEd Tanous using std::chrono::seconds; 5076*1b8b02a4SEd Tanous using std::chrono::minutes; 5077*1b8b02a4SEd Tanous using std::chrono::hours; 5078*1b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> ss(os); 5079*1b8b02a4SEd Tanous os.fill(' '); 5080*1b8b02a4SEd Tanous os.flags(std::ios::skipws | std::ios::dec); 5081*1b8b02a4SEd Tanous os.width(0); 5082*1b8b02a4SEd Tanous tm tm{}; 5083*1b8b02a4SEd Tanous bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero(); 5084*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5085*1b8b02a4SEd Tanous auto& facet = std::use_facet<std::time_put<CharT>>(os.getloc()); 5086*1b8b02a4SEd Tanous #endif 5087*1b8b02a4SEd Tanous const CharT* command = nullptr; 5088*1b8b02a4SEd Tanous CharT modified = CharT{}; 5089*1b8b02a4SEd Tanous for (; *fmt; ++fmt) 5090*1b8b02a4SEd Tanous { 5091*1b8b02a4SEd Tanous switch (*fmt) 5092*1b8b02a4SEd Tanous { 5093*1b8b02a4SEd Tanous case 'a': 5094*1b8b02a4SEd Tanous case 'A': 5095*1b8b02a4SEd Tanous if (command) 5096*1b8b02a4SEd Tanous { 5097*1b8b02a4SEd Tanous if (modified == CharT{}) 5098*1b8b02a4SEd Tanous { 5099*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 5100*1b8b02a4SEd Tanous if (os.fail()) 5101*1b8b02a4SEd Tanous return os; 5102*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5103*1b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 5104*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5105*1b8b02a4SEd Tanous #else // ONLY_C_LOCALE 5106*1b8b02a4SEd Tanous os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')]; 5107*1b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 5108*1b8b02a4SEd Tanous } 5109*1b8b02a4SEd Tanous else 5110*1b8b02a4SEd Tanous { 5111*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5112*1b8b02a4SEd Tanous modified = CharT{}; 5113*1b8b02a4SEd Tanous } 5114*1b8b02a4SEd Tanous command = nullptr; 5115*1b8b02a4SEd Tanous } 5116*1b8b02a4SEd Tanous else 5117*1b8b02a4SEd Tanous os << *fmt; 5118*1b8b02a4SEd Tanous break; 5119*1b8b02a4SEd Tanous case 'b': 5120*1b8b02a4SEd Tanous case 'B': 5121*1b8b02a4SEd Tanous case 'h': 5122*1b8b02a4SEd Tanous if (command) 5123*1b8b02a4SEd Tanous { 5124*1b8b02a4SEd Tanous if (modified == CharT{}) 5125*1b8b02a4SEd Tanous { 5126*1b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(extract_month(os, fds)) - 1; 5127*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5128*1b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 5129*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5130*1b8b02a4SEd Tanous #else // ONLY_C_LOCALE 5131*1b8b02a4SEd Tanous os << month_names().first[tm.tm_mon+12*(*fmt != 'B')]; 5132*1b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 5133*1b8b02a4SEd Tanous } 5134*1b8b02a4SEd Tanous else 5135*1b8b02a4SEd Tanous { 5136*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5137*1b8b02a4SEd Tanous modified = CharT{}; 5138*1b8b02a4SEd Tanous } 5139*1b8b02a4SEd Tanous command = nullptr; 5140*1b8b02a4SEd Tanous } 5141*1b8b02a4SEd Tanous else 5142*1b8b02a4SEd Tanous os << *fmt; 5143*1b8b02a4SEd Tanous break; 5144*1b8b02a4SEd Tanous case 'c': 5145*1b8b02a4SEd Tanous case 'x': 5146*1b8b02a4SEd Tanous if (command) 5147*1b8b02a4SEd Tanous { 5148*1b8b02a4SEd Tanous if (modified == CharT{'O'}) 5149*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5150*1b8b02a4SEd Tanous else 5151*1b8b02a4SEd Tanous { 5152*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 5153*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5154*1b8b02a4SEd Tanous if (*fmt == 'c' && !fds.has_tod) 5155*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5156*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5157*1b8b02a4SEd Tanous tm = std::tm{}; 5158*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5159*1b8b02a4SEd Tanous auto ld = local_days(ymd); 5160*1b8b02a4SEd Tanous if (*fmt == 'c') 5161*1b8b02a4SEd Tanous { 5162*1b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 5163*1b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 5164*1b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 5165*1b8b02a4SEd Tanous } 5166*1b8b02a4SEd Tanous tm.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day())); 5167*1b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(extract_month(os, fds) - 1); 5168*1b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 5169*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 5170*1b8b02a4SEd Tanous if (os.fail()) 5171*1b8b02a4SEd Tanous return os; 5172*1b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 5173*1b8b02a4SEd Tanous CharT f[3] = {'%'}; 5174*1b8b02a4SEd Tanous auto fe = std::begin(f) + 1; 5175*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5176*1b8b02a4SEd Tanous *fe++ = modified; 5177*1b8b02a4SEd Tanous *fe++ = *fmt; 5178*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), fe); 5179*1b8b02a4SEd Tanous #else // ONLY_C_LOCALE 5180*1b8b02a4SEd Tanous if (*fmt == 'c') 5181*1b8b02a4SEd Tanous { 5182*1b8b02a4SEd Tanous auto wd = static_cast<int>(extract_weekday(os, fds)); 5183*1b8b02a4SEd Tanous os << weekday_names().first[static_cast<unsigned>(wd)+7] 5184*1b8b02a4SEd Tanous << ' '; 5185*1b8b02a4SEd Tanous os << month_names().first[extract_month(os, fds)-1+12] << ' '; 5186*1b8b02a4SEd Tanous auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day())); 5187*1b8b02a4SEd Tanous if (d < 10) 5188*1b8b02a4SEd Tanous os << ' '; 5189*1b8b02a4SEd Tanous os << d << ' ' 5190*1b8b02a4SEd Tanous << make_time(duration_cast<seconds>(fds.tod.to_duration())) 5191*1b8b02a4SEd Tanous << ' ' << fds.ymd.year(); 5192*1b8b02a4SEd Tanous 5193*1b8b02a4SEd Tanous } 5194*1b8b02a4SEd Tanous else // *fmt == 'x' 5195*1b8b02a4SEd Tanous { 5196*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5197*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5198*1b8b02a4SEd Tanous os.fill('0'); 5199*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5200*1b8b02a4SEd Tanous os.width(2); 5201*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'/'}; 5202*1b8b02a4SEd Tanous os.width(2); 5203*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()) << CharT{'/'}; 5204*1b8b02a4SEd Tanous os.width(2); 5205*1b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) % 100; 5206*1b8b02a4SEd Tanous } 5207*1b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 5208*1b8b02a4SEd Tanous } 5209*1b8b02a4SEd Tanous command = nullptr; 5210*1b8b02a4SEd Tanous modified = CharT{}; 5211*1b8b02a4SEd Tanous } 5212*1b8b02a4SEd Tanous else 5213*1b8b02a4SEd Tanous os << *fmt; 5214*1b8b02a4SEd Tanous break; 5215*1b8b02a4SEd Tanous case 'C': 5216*1b8b02a4SEd Tanous if (command) 5217*1b8b02a4SEd Tanous { 5218*1b8b02a4SEd Tanous if (modified == CharT{'O'}) 5219*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5220*1b8b02a4SEd Tanous else 5221*1b8b02a4SEd Tanous { 5222*1b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 5223*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5224*1b8b02a4SEd Tanous auto y = static_cast<int>(fds.ymd.year()); 5225*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5226*1b8b02a4SEd Tanous if (modified == CharT{}) 5227*1b8b02a4SEd Tanous #endif 5228*1b8b02a4SEd Tanous { 5229*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5230*1b8b02a4SEd Tanous os.fill('0'); 5231*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5232*1b8b02a4SEd Tanous if (y >= 0) 5233*1b8b02a4SEd Tanous { 5234*1b8b02a4SEd Tanous os.width(2); 5235*1b8b02a4SEd Tanous os << y/100; 5236*1b8b02a4SEd Tanous } 5237*1b8b02a4SEd Tanous else 5238*1b8b02a4SEd Tanous { 5239*1b8b02a4SEd Tanous os << CharT{'-'}; 5240*1b8b02a4SEd Tanous os.width(2); 5241*1b8b02a4SEd Tanous os << -(y-99)/100; 5242*1b8b02a4SEd Tanous } 5243*1b8b02a4SEd Tanous } 5244*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5245*1b8b02a4SEd Tanous else if (modified == CharT{'E'}) 5246*1b8b02a4SEd Tanous { 5247*1b8b02a4SEd Tanous tm.tm_year = y - 1900; 5248*1b8b02a4SEd Tanous CharT f[3] = {'%', 'E', 'C'}; 5249*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5250*1b8b02a4SEd Tanous } 5251*1b8b02a4SEd Tanous #endif 5252*1b8b02a4SEd Tanous } 5253*1b8b02a4SEd Tanous command = nullptr; 5254*1b8b02a4SEd Tanous modified = CharT{}; 5255*1b8b02a4SEd Tanous } 5256*1b8b02a4SEd Tanous else 5257*1b8b02a4SEd Tanous os << *fmt; 5258*1b8b02a4SEd Tanous break; 5259*1b8b02a4SEd Tanous case 'd': 5260*1b8b02a4SEd Tanous case 'e': 5261*1b8b02a4SEd Tanous if (command) 5262*1b8b02a4SEd Tanous { 5263*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5264*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5265*1b8b02a4SEd Tanous else 5266*1b8b02a4SEd Tanous { 5267*1b8b02a4SEd Tanous if (!fds.ymd.day().ok()) 5268*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5269*1b8b02a4SEd Tanous auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day())); 5270*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5271*1b8b02a4SEd Tanous if (modified == CharT{}) 5272*1b8b02a4SEd Tanous #endif 5273*1b8b02a4SEd Tanous { 5274*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5275*1b8b02a4SEd Tanous if (*fmt == CharT{'d'}) 5276*1b8b02a4SEd Tanous os.fill('0'); 5277*1b8b02a4SEd Tanous else 5278*1b8b02a4SEd Tanous os.fill(' '); 5279*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5280*1b8b02a4SEd Tanous os.width(2); 5281*1b8b02a4SEd Tanous os << d; 5282*1b8b02a4SEd Tanous } 5283*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5284*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5285*1b8b02a4SEd Tanous { 5286*1b8b02a4SEd Tanous tm.tm_mday = d; 5287*1b8b02a4SEd Tanous CharT f[3] = {'%', 'O', *fmt}; 5288*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5289*1b8b02a4SEd Tanous } 5290*1b8b02a4SEd Tanous #endif 5291*1b8b02a4SEd Tanous } 5292*1b8b02a4SEd Tanous command = nullptr; 5293*1b8b02a4SEd Tanous modified = CharT{}; 5294*1b8b02a4SEd Tanous } 5295*1b8b02a4SEd Tanous else 5296*1b8b02a4SEd Tanous os << *fmt; 5297*1b8b02a4SEd Tanous break; 5298*1b8b02a4SEd Tanous case 'D': 5299*1b8b02a4SEd Tanous if (command) 5300*1b8b02a4SEd Tanous { 5301*1b8b02a4SEd Tanous if (modified == CharT{}) 5302*1b8b02a4SEd Tanous { 5303*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 5304*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5305*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5306*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5307*1b8b02a4SEd Tanous os.fill('0'); 5308*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5309*1b8b02a4SEd Tanous os.width(2); 5310*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'/'}; 5311*1b8b02a4SEd Tanous os.width(2); 5312*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()) << CharT{'/'}; 5313*1b8b02a4SEd Tanous os.width(2); 5314*1b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) % 100; 5315*1b8b02a4SEd Tanous } 5316*1b8b02a4SEd Tanous else 5317*1b8b02a4SEd Tanous { 5318*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5319*1b8b02a4SEd Tanous modified = CharT{}; 5320*1b8b02a4SEd Tanous } 5321*1b8b02a4SEd Tanous command = nullptr; 5322*1b8b02a4SEd Tanous } 5323*1b8b02a4SEd Tanous else 5324*1b8b02a4SEd Tanous os << *fmt; 5325*1b8b02a4SEd Tanous break; 5326*1b8b02a4SEd Tanous case 'F': 5327*1b8b02a4SEd Tanous if (command) 5328*1b8b02a4SEd Tanous { 5329*1b8b02a4SEd Tanous if (modified == CharT{}) 5330*1b8b02a4SEd Tanous { 5331*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 5332*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5333*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5334*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5335*1b8b02a4SEd Tanous os.imbue(std::locale::classic()); 5336*1b8b02a4SEd Tanous os.fill('0'); 5337*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5338*1b8b02a4SEd Tanous os.width(4); 5339*1b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) << CharT{'-'}; 5340*1b8b02a4SEd Tanous os.width(2); 5341*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'-'}; 5342*1b8b02a4SEd Tanous os.width(2); 5343*1b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()); 5344*1b8b02a4SEd Tanous } 5345*1b8b02a4SEd Tanous else 5346*1b8b02a4SEd Tanous { 5347*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5348*1b8b02a4SEd Tanous modified = CharT{}; 5349*1b8b02a4SEd Tanous } 5350*1b8b02a4SEd Tanous command = nullptr; 5351*1b8b02a4SEd Tanous } 5352*1b8b02a4SEd Tanous else 5353*1b8b02a4SEd Tanous os << *fmt; 5354*1b8b02a4SEd Tanous break; 5355*1b8b02a4SEd Tanous case 'g': 5356*1b8b02a4SEd Tanous case 'G': 5357*1b8b02a4SEd Tanous if (command) 5358*1b8b02a4SEd Tanous { 5359*1b8b02a4SEd Tanous if (modified == CharT{}) 5360*1b8b02a4SEd Tanous { 5361*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 5362*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5363*1b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 5364*1b8b02a4SEd Tanous auto y = year_month_day{ld + days{3}}.year(); 5365*1b8b02a4SEd Tanous auto start = local_days((y-years{1})/December/Thursday[last]) + 5366*1b8b02a4SEd Tanous (Monday-Thursday); 5367*1b8b02a4SEd Tanous if (ld < start) 5368*1b8b02a4SEd Tanous --y; 5369*1b8b02a4SEd Tanous if (*fmt == CharT{'G'}) 5370*1b8b02a4SEd Tanous os << y; 5371*1b8b02a4SEd Tanous else 5372*1b8b02a4SEd Tanous { 5373*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5374*1b8b02a4SEd Tanous os.fill('0'); 5375*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5376*1b8b02a4SEd Tanous os.width(2); 5377*1b8b02a4SEd Tanous os << std::abs(static_cast<int>(y)) % 100; 5378*1b8b02a4SEd Tanous } 5379*1b8b02a4SEd Tanous } 5380*1b8b02a4SEd Tanous else 5381*1b8b02a4SEd Tanous { 5382*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5383*1b8b02a4SEd Tanous modified = CharT{}; 5384*1b8b02a4SEd Tanous } 5385*1b8b02a4SEd Tanous command = nullptr; 5386*1b8b02a4SEd Tanous } 5387*1b8b02a4SEd Tanous else 5388*1b8b02a4SEd Tanous os << *fmt; 5389*1b8b02a4SEd Tanous break; 5390*1b8b02a4SEd Tanous case 'H': 5391*1b8b02a4SEd Tanous case 'I': 5392*1b8b02a4SEd Tanous if (command) 5393*1b8b02a4SEd Tanous { 5394*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5395*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5396*1b8b02a4SEd Tanous else 5397*1b8b02a4SEd Tanous { 5398*1b8b02a4SEd Tanous if (!fds.has_tod) 5399*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5400*1b8b02a4SEd Tanous if (insert_negative) 5401*1b8b02a4SEd Tanous { 5402*1b8b02a4SEd Tanous os << '-'; 5403*1b8b02a4SEd Tanous insert_negative = false; 5404*1b8b02a4SEd Tanous } 5405*1b8b02a4SEd Tanous auto hms = fds.tod; 5406*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5407*1b8b02a4SEd Tanous if (modified == CharT{}) 5408*1b8b02a4SEd Tanous #endif 5409*1b8b02a4SEd Tanous { 5410*1b8b02a4SEd Tanous auto h = *fmt == CharT{'I'} ? date::make12(hms.hours()) : hms.hours(); 5411*1b8b02a4SEd Tanous if (h < hours{10}) 5412*1b8b02a4SEd Tanous os << CharT{'0'}; 5413*1b8b02a4SEd Tanous os << h.count(); 5414*1b8b02a4SEd Tanous } 5415*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5416*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5417*1b8b02a4SEd Tanous { 5418*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5419*1b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(hms.hours().count()); 5420*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5421*1b8b02a4SEd Tanous } 5422*1b8b02a4SEd Tanous #endif 5423*1b8b02a4SEd Tanous } 5424*1b8b02a4SEd Tanous modified = CharT{}; 5425*1b8b02a4SEd Tanous command = nullptr; 5426*1b8b02a4SEd Tanous } 5427*1b8b02a4SEd Tanous else 5428*1b8b02a4SEd Tanous os << *fmt; 5429*1b8b02a4SEd Tanous break; 5430*1b8b02a4SEd Tanous case 'j': 5431*1b8b02a4SEd Tanous if (command) 5432*1b8b02a4SEd Tanous { 5433*1b8b02a4SEd Tanous if (modified == CharT{}) 5434*1b8b02a4SEd Tanous { 5435*1b8b02a4SEd Tanous if (fds.ymd.ok() || fds.has_tod) 5436*1b8b02a4SEd Tanous { 5437*1b8b02a4SEd Tanous days doy; 5438*1b8b02a4SEd Tanous if (fds.ymd.ok()) 5439*1b8b02a4SEd Tanous { 5440*1b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 5441*1b8b02a4SEd Tanous auto y = fds.ymd.year(); 5442*1b8b02a4SEd Tanous doy = ld - local_days(y/January/1) + days{1}; 5443*1b8b02a4SEd Tanous } 5444*1b8b02a4SEd Tanous else 5445*1b8b02a4SEd Tanous { 5446*1b8b02a4SEd Tanous doy = duration_cast<days>(fds.tod.to_duration()); 5447*1b8b02a4SEd Tanous } 5448*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5449*1b8b02a4SEd Tanous os.fill('0'); 5450*1b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 5451*1b8b02a4SEd Tanous os.width(3); 5452*1b8b02a4SEd Tanous os << doy.count(); 5453*1b8b02a4SEd Tanous } 5454*1b8b02a4SEd Tanous else 5455*1b8b02a4SEd Tanous { 5456*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5457*1b8b02a4SEd Tanous } 5458*1b8b02a4SEd Tanous } 5459*1b8b02a4SEd Tanous else 5460*1b8b02a4SEd Tanous { 5461*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5462*1b8b02a4SEd Tanous modified = CharT{}; 5463*1b8b02a4SEd Tanous } 5464*1b8b02a4SEd Tanous command = nullptr; 5465*1b8b02a4SEd Tanous } 5466*1b8b02a4SEd Tanous else 5467*1b8b02a4SEd Tanous os << *fmt; 5468*1b8b02a4SEd Tanous break; 5469*1b8b02a4SEd Tanous case 'm': 5470*1b8b02a4SEd Tanous if (command) 5471*1b8b02a4SEd Tanous { 5472*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5473*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5474*1b8b02a4SEd Tanous else 5475*1b8b02a4SEd Tanous { 5476*1b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 5477*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5478*1b8b02a4SEd Tanous auto m = static_cast<unsigned>(fds.ymd.month()); 5479*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5480*1b8b02a4SEd Tanous if (modified == CharT{}) 5481*1b8b02a4SEd Tanous #endif 5482*1b8b02a4SEd Tanous { 5483*1b8b02a4SEd Tanous if (m < 10) 5484*1b8b02a4SEd Tanous os << CharT{'0'}; 5485*1b8b02a4SEd Tanous os << m; 5486*1b8b02a4SEd Tanous } 5487*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5488*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5489*1b8b02a4SEd Tanous { 5490*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5491*1b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(m-1); 5492*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5493*1b8b02a4SEd Tanous } 5494*1b8b02a4SEd Tanous #endif 5495*1b8b02a4SEd Tanous } 5496*1b8b02a4SEd Tanous modified = CharT{}; 5497*1b8b02a4SEd Tanous command = nullptr; 5498*1b8b02a4SEd Tanous } 5499*1b8b02a4SEd Tanous else 5500*1b8b02a4SEd Tanous os << *fmt; 5501*1b8b02a4SEd Tanous break; 5502*1b8b02a4SEd Tanous case 'M': 5503*1b8b02a4SEd Tanous if (command) 5504*1b8b02a4SEd Tanous { 5505*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5506*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5507*1b8b02a4SEd Tanous else 5508*1b8b02a4SEd Tanous { 5509*1b8b02a4SEd Tanous if (!fds.has_tod) 5510*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5511*1b8b02a4SEd Tanous if (insert_negative) 5512*1b8b02a4SEd Tanous { 5513*1b8b02a4SEd Tanous os << '-'; 5514*1b8b02a4SEd Tanous insert_negative = false; 5515*1b8b02a4SEd Tanous } 5516*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5517*1b8b02a4SEd Tanous if (modified == CharT{}) 5518*1b8b02a4SEd Tanous #endif 5519*1b8b02a4SEd Tanous { 5520*1b8b02a4SEd Tanous if (fds.tod.minutes() < minutes{10}) 5521*1b8b02a4SEd Tanous os << CharT{'0'}; 5522*1b8b02a4SEd Tanous os << fds.tod.minutes().count(); 5523*1b8b02a4SEd Tanous } 5524*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5525*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5526*1b8b02a4SEd Tanous { 5527*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5528*1b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 5529*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5530*1b8b02a4SEd Tanous } 5531*1b8b02a4SEd Tanous #endif 5532*1b8b02a4SEd Tanous } 5533*1b8b02a4SEd Tanous modified = CharT{}; 5534*1b8b02a4SEd Tanous command = nullptr; 5535*1b8b02a4SEd Tanous } 5536*1b8b02a4SEd Tanous else 5537*1b8b02a4SEd Tanous os << *fmt; 5538*1b8b02a4SEd Tanous break; 5539*1b8b02a4SEd Tanous case 'n': 5540*1b8b02a4SEd Tanous if (command) 5541*1b8b02a4SEd Tanous { 5542*1b8b02a4SEd Tanous if (modified == CharT{}) 5543*1b8b02a4SEd Tanous os << CharT{'\n'}; 5544*1b8b02a4SEd Tanous else 5545*1b8b02a4SEd Tanous { 5546*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5547*1b8b02a4SEd Tanous modified = CharT{}; 5548*1b8b02a4SEd Tanous } 5549*1b8b02a4SEd Tanous command = nullptr; 5550*1b8b02a4SEd Tanous } 5551*1b8b02a4SEd Tanous else 5552*1b8b02a4SEd Tanous os << *fmt; 5553*1b8b02a4SEd Tanous break; 5554*1b8b02a4SEd Tanous case 'p': 5555*1b8b02a4SEd Tanous if (command) 5556*1b8b02a4SEd Tanous { 5557*1b8b02a4SEd Tanous if (modified == CharT{}) 5558*1b8b02a4SEd Tanous { 5559*1b8b02a4SEd Tanous if (!fds.has_tod) 5560*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5561*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5562*1b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 5563*1b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 5564*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5565*1b8b02a4SEd Tanous #else 5566*1b8b02a4SEd Tanous if (date::is_am(fds.tod.hours())) 5567*1b8b02a4SEd Tanous os << ampm_names().first[0]; 5568*1b8b02a4SEd Tanous else 5569*1b8b02a4SEd Tanous os << ampm_names().first[1]; 5570*1b8b02a4SEd Tanous #endif 5571*1b8b02a4SEd Tanous } 5572*1b8b02a4SEd Tanous else 5573*1b8b02a4SEd Tanous { 5574*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5575*1b8b02a4SEd Tanous } 5576*1b8b02a4SEd Tanous modified = CharT{}; 5577*1b8b02a4SEd Tanous command = nullptr; 5578*1b8b02a4SEd Tanous } 5579*1b8b02a4SEd Tanous else 5580*1b8b02a4SEd Tanous os << *fmt; 5581*1b8b02a4SEd Tanous break; 5582*1b8b02a4SEd Tanous case 'Q': 5583*1b8b02a4SEd Tanous case 'q': 5584*1b8b02a4SEd Tanous if (command) 5585*1b8b02a4SEd Tanous { 5586*1b8b02a4SEd Tanous if (modified == CharT{}) 5587*1b8b02a4SEd Tanous { 5588*1b8b02a4SEd Tanous if (!fds.has_tod) 5589*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5590*1b8b02a4SEd Tanous auto d = fds.tod.to_duration(); 5591*1b8b02a4SEd Tanous if (*fmt == 'q') 5592*1b8b02a4SEd Tanous os << get_units<CharT>(typename decltype(d)::period::type{}); 5593*1b8b02a4SEd Tanous else 5594*1b8b02a4SEd Tanous os << d.count(); 5595*1b8b02a4SEd Tanous } 5596*1b8b02a4SEd Tanous else 5597*1b8b02a4SEd Tanous { 5598*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5599*1b8b02a4SEd Tanous } 5600*1b8b02a4SEd Tanous modified = CharT{}; 5601*1b8b02a4SEd Tanous command = nullptr; 5602*1b8b02a4SEd Tanous } 5603*1b8b02a4SEd Tanous else 5604*1b8b02a4SEd Tanous os << *fmt; 5605*1b8b02a4SEd Tanous break; 5606*1b8b02a4SEd Tanous case 'r': 5607*1b8b02a4SEd Tanous if (command) 5608*1b8b02a4SEd Tanous { 5609*1b8b02a4SEd Tanous if (modified == CharT{}) 5610*1b8b02a4SEd Tanous { 5611*1b8b02a4SEd Tanous if (!fds.has_tod) 5612*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5613*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5614*1b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 5615*1b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 5616*1b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 5617*1b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 5618*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5619*1b8b02a4SEd Tanous #else 5620*1b8b02a4SEd Tanous hh_mm_ss<seconds> tod(duration_cast<seconds>(fds.tod.to_duration())); 5621*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 5622*1b8b02a4SEd Tanous os.fill('0'); 5623*1b8b02a4SEd Tanous os.width(2); 5624*1b8b02a4SEd Tanous os << date::make12(tod.hours()).count() << CharT{':'}; 5625*1b8b02a4SEd Tanous os.width(2); 5626*1b8b02a4SEd Tanous os << tod.minutes().count() << CharT{':'}; 5627*1b8b02a4SEd Tanous os.width(2); 5628*1b8b02a4SEd Tanous os << tod.seconds().count() << CharT{' '}; 5629*1b8b02a4SEd Tanous if (date::is_am(tod.hours())) 5630*1b8b02a4SEd Tanous os << ampm_names().first[0]; 5631*1b8b02a4SEd Tanous else 5632*1b8b02a4SEd Tanous os << ampm_names().first[1]; 5633*1b8b02a4SEd Tanous #endif 5634*1b8b02a4SEd Tanous } 5635*1b8b02a4SEd Tanous else 5636*1b8b02a4SEd Tanous { 5637*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5638*1b8b02a4SEd Tanous } 5639*1b8b02a4SEd Tanous modified = CharT{}; 5640*1b8b02a4SEd Tanous command = nullptr; 5641*1b8b02a4SEd Tanous } 5642*1b8b02a4SEd Tanous else 5643*1b8b02a4SEd Tanous os << *fmt; 5644*1b8b02a4SEd Tanous break; 5645*1b8b02a4SEd Tanous case 'R': 5646*1b8b02a4SEd Tanous if (command) 5647*1b8b02a4SEd Tanous { 5648*1b8b02a4SEd Tanous if (modified == CharT{}) 5649*1b8b02a4SEd Tanous { 5650*1b8b02a4SEd Tanous if (!fds.has_tod) 5651*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5652*1b8b02a4SEd Tanous if (fds.tod.hours() < hours{10}) 5653*1b8b02a4SEd Tanous os << CharT{'0'}; 5654*1b8b02a4SEd Tanous os << fds.tod.hours().count() << CharT{':'}; 5655*1b8b02a4SEd Tanous if (fds.tod.minutes() < minutes{10}) 5656*1b8b02a4SEd Tanous os << CharT{'0'}; 5657*1b8b02a4SEd Tanous os << fds.tod.minutes().count(); 5658*1b8b02a4SEd Tanous } 5659*1b8b02a4SEd Tanous else 5660*1b8b02a4SEd Tanous { 5661*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5662*1b8b02a4SEd Tanous modified = CharT{}; 5663*1b8b02a4SEd Tanous } 5664*1b8b02a4SEd Tanous command = nullptr; 5665*1b8b02a4SEd Tanous } 5666*1b8b02a4SEd Tanous else 5667*1b8b02a4SEd Tanous os << *fmt; 5668*1b8b02a4SEd Tanous break; 5669*1b8b02a4SEd Tanous case 'S': 5670*1b8b02a4SEd Tanous if (command) 5671*1b8b02a4SEd Tanous { 5672*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5673*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5674*1b8b02a4SEd Tanous else 5675*1b8b02a4SEd Tanous { 5676*1b8b02a4SEd Tanous if (!fds.has_tod) 5677*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5678*1b8b02a4SEd Tanous if (insert_negative) 5679*1b8b02a4SEd Tanous { 5680*1b8b02a4SEd Tanous os << '-'; 5681*1b8b02a4SEd Tanous insert_negative = false; 5682*1b8b02a4SEd Tanous } 5683*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5684*1b8b02a4SEd Tanous if (modified == CharT{}) 5685*1b8b02a4SEd Tanous #endif 5686*1b8b02a4SEd Tanous { 5687*1b8b02a4SEd Tanous os << fds.tod.s_; 5688*1b8b02a4SEd Tanous } 5689*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5690*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5691*1b8b02a4SEd Tanous { 5692*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5693*1b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.s_.seconds().count()); 5694*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5695*1b8b02a4SEd Tanous } 5696*1b8b02a4SEd Tanous #endif 5697*1b8b02a4SEd Tanous } 5698*1b8b02a4SEd Tanous modified = CharT{}; 5699*1b8b02a4SEd Tanous command = nullptr; 5700*1b8b02a4SEd Tanous } 5701*1b8b02a4SEd Tanous else 5702*1b8b02a4SEd Tanous os << *fmt; 5703*1b8b02a4SEd Tanous break; 5704*1b8b02a4SEd Tanous case 't': 5705*1b8b02a4SEd Tanous if (command) 5706*1b8b02a4SEd Tanous { 5707*1b8b02a4SEd Tanous if (modified == CharT{}) 5708*1b8b02a4SEd Tanous os << CharT{'\t'}; 5709*1b8b02a4SEd Tanous else 5710*1b8b02a4SEd Tanous { 5711*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5712*1b8b02a4SEd Tanous modified = CharT{}; 5713*1b8b02a4SEd Tanous } 5714*1b8b02a4SEd Tanous command = nullptr; 5715*1b8b02a4SEd Tanous } 5716*1b8b02a4SEd Tanous else 5717*1b8b02a4SEd Tanous os << *fmt; 5718*1b8b02a4SEd Tanous break; 5719*1b8b02a4SEd Tanous case 'T': 5720*1b8b02a4SEd Tanous if (command) 5721*1b8b02a4SEd Tanous { 5722*1b8b02a4SEd Tanous if (modified == CharT{}) 5723*1b8b02a4SEd Tanous { 5724*1b8b02a4SEd Tanous if (!fds.has_tod) 5725*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5726*1b8b02a4SEd Tanous os << fds.tod; 5727*1b8b02a4SEd Tanous } 5728*1b8b02a4SEd Tanous else 5729*1b8b02a4SEd Tanous { 5730*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5731*1b8b02a4SEd Tanous modified = CharT{}; 5732*1b8b02a4SEd Tanous } 5733*1b8b02a4SEd Tanous command = nullptr; 5734*1b8b02a4SEd Tanous } 5735*1b8b02a4SEd Tanous else 5736*1b8b02a4SEd Tanous os << *fmt; 5737*1b8b02a4SEd Tanous break; 5738*1b8b02a4SEd Tanous case 'u': 5739*1b8b02a4SEd Tanous if (command) 5740*1b8b02a4SEd Tanous { 5741*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5742*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5743*1b8b02a4SEd Tanous else 5744*1b8b02a4SEd Tanous { 5745*1b8b02a4SEd Tanous auto wd = extract_weekday(os, fds); 5746*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5747*1b8b02a4SEd Tanous if (modified == CharT{}) 5748*1b8b02a4SEd Tanous #endif 5749*1b8b02a4SEd Tanous { 5750*1b8b02a4SEd Tanous os << (wd != 0 ? wd : 7u); 5751*1b8b02a4SEd Tanous } 5752*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5753*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5754*1b8b02a4SEd Tanous { 5755*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5756*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(wd); 5757*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5758*1b8b02a4SEd Tanous } 5759*1b8b02a4SEd Tanous #endif 5760*1b8b02a4SEd Tanous } 5761*1b8b02a4SEd Tanous modified = CharT{}; 5762*1b8b02a4SEd Tanous command = nullptr; 5763*1b8b02a4SEd Tanous } 5764*1b8b02a4SEd Tanous else 5765*1b8b02a4SEd Tanous os << *fmt; 5766*1b8b02a4SEd Tanous break; 5767*1b8b02a4SEd Tanous case 'U': 5768*1b8b02a4SEd Tanous if (command) 5769*1b8b02a4SEd Tanous { 5770*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5771*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5772*1b8b02a4SEd Tanous else 5773*1b8b02a4SEd Tanous { 5774*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5775*1b8b02a4SEd Tanous if (!ymd.ok()) 5776*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5777*1b8b02a4SEd Tanous auto ld = local_days(ymd); 5778*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5779*1b8b02a4SEd Tanous if (modified == CharT{}) 5780*1b8b02a4SEd Tanous #endif 5781*1b8b02a4SEd Tanous { 5782*1b8b02a4SEd Tanous auto st = local_days(Sunday[1]/January/ymd.year()); 5783*1b8b02a4SEd Tanous if (ld < st) 5784*1b8b02a4SEd Tanous os << CharT{'0'} << CharT{'0'}; 5785*1b8b02a4SEd Tanous else 5786*1b8b02a4SEd Tanous { 5787*1b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 5788*1b8b02a4SEd Tanous if (wn < 10) 5789*1b8b02a4SEd Tanous os << CharT{'0'}; 5790*1b8b02a4SEd Tanous os << wn; 5791*1b8b02a4SEd Tanous } 5792*1b8b02a4SEd Tanous } 5793*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5794*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5795*1b8b02a4SEd Tanous { 5796*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5797*1b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 5798*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 5799*1b8b02a4SEd Tanous if (os.fail()) 5800*1b8b02a4SEd Tanous return os; 5801*1b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 5802*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5803*1b8b02a4SEd Tanous } 5804*1b8b02a4SEd Tanous #endif 5805*1b8b02a4SEd Tanous } 5806*1b8b02a4SEd Tanous modified = CharT{}; 5807*1b8b02a4SEd Tanous command = nullptr; 5808*1b8b02a4SEd Tanous } 5809*1b8b02a4SEd Tanous else 5810*1b8b02a4SEd Tanous os << *fmt; 5811*1b8b02a4SEd Tanous break; 5812*1b8b02a4SEd Tanous case 'V': 5813*1b8b02a4SEd Tanous if (command) 5814*1b8b02a4SEd Tanous { 5815*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5816*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5817*1b8b02a4SEd Tanous else 5818*1b8b02a4SEd Tanous { 5819*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 5820*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5821*1b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 5822*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5823*1b8b02a4SEd Tanous if (modified == CharT{}) 5824*1b8b02a4SEd Tanous #endif 5825*1b8b02a4SEd Tanous { 5826*1b8b02a4SEd Tanous auto y = year_month_day{ld + days{3}}.year(); 5827*1b8b02a4SEd Tanous auto st = local_days((y-years{1})/12/Thursday[last]) + 5828*1b8b02a4SEd Tanous (Monday-Thursday); 5829*1b8b02a4SEd Tanous if (ld < st) 5830*1b8b02a4SEd Tanous { 5831*1b8b02a4SEd Tanous --y; 5832*1b8b02a4SEd Tanous st = local_days((y - years{1})/12/Thursday[last]) + 5833*1b8b02a4SEd Tanous (Monday-Thursday); 5834*1b8b02a4SEd Tanous } 5835*1b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 5836*1b8b02a4SEd Tanous if (wn < 10) 5837*1b8b02a4SEd Tanous os << CharT{'0'}; 5838*1b8b02a4SEd Tanous os << wn; 5839*1b8b02a4SEd Tanous } 5840*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5841*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5842*1b8b02a4SEd Tanous { 5843*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5844*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5845*1b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 5846*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 5847*1b8b02a4SEd Tanous if (os.fail()) 5848*1b8b02a4SEd Tanous return os; 5849*1b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 5850*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5851*1b8b02a4SEd Tanous } 5852*1b8b02a4SEd Tanous #endif 5853*1b8b02a4SEd Tanous } 5854*1b8b02a4SEd Tanous modified = CharT{}; 5855*1b8b02a4SEd Tanous command = nullptr; 5856*1b8b02a4SEd Tanous } 5857*1b8b02a4SEd Tanous else 5858*1b8b02a4SEd Tanous os << *fmt; 5859*1b8b02a4SEd Tanous break; 5860*1b8b02a4SEd Tanous case 'w': 5861*1b8b02a4SEd Tanous if (command) 5862*1b8b02a4SEd Tanous { 5863*1b8b02a4SEd Tanous auto wd = extract_weekday(os, fds); 5864*1b8b02a4SEd Tanous if (os.fail()) 5865*1b8b02a4SEd Tanous return os; 5866*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5867*1b8b02a4SEd Tanous if (modified == CharT{}) 5868*1b8b02a4SEd Tanous #else 5869*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 5870*1b8b02a4SEd Tanous #endif 5871*1b8b02a4SEd Tanous { 5872*1b8b02a4SEd Tanous os << wd; 5873*1b8b02a4SEd Tanous } 5874*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5875*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5876*1b8b02a4SEd Tanous { 5877*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5878*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(wd); 5879*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5880*1b8b02a4SEd Tanous } 5881*1b8b02a4SEd Tanous #endif 5882*1b8b02a4SEd Tanous else 5883*1b8b02a4SEd Tanous { 5884*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5885*1b8b02a4SEd Tanous } 5886*1b8b02a4SEd Tanous modified = CharT{}; 5887*1b8b02a4SEd Tanous command = nullptr; 5888*1b8b02a4SEd Tanous } 5889*1b8b02a4SEd Tanous else 5890*1b8b02a4SEd Tanous os << *fmt; 5891*1b8b02a4SEd Tanous break; 5892*1b8b02a4SEd Tanous case 'W': 5893*1b8b02a4SEd Tanous if (command) 5894*1b8b02a4SEd Tanous { 5895*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5896*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5897*1b8b02a4SEd Tanous else 5898*1b8b02a4SEd Tanous { 5899*1b8b02a4SEd Tanous auto const& ymd = fds.ymd; 5900*1b8b02a4SEd Tanous if (!ymd.ok()) 5901*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5902*1b8b02a4SEd Tanous auto ld = local_days(ymd); 5903*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5904*1b8b02a4SEd Tanous if (modified == CharT{}) 5905*1b8b02a4SEd Tanous #endif 5906*1b8b02a4SEd Tanous { 5907*1b8b02a4SEd Tanous auto st = local_days(Monday[1]/January/ymd.year()); 5908*1b8b02a4SEd Tanous if (ld < st) 5909*1b8b02a4SEd Tanous os << CharT{'0'} << CharT{'0'}; 5910*1b8b02a4SEd Tanous else 5911*1b8b02a4SEd Tanous { 5912*1b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 5913*1b8b02a4SEd Tanous if (wn < 10) 5914*1b8b02a4SEd Tanous os << CharT{'0'}; 5915*1b8b02a4SEd Tanous os << wn; 5916*1b8b02a4SEd Tanous } 5917*1b8b02a4SEd Tanous } 5918*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5919*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 5920*1b8b02a4SEd Tanous { 5921*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5922*1b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 5923*1b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 5924*1b8b02a4SEd Tanous if (os.fail()) 5925*1b8b02a4SEd Tanous return os; 5926*1b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 5927*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5928*1b8b02a4SEd Tanous } 5929*1b8b02a4SEd Tanous #endif 5930*1b8b02a4SEd Tanous } 5931*1b8b02a4SEd Tanous modified = CharT{}; 5932*1b8b02a4SEd Tanous command = nullptr; 5933*1b8b02a4SEd Tanous } 5934*1b8b02a4SEd Tanous else 5935*1b8b02a4SEd Tanous os << *fmt; 5936*1b8b02a4SEd Tanous break; 5937*1b8b02a4SEd Tanous case 'X': 5938*1b8b02a4SEd Tanous if (command) 5939*1b8b02a4SEd Tanous { 5940*1b8b02a4SEd Tanous if (modified == CharT{'O'}) 5941*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 5942*1b8b02a4SEd Tanous else 5943*1b8b02a4SEd Tanous { 5944*1b8b02a4SEd Tanous if (!fds.has_tod) 5945*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5946*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5947*1b8b02a4SEd Tanous tm = std::tm{}; 5948*1b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 5949*1b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 5950*1b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 5951*1b8b02a4SEd Tanous CharT f[3] = {'%'}; 5952*1b8b02a4SEd Tanous auto fe = std::begin(f) + 1; 5953*1b8b02a4SEd Tanous if (modified == CharT{'E'}) 5954*1b8b02a4SEd Tanous *fe++ = modified; 5955*1b8b02a4SEd Tanous *fe++ = *fmt; 5956*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), fe); 5957*1b8b02a4SEd Tanous #else 5958*1b8b02a4SEd Tanous os << fds.tod; 5959*1b8b02a4SEd Tanous #endif 5960*1b8b02a4SEd Tanous } 5961*1b8b02a4SEd Tanous command = nullptr; 5962*1b8b02a4SEd Tanous modified = CharT{}; 5963*1b8b02a4SEd Tanous } 5964*1b8b02a4SEd Tanous else 5965*1b8b02a4SEd Tanous os << *fmt; 5966*1b8b02a4SEd Tanous break; 5967*1b8b02a4SEd Tanous case 'y': 5968*1b8b02a4SEd Tanous if (command) 5969*1b8b02a4SEd Tanous { 5970*1b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 5971*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 5972*1b8b02a4SEd Tanous auto y = static_cast<int>(fds.ymd.year()); 5973*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5974*1b8b02a4SEd Tanous if (modified == CharT{}) 5975*1b8b02a4SEd Tanous { 5976*1b8b02a4SEd Tanous #endif 5977*1b8b02a4SEd Tanous y = std::abs(y) % 100; 5978*1b8b02a4SEd Tanous if (y < 10) 5979*1b8b02a4SEd Tanous os << CharT{'0'}; 5980*1b8b02a4SEd Tanous os << y; 5981*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 5982*1b8b02a4SEd Tanous } 5983*1b8b02a4SEd Tanous else 5984*1b8b02a4SEd Tanous { 5985*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 5986*1b8b02a4SEd Tanous tm.tm_year = y - 1900; 5987*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 5988*1b8b02a4SEd Tanous } 5989*1b8b02a4SEd Tanous #endif 5990*1b8b02a4SEd Tanous modified = CharT{}; 5991*1b8b02a4SEd Tanous command = nullptr; 5992*1b8b02a4SEd Tanous } 5993*1b8b02a4SEd Tanous else 5994*1b8b02a4SEd Tanous os << *fmt; 5995*1b8b02a4SEd Tanous break; 5996*1b8b02a4SEd Tanous case 'Y': 5997*1b8b02a4SEd Tanous if (command) 5998*1b8b02a4SEd Tanous { 5999*1b8b02a4SEd Tanous if (modified == CharT{'O'}) 6000*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 6001*1b8b02a4SEd Tanous else 6002*1b8b02a4SEd Tanous { 6003*1b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 6004*1b8b02a4SEd Tanous os.setstate(std::ios::failbit); 6005*1b8b02a4SEd Tanous auto y = fds.ymd.year(); 6006*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6007*1b8b02a4SEd Tanous if (modified == CharT{}) 6008*1b8b02a4SEd Tanous #endif 6009*1b8b02a4SEd Tanous { 6010*1b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 6011*1b8b02a4SEd Tanous os.imbue(std::locale::classic()); 6012*1b8b02a4SEd Tanous os << y; 6013*1b8b02a4SEd Tanous } 6014*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6015*1b8b02a4SEd Tanous else if (modified == CharT{'E'}) 6016*1b8b02a4SEd Tanous { 6017*1b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 6018*1b8b02a4SEd Tanous tm.tm_year = static_cast<int>(y) - 1900; 6019*1b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 6020*1b8b02a4SEd Tanous } 6021*1b8b02a4SEd Tanous #endif 6022*1b8b02a4SEd Tanous } 6023*1b8b02a4SEd Tanous modified = CharT{}; 6024*1b8b02a4SEd Tanous command = nullptr; 6025*1b8b02a4SEd Tanous } 6026*1b8b02a4SEd Tanous else 6027*1b8b02a4SEd Tanous os << *fmt; 6028*1b8b02a4SEd Tanous break; 6029*1b8b02a4SEd Tanous case 'z': 6030*1b8b02a4SEd Tanous if (command) 6031*1b8b02a4SEd Tanous { 6032*1b8b02a4SEd Tanous if (offset_sec == nullptr) 6033*1b8b02a4SEd Tanous { 6034*1b8b02a4SEd Tanous // Can not format %z with unknown offset 6035*1b8b02a4SEd Tanous os.setstate(ios::failbit); 6036*1b8b02a4SEd Tanous return os; 6037*1b8b02a4SEd Tanous } 6038*1b8b02a4SEd Tanous auto m = duration_cast<minutes>(*offset_sec); 6039*1b8b02a4SEd Tanous auto neg = m < minutes{0}; 6040*1b8b02a4SEd Tanous m = date::abs(m); 6041*1b8b02a4SEd Tanous auto h = duration_cast<hours>(m); 6042*1b8b02a4SEd Tanous m -= h; 6043*1b8b02a4SEd Tanous if (neg) 6044*1b8b02a4SEd Tanous os << CharT{'-'}; 6045*1b8b02a4SEd Tanous else 6046*1b8b02a4SEd Tanous os << CharT{'+'}; 6047*1b8b02a4SEd Tanous if (h < hours{10}) 6048*1b8b02a4SEd Tanous os << CharT{'0'}; 6049*1b8b02a4SEd Tanous os << h.count(); 6050*1b8b02a4SEd Tanous if (modified != CharT{}) 6051*1b8b02a4SEd Tanous os << CharT{':'}; 6052*1b8b02a4SEd Tanous if (m < minutes{10}) 6053*1b8b02a4SEd Tanous os << CharT{'0'}; 6054*1b8b02a4SEd Tanous os << m.count(); 6055*1b8b02a4SEd Tanous command = nullptr; 6056*1b8b02a4SEd Tanous modified = CharT{}; 6057*1b8b02a4SEd Tanous } 6058*1b8b02a4SEd Tanous else 6059*1b8b02a4SEd Tanous os << *fmt; 6060*1b8b02a4SEd Tanous break; 6061*1b8b02a4SEd Tanous case 'Z': 6062*1b8b02a4SEd Tanous if (command) 6063*1b8b02a4SEd Tanous { 6064*1b8b02a4SEd Tanous if (modified == CharT{}) 6065*1b8b02a4SEd Tanous { 6066*1b8b02a4SEd Tanous if (abbrev == nullptr) 6067*1b8b02a4SEd Tanous { 6068*1b8b02a4SEd Tanous // Can not format %Z with unknown time_zone 6069*1b8b02a4SEd Tanous os.setstate(ios::failbit); 6070*1b8b02a4SEd Tanous return os; 6071*1b8b02a4SEd Tanous } 6072*1b8b02a4SEd Tanous for (auto c : *abbrev) 6073*1b8b02a4SEd Tanous os << CharT(c); 6074*1b8b02a4SEd Tanous } 6075*1b8b02a4SEd Tanous else 6076*1b8b02a4SEd Tanous { 6077*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 6078*1b8b02a4SEd Tanous modified = CharT{}; 6079*1b8b02a4SEd Tanous } 6080*1b8b02a4SEd Tanous command = nullptr; 6081*1b8b02a4SEd Tanous } 6082*1b8b02a4SEd Tanous else 6083*1b8b02a4SEd Tanous os << *fmt; 6084*1b8b02a4SEd Tanous break; 6085*1b8b02a4SEd Tanous case 'E': 6086*1b8b02a4SEd Tanous case 'O': 6087*1b8b02a4SEd Tanous if (command) 6088*1b8b02a4SEd Tanous { 6089*1b8b02a4SEd Tanous if (modified == CharT{}) 6090*1b8b02a4SEd Tanous { 6091*1b8b02a4SEd Tanous modified = *fmt; 6092*1b8b02a4SEd Tanous } 6093*1b8b02a4SEd Tanous else 6094*1b8b02a4SEd Tanous { 6095*1b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 6096*1b8b02a4SEd Tanous command = nullptr; 6097*1b8b02a4SEd Tanous modified = CharT{}; 6098*1b8b02a4SEd Tanous } 6099*1b8b02a4SEd Tanous } 6100*1b8b02a4SEd Tanous else 6101*1b8b02a4SEd Tanous os << *fmt; 6102*1b8b02a4SEd Tanous break; 6103*1b8b02a4SEd Tanous case '%': 6104*1b8b02a4SEd Tanous if (command) 6105*1b8b02a4SEd Tanous { 6106*1b8b02a4SEd Tanous if (modified == CharT{}) 6107*1b8b02a4SEd Tanous { 6108*1b8b02a4SEd Tanous os << CharT{'%'}; 6109*1b8b02a4SEd Tanous command = nullptr; 6110*1b8b02a4SEd Tanous } 6111*1b8b02a4SEd Tanous else 6112*1b8b02a4SEd Tanous { 6113*1b8b02a4SEd Tanous os << CharT{'%'} << modified << CharT{'%'}; 6114*1b8b02a4SEd Tanous command = nullptr; 6115*1b8b02a4SEd Tanous modified = CharT{}; 6116*1b8b02a4SEd Tanous } 6117*1b8b02a4SEd Tanous } 6118*1b8b02a4SEd Tanous else 6119*1b8b02a4SEd Tanous command = fmt; 6120*1b8b02a4SEd Tanous break; 6121*1b8b02a4SEd Tanous default: 6122*1b8b02a4SEd Tanous if (command) 6123*1b8b02a4SEd Tanous { 6124*1b8b02a4SEd Tanous os << CharT{'%'}; 6125*1b8b02a4SEd Tanous command = nullptr; 6126*1b8b02a4SEd Tanous } 6127*1b8b02a4SEd Tanous if (modified != CharT{}) 6128*1b8b02a4SEd Tanous { 6129*1b8b02a4SEd Tanous os << modified; 6130*1b8b02a4SEd Tanous modified = CharT{}; 6131*1b8b02a4SEd Tanous } 6132*1b8b02a4SEd Tanous os << *fmt; 6133*1b8b02a4SEd Tanous break; 6134*1b8b02a4SEd Tanous } 6135*1b8b02a4SEd Tanous } 6136*1b8b02a4SEd Tanous if (command) 6137*1b8b02a4SEd Tanous os << CharT{'%'}; 6138*1b8b02a4SEd Tanous if (modified != CharT{}) 6139*1b8b02a4SEd Tanous os << modified; 6140*1b8b02a4SEd Tanous return os; 6141*1b8b02a4SEd Tanous } 6142*1b8b02a4SEd Tanous 6143*1b8b02a4SEd Tanous template <class CharT, class Traits> 6144*1b8b02a4SEd Tanous inline 6145*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6146*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year& y) 6147*1b8b02a4SEd Tanous { 6148*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6149*1b8b02a4SEd Tanous fields<CT> fds{y/0/0}; 6150*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6151*1b8b02a4SEd Tanous } 6152*1b8b02a4SEd Tanous 6153*1b8b02a4SEd Tanous template <class CharT, class Traits> 6154*1b8b02a4SEd Tanous inline 6155*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6156*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month& m) 6157*1b8b02a4SEd Tanous { 6158*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6159*1b8b02a4SEd Tanous fields<CT> fds{m/0/nanyear}; 6160*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6161*1b8b02a4SEd Tanous } 6162*1b8b02a4SEd Tanous 6163*1b8b02a4SEd Tanous template <class CharT, class Traits> 6164*1b8b02a4SEd Tanous inline 6165*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6166*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const day& d) 6167*1b8b02a4SEd Tanous { 6168*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6169*1b8b02a4SEd Tanous fields<CT> fds{d/0/nanyear}; 6170*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6171*1b8b02a4SEd Tanous } 6172*1b8b02a4SEd Tanous 6173*1b8b02a4SEd Tanous template <class CharT, class Traits> 6174*1b8b02a4SEd Tanous inline 6175*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6176*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const weekday& wd) 6177*1b8b02a4SEd Tanous { 6178*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6179*1b8b02a4SEd Tanous fields<CT> fds{wd}; 6180*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6181*1b8b02a4SEd Tanous } 6182*1b8b02a4SEd Tanous 6183*1b8b02a4SEd Tanous template <class CharT, class Traits> 6184*1b8b02a4SEd Tanous inline 6185*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6186*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year_month& ym) 6187*1b8b02a4SEd Tanous { 6188*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6189*1b8b02a4SEd Tanous fields<CT> fds{ym/0}; 6190*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6191*1b8b02a4SEd Tanous } 6192*1b8b02a4SEd Tanous 6193*1b8b02a4SEd Tanous template <class CharT, class Traits> 6194*1b8b02a4SEd Tanous inline 6195*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6196*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month_day& md) 6197*1b8b02a4SEd Tanous { 6198*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6199*1b8b02a4SEd Tanous fields<CT> fds{md/nanyear}; 6200*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6201*1b8b02a4SEd Tanous } 6202*1b8b02a4SEd Tanous 6203*1b8b02a4SEd Tanous template <class CharT, class Traits> 6204*1b8b02a4SEd Tanous inline 6205*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6206*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 6207*1b8b02a4SEd Tanous const year_month_day& ymd) 6208*1b8b02a4SEd Tanous { 6209*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 6210*1b8b02a4SEd Tanous fields<CT> fds{ymd}; 6211*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6212*1b8b02a4SEd Tanous } 6213*1b8b02a4SEd Tanous 6214*1b8b02a4SEd Tanous template <class CharT, class Traits, class Rep, class Period> 6215*1b8b02a4SEd Tanous inline 6216*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6217*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 6218*1b8b02a4SEd Tanous const std::chrono::duration<Rep, Period>& d) 6219*1b8b02a4SEd Tanous { 6220*1b8b02a4SEd Tanous using Duration = std::chrono::duration<Rep, Period>; 6221*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 6222*1b8b02a4SEd Tanous fields<CT> fds{hh_mm_ss<CT>{d}}; 6223*1b8b02a4SEd Tanous return to_stream(os, fmt, fds); 6224*1b8b02a4SEd Tanous } 6225*1b8b02a4SEd Tanous 6226*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 6227*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6228*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 6229*1b8b02a4SEd Tanous const local_time<Duration>& tp, const std::string* abbrev = nullptr, 6230*1b8b02a4SEd Tanous const std::chrono::seconds* offset_sec = nullptr) 6231*1b8b02a4SEd Tanous { 6232*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 6233*1b8b02a4SEd Tanous auto ld = std::chrono::time_point_cast<days>(tp); 6234*1b8b02a4SEd Tanous fields<CT> fds; 6235*1b8b02a4SEd Tanous if (ld <= tp) 6236*1b8b02a4SEd Tanous fds = fields<CT>{year_month_day{ld}, hh_mm_ss<CT>{tp-local_seconds{ld}}}; 6237*1b8b02a4SEd Tanous else 6238*1b8b02a4SEd Tanous fds = fields<CT>{year_month_day{ld - days{1}}, 6239*1b8b02a4SEd Tanous hh_mm_ss<CT>{days{1} - (local_seconds{ld} - tp)}}; 6240*1b8b02a4SEd Tanous return to_stream(os, fmt, fds, abbrev, offset_sec); 6241*1b8b02a4SEd Tanous } 6242*1b8b02a4SEd Tanous 6243*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 6244*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6245*1b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 6246*1b8b02a4SEd Tanous const sys_time<Duration>& tp) 6247*1b8b02a4SEd Tanous { 6248*1b8b02a4SEd Tanous using std::chrono::seconds; 6249*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, seconds>::type; 6250*1b8b02a4SEd Tanous const std::string abbrev("UTC"); 6251*1b8b02a4SEd Tanous CONSTDATA seconds offset{0}; 6252*1b8b02a4SEd Tanous auto sd = std::chrono::time_point_cast<days>(tp); 6253*1b8b02a4SEd Tanous fields<CT> fds; 6254*1b8b02a4SEd Tanous if (sd <= tp) 6255*1b8b02a4SEd Tanous fds = fields<CT>{year_month_day{sd}, hh_mm_ss<CT>{tp-sys_seconds{sd}}}; 6256*1b8b02a4SEd Tanous else 6257*1b8b02a4SEd Tanous fds = fields<CT>{year_month_day{sd - days{1}}, 6258*1b8b02a4SEd Tanous hh_mm_ss<CT>{days{1} - (sys_seconds{sd} - tp)}}; 6259*1b8b02a4SEd Tanous return to_stream(os, fmt, fds, &abbrev, &offset); 6260*1b8b02a4SEd Tanous } 6261*1b8b02a4SEd Tanous 6262*1b8b02a4SEd Tanous // format 6263*1b8b02a4SEd Tanous 6264*1b8b02a4SEd Tanous template <class CharT, class Streamable> 6265*1b8b02a4SEd Tanous auto 6266*1b8b02a4SEd Tanous format(const std::locale& loc, const CharT* fmt, const Streamable& tp) 6267*1b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp), 6268*1b8b02a4SEd Tanous std::basic_string<CharT>{}) 6269*1b8b02a4SEd Tanous { 6270*1b8b02a4SEd Tanous std::basic_ostringstream<CharT> os; 6271*1b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 6272*1b8b02a4SEd Tanous os.imbue(loc); 6273*1b8b02a4SEd Tanous to_stream(os, fmt, tp); 6274*1b8b02a4SEd Tanous return os.str(); 6275*1b8b02a4SEd Tanous } 6276*1b8b02a4SEd Tanous 6277*1b8b02a4SEd Tanous template <class CharT, class Streamable> 6278*1b8b02a4SEd Tanous auto 6279*1b8b02a4SEd Tanous format(const CharT* fmt, const Streamable& tp) 6280*1b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp), 6281*1b8b02a4SEd Tanous std::basic_string<CharT>{}) 6282*1b8b02a4SEd Tanous { 6283*1b8b02a4SEd Tanous std::basic_ostringstream<CharT> os; 6284*1b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 6285*1b8b02a4SEd Tanous to_stream(os, fmt, tp); 6286*1b8b02a4SEd Tanous return os.str(); 6287*1b8b02a4SEd Tanous } 6288*1b8b02a4SEd Tanous 6289*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, class Streamable> 6290*1b8b02a4SEd Tanous auto 6291*1b8b02a4SEd Tanous format(const std::locale& loc, const std::basic_string<CharT, Traits, Alloc>& fmt, 6292*1b8b02a4SEd Tanous const Streamable& tp) 6293*1b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp), 6294*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>{}) 6295*1b8b02a4SEd Tanous { 6296*1b8b02a4SEd Tanous std::basic_ostringstream<CharT, Traits, Alloc> os; 6297*1b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 6298*1b8b02a4SEd Tanous os.imbue(loc); 6299*1b8b02a4SEd Tanous to_stream(os, fmt.c_str(), tp); 6300*1b8b02a4SEd Tanous return os.str(); 6301*1b8b02a4SEd Tanous } 6302*1b8b02a4SEd Tanous 6303*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, class Streamable> 6304*1b8b02a4SEd Tanous auto 6305*1b8b02a4SEd Tanous format(const std::basic_string<CharT, Traits, Alloc>& fmt, const Streamable& tp) 6306*1b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp), 6307*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>{}) 6308*1b8b02a4SEd Tanous { 6309*1b8b02a4SEd Tanous std::basic_ostringstream<CharT, Traits, Alloc> os; 6310*1b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 6311*1b8b02a4SEd Tanous to_stream(os, fmt.c_str(), tp); 6312*1b8b02a4SEd Tanous return os.str(); 6313*1b8b02a4SEd Tanous } 6314*1b8b02a4SEd Tanous 6315*1b8b02a4SEd Tanous // parse 6316*1b8b02a4SEd Tanous 6317*1b8b02a4SEd Tanous namespace detail 6318*1b8b02a4SEd Tanous { 6319*1b8b02a4SEd Tanous 6320*1b8b02a4SEd Tanous template <class CharT, class Traits> 6321*1b8b02a4SEd Tanous bool 6322*1b8b02a4SEd Tanous read_char(std::basic_istream<CharT, Traits>& is, CharT fmt, std::ios::iostate& err) 6323*1b8b02a4SEd Tanous { 6324*1b8b02a4SEd Tanous auto ic = is.get(); 6325*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof()) || 6326*1b8b02a4SEd Tanous !Traits::eq(Traits::to_char_type(ic), fmt)) 6327*1b8b02a4SEd Tanous { 6328*1b8b02a4SEd Tanous err |= std::ios::failbit; 6329*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6330*1b8b02a4SEd Tanous return false; 6331*1b8b02a4SEd Tanous } 6332*1b8b02a4SEd Tanous return true; 6333*1b8b02a4SEd Tanous } 6334*1b8b02a4SEd Tanous 6335*1b8b02a4SEd Tanous template <class CharT, class Traits> 6336*1b8b02a4SEd Tanous unsigned 6337*1b8b02a4SEd Tanous read_unsigned(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 6338*1b8b02a4SEd Tanous { 6339*1b8b02a4SEd Tanous unsigned x = 0; 6340*1b8b02a4SEd Tanous unsigned count = 0; 6341*1b8b02a4SEd Tanous while (true) 6342*1b8b02a4SEd Tanous { 6343*1b8b02a4SEd Tanous auto ic = is.peek(); 6344*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 6345*1b8b02a4SEd Tanous break; 6346*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 6347*1b8b02a4SEd Tanous if (!('0' <= c && c <= '9')) 6348*1b8b02a4SEd Tanous break; 6349*1b8b02a4SEd Tanous (void)is.get(); 6350*1b8b02a4SEd Tanous ++count; 6351*1b8b02a4SEd Tanous x = 10*x + static_cast<unsigned>(c - '0'); 6352*1b8b02a4SEd Tanous if (count == M) 6353*1b8b02a4SEd Tanous break; 6354*1b8b02a4SEd Tanous } 6355*1b8b02a4SEd Tanous if (count < m) 6356*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6357*1b8b02a4SEd Tanous return x; 6358*1b8b02a4SEd Tanous } 6359*1b8b02a4SEd Tanous 6360*1b8b02a4SEd Tanous template <class CharT, class Traits> 6361*1b8b02a4SEd Tanous int 6362*1b8b02a4SEd Tanous read_signed(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 6363*1b8b02a4SEd Tanous { 6364*1b8b02a4SEd Tanous auto ic = is.peek(); 6365*1b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 6366*1b8b02a4SEd Tanous { 6367*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 6368*1b8b02a4SEd Tanous if (('0' <= c && c <= '9') || c == '-' || c == '+') 6369*1b8b02a4SEd Tanous { 6370*1b8b02a4SEd Tanous if (c == '-' || c == '+') 6371*1b8b02a4SEd Tanous (void)is.get(); 6372*1b8b02a4SEd Tanous auto x = static_cast<int>(read_unsigned(is, std::max(m, 1u), M)); 6373*1b8b02a4SEd Tanous if (!is.fail()) 6374*1b8b02a4SEd Tanous { 6375*1b8b02a4SEd Tanous if (c == '-') 6376*1b8b02a4SEd Tanous x = -x; 6377*1b8b02a4SEd Tanous return x; 6378*1b8b02a4SEd Tanous } 6379*1b8b02a4SEd Tanous } 6380*1b8b02a4SEd Tanous } 6381*1b8b02a4SEd Tanous if (m > 0) 6382*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6383*1b8b02a4SEd Tanous return 0; 6384*1b8b02a4SEd Tanous } 6385*1b8b02a4SEd Tanous 6386*1b8b02a4SEd Tanous template <class CharT, class Traits> 6387*1b8b02a4SEd Tanous long double 6388*1b8b02a4SEd Tanous read_long_double(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 6389*1b8b02a4SEd Tanous { 6390*1b8b02a4SEd Tanous unsigned count = 0; 6391*1b8b02a4SEd Tanous unsigned fcount = 0; 6392*1b8b02a4SEd Tanous unsigned long long i = 0; 6393*1b8b02a4SEd Tanous unsigned long long f = 0; 6394*1b8b02a4SEd Tanous bool parsing_fraction = false; 6395*1b8b02a4SEd Tanous #if ONLY_C_LOCALE 6396*1b8b02a4SEd Tanous typename Traits::int_type decimal_point = '.'; 6397*1b8b02a4SEd Tanous #else 6398*1b8b02a4SEd Tanous auto decimal_point = Traits::to_int_type( 6399*1b8b02a4SEd Tanous std::use_facet<std::numpunct<CharT>>(is.getloc()).decimal_point()); 6400*1b8b02a4SEd Tanous #endif 6401*1b8b02a4SEd Tanous while (true) 6402*1b8b02a4SEd Tanous { 6403*1b8b02a4SEd Tanous auto ic = is.peek(); 6404*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 6405*1b8b02a4SEd Tanous break; 6406*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, decimal_point)) 6407*1b8b02a4SEd Tanous { 6408*1b8b02a4SEd Tanous decimal_point = Traits::eof(); 6409*1b8b02a4SEd Tanous parsing_fraction = true; 6410*1b8b02a4SEd Tanous } 6411*1b8b02a4SEd Tanous else 6412*1b8b02a4SEd Tanous { 6413*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 6414*1b8b02a4SEd Tanous if (!('0' <= c && c <= '9')) 6415*1b8b02a4SEd Tanous break; 6416*1b8b02a4SEd Tanous if (!parsing_fraction) 6417*1b8b02a4SEd Tanous { 6418*1b8b02a4SEd Tanous i = 10*i + static_cast<unsigned>(c - '0'); 6419*1b8b02a4SEd Tanous } 6420*1b8b02a4SEd Tanous else 6421*1b8b02a4SEd Tanous { 6422*1b8b02a4SEd Tanous f = 10*f + static_cast<unsigned>(c - '0'); 6423*1b8b02a4SEd Tanous ++fcount; 6424*1b8b02a4SEd Tanous } 6425*1b8b02a4SEd Tanous } 6426*1b8b02a4SEd Tanous (void)is.get(); 6427*1b8b02a4SEd Tanous if (++count == M) 6428*1b8b02a4SEd Tanous break; 6429*1b8b02a4SEd Tanous } 6430*1b8b02a4SEd Tanous if (count < m) 6431*1b8b02a4SEd Tanous { 6432*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6433*1b8b02a4SEd Tanous return 0; 6434*1b8b02a4SEd Tanous } 6435*1b8b02a4SEd Tanous return static_cast<long double>(i) + static_cast<long double>(f)/std::pow(10.L, fcount); 6436*1b8b02a4SEd Tanous } 6437*1b8b02a4SEd Tanous 6438*1b8b02a4SEd Tanous struct rs 6439*1b8b02a4SEd Tanous { 6440*1b8b02a4SEd Tanous int& i; 6441*1b8b02a4SEd Tanous unsigned m; 6442*1b8b02a4SEd Tanous unsigned M; 6443*1b8b02a4SEd Tanous }; 6444*1b8b02a4SEd Tanous 6445*1b8b02a4SEd Tanous struct ru 6446*1b8b02a4SEd Tanous { 6447*1b8b02a4SEd Tanous int& i; 6448*1b8b02a4SEd Tanous unsigned m; 6449*1b8b02a4SEd Tanous unsigned M; 6450*1b8b02a4SEd Tanous }; 6451*1b8b02a4SEd Tanous 6452*1b8b02a4SEd Tanous struct rld 6453*1b8b02a4SEd Tanous { 6454*1b8b02a4SEd Tanous long double& i; 6455*1b8b02a4SEd Tanous unsigned m; 6456*1b8b02a4SEd Tanous unsigned M; 6457*1b8b02a4SEd Tanous }; 6458*1b8b02a4SEd Tanous 6459*1b8b02a4SEd Tanous template <class CharT, class Traits> 6460*1b8b02a4SEd Tanous void 6461*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>&) 6462*1b8b02a4SEd Tanous { 6463*1b8b02a4SEd Tanous } 6464*1b8b02a4SEd Tanous 6465*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6466*1b8b02a4SEd Tanous void 6467*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args); 6468*1b8b02a4SEd Tanous 6469*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6470*1b8b02a4SEd Tanous void 6471*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args); 6472*1b8b02a4SEd Tanous 6473*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6474*1b8b02a4SEd Tanous void 6475*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args); 6476*1b8b02a4SEd Tanous 6477*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6478*1b8b02a4SEd Tanous void 6479*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args); 6480*1b8b02a4SEd Tanous 6481*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6482*1b8b02a4SEd Tanous void 6483*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args); 6484*1b8b02a4SEd Tanous 6485*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6486*1b8b02a4SEd Tanous void 6487*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args) 6488*1b8b02a4SEd Tanous { 6489*1b8b02a4SEd Tanous // No-op if a0 == CharT{} 6490*1b8b02a4SEd Tanous if (a0 != CharT{}) 6491*1b8b02a4SEd Tanous { 6492*1b8b02a4SEd Tanous auto ic = is.peek(); 6493*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 6494*1b8b02a4SEd Tanous { 6495*1b8b02a4SEd Tanous is.setstate(std::ios::failbit | std::ios::eofbit); 6496*1b8b02a4SEd Tanous return; 6497*1b8b02a4SEd Tanous } 6498*1b8b02a4SEd Tanous if (!Traits::eq(Traits::to_char_type(ic), a0)) 6499*1b8b02a4SEd Tanous { 6500*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6501*1b8b02a4SEd Tanous return; 6502*1b8b02a4SEd Tanous } 6503*1b8b02a4SEd Tanous (void)is.get(); 6504*1b8b02a4SEd Tanous } 6505*1b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 6506*1b8b02a4SEd Tanous } 6507*1b8b02a4SEd Tanous 6508*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6509*1b8b02a4SEd Tanous void 6510*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args) 6511*1b8b02a4SEd Tanous { 6512*1b8b02a4SEd Tanous auto x = read_signed(is, a0.m, a0.M); 6513*1b8b02a4SEd Tanous if (is.fail()) 6514*1b8b02a4SEd Tanous return; 6515*1b8b02a4SEd Tanous a0.i = x; 6516*1b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 6517*1b8b02a4SEd Tanous } 6518*1b8b02a4SEd Tanous 6519*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6520*1b8b02a4SEd Tanous void 6521*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args) 6522*1b8b02a4SEd Tanous { 6523*1b8b02a4SEd Tanous auto x = read_unsigned(is, a0.m, a0.M); 6524*1b8b02a4SEd Tanous if (is.fail()) 6525*1b8b02a4SEd Tanous return; 6526*1b8b02a4SEd Tanous a0.i = static_cast<int>(x); 6527*1b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 6528*1b8b02a4SEd Tanous } 6529*1b8b02a4SEd Tanous 6530*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6531*1b8b02a4SEd Tanous void 6532*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args) 6533*1b8b02a4SEd Tanous { 6534*1b8b02a4SEd Tanous if (a0 != -1) 6535*1b8b02a4SEd Tanous { 6536*1b8b02a4SEd Tanous auto u = static_cast<unsigned>(a0); 6537*1b8b02a4SEd Tanous CharT buf[std::numeric_limits<unsigned>::digits10+2u] = {}; 6538*1b8b02a4SEd Tanous auto e = buf; 6539*1b8b02a4SEd Tanous do 6540*1b8b02a4SEd Tanous { 6541*1b8b02a4SEd Tanous *e++ = static_cast<CharT>(CharT(u % 10) + CharT{'0'}); 6542*1b8b02a4SEd Tanous u /= 10; 6543*1b8b02a4SEd Tanous } while (u > 0); 6544*1b8b02a4SEd Tanous std::reverse(buf, e); 6545*1b8b02a4SEd Tanous for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) 6546*1b8b02a4SEd Tanous read(is, *p); 6547*1b8b02a4SEd Tanous } 6548*1b8b02a4SEd Tanous if (is.rdstate() == std::ios::goodbit) 6549*1b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 6550*1b8b02a4SEd Tanous } 6551*1b8b02a4SEd Tanous 6552*1b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 6553*1b8b02a4SEd Tanous void 6554*1b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args) 6555*1b8b02a4SEd Tanous { 6556*1b8b02a4SEd Tanous auto x = read_long_double(is, a0.m, a0.M); 6557*1b8b02a4SEd Tanous if (is.fail()) 6558*1b8b02a4SEd Tanous return; 6559*1b8b02a4SEd Tanous a0.i = x; 6560*1b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 6561*1b8b02a4SEd Tanous } 6562*1b8b02a4SEd Tanous 6563*1b8b02a4SEd Tanous template <class T, class CharT, class Traits> 6564*1b8b02a4SEd Tanous inline 6565*1b8b02a4SEd Tanous void 6566*1b8b02a4SEd Tanous checked_set(T& value, T from, T not_a_value, std::basic_ios<CharT, Traits>& is) 6567*1b8b02a4SEd Tanous { 6568*1b8b02a4SEd Tanous if (!is.fail()) 6569*1b8b02a4SEd Tanous { 6570*1b8b02a4SEd Tanous if (value == not_a_value) 6571*1b8b02a4SEd Tanous value = std::move(from); 6572*1b8b02a4SEd Tanous else if (value != from) 6573*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 6574*1b8b02a4SEd Tanous } 6575*1b8b02a4SEd Tanous } 6576*1b8b02a4SEd Tanous 6577*1b8b02a4SEd Tanous } // namespace detail; 6578*1b8b02a4SEd Tanous 6579*1b8b02a4SEd Tanous template <class CharT, class Traits, class Duration, class Alloc = std::allocator<CharT>> 6580*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 6581*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 6582*1b8b02a4SEd Tanous fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev, 6583*1b8b02a4SEd Tanous std::chrono::minutes* offset) 6584*1b8b02a4SEd Tanous { 6585*1b8b02a4SEd Tanous using std::numeric_limits; 6586*1b8b02a4SEd Tanous using std::ios; 6587*1b8b02a4SEd Tanous using std::chrono::duration; 6588*1b8b02a4SEd Tanous using std::chrono::duration_cast; 6589*1b8b02a4SEd Tanous using std::chrono::seconds; 6590*1b8b02a4SEd Tanous using std::chrono::minutes; 6591*1b8b02a4SEd Tanous using std::chrono::hours; 6592*1b8b02a4SEd Tanous using detail::round_i; 6593*1b8b02a4SEd Tanous typename std::basic_istream<CharT, Traits>::sentry ok{is, true}; 6594*1b8b02a4SEd Tanous if (ok) 6595*1b8b02a4SEd Tanous { 6596*1b8b02a4SEd Tanous date::detail::save_istream<CharT, Traits> ss(is); 6597*1b8b02a4SEd Tanous is.fill(' '); 6598*1b8b02a4SEd Tanous is.flags(std::ios::skipws | std::ios::dec); 6599*1b8b02a4SEd Tanous is.width(0); 6600*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6601*1b8b02a4SEd Tanous auto& f = std::use_facet<std::time_get<CharT>>(is.getloc()); 6602*1b8b02a4SEd Tanous std::tm tm{}; 6603*1b8b02a4SEd Tanous #endif 6604*1b8b02a4SEd Tanous const CharT* command = nullptr; 6605*1b8b02a4SEd Tanous auto modified = CharT{}; 6606*1b8b02a4SEd Tanous auto width = -1; 6607*1b8b02a4SEd Tanous 6608*1b8b02a4SEd Tanous CONSTDATA int not_a_year = numeric_limits<short>::min(); 6609*1b8b02a4SEd Tanous CONSTDATA int not_a_2digit_year = 100; 6610*1b8b02a4SEd Tanous CONSTDATA int not_a_century = not_a_year / 100; 6611*1b8b02a4SEd Tanous CONSTDATA int not_a_month = 0; 6612*1b8b02a4SEd Tanous CONSTDATA int not_a_day = 0; 6613*1b8b02a4SEd Tanous CONSTDATA int not_a_hour = numeric_limits<int>::min(); 6614*1b8b02a4SEd Tanous CONSTDATA int not_a_hour_12_value = 0; 6615*1b8b02a4SEd Tanous CONSTDATA int not_a_minute = not_a_hour; 6616*1b8b02a4SEd Tanous CONSTDATA Duration not_a_second = Duration::min(); 6617*1b8b02a4SEd Tanous CONSTDATA int not_a_doy = -1; 6618*1b8b02a4SEd Tanous CONSTDATA int not_a_weekday = 8; 6619*1b8b02a4SEd Tanous CONSTDATA int not_a_week_num = 100; 6620*1b8b02a4SEd Tanous CONSTDATA int not_a_ampm = -1; 6621*1b8b02a4SEd Tanous CONSTDATA minutes not_a_offset = minutes::min(); 6622*1b8b02a4SEd Tanous 6623*1b8b02a4SEd Tanous int Y = not_a_year; // c, F, Y * 6624*1b8b02a4SEd Tanous int y = not_a_2digit_year; // D, x, y * 6625*1b8b02a4SEd Tanous int g = not_a_2digit_year; // g * 6626*1b8b02a4SEd Tanous int G = not_a_year; // G * 6627*1b8b02a4SEd Tanous int C = not_a_century; // C * 6628*1b8b02a4SEd Tanous int m = not_a_month; // b, B, h, m, c, D, F, x * 6629*1b8b02a4SEd Tanous int d = not_a_day; // c, d, D, e, F, x * 6630*1b8b02a4SEd Tanous int j = not_a_doy; // j * 6631*1b8b02a4SEd Tanous int wd = not_a_weekday; // a, A, u, w * 6632*1b8b02a4SEd Tanous int H = not_a_hour; // c, H, R, T, X * 6633*1b8b02a4SEd Tanous int I = not_a_hour_12_value; // I, r * 6634*1b8b02a4SEd Tanous int p = not_a_ampm; // p, r * 6635*1b8b02a4SEd Tanous int M = not_a_minute; // c, M, r, R, T, X * 6636*1b8b02a4SEd Tanous Duration s = not_a_second; // c, r, S, T, X * 6637*1b8b02a4SEd Tanous int U = not_a_week_num; // U * 6638*1b8b02a4SEd Tanous int V = not_a_week_num; // V * 6639*1b8b02a4SEd Tanous int W = not_a_week_num; // W * 6640*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> temp_abbrev; // Z * 6641*1b8b02a4SEd Tanous minutes temp_offset = not_a_offset; // z * 6642*1b8b02a4SEd Tanous 6643*1b8b02a4SEd Tanous using detail::read; 6644*1b8b02a4SEd Tanous using detail::rs; 6645*1b8b02a4SEd Tanous using detail::ru; 6646*1b8b02a4SEd Tanous using detail::rld; 6647*1b8b02a4SEd Tanous using detail::checked_set; 6648*1b8b02a4SEd Tanous for (; *fmt != CharT{} && !is.fail(); ++fmt) 6649*1b8b02a4SEd Tanous { 6650*1b8b02a4SEd Tanous switch (*fmt) 6651*1b8b02a4SEd Tanous { 6652*1b8b02a4SEd Tanous case 'a': 6653*1b8b02a4SEd Tanous case 'A': 6654*1b8b02a4SEd Tanous case 'u': 6655*1b8b02a4SEd Tanous case 'w': // wd: a, A, u, w 6656*1b8b02a4SEd Tanous if (command) 6657*1b8b02a4SEd Tanous { 6658*1b8b02a4SEd Tanous int trial_wd = not_a_weekday; 6659*1b8b02a4SEd Tanous if (*fmt == 'a' || *fmt == 'A') 6660*1b8b02a4SEd Tanous { 6661*1b8b02a4SEd Tanous if (modified == CharT{}) 6662*1b8b02a4SEd Tanous { 6663*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6664*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6665*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6666*1b8b02a4SEd Tanous is.setstate(err); 6667*1b8b02a4SEd Tanous if (!is.fail()) 6668*1b8b02a4SEd Tanous trial_wd = tm.tm_wday; 6669*1b8b02a4SEd Tanous #else 6670*1b8b02a4SEd Tanous auto nm = detail::weekday_names(); 6671*1b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 6672*1b8b02a4SEd Tanous if (!is.fail()) 6673*1b8b02a4SEd Tanous trial_wd = i % 7; 6674*1b8b02a4SEd Tanous #endif 6675*1b8b02a4SEd Tanous } 6676*1b8b02a4SEd Tanous else 6677*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6678*1b8b02a4SEd Tanous } 6679*1b8b02a4SEd Tanous else // *fmt == 'u' || *fmt == 'w' 6680*1b8b02a4SEd Tanous { 6681*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6682*1b8b02a4SEd Tanous if (modified == CharT{}) 6683*1b8b02a4SEd Tanous #else 6684*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 6685*1b8b02a4SEd Tanous #endif 6686*1b8b02a4SEd Tanous { 6687*1b8b02a4SEd Tanous read(is, ru{trial_wd, 1, width == -1 ? 6688*1b8b02a4SEd Tanous 1u : static_cast<unsigned>(width)}); 6689*1b8b02a4SEd Tanous if (!is.fail()) 6690*1b8b02a4SEd Tanous { 6691*1b8b02a4SEd Tanous if (*fmt == 'u') 6692*1b8b02a4SEd Tanous { 6693*1b8b02a4SEd Tanous if (!(1 <= trial_wd && trial_wd <= 7)) 6694*1b8b02a4SEd Tanous { 6695*1b8b02a4SEd Tanous trial_wd = not_a_weekday; 6696*1b8b02a4SEd Tanous is.setstate(ios::failbit); 6697*1b8b02a4SEd Tanous } 6698*1b8b02a4SEd Tanous else if (trial_wd == 7) 6699*1b8b02a4SEd Tanous trial_wd = 0; 6700*1b8b02a4SEd Tanous } 6701*1b8b02a4SEd Tanous else // *fmt == 'w' 6702*1b8b02a4SEd Tanous { 6703*1b8b02a4SEd Tanous if (!(0 <= trial_wd && trial_wd <= 6)) 6704*1b8b02a4SEd Tanous { 6705*1b8b02a4SEd Tanous trial_wd = not_a_weekday; 6706*1b8b02a4SEd Tanous is.setstate(ios::failbit); 6707*1b8b02a4SEd Tanous } 6708*1b8b02a4SEd Tanous } 6709*1b8b02a4SEd Tanous } 6710*1b8b02a4SEd Tanous } 6711*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6712*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 6713*1b8b02a4SEd Tanous { 6714*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6715*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6716*1b8b02a4SEd Tanous is.setstate(err); 6717*1b8b02a4SEd Tanous if (!is.fail()) 6718*1b8b02a4SEd Tanous trial_wd = tm.tm_wday; 6719*1b8b02a4SEd Tanous } 6720*1b8b02a4SEd Tanous #endif 6721*1b8b02a4SEd Tanous else 6722*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6723*1b8b02a4SEd Tanous } 6724*1b8b02a4SEd Tanous if (trial_wd != not_a_weekday) 6725*1b8b02a4SEd Tanous checked_set(wd, trial_wd, not_a_weekday, is); 6726*1b8b02a4SEd Tanous } 6727*1b8b02a4SEd Tanous else // !command 6728*1b8b02a4SEd Tanous read(is, *fmt); 6729*1b8b02a4SEd Tanous command = nullptr; 6730*1b8b02a4SEd Tanous width = -1; 6731*1b8b02a4SEd Tanous modified = CharT{}; 6732*1b8b02a4SEd Tanous break; 6733*1b8b02a4SEd Tanous case 'b': 6734*1b8b02a4SEd Tanous case 'B': 6735*1b8b02a4SEd Tanous case 'h': 6736*1b8b02a4SEd Tanous if (command) 6737*1b8b02a4SEd Tanous { 6738*1b8b02a4SEd Tanous if (modified == CharT{}) 6739*1b8b02a4SEd Tanous { 6740*1b8b02a4SEd Tanous int ttm = not_a_month; 6741*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6742*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6743*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6744*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 6745*1b8b02a4SEd Tanous ttm = tm.tm_mon + 1; 6746*1b8b02a4SEd Tanous is.setstate(err); 6747*1b8b02a4SEd Tanous #else 6748*1b8b02a4SEd Tanous auto nm = detail::month_names(); 6749*1b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 6750*1b8b02a4SEd Tanous if (!is.fail()) 6751*1b8b02a4SEd Tanous ttm = i % 12 + 1; 6752*1b8b02a4SEd Tanous #endif 6753*1b8b02a4SEd Tanous checked_set(m, ttm, not_a_month, is); 6754*1b8b02a4SEd Tanous } 6755*1b8b02a4SEd Tanous else 6756*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6757*1b8b02a4SEd Tanous command = nullptr; 6758*1b8b02a4SEd Tanous width = -1; 6759*1b8b02a4SEd Tanous modified = CharT{}; 6760*1b8b02a4SEd Tanous } 6761*1b8b02a4SEd Tanous else 6762*1b8b02a4SEd Tanous read(is, *fmt); 6763*1b8b02a4SEd Tanous break; 6764*1b8b02a4SEd Tanous case 'c': 6765*1b8b02a4SEd Tanous if (command) 6766*1b8b02a4SEd Tanous { 6767*1b8b02a4SEd Tanous if (modified != CharT{'O'}) 6768*1b8b02a4SEd Tanous { 6769*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6770*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6771*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6772*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 6773*1b8b02a4SEd Tanous { 6774*1b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 6775*1b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 6776*1b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 6777*1b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 6778*1b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 6779*1b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 6780*1b8b02a4SEd Tanous not_a_second, is); 6781*1b8b02a4SEd Tanous } 6782*1b8b02a4SEd Tanous is.setstate(err); 6783*1b8b02a4SEd Tanous #else 6784*1b8b02a4SEd Tanous // "%a %b %e %T %Y" 6785*1b8b02a4SEd Tanous auto nm = detail::weekday_names(); 6786*1b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 6787*1b8b02a4SEd Tanous checked_set(wd, static_cast<int>(i % 7), not_a_weekday, is); 6788*1b8b02a4SEd Tanous ws(is); 6789*1b8b02a4SEd Tanous nm = detail::month_names(); 6790*1b8b02a4SEd Tanous i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 6791*1b8b02a4SEd Tanous checked_set(m, static_cast<int>(i % 12 + 1), not_a_month, is); 6792*1b8b02a4SEd Tanous ws(is); 6793*1b8b02a4SEd Tanous int td = not_a_day; 6794*1b8b02a4SEd Tanous read(is, rs{td, 1, 2}); 6795*1b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 6796*1b8b02a4SEd Tanous ws(is); 6797*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 6798*1b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 6799*1b8b02a4SEd Tanous int tH; 6800*1b8b02a4SEd Tanous int tM; 6801*1b8b02a4SEd Tanous long double S{}; 6802*1b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 6803*1b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 6804*1b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 6805*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 6806*1b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 6807*1b8b02a4SEd Tanous not_a_second, is); 6808*1b8b02a4SEd Tanous ws(is); 6809*1b8b02a4SEd Tanous int tY = not_a_year; 6810*1b8b02a4SEd Tanous read(is, rs{tY, 1, 4u}); 6811*1b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 6812*1b8b02a4SEd Tanous #endif 6813*1b8b02a4SEd Tanous } 6814*1b8b02a4SEd Tanous else 6815*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6816*1b8b02a4SEd Tanous command = nullptr; 6817*1b8b02a4SEd Tanous width = -1; 6818*1b8b02a4SEd Tanous modified = CharT{}; 6819*1b8b02a4SEd Tanous } 6820*1b8b02a4SEd Tanous else 6821*1b8b02a4SEd Tanous read(is, *fmt); 6822*1b8b02a4SEd Tanous break; 6823*1b8b02a4SEd Tanous case 'x': 6824*1b8b02a4SEd Tanous if (command) 6825*1b8b02a4SEd Tanous { 6826*1b8b02a4SEd Tanous if (modified != CharT{'O'}) 6827*1b8b02a4SEd Tanous { 6828*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6829*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6830*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6831*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 6832*1b8b02a4SEd Tanous { 6833*1b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 6834*1b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 6835*1b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 6836*1b8b02a4SEd Tanous } 6837*1b8b02a4SEd Tanous is.setstate(err); 6838*1b8b02a4SEd Tanous #else 6839*1b8b02a4SEd Tanous // "%m/%d/%y" 6840*1b8b02a4SEd Tanous int ty = not_a_2digit_year; 6841*1b8b02a4SEd Tanous int tm = not_a_month; 6842*1b8b02a4SEd Tanous int td = not_a_day; 6843*1b8b02a4SEd Tanous read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'}, 6844*1b8b02a4SEd Tanous rs{ty, 1, 2}); 6845*1b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 6846*1b8b02a4SEd Tanous checked_set(m, tm, not_a_month, is); 6847*1b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 6848*1b8b02a4SEd Tanous #endif 6849*1b8b02a4SEd Tanous } 6850*1b8b02a4SEd Tanous else 6851*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6852*1b8b02a4SEd Tanous command = nullptr; 6853*1b8b02a4SEd Tanous width = -1; 6854*1b8b02a4SEd Tanous modified = CharT{}; 6855*1b8b02a4SEd Tanous } 6856*1b8b02a4SEd Tanous else 6857*1b8b02a4SEd Tanous read(is, *fmt); 6858*1b8b02a4SEd Tanous break; 6859*1b8b02a4SEd Tanous case 'X': 6860*1b8b02a4SEd Tanous if (command) 6861*1b8b02a4SEd Tanous { 6862*1b8b02a4SEd Tanous if (modified != CharT{'O'}) 6863*1b8b02a4SEd Tanous { 6864*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6865*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6866*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6867*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 6868*1b8b02a4SEd Tanous { 6869*1b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 6870*1b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 6871*1b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 6872*1b8b02a4SEd Tanous not_a_second, is); 6873*1b8b02a4SEd Tanous } 6874*1b8b02a4SEd Tanous is.setstate(err); 6875*1b8b02a4SEd Tanous #else 6876*1b8b02a4SEd Tanous // "%T" 6877*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 6878*1b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 6879*1b8b02a4SEd Tanous int tH = not_a_hour; 6880*1b8b02a4SEd Tanous int tM = not_a_minute; 6881*1b8b02a4SEd Tanous long double S{}; 6882*1b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 6883*1b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 6884*1b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 6885*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 6886*1b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 6887*1b8b02a4SEd Tanous not_a_second, is); 6888*1b8b02a4SEd Tanous #endif 6889*1b8b02a4SEd Tanous } 6890*1b8b02a4SEd Tanous else 6891*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6892*1b8b02a4SEd Tanous command = nullptr; 6893*1b8b02a4SEd Tanous width = -1; 6894*1b8b02a4SEd Tanous modified = CharT{}; 6895*1b8b02a4SEd Tanous } 6896*1b8b02a4SEd Tanous else 6897*1b8b02a4SEd Tanous read(is, *fmt); 6898*1b8b02a4SEd Tanous break; 6899*1b8b02a4SEd Tanous case 'C': 6900*1b8b02a4SEd Tanous if (command) 6901*1b8b02a4SEd Tanous { 6902*1b8b02a4SEd Tanous int tC = not_a_century; 6903*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6904*1b8b02a4SEd Tanous if (modified == CharT{}) 6905*1b8b02a4SEd Tanous { 6906*1b8b02a4SEd Tanous #endif 6907*1b8b02a4SEd Tanous read(is, rs{tC, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 6908*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6909*1b8b02a4SEd Tanous } 6910*1b8b02a4SEd Tanous else 6911*1b8b02a4SEd Tanous { 6912*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6913*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6914*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 6915*1b8b02a4SEd Tanous { 6916*1b8b02a4SEd Tanous auto tY = tm.tm_year + 1900; 6917*1b8b02a4SEd Tanous tC = (tY >= 0 ? tY : tY-99) / 100; 6918*1b8b02a4SEd Tanous } 6919*1b8b02a4SEd Tanous is.setstate(err); 6920*1b8b02a4SEd Tanous } 6921*1b8b02a4SEd Tanous #endif 6922*1b8b02a4SEd Tanous checked_set(C, tC, not_a_century, is); 6923*1b8b02a4SEd Tanous command = nullptr; 6924*1b8b02a4SEd Tanous width = -1; 6925*1b8b02a4SEd Tanous modified = CharT{}; 6926*1b8b02a4SEd Tanous } 6927*1b8b02a4SEd Tanous else 6928*1b8b02a4SEd Tanous read(is, *fmt); 6929*1b8b02a4SEd Tanous break; 6930*1b8b02a4SEd Tanous case 'D': 6931*1b8b02a4SEd Tanous if (command) 6932*1b8b02a4SEd Tanous { 6933*1b8b02a4SEd Tanous if (modified == CharT{}) 6934*1b8b02a4SEd Tanous { 6935*1b8b02a4SEd Tanous int tn = not_a_month; 6936*1b8b02a4SEd Tanous int td = not_a_day; 6937*1b8b02a4SEd Tanous int ty = not_a_2digit_year; 6938*1b8b02a4SEd Tanous read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, 6939*1b8b02a4SEd Tanous ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, 6940*1b8b02a4SEd Tanous rs{ty, 1, 2}); 6941*1b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 6942*1b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 6943*1b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 6944*1b8b02a4SEd Tanous } 6945*1b8b02a4SEd Tanous else 6946*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6947*1b8b02a4SEd Tanous command = nullptr; 6948*1b8b02a4SEd Tanous width = -1; 6949*1b8b02a4SEd Tanous modified = CharT{}; 6950*1b8b02a4SEd Tanous } 6951*1b8b02a4SEd Tanous else 6952*1b8b02a4SEd Tanous read(is, *fmt); 6953*1b8b02a4SEd Tanous break; 6954*1b8b02a4SEd Tanous case 'F': 6955*1b8b02a4SEd Tanous if (command) 6956*1b8b02a4SEd Tanous { 6957*1b8b02a4SEd Tanous if (modified == CharT{}) 6958*1b8b02a4SEd Tanous { 6959*1b8b02a4SEd Tanous int tY = not_a_year; 6960*1b8b02a4SEd Tanous int tn = not_a_month; 6961*1b8b02a4SEd Tanous int td = not_a_day; 6962*1b8b02a4SEd Tanous read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)}, 6963*1b8b02a4SEd Tanous CharT{'-'}, ru{tn, 1, 2}, CharT{'-'}, ru{td, 1, 2}); 6964*1b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 6965*1b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 6966*1b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 6967*1b8b02a4SEd Tanous } 6968*1b8b02a4SEd Tanous else 6969*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 6970*1b8b02a4SEd Tanous command = nullptr; 6971*1b8b02a4SEd Tanous width = -1; 6972*1b8b02a4SEd Tanous modified = CharT{}; 6973*1b8b02a4SEd Tanous } 6974*1b8b02a4SEd Tanous else 6975*1b8b02a4SEd Tanous read(is, *fmt); 6976*1b8b02a4SEd Tanous break; 6977*1b8b02a4SEd Tanous case 'd': 6978*1b8b02a4SEd Tanous case 'e': 6979*1b8b02a4SEd Tanous if (command) 6980*1b8b02a4SEd Tanous { 6981*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6982*1b8b02a4SEd Tanous if (modified == CharT{}) 6983*1b8b02a4SEd Tanous #else 6984*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 6985*1b8b02a4SEd Tanous #endif 6986*1b8b02a4SEd Tanous { 6987*1b8b02a4SEd Tanous int td = not_a_day; 6988*1b8b02a4SEd Tanous read(is, rs{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 6989*1b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 6990*1b8b02a4SEd Tanous } 6991*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 6992*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 6993*1b8b02a4SEd Tanous { 6994*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 6995*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 6996*1b8b02a4SEd Tanous command = nullptr; 6997*1b8b02a4SEd Tanous width = -1; 6998*1b8b02a4SEd Tanous modified = CharT{}; 6999*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7000*1b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 7001*1b8b02a4SEd Tanous is.setstate(err); 7002*1b8b02a4SEd Tanous } 7003*1b8b02a4SEd Tanous #endif 7004*1b8b02a4SEd Tanous else 7005*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7006*1b8b02a4SEd Tanous command = nullptr; 7007*1b8b02a4SEd Tanous width = -1; 7008*1b8b02a4SEd Tanous modified = CharT{}; 7009*1b8b02a4SEd Tanous } 7010*1b8b02a4SEd Tanous else 7011*1b8b02a4SEd Tanous read(is, *fmt); 7012*1b8b02a4SEd Tanous break; 7013*1b8b02a4SEd Tanous case 'H': 7014*1b8b02a4SEd Tanous if (command) 7015*1b8b02a4SEd Tanous { 7016*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7017*1b8b02a4SEd Tanous if (modified == CharT{}) 7018*1b8b02a4SEd Tanous #else 7019*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 7020*1b8b02a4SEd Tanous #endif 7021*1b8b02a4SEd Tanous { 7022*1b8b02a4SEd Tanous int tH = not_a_hour; 7023*1b8b02a4SEd Tanous read(is, ru{tH, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7024*1b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 7025*1b8b02a4SEd Tanous } 7026*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7027*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 7028*1b8b02a4SEd Tanous { 7029*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7030*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7031*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7032*1b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 7033*1b8b02a4SEd Tanous is.setstate(err); 7034*1b8b02a4SEd Tanous } 7035*1b8b02a4SEd Tanous #endif 7036*1b8b02a4SEd Tanous else 7037*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7038*1b8b02a4SEd Tanous command = nullptr; 7039*1b8b02a4SEd Tanous width = -1; 7040*1b8b02a4SEd Tanous modified = CharT{}; 7041*1b8b02a4SEd Tanous } 7042*1b8b02a4SEd Tanous else 7043*1b8b02a4SEd Tanous read(is, *fmt); 7044*1b8b02a4SEd Tanous break; 7045*1b8b02a4SEd Tanous case 'I': 7046*1b8b02a4SEd Tanous if (command) 7047*1b8b02a4SEd Tanous { 7048*1b8b02a4SEd Tanous if (modified == CharT{}) 7049*1b8b02a4SEd Tanous { 7050*1b8b02a4SEd Tanous int tI = not_a_hour_12_value; 7051*1b8b02a4SEd Tanous // reads in an hour into I, but most be in [1, 12] 7052*1b8b02a4SEd Tanous read(is, rs{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7053*1b8b02a4SEd Tanous if (!(1 <= tI && tI <= 12)) 7054*1b8b02a4SEd Tanous is.setstate(ios::failbit); 7055*1b8b02a4SEd Tanous checked_set(I, tI, not_a_hour_12_value, is); 7056*1b8b02a4SEd Tanous } 7057*1b8b02a4SEd Tanous else 7058*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7059*1b8b02a4SEd Tanous command = nullptr; 7060*1b8b02a4SEd Tanous width = -1; 7061*1b8b02a4SEd Tanous modified = CharT{}; 7062*1b8b02a4SEd Tanous } 7063*1b8b02a4SEd Tanous else 7064*1b8b02a4SEd Tanous read(is, *fmt); 7065*1b8b02a4SEd Tanous break; 7066*1b8b02a4SEd Tanous case 'j': 7067*1b8b02a4SEd Tanous if (command) 7068*1b8b02a4SEd Tanous { 7069*1b8b02a4SEd Tanous if (modified == CharT{}) 7070*1b8b02a4SEd Tanous { 7071*1b8b02a4SEd Tanous int tj = not_a_doy; 7072*1b8b02a4SEd Tanous read(is, ru{tj, 1, width == -1 ? 3u : static_cast<unsigned>(width)}); 7073*1b8b02a4SEd Tanous checked_set(j, tj, not_a_doy, is); 7074*1b8b02a4SEd Tanous } 7075*1b8b02a4SEd Tanous else 7076*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7077*1b8b02a4SEd Tanous command = nullptr; 7078*1b8b02a4SEd Tanous width = -1; 7079*1b8b02a4SEd Tanous modified = CharT{}; 7080*1b8b02a4SEd Tanous } 7081*1b8b02a4SEd Tanous else 7082*1b8b02a4SEd Tanous read(is, *fmt); 7083*1b8b02a4SEd Tanous break; 7084*1b8b02a4SEd Tanous case 'M': 7085*1b8b02a4SEd Tanous if (command) 7086*1b8b02a4SEd Tanous { 7087*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7088*1b8b02a4SEd Tanous if (modified == CharT{}) 7089*1b8b02a4SEd Tanous #else 7090*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 7091*1b8b02a4SEd Tanous #endif 7092*1b8b02a4SEd Tanous { 7093*1b8b02a4SEd Tanous int tM = not_a_minute; 7094*1b8b02a4SEd Tanous read(is, ru{tM, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7095*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 7096*1b8b02a4SEd Tanous } 7097*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7098*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 7099*1b8b02a4SEd Tanous { 7100*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7101*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7102*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7103*1b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 7104*1b8b02a4SEd Tanous is.setstate(err); 7105*1b8b02a4SEd Tanous } 7106*1b8b02a4SEd Tanous #endif 7107*1b8b02a4SEd Tanous else 7108*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7109*1b8b02a4SEd Tanous command = nullptr; 7110*1b8b02a4SEd Tanous width = -1; 7111*1b8b02a4SEd Tanous modified = CharT{}; 7112*1b8b02a4SEd Tanous } 7113*1b8b02a4SEd Tanous else 7114*1b8b02a4SEd Tanous read(is, *fmt); 7115*1b8b02a4SEd Tanous break; 7116*1b8b02a4SEd Tanous case 'm': 7117*1b8b02a4SEd Tanous if (command) 7118*1b8b02a4SEd Tanous { 7119*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7120*1b8b02a4SEd Tanous if (modified == CharT{}) 7121*1b8b02a4SEd Tanous #else 7122*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 7123*1b8b02a4SEd Tanous #endif 7124*1b8b02a4SEd Tanous { 7125*1b8b02a4SEd Tanous int tn = not_a_month; 7126*1b8b02a4SEd Tanous read(is, rs{tn, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7127*1b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 7128*1b8b02a4SEd Tanous } 7129*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7130*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 7131*1b8b02a4SEd Tanous { 7132*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7133*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7134*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7135*1b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 7136*1b8b02a4SEd Tanous is.setstate(err); 7137*1b8b02a4SEd Tanous } 7138*1b8b02a4SEd Tanous #endif 7139*1b8b02a4SEd Tanous else 7140*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7141*1b8b02a4SEd Tanous command = nullptr; 7142*1b8b02a4SEd Tanous width = -1; 7143*1b8b02a4SEd Tanous modified = CharT{}; 7144*1b8b02a4SEd Tanous } 7145*1b8b02a4SEd Tanous else 7146*1b8b02a4SEd Tanous read(is, *fmt); 7147*1b8b02a4SEd Tanous break; 7148*1b8b02a4SEd Tanous case 'n': 7149*1b8b02a4SEd Tanous case 't': 7150*1b8b02a4SEd Tanous if (command) 7151*1b8b02a4SEd Tanous { 7152*1b8b02a4SEd Tanous if (modified == CharT{}) 7153*1b8b02a4SEd Tanous { 7154*1b8b02a4SEd Tanous // %n matches a single white space character 7155*1b8b02a4SEd Tanous // %t matches 0 or 1 white space characters 7156*1b8b02a4SEd Tanous auto ic = is.peek(); 7157*1b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 7158*1b8b02a4SEd Tanous { 7159*1b8b02a4SEd Tanous ios::iostate err = ios::eofbit; 7160*1b8b02a4SEd Tanous if (*fmt == 'n') 7161*1b8b02a4SEd Tanous err |= ios::failbit; 7162*1b8b02a4SEd Tanous is.setstate(err); 7163*1b8b02a4SEd Tanous break; 7164*1b8b02a4SEd Tanous } 7165*1b8b02a4SEd Tanous if (isspace(ic)) 7166*1b8b02a4SEd Tanous { 7167*1b8b02a4SEd Tanous (void)is.get(); 7168*1b8b02a4SEd Tanous } 7169*1b8b02a4SEd Tanous else if (*fmt == 'n') 7170*1b8b02a4SEd Tanous is.setstate(ios::failbit); 7171*1b8b02a4SEd Tanous } 7172*1b8b02a4SEd Tanous else 7173*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7174*1b8b02a4SEd Tanous command = nullptr; 7175*1b8b02a4SEd Tanous width = -1; 7176*1b8b02a4SEd Tanous modified = CharT{}; 7177*1b8b02a4SEd Tanous } 7178*1b8b02a4SEd Tanous else 7179*1b8b02a4SEd Tanous read(is, *fmt); 7180*1b8b02a4SEd Tanous break; 7181*1b8b02a4SEd Tanous case 'p': 7182*1b8b02a4SEd Tanous if (command) 7183*1b8b02a4SEd Tanous { 7184*1b8b02a4SEd Tanous if (modified == CharT{}) 7185*1b8b02a4SEd Tanous { 7186*1b8b02a4SEd Tanous int tp = not_a_ampm; 7187*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7188*1b8b02a4SEd Tanous tm = std::tm{}; 7189*1b8b02a4SEd Tanous tm.tm_hour = 1; 7190*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7191*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7192*1b8b02a4SEd Tanous is.setstate(err); 7193*1b8b02a4SEd Tanous if (tm.tm_hour == 1) 7194*1b8b02a4SEd Tanous tp = 0; 7195*1b8b02a4SEd Tanous else if (tm.tm_hour == 13) 7196*1b8b02a4SEd Tanous tp = 1; 7197*1b8b02a4SEd Tanous else 7198*1b8b02a4SEd Tanous is.setstate(err); 7199*1b8b02a4SEd Tanous #else 7200*1b8b02a4SEd Tanous auto nm = detail::ampm_names(); 7201*1b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 7202*1b8b02a4SEd Tanous tp = static_cast<decltype(tp)>(i); 7203*1b8b02a4SEd Tanous #endif 7204*1b8b02a4SEd Tanous checked_set(p, tp, not_a_ampm, is); 7205*1b8b02a4SEd Tanous } 7206*1b8b02a4SEd Tanous else 7207*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7208*1b8b02a4SEd Tanous command = nullptr; 7209*1b8b02a4SEd Tanous width = -1; 7210*1b8b02a4SEd Tanous modified = CharT{}; 7211*1b8b02a4SEd Tanous } 7212*1b8b02a4SEd Tanous else 7213*1b8b02a4SEd Tanous read(is, *fmt); 7214*1b8b02a4SEd Tanous 7215*1b8b02a4SEd Tanous break; 7216*1b8b02a4SEd Tanous case 'r': 7217*1b8b02a4SEd Tanous if (command) 7218*1b8b02a4SEd Tanous { 7219*1b8b02a4SEd Tanous if (modified == CharT{}) 7220*1b8b02a4SEd Tanous { 7221*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7222*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7223*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7224*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7225*1b8b02a4SEd Tanous { 7226*1b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 7227*1b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_hour, is); 7228*1b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 7229*1b8b02a4SEd Tanous not_a_second, is); 7230*1b8b02a4SEd Tanous } 7231*1b8b02a4SEd Tanous is.setstate(err); 7232*1b8b02a4SEd Tanous #else 7233*1b8b02a4SEd Tanous // "%I:%M:%S %p" 7234*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 7235*1b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 7236*1b8b02a4SEd Tanous long double S{}; 7237*1b8b02a4SEd Tanous int tI = not_a_hour_12_value; 7238*1b8b02a4SEd Tanous int tM = not_a_minute; 7239*1b8b02a4SEd Tanous read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 7240*1b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 7241*1b8b02a4SEd Tanous checked_set(I, tI, not_a_hour_12_value, is); 7242*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 7243*1b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 7244*1b8b02a4SEd Tanous not_a_second, is); 7245*1b8b02a4SEd Tanous ws(is); 7246*1b8b02a4SEd Tanous auto nm = detail::ampm_names(); 7247*1b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 7248*1b8b02a4SEd Tanous checked_set(p, static_cast<int>(i), not_a_ampm, is); 7249*1b8b02a4SEd Tanous #endif 7250*1b8b02a4SEd Tanous } 7251*1b8b02a4SEd Tanous else 7252*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7253*1b8b02a4SEd Tanous command = nullptr; 7254*1b8b02a4SEd Tanous width = -1; 7255*1b8b02a4SEd Tanous modified = CharT{}; 7256*1b8b02a4SEd Tanous } 7257*1b8b02a4SEd Tanous else 7258*1b8b02a4SEd Tanous read(is, *fmt); 7259*1b8b02a4SEd Tanous break; 7260*1b8b02a4SEd Tanous case 'R': 7261*1b8b02a4SEd Tanous if (command) 7262*1b8b02a4SEd Tanous { 7263*1b8b02a4SEd Tanous if (modified == CharT{}) 7264*1b8b02a4SEd Tanous { 7265*1b8b02a4SEd Tanous int tH = not_a_hour; 7266*1b8b02a4SEd Tanous int tM = not_a_minute; 7267*1b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'}, 7268*1b8b02a4SEd Tanous ru{tM, 1, 2}, CharT{'\0'}); 7269*1b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 7270*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 7271*1b8b02a4SEd Tanous } 7272*1b8b02a4SEd Tanous else 7273*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7274*1b8b02a4SEd Tanous command = nullptr; 7275*1b8b02a4SEd Tanous width = -1; 7276*1b8b02a4SEd Tanous modified = CharT{}; 7277*1b8b02a4SEd Tanous } 7278*1b8b02a4SEd Tanous else 7279*1b8b02a4SEd Tanous read(is, *fmt); 7280*1b8b02a4SEd Tanous break; 7281*1b8b02a4SEd Tanous case 'S': 7282*1b8b02a4SEd Tanous if (command) 7283*1b8b02a4SEd Tanous { 7284*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7285*1b8b02a4SEd Tanous if (modified == CharT{}) 7286*1b8b02a4SEd Tanous #else 7287*1b8b02a4SEd Tanous if (modified != CharT{'E'}) 7288*1b8b02a4SEd Tanous #endif 7289*1b8b02a4SEd Tanous { 7290*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 7291*1b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 7292*1b8b02a4SEd Tanous long double S{}; 7293*1b8b02a4SEd Tanous read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)}); 7294*1b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 7295*1b8b02a4SEd Tanous not_a_second, is); 7296*1b8b02a4SEd Tanous } 7297*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7298*1b8b02a4SEd Tanous else if (modified == CharT{'O'}) 7299*1b8b02a4SEd Tanous { 7300*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7301*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7302*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7303*1b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 7304*1b8b02a4SEd Tanous not_a_second, is); 7305*1b8b02a4SEd Tanous is.setstate(err); 7306*1b8b02a4SEd Tanous } 7307*1b8b02a4SEd Tanous #endif 7308*1b8b02a4SEd Tanous else 7309*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7310*1b8b02a4SEd Tanous command = nullptr; 7311*1b8b02a4SEd Tanous width = -1; 7312*1b8b02a4SEd Tanous modified = CharT{}; 7313*1b8b02a4SEd Tanous } 7314*1b8b02a4SEd Tanous else 7315*1b8b02a4SEd Tanous read(is, *fmt); 7316*1b8b02a4SEd Tanous break; 7317*1b8b02a4SEd Tanous case 'T': 7318*1b8b02a4SEd Tanous if (command) 7319*1b8b02a4SEd Tanous { 7320*1b8b02a4SEd Tanous if (modified == CharT{}) 7321*1b8b02a4SEd Tanous { 7322*1b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 7323*1b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 7324*1b8b02a4SEd Tanous int tH = not_a_hour; 7325*1b8b02a4SEd Tanous int tM = not_a_minute; 7326*1b8b02a4SEd Tanous long double S{}; 7327*1b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 7328*1b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 7329*1b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 7330*1b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 7331*1b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 7332*1b8b02a4SEd Tanous not_a_second, is); 7333*1b8b02a4SEd Tanous } 7334*1b8b02a4SEd Tanous else 7335*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7336*1b8b02a4SEd Tanous command = nullptr; 7337*1b8b02a4SEd Tanous width = -1; 7338*1b8b02a4SEd Tanous modified = CharT{}; 7339*1b8b02a4SEd Tanous } 7340*1b8b02a4SEd Tanous else 7341*1b8b02a4SEd Tanous read(is, *fmt); 7342*1b8b02a4SEd Tanous break; 7343*1b8b02a4SEd Tanous case 'Y': 7344*1b8b02a4SEd Tanous if (command) 7345*1b8b02a4SEd Tanous { 7346*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7347*1b8b02a4SEd Tanous if (modified == CharT{}) 7348*1b8b02a4SEd Tanous #else 7349*1b8b02a4SEd Tanous if (modified != CharT{'O'}) 7350*1b8b02a4SEd Tanous #endif 7351*1b8b02a4SEd Tanous { 7352*1b8b02a4SEd Tanous int tY = not_a_year; 7353*1b8b02a4SEd Tanous read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)}); 7354*1b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 7355*1b8b02a4SEd Tanous } 7356*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7357*1b8b02a4SEd Tanous else if (modified == CharT{'E'}) 7358*1b8b02a4SEd Tanous { 7359*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7360*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7361*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7362*1b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 7363*1b8b02a4SEd Tanous is.setstate(err); 7364*1b8b02a4SEd Tanous } 7365*1b8b02a4SEd Tanous #endif 7366*1b8b02a4SEd Tanous else 7367*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7368*1b8b02a4SEd Tanous command = nullptr; 7369*1b8b02a4SEd Tanous width = -1; 7370*1b8b02a4SEd Tanous modified = CharT{}; 7371*1b8b02a4SEd Tanous } 7372*1b8b02a4SEd Tanous else 7373*1b8b02a4SEd Tanous read(is, *fmt); 7374*1b8b02a4SEd Tanous break; 7375*1b8b02a4SEd Tanous case 'y': 7376*1b8b02a4SEd Tanous if (command) 7377*1b8b02a4SEd Tanous { 7378*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7379*1b8b02a4SEd Tanous if (modified == CharT{}) 7380*1b8b02a4SEd Tanous #endif 7381*1b8b02a4SEd Tanous { 7382*1b8b02a4SEd Tanous int ty = not_a_2digit_year; 7383*1b8b02a4SEd Tanous read(is, ru{ty, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7384*1b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 7385*1b8b02a4SEd Tanous } 7386*1b8b02a4SEd Tanous #if !ONLY_C_LOCALE 7387*1b8b02a4SEd Tanous else 7388*1b8b02a4SEd Tanous { 7389*1b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 7390*1b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 7391*1b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 7392*1b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 7393*1b8b02a4SEd Tanous is.setstate(err); 7394*1b8b02a4SEd Tanous } 7395*1b8b02a4SEd Tanous #endif 7396*1b8b02a4SEd Tanous command = nullptr; 7397*1b8b02a4SEd Tanous width = -1; 7398*1b8b02a4SEd Tanous modified = CharT{}; 7399*1b8b02a4SEd Tanous } 7400*1b8b02a4SEd Tanous else 7401*1b8b02a4SEd Tanous read(is, *fmt); 7402*1b8b02a4SEd Tanous break; 7403*1b8b02a4SEd Tanous case 'g': 7404*1b8b02a4SEd Tanous if (command) 7405*1b8b02a4SEd Tanous { 7406*1b8b02a4SEd Tanous if (modified == CharT{}) 7407*1b8b02a4SEd Tanous { 7408*1b8b02a4SEd Tanous int tg = not_a_2digit_year; 7409*1b8b02a4SEd Tanous read(is, ru{tg, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7410*1b8b02a4SEd Tanous checked_set(g, tg, not_a_2digit_year, is); 7411*1b8b02a4SEd Tanous } 7412*1b8b02a4SEd Tanous else 7413*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7414*1b8b02a4SEd Tanous command = nullptr; 7415*1b8b02a4SEd Tanous width = -1; 7416*1b8b02a4SEd Tanous modified = CharT{}; 7417*1b8b02a4SEd Tanous } 7418*1b8b02a4SEd Tanous else 7419*1b8b02a4SEd Tanous read(is, *fmt); 7420*1b8b02a4SEd Tanous break; 7421*1b8b02a4SEd Tanous case 'G': 7422*1b8b02a4SEd Tanous if (command) 7423*1b8b02a4SEd Tanous { 7424*1b8b02a4SEd Tanous if (modified == CharT{}) 7425*1b8b02a4SEd Tanous { 7426*1b8b02a4SEd Tanous int tG = not_a_year; 7427*1b8b02a4SEd Tanous read(is, rs{tG, 1, width == -1 ? 4u : static_cast<unsigned>(width)}); 7428*1b8b02a4SEd Tanous checked_set(G, tG, not_a_year, is); 7429*1b8b02a4SEd Tanous } 7430*1b8b02a4SEd Tanous else 7431*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7432*1b8b02a4SEd Tanous command = nullptr; 7433*1b8b02a4SEd Tanous width = -1; 7434*1b8b02a4SEd Tanous modified = CharT{}; 7435*1b8b02a4SEd Tanous } 7436*1b8b02a4SEd Tanous else 7437*1b8b02a4SEd Tanous read(is, *fmt); 7438*1b8b02a4SEd Tanous break; 7439*1b8b02a4SEd Tanous case 'U': 7440*1b8b02a4SEd Tanous if (command) 7441*1b8b02a4SEd Tanous { 7442*1b8b02a4SEd Tanous if (modified == CharT{}) 7443*1b8b02a4SEd Tanous { 7444*1b8b02a4SEd Tanous int tU = not_a_week_num; 7445*1b8b02a4SEd Tanous read(is, ru{tU, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7446*1b8b02a4SEd Tanous checked_set(U, tU, not_a_week_num, is); 7447*1b8b02a4SEd Tanous } 7448*1b8b02a4SEd Tanous else 7449*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7450*1b8b02a4SEd Tanous command = nullptr; 7451*1b8b02a4SEd Tanous width = -1; 7452*1b8b02a4SEd Tanous modified = CharT{}; 7453*1b8b02a4SEd Tanous } 7454*1b8b02a4SEd Tanous else 7455*1b8b02a4SEd Tanous read(is, *fmt); 7456*1b8b02a4SEd Tanous break; 7457*1b8b02a4SEd Tanous case 'V': 7458*1b8b02a4SEd Tanous if (command) 7459*1b8b02a4SEd Tanous { 7460*1b8b02a4SEd Tanous if (modified == CharT{}) 7461*1b8b02a4SEd Tanous { 7462*1b8b02a4SEd Tanous int tV = not_a_week_num; 7463*1b8b02a4SEd Tanous read(is, ru{tV, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7464*1b8b02a4SEd Tanous checked_set(V, tV, not_a_week_num, is); 7465*1b8b02a4SEd Tanous } 7466*1b8b02a4SEd Tanous else 7467*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7468*1b8b02a4SEd Tanous command = nullptr; 7469*1b8b02a4SEd Tanous width = -1; 7470*1b8b02a4SEd Tanous modified = CharT{}; 7471*1b8b02a4SEd Tanous } 7472*1b8b02a4SEd Tanous else 7473*1b8b02a4SEd Tanous read(is, *fmt); 7474*1b8b02a4SEd Tanous break; 7475*1b8b02a4SEd Tanous case 'W': 7476*1b8b02a4SEd Tanous if (command) 7477*1b8b02a4SEd Tanous { 7478*1b8b02a4SEd Tanous if (modified == CharT{}) 7479*1b8b02a4SEd Tanous { 7480*1b8b02a4SEd Tanous int tW = not_a_week_num; 7481*1b8b02a4SEd Tanous read(is, ru{tW, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 7482*1b8b02a4SEd Tanous checked_set(W, tW, not_a_week_num, is); 7483*1b8b02a4SEd Tanous } 7484*1b8b02a4SEd Tanous else 7485*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7486*1b8b02a4SEd Tanous command = nullptr; 7487*1b8b02a4SEd Tanous width = -1; 7488*1b8b02a4SEd Tanous modified = CharT{}; 7489*1b8b02a4SEd Tanous } 7490*1b8b02a4SEd Tanous else 7491*1b8b02a4SEd Tanous read(is, *fmt); 7492*1b8b02a4SEd Tanous break; 7493*1b8b02a4SEd Tanous case 'E': 7494*1b8b02a4SEd Tanous case 'O': 7495*1b8b02a4SEd Tanous if (command) 7496*1b8b02a4SEd Tanous { 7497*1b8b02a4SEd Tanous if (modified == CharT{}) 7498*1b8b02a4SEd Tanous { 7499*1b8b02a4SEd Tanous modified = *fmt; 7500*1b8b02a4SEd Tanous } 7501*1b8b02a4SEd Tanous else 7502*1b8b02a4SEd Tanous { 7503*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7504*1b8b02a4SEd Tanous command = nullptr; 7505*1b8b02a4SEd Tanous width = -1; 7506*1b8b02a4SEd Tanous modified = CharT{}; 7507*1b8b02a4SEd Tanous } 7508*1b8b02a4SEd Tanous } 7509*1b8b02a4SEd Tanous else 7510*1b8b02a4SEd Tanous read(is, *fmt); 7511*1b8b02a4SEd Tanous break; 7512*1b8b02a4SEd Tanous case '%': 7513*1b8b02a4SEd Tanous if (command) 7514*1b8b02a4SEd Tanous { 7515*1b8b02a4SEd Tanous if (modified == CharT{}) 7516*1b8b02a4SEd Tanous read(is, *fmt); 7517*1b8b02a4SEd Tanous else 7518*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7519*1b8b02a4SEd Tanous command = nullptr; 7520*1b8b02a4SEd Tanous width = -1; 7521*1b8b02a4SEd Tanous modified = CharT{}; 7522*1b8b02a4SEd Tanous } 7523*1b8b02a4SEd Tanous else 7524*1b8b02a4SEd Tanous command = fmt; 7525*1b8b02a4SEd Tanous break; 7526*1b8b02a4SEd Tanous case 'z': 7527*1b8b02a4SEd Tanous if (command) 7528*1b8b02a4SEd Tanous { 7529*1b8b02a4SEd Tanous int tH, tM; 7530*1b8b02a4SEd Tanous minutes toff = not_a_offset; 7531*1b8b02a4SEd Tanous bool neg = false; 7532*1b8b02a4SEd Tanous auto ic = is.peek(); 7533*1b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 7534*1b8b02a4SEd Tanous { 7535*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 7536*1b8b02a4SEd Tanous if (c == '-') 7537*1b8b02a4SEd Tanous neg = true; 7538*1b8b02a4SEd Tanous } 7539*1b8b02a4SEd Tanous if (modified == CharT{}) 7540*1b8b02a4SEd Tanous { 7541*1b8b02a4SEd Tanous read(is, rs{tH, 2, 2}); 7542*1b8b02a4SEd Tanous if (!is.fail()) 7543*1b8b02a4SEd Tanous toff = hours{std::abs(tH)}; 7544*1b8b02a4SEd Tanous if (is.good()) 7545*1b8b02a4SEd Tanous { 7546*1b8b02a4SEd Tanous ic = is.peek(); 7547*1b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 7548*1b8b02a4SEd Tanous { 7549*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 7550*1b8b02a4SEd Tanous if ('0' <= c && c <= '9') 7551*1b8b02a4SEd Tanous { 7552*1b8b02a4SEd Tanous read(is, ru{tM, 2, 2}); 7553*1b8b02a4SEd Tanous if (!is.fail()) 7554*1b8b02a4SEd Tanous toff += minutes{tM}; 7555*1b8b02a4SEd Tanous } 7556*1b8b02a4SEd Tanous } 7557*1b8b02a4SEd Tanous } 7558*1b8b02a4SEd Tanous } 7559*1b8b02a4SEd Tanous else 7560*1b8b02a4SEd Tanous { 7561*1b8b02a4SEd Tanous read(is, rs{tH, 1, 2}); 7562*1b8b02a4SEd Tanous if (!is.fail()) 7563*1b8b02a4SEd Tanous toff = hours{std::abs(tH)}; 7564*1b8b02a4SEd Tanous if (is.good()) 7565*1b8b02a4SEd Tanous { 7566*1b8b02a4SEd Tanous ic = is.peek(); 7567*1b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 7568*1b8b02a4SEd Tanous { 7569*1b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 7570*1b8b02a4SEd Tanous if (c == ':') 7571*1b8b02a4SEd Tanous { 7572*1b8b02a4SEd Tanous (void)is.get(); 7573*1b8b02a4SEd Tanous read(is, ru{tM, 2, 2}); 7574*1b8b02a4SEd Tanous if (!is.fail()) 7575*1b8b02a4SEd Tanous toff += minutes{tM}; 7576*1b8b02a4SEd Tanous } 7577*1b8b02a4SEd Tanous } 7578*1b8b02a4SEd Tanous } 7579*1b8b02a4SEd Tanous } 7580*1b8b02a4SEd Tanous if (neg) 7581*1b8b02a4SEd Tanous toff = -toff; 7582*1b8b02a4SEd Tanous checked_set(temp_offset, toff, not_a_offset, is); 7583*1b8b02a4SEd Tanous command = nullptr; 7584*1b8b02a4SEd Tanous width = -1; 7585*1b8b02a4SEd Tanous modified = CharT{}; 7586*1b8b02a4SEd Tanous } 7587*1b8b02a4SEd Tanous else 7588*1b8b02a4SEd Tanous read(is, *fmt); 7589*1b8b02a4SEd Tanous break; 7590*1b8b02a4SEd Tanous case 'Z': 7591*1b8b02a4SEd Tanous if (command) 7592*1b8b02a4SEd Tanous { 7593*1b8b02a4SEd Tanous if (modified == CharT{}) 7594*1b8b02a4SEd Tanous { 7595*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> buf; 7596*1b8b02a4SEd Tanous while (is.rdstate() == std::ios::goodbit) 7597*1b8b02a4SEd Tanous { 7598*1b8b02a4SEd Tanous auto i = is.rdbuf()->sgetc(); 7599*1b8b02a4SEd Tanous if (Traits::eq_int_type(i, Traits::eof())) 7600*1b8b02a4SEd Tanous { 7601*1b8b02a4SEd Tanous is.setstate(ios::eofbit); 7602*1b8b02a4SEd Tanous break; 7603*1b8b02a4SEd Tanous } 7604*1b8b02a4SEd Tanous auto wc = Traits::to_char_type(i); 7605*1b8b02a4SEd Tanous auto c = static_cast<char>(wc); 7606*1b8b02a4SEd Tanous // is c a valid time zone name or abbreviation character? 7607*1b8b02a4SEd Tanous if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) || 7608*1b8b02a4SEd Tanous c == '_' || c == '/' || c == '-' || c == '+')) 7609*1b8b02a4SEd Tanous break; 7610*1b8b02a4SEd Tanous buf.push_back(c); 7611*1b8b02a4SEd Tanous is.rdbuf()->sbumpc(); 7612*1b8b02a4SEd Tanous } 7613*1b8b02a4SEd Tanous if (buf.empty()) 7614*1b8b02a4SEd Tanous is.setstate(ios::failbit); 7615*1b8b02a4SEd Tanous checked_set(temp_abbrev, buf, {}, is); 7616*1b8b02a4SEd Tanous } 7617*1b8b02a4SEd Tanous else 7618*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7619*1b8b02a4SEd Tanous command = nullptr; 7620*1b8b02a4SEd Tanous width = -1; 7621*1b8b02a4SEd Tanous modified = CharT{}; 7622*1b8b02a4SEd Tanous } 7623*1b8b02a4SEd Tanous else 7624*1b8b02a4SEd Tanous read(is, *fmt); 7625*1b8b02a4SEd Tanous break; 7626*1b8b02a4SEd Tanous default: 7627*1b8b02a4SEd Tanous if (command) 7628*1b8b02a4SEd Tanous { 7629*1b8b02a4SEd Tanous if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') 7630*1b8b02a4SEd Tanous { 7631*1b8b02a4SEd Tanous width = static_cast<char>(*fmt) - '0'; 7632*1b8b02a4SEd Tanous while ('0' <= fmt[1] && fmt[1] <= '9') 7633*1b8b02a4SEd Tanous width = 10*width + static_cast<char>(*++fmt) - '0'; 7634*1b8b02a4SEd Tanous } 7635*1b8b02a4SEd Tanous else 7636*1b8b02a4SEd Tanous { 7637*1b8b02a4SEd Tanous if (modified == CharT{}) 7638*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, *fmt); 7639*1b8b02a4SEd Tanous else 7640*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 7641*1b8b02a4SEd Tanous command = nullptr; 7642*1b8b02a4SEd Tanous width = -1; 7643*1b8b02a4SEd Tanous modified = CharT{}; 7644*1b8b02a4SEd Tanous } 7645*1b8b02a4SEd Tanous } 7646*1b8b02a4SEd Tanous else // !command 7647*1b8b02a4SEd Tanous { 7648*1b8b02a4SEd Tanous if (isspace(static_cast<unsigned char>(*fmt))) 7649*1b8b02a4SEd Tanous { 7650*1b8b02a4SEd Tanous // space matches 0 or more white space characters 7651*1b8b02a4SEd Tanous if (is.good()) 7652*1b8b02a4SEd Tanous ws(is); 7653*1b8b02a4SEd Tanous } 7654*1b8b02a4SEd Tanous else 7655*1b8b02a4SEd Tanous read(is, *fmt); 7656*1b8b02a4SEd Tanous } 7657*1b8b02a4SEd Tanous break; 7658*1b8b02a4SEd Tanous } 7659*1b8b02a4SEd Tanous } 7660*1b8b02a4SEd Tanous // is.fail() || *fmt == CharT{} 7661*1b8b02a4SEd Tanous if (is.rdstate() == ios::goodbit && command) 7662*1b8b02a4SEd Tanous { 7663*1b8b02a4SEd Tanous if (modified == CharT{}) 7664*1b8b02a4SEd Tanous read(is, CharT{'%'}, width); 7665*1b8b02a4SEd Tanous else 7666*1b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified); 7667*1b8b02a4SEd Tanous } 7668*1b8b02a4SEd Tanous if (!is.fail()) 7669*1b8b02a4SEd Tanous { 7670*1b8b02a4SEd Tanous if (y != not_a_2digit_year) 7671*1b8b02a4SEd Tanous { 7672*1b8b02a4SEd Tanous // Convert y and an optional C to Y 7673*1b8b02a4SEd Tanous if (!(0 <= y && y <= 99)) 7674*1b8b02a4SEd Tanous goto broken; 7675*1b8b02a4SEd Tanous if (C == not_a_century) 7676*1b8b02a4SEd Tanous { 7677*1b8b02a4SEd Tanous if (Y == not_a_year) 7678*1b8b02a4SEd Tanous { 7679*1b8b02a4SEd Tanous if (y >= 69) 7680*1b8b02a4SEd Tanous C = 19; 7681*1b8b02a4SEd Tanous else 7682*1b8b02a4SEd Tanous C = 20; 7683*1b8b02a4SEd Tanous } 7684*1b8b02a4SEd Tanous else 7685*1b8b02a4SEd Tanous { 7686*1b8b02a4SEd Tanous C = (Y >= 0 ? Y : Y-100) / 100; 7687*1b8b02a4SEd Tanous } 7688*1b8b02a4SEd Tanous } 7689*1b8b02a4SEd Tanous int tY; 7690*1b8b02a4SEd Tanous if (C >= 0) 7691*1b8b02a4SEd Tanous tY = 100*C + y; 7692*1b8b02a4SEd Tanous else 7693*1b8b02a4SEd Tanous tY = 100*(C+1) - (y == 0 ? 100 : y); 7694*1b8b02a4SEd Tanous if (Y != not_a_year && Y != tY) 7695*1b8b02a4SEd Tanous goto broken; 7696*1b8b02a4SEd Tanous Y = tY; 7697*1b8b02a4SEd Tanous } 7698*1b8b02a4SEd Tanous if (g != not_a_2digit_year) 7699*1b8b02a4SEd Tanous { 7700*1b8b02a4SEd Tanous // Convert g and an optional C to G 7701*1b8b02a4SEd Tanous if (!(0 <= g && g <= 99)) 7702*1b8b02a4SEd Tanous goto broken; 7703*1b8b02a4SEd Tanous if (C == not_a_century) 7704*1b8b02a4SEd Tanous { 7705*1b8b02a4SEd Tanous if (G == not_a_year) 7706*1b8b02a4SEd Tanous { 7707*1b8b02a4SEd Tanous if (g >= 69) 7708*1b8b02a4SEd Tanous C = 19; 7709*1b8b02a4SEd Tanous else 7710*1b8b02a4SEd Tanous C = 20; 7711*1b8b02a4SEd Tanous } 7712*1b8b02a4SEd Tanous else 7713*1b8b02a4SEd Tanous { 7714*1b8b02a4SEd Tanous C = (G >= 0 ? G : G-100) / 100; 7715*1b8b02a4SEd Tanous } 7716*1b8b02a4SEd Tanous } 7717*1b8b02a4SEd Tanous int tG; 7718*1b8b02a4SEd Tanous if (C >= 0) 7719*1b8b02a4SEd Tanous tG = 100*C + g; 7720*1b8b02a4SEd Tanous else 7721*1b8b02a4SEd Tanous tG = 100*(C+1) - (g == 0 ? 100 : g); 7722*1b8b02a4SEd Tanous if (G != not_a_year && G != tG) 7723*1b8b02a4SEd Tanous goto broken; 7724*1b8b02a4SEd Tanous G = tG; 7725*1b8b02a4SEd Tanous } 7726*1b8b02a4SEd Tanous if (Y < static_cast<int>(year::min()) || Y > static_cast<int>(year::max())) 7727*1b8b02a4SEd Tanous Y = not_a_year; 7728*1b8b02a4SEd Tanous bool computed = false; 7729*1b8b02a4SEd Tanous if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) 7730*1b8b02a4SEd Tanous { 7731*1b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{G-1}/December/Thursday[last]) + 7732*1b8b02a4SEd Tanous (Monday-Thursday) + weeks{V-1} + 7733*1b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)}-Monday); 7734*1b8b02a4SEd Tanous if (Y == not_a_year) 7735*1b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 7736*1b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 7737*1b8b02a4SEd Tanous goto broken; 7738*1b8b02a4SEd Tanous if (m == not_a_month) 7739*1b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 7740*1b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 7741*1b8b02a4SEd Tanous goto broken; 7742*1b8b02a4SEd Tanous if (d == not_a_day) 7743*1b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 7744*1b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 7745*1b8b02a4SEd Tanous goto broken; 7746*1b8b02a4SEd Tanous computed = true; 7747*1b8b02a4SEd Tanous } 7748*1b8b02a4SEd Tanous if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday) 7749*1b8b02a4SEd Tanous { 7750*1b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) + 7751*1b8b02a4SEd Tanous weeks{U-1} + 7752*1b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)} - Sunday); 7753*1b8b02a4SEd Tanous if (Y == not_a_year) 7754*1b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 7755*1b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 7756*1b8b02a4SEd Tanous goto broken; 7757*1b8b02a4SEd Tanous if (m == not_a_month) 7758*1b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 7759*1b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 7760*1b8b02a4SEd Tanous goto broken; 7761*1b8b02a4SEd Tanous if (d == not_a_day) 7762*1b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 7763*1b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 7764*1b8b02a4SEd Tanous goto broken; 7765*1b8b02a4SEd Tanous computed = true; 7766*1b8b02a4SEd Tanous } 7767*1b8b02a4SEd Tanous if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday) 7768*1b8b02a4SEd Tanous { 7769*1b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) + 7770*1b8b02a4SEd Tanous weeks{W-1} + 7771*1b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)} - Monday); 7772*1b8b02a4SEd Tanous if (Y == not_a_year) 7773*1b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 7774*1b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 7775*1b8b02a4SEd Tanous goto broken; 7776*1b8b02a4SEd Tanous if (m == not_a_month) 7777*1b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 7778*1b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 7779*1b8b02a4SEd Tanous goto broken; 7780*1b8b02a4SEd Tanous if (d == not_a_day) 7781*1b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 7782*1b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 7783*1b8b02a4SEd Tanous goto broken; 7784*1b8b02a4SEd Tanous computed = true; 7785*1b8b02a4SEd Tanous } 7786*1b8b02a4SEd Tanous if (j != not_a_doy && Y != not_a_year) 7787*1b8b02a4SEd Tanous { 7788*1b8b02a4SEd Tanous auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; 7789*1b8b02a4SEd Tanous if (m == not_a_month) 7790*1b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 7791*1b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 7792*1b8b02a4SEd Tanous goto broken; 7793*1b8b02a4SEd Tanous if (d == not_a_day) 7794*1b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 7795*1b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 7796*1b8b02a4SEd Tanous goto broken; 7797*1b8b02a4SEd Tanous j = not_a_doy; 7798*1b8b02a4SEd Tanous } 7799*1b8b02a4SEd Tanous auto ymd = year{Y}/m/d; 7800*1b8b02a4SEd Tanous if (ymd.ok()) 7801*1b8b02a4SEd Tanous { 7802*1b8b02a4SEd Tanous if (wd == not_a_weekday) 7803*1b8b02a4SEd Tanous wd = static_cast<int>((weekday(sys_days(ymd)) - Sunday).count()); 7804*1b8b02a4SEd Tanous else if (wd != static_cast<int>((weekday(sys_days(ymd)) - Sunday).count())) 7805*1b8b02a4SEd Tanous goto broken; 7806*1b8b02a4SEd Tanous if (!computed) 7807*1b8b02a4SEd Tanous { 7808*1b8b02a4SEd Tanous if (G != not_a_year || V != not_a_week_num) 7809*1b8b02a4SEd Tanous { 7810*1b8b02a4SEd Tanous sys_days sd = ymd; 7811*1b8b02a4SEd Tanous auto G_trial = year_month_day{sd + days{3}}.year(); 7812*1b8b02a4SEd Tanous auto start = sys_days((G_trial - years{1})/December/Thursday[last]) + 7813*1b8b02a4SEd Tanous (Monday - Thursday); 7814*1b8b02a4SEd Tanous if (sd < start) 7815*1b8b02a4SEd Tanous { 7816*1b8b02a4SEd Tanous --G_trial; 7817*1b8b02a4SEd Tanous if (V != not_a_week_num) 7818*1b8b02a4SEd Tanous start = sys_days((G_trial - years{1})/December/Thursday[last]) 7819*1b8b02a4SEd Tanous + (Monday - Thursday); 7820*1b8b02a4SEd Tanous } 7821*1b8b02a4SEd Tanous if (G != not_a_year && G != static_cast<int>(G_trial)) 7822*1b8b02a4SEd Tanous goto broken; 7823*1b8b02a4SEd Tanous if (V != not_a_week_num) 7824*1b8b02a4SEd Tanous { 7825*1b8b02a4SEd Tanous auto V_trial = duration_cast<weeks>(sd - start).count() + 1; 7826*1b8b02a4SEd Tanous if (V != V_trial) 7827*1b8b02a4SEd Tanous goto broken; 7828*1b8b02a4SEd Tanous } 7829*1b8b02a4SEd Tanous } 7830*1b8b02a4SEd Tanous if (U != not_a_week_num) 7831*1b8b02a4SEd Tanous { 7832*1b8b02a4SEd Tanous auto start = sys_days(Sunday[1]/January/ymd.year()); 7833*1b8b02a4SEd Tanous auto U_trial = floor<weeks>(sys_days(ymd) - start).count() + 1; 7834*1b8b02a4SEd Tanous if (U != U_trial) 7835*1b8b02a4SEd Tanous goto broken; 7836*1b8b02a4SEd Tanous } 7837*1b8b02a4SEd Tanous if (W != not_a_week_num) 7838*1b8b02a4SEd Tanous { 7839*1b8b02a4SEd Tanous auto start = sys_days(Monday[1]/January/ymd.year()); 7840*1b8b02a4SEd Tanous auto W_trial = floor<weeks>(sys_days(ymd) - start).count() + 1; 7841*1b8b02a4SEd Tanous if (W != W_trial) 7842*1b8b02a4SEd Tanous goto broken; 7843*1b8b02a4SEd Tanous } 7844*1b8b02a4SEd Tanous } 7845*1b8b02a4SEd Tanous } 7846*1b8b02a4SEd Tanous fds.ymd = ymd; 7847*1b8b02a4SEd Tanous if (I != not_a_hour_12_value) 7848*1b8b02a4SEd Tanous { 7849*1b8b02a4SEd Tanous if (!(1 <= I && I <= 12)) 7850*1b8b02a4SEd Tanous goto broken; 7851*1b8b02a4SEd Tanous if (p != not_a_ampm) 7852*1b8b02a4SEd Tanous { 7853*1b8b02a4SEd Tanous // p is in [0, 1] == [AM, PM] 7854*1b8b02a4SEd Tanous // Store trial H in I 7855*1b8b02a4SEd Tanous if (I == 12) 7856*1b8b02a4SEd Tanous --p; 7857*1b8b02a4SEd Tanous I += p*12; 7858*1b8b02a4SEd Tanous // Either set H from I or make sure H and I are consistent 7859*1b8b02a4SEd Tanous if (H == not_a_hour) 7860*1b8b02a4SEd Tanous H = I; 7861*1b8b02a4SEd Tanous else if (I != H) 7862*1b8b02a4SEd Tanous goto broken; 7863*1b8b02a4SEd Tanous } 7864*1b8b02a4SEd Tanous else // p == not_a_ampm 7865*1b8b02a4SEd Tanous { 7866*1b8b02a4SEd Tanous // if H, make sure H and I could be consistent 7867*1b8b02a4SEd Tanous if (H != not_a_hour) 7868*1b8b02a4SEd Tanous { 7869*1b8b02a4SEd Tanous if (I == 12) 7870*1b8b02a4SEd Tanous { 7871*1b8b02a4SEd Tanous if (H != 0 && H != 12) 7872*1b8b02a4SEd Tanous goto broken; 7873*1b8b02a4SEd Tanous } 7874*1b8b02a4SEd Tanous else if (!(I == H || I == H+12)) 7875*1b8b02a4SEd Tanous { 7876*1b8b02a4SEd Tanous goto broken; 7877*1b8b02a4SEd Tanous } 7878*1b8b02a4SEd Tanous } 7879*1b8b02a4SEd Tanous else // I is ambiguous, AM or PM? 7880*1b8b02a4SEd Tanous goto broken; 7881*1b8b02a4SEd Tanous } 7882*1b8b02a4SEd Tanous } 7883*1b8b02a4SEd Tanous if (H != not_a_hour) 7884*1b8b02a4SEd Tanous { 7885*1b8b02a4SEd Tanous fds.has_tod = true; 7886*1b8b02a4SEd Tanous fds.tod = hh_mm_ss<Duration>{hours{H}}; 7887*1b8b02a4SEd Tanous } 7888*1b8b02a4SEd Tanous if (M != not_a_minute) 7889*1b8b02a4SEd Tanous { 7890*1b8b02a4SEd Tanous fds.has_tod = true; 7891*1b8b02a4SEd Tanous fds.tod.m_ = minutes{M}; 7892*1b8b02a4SEd Tanous } 7893*1b8b02a4SEd Tanous if (s != not_a_second) 7894*1b8b02a4SEd Tanous { 7895*1b8b02a4SEd Tanous fds.has_tod = true; 7896*1b8b02a4SEd Tanous fds.tod.s_ = detail::decimal_format_seconds<Duration>{s}; 7897*1b8b02a4SEd Tanous } 7898*1b8b02a4SEd Tanous if (j != not_a_doy) 7899*1b8b02a4SEd Tanous { 7900*1b8b02a4SEd Tanous fds.has_tod = true; 7901*1b8b02a4SEd Tanous fds.tod.h_ += hours{days{j}}; 7902*1b8b02a4SEd Tanous } 7903*1b8b02a4SEd Tanous if (wd != not_a_weekday) 7904*1b8b02a4SEd Tanous fds.wd = weekday{static_cast<unsigned>(wd)}; 7905*1b8b02a4SEd Tanous if (abbrev != nullptr) 7906*1b8b02a4SEd Tanous *abbrev = std::move(temp_abbrev); 7907*1b8b02a4SEd Tanous if (offset != nullptr && temp_offset != not_a_offset) 7908*1b8b02a4SEd Tanous *offset = temp_offset; 7909*1b8b02a4SEd Tanous } 7910*1b8b02a4SEd Tanous return is; 7911*1b8b02a4SEd Tanous } 7912*1b8b02a4SEd Tanous broken: 7913*1b8b02a4SEd Tanous is.setstate(ios::failbit); 7914*1b8b02a4SEd Tanous return is; 7915*1b8b02a4SEd Tanous } 7916*1b8b02a4SEd Tanous 7917*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7918*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7919*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year& y, 7920*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 7921*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 7922*1b8b02a4SEd Tanous { 7923*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 7924*1b8b02a4SEd Tanous fields<CT> fds{}; 7925*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 7926*1b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 7927*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 7928*1b8b02a4SEd Tanous if (!is.fail()) 7929*1b8b02a4SEd Tanous y = fds.ymd.year(); 7930*1b8b02a4SEd Tanous return is; 7931*1b8b02a4SEd Tanous } 7932*1b8b02a4SEd Tanous 7933*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7934*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7935*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month& m, 7936*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 7937*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 7938*1b8b02a4SEd Tanous { 7939*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 7940*1b8b02a4SEd Tanous fields<CT> fds{}; 7941*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 7942*1b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 7943*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 7944*1b8b02a4SEd Tanous if (!is.fail()) 7945*1b8b02a4SEd Tanous m = fds.ymd.month(); 7946*1b8b02a4SEd Tanous return is; 7947*1b8b02a4SEd Tanous } 7948*1b8b02a4SEd Tanous 7949*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7950*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7951*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, day& d, 7952*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 7953*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 7954*1b8b02a4SEd Tanous { 7955*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 7956*1b8b02a4SEd Tanous fields<CT> fds{}; 7957*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 7958*1b8b02a4SEd Tanous if (!fds.ymd.day().ok()) 7959*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 7960*1b8b02a4SEd Tanous if (!is.fail()) 7961*1b8b02a4SEd Tanous d = fds.ymd.day(); 7962*1b8b02a4SEd Tanous return is; 7963*1b8b02a4SEd Tanous } 7964*1b8b02a4SEd Tanous 7965*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7966*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7967*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, weekday& wd, 7968*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 7969*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 7970*1b8b02a4SEd Tanous { 7971*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 7972*1b8b02a4SEd Tanous fields<CT> fds{}; 7973*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 7974*1b8b02a4SEd Tanous if (!fds.wd.ok()) 7975*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 7976*1b8b02a4SEd Tanous if (!is.fail()) 7977*1b8b02a4SEd Tanous wd = fds.wd; 7978*1b8b02a4SEd Tanous return is; 7979*1b8b02a4SEd Tanous } 7980*1b8b02a4SEd Tanous 7981*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7982*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7983*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month& ym, 7984*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 7985*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 7986*1b8b02a4SEd Tanous { 7987*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 7988*1b8b02a4SEd Tanous fields<CT> fds{}; 7989*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 7990*1b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 7991*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 7992*1b8b02a4SEd Tanous if (!is.fail()) 7993*1b8b02a4SEd Tanous ym = fds.ymd.year()/fds.ymd.month(); 7994*1b8b02a4SEd Tanous return is; 7995*1b8b02a4SEd Tanous } 7996*1b8b02a4SEd Tanous 7997*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 7998*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 7999*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month_day& md, 8000*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8001*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8002*1b8b02a4SEd Tanous { 8003*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 8004*1b8b02a4SEd Tanous fields<CT> fds{}; 8005*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 8006*1b8b02a4SEd Tanous if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) 8007*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 8008*1b8b02a4SEd Tanous if (!is.fail()) 8009*1b8b02a4SEd Tanous md = fds.ymd.month()/fds.ymd.day(); 8010*1b8b02a4SEd Tanous return is; 8011*1b8b02a4SEd Tanous } 8012*1b8b02a4SEd Tanous 8013*1b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 8014*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 8015*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 8016*1b8b02a4SEd Tanous year_month_day& ymd, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8017*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8018*1b8b02a4SEd Tanous { 8019*1b8b02a4SEd Tanous using CT = std::chrono::seconds; 8020*1b8b02a4SEd Tanous fields<CT> fds{}; 8021*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 8022*1b8b02a4SEd Tanous if (!fds.ymd.ok()) 8023*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 8024*1b8b02a4SEd Tanous if (!is.fail()) 8025*1b8b02a4SEd Tanous ymd = fds.ymd; 8026*1b8b02a4SEd Tanous return is; 8027*1b8b02a4SEd Tanous } 8028*1b8b02a4SEd Tanous 8029*1b8b02a4SEd Tanous template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>> 8030*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 8031*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 8032*1b8b02a4SEd Tanous sys_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8033*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8034*1b8b02a4SEd Tanous { 8035*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 8036*1b8b02a4SEd Tanous using detail::round_i; 8037*1b8b02a4SEd Tanous std::chrono::minutes offset_local{}; 8038*1b8b02a4SEd Tanous auto offptr = offset ? offset : &offset_local; 8039*1b8b02a4SEd Tanous fields<CT> fds{}; 8040*1b8b02a4SEd Tanous fds.has_tod = true; 8041*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offptr); 8042*1b8b02a4SEd Tanous if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) 8043*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 8044*1b8b02a4SEd Tanous if (!is.fail()) 8045*1b8b02a4SEd Tanous tp = round_i<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); 8046*1b8b02a4SEd Tanous return is; 8047*1b8b02a4SEd Tanous } 8048*1b8b02a4SEd Tanous 8049*1b8b02a4SEd Tanous template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>> 8050*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 8051*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 8052*1b8b02a4SEd Tanous local_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8053*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8054*1b8b02a4SEd Tanous { 8055*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 8056*1b8b02a4SEd Tanous using detail::round_i; 8057*1b8b02a4SEd Tanous fields<CT> fds{}; 8058*1b8b02a4SEd Tanous fds.has_tod = true; 8059*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 8060*1b8b02a4SEd Tanous if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) 8061*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 8062*1b8b02a4SEd Tanous if (!is.fail()) 8063*1b8b02a4SEd Tanous tp = round_i<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); 8064*1b8b02a4SEd Tanous return is; 8065*1b8b02a4SEd Tanous } 8066*1b8b02a4SEd Tanous 8067*1b8b02a4SEd Tanous template <class Rep, class Period, class CharT, class Traits, class Alloc = std::allocator<CharT>> 8068*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 8069*1b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 8070*1b8b02a4SEd Tanous std::chrono::duration<Rep, Period>& d, 8071*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8072*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8073*1b8b02a4SEd Tanous { 8074*1b8b02a4SEd Tanous using Duration = std::chrono::duration<Rep, Period>; 8075*1b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 8076*1b8b02a4SEd Tanous using detail::round_i; 8077*1b8b02a4SEd Tanous fields<CT> fds{}; 8078*1b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 8079*1b8b02a4SEd Tanous if (!fds.has_tod) 8080*1b8b02a4SEd Tanous is.setstate(std::ios::failbit); 8081*1b8b02a4SEd Tanous if (!is.fail()) 8082*1b8b02a4SEd Tanous d = round_i<Duration>(fds.tod.to_duration()); 8083*1b8b02a4SEd Tanous return is; 8084*1b8b02a4SEd Tanous } 8085*1b8b02a4SEd Tanous 8086*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits = std::char_traits<CharT>, 8087*1b8b02a4SEd Tanous class Alloc = std::allocator<CharT>> 8088*1b8b02a4SEd Tanous struct parse_manip 8089*1b8b02a4SEd Tanous { 8090*1b8b02a4SEd Tanous const std::basic_string<CharT, Traits, Alloc> format_; 8091*1b8b02a4SEd Tanous Parsable& tp_; 8092*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev_; 8093*1b8b02a4SEd Tanous std::chrono::minutes* offset_; 8094*1b8b02a4SEd Tanous 8095*1b8b02a4SEd Tanous public: 8096*1b8b02a4SEd Tanous parse_manip(std::basic_string<CharT, Traits, Alloc> format, Parsable& tp, 8097*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8098*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8099*1b8b02a4SEd Tanous : format_(std::move(format)) 8100*1b8b02a4SEd Tanous , tp_(tp) 8101*1b8b02a4SEd Tanous , abbrev_(abbrev) 8102*1b8b02a4SEd Tanous , offset_(offset) 8103*1b8b02a4SEd Tanous {} 8104*1b8b02a4SEd Tanous 8105*1b8b02a4SEd Tanous #if HAS_STRING_VIEW 8106*1b8b02a4SEd Tanous parse_manip(const CharT* format, Parsable& tp, 8107*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8108*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8109*1b8b02a4SEd Tanous : format_(format) 8110*1b8b02a4SEd Tanous , tp_(tp) 8111*1b8b02a4SEd Tanous , abbrev_(abbrev) 8112*1b8b02a4SEd Tanous , offset_(offset) 8113*1b8b02a4SEd Tanous {} 8114*1b8b02a4SEd Tanous 8115*1b8b02a4SEd Tanous parse_manip(std::basic_string_view<CharT, Traits> format, Parsable& tp, 8116*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 8117*1b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 8118*1b8b02a4SEd Tanous : format_(format) 8119*1b8b02a4SEd Tanous , tp_(tp) 8120*1b8b02a4SEd Tanous , abbrev_(abbrev) 8121*1b8b02a4SEd Tanous , offset_(offset) 8122*1b8b02a4SEd Tanous {} 8123*1b8b02a4SEd Tanous #endif // HAS_STRING_VIEW 8124*1b8b02a4SEd Tanous }; 8125*1b8b02a4SEd Tanous 8126*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8127*1b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 8128*1b8b02a4SEd Tanous operator>>(std::basic_istream<CharT, Traits>& is, 8129*1b8b02a4SEd Tanous const parse_manip<Parsable, CharT, Traits, Alloc>& x) 8130*1b8b02a4SEd Tanous { 8131*1b8b02a4SEd Tanous return date::from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); 8132*1b8b02a4SEd Tanous } 8133*1b8b02a4SEd Tanous 8134*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8135*1b8b02a4SEd Tanous inline 8136*1b8b02a4SEd Tanous auto 8137*1b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp) 8138*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 8139*1b8b02a4SEd Tanous format.c_str(), tp), 8140*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp}) 8141*1b8b02a4SEd Tanous { 8142*1b8b02a4SEd Tanous return {format, tp}; 8143*1b8b02a4SEd Tanous } 8144*1b8b02a4SEd Tanous 8145*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8146*1b8b02a4SEd Tanous inline 8147*1b8b02a4SEd Tanous auto 8148*1b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 8149*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev) 8150*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 8151*1b8b02a4SEd Tanous format.c_str(), tp, &abbrev), 8152*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev}) 8153*1b8b02a4SEd Tanous { 8154*1b8b02a4SEd Tanous return {format, tp, &abbrev}; 8155*1b8b02a4SEd Tanous } 8156*1b8b02a4SEd Tanous 8157*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8158*1b8b02a4SEd Tanous inline 8159*1b8b02a4SEd Tanous auto 8160*1b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 8161*1b8b02a4SEd Tanous std::chrono::minutes& offset) 8162*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 8163*1b8b02a4SEd Tanous format.c_str(), tp, 8164*1b8b02a4SEd Tanous std::declval<std::basic_string<CharT, Traits, Alloc>*>(), 8165*1b8b02a4SEd Tanous &offset), 8166*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, nullptr, &offset}) 8167*1b8b02a4SEd Tanous { 8168*1b8b02a4SEd Tanous return {format, tp, nullptr, &offset}; 8169*1b8b02a4SEd Tanous } 8170*1b8b02a4SEd Tanous 8171*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8172*1b8b02a4SEd Tanous inline 8173*1b8b02a4SEd Tanous auto 8174*1b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 8175*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset) 8176*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 8177*1b8b02a4SEd Tanous format.c_str(), tp, &abbrev, &offset), 8178*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset}) 8179*1b8b02a4SEd Tanous { 8180*1b8b02a4SEd Tanous return {format, tp, &abbrev, &offset}; 8181*1b8b02a4SEd Tanous } 8182*1b8b02a4SEd Tanous 8183*1b8b02a4SEd Tanous // const CharT* formats 8184*1b8b02a4SEd Tanous 8185*1b8b02a4SEd Tanous template <class Parsable, class CharT> 8186*1b8b02a4SEd Tanous inline 8187*1b8b02a4SEd Tanous auto 8188*1b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp) 8189*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp), 8190*1b8b02a4SEd Tanous parse_manip<Parsable, CharT>{format, tp}) 8191*1b8b02a4SEd Tanous { 8192*1b8b02a4SEd Tanous return {format, tp}; 8193*1b8b02a4SEd Tanous } 8194*1b8b02a4SEd Tanous 8195*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8196*1b8b02a4SEd Tanous inline 8197*1b8b02a4SEd Tanous auto 8198*1b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits, Alloc>& abbrev) 8199*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, 8200*1b8b02a4SEd Tanous tp, &abbrev), 8201*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev}) 8202*1b8b02a4SEd Tanous { 8203*1b8b02a4SEd Tanous return {format, tp, &abbrev}; 8204*1b8b02a4SEd Tanous } 8205*1b8b02a4SEd Tanous 8206*1b8b02a4SEd Tanous template <class Parsable, class CharT> 8207*1b8b02a4SEd Tanous inline 8208*1b8b02a4SEd Tanous auto 8209*1b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) 8210*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT>&>(), format, 8211*1b8b02a4SEd Tanous tp, std::declval<std::basic_string<CharT>*>(), &offset), 8212*1b8b02a4SEd Tanous parse_manip<Parsable, CharT>{format, tp, nullptr, &offset}) 8213*1b8b02a4SEd Tanous { 8214*1b8b02a4SEd Tanous return {format, tp, nullptr, &offset}; 8215*1b8b02a4SEd Tanous } 8216*1b8b02a4SEd Tanous 8217*1b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 8218*1b8b02a4SEd Tanous inline 8219*1b8b02a4SEd Tanous auto 8220*1b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, 8221*1b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset) 8222*1b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, 8223*1b8b02a4SEd Tanous tp, &abbrev, &offset), 8224*1b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset}) 8225*1b8b02a4SEd Tanous { 8226*1b8b02a4SEd Tanous return {format, tp, &abbrev, &offset}; 8227*1b8b02a4SEd Tanous } 8228*1b8b02a4SEd Tanous 8229*1b8b02a4SEd Tanous // duration streaming 8230*1b8b02a4SEd Tanous 8231*1b8b02a4SEd Tanous template <class CharT, class Traits, class Rep, class Period> 8232*1b8b02a4SEd Tanous inline 8233*1b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 8234*1b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, 8235*1b8b02a4SEd Tanous const std::chrono::duration<Rep, Period>& d) 8236*1b8b02a4SEd Tanous { 8237*1b8b02a4SEd Tanous return os << detail::make_string<CharT, Traits>::from(d.count()) + 8238*1b8b02a4SEd Tanous detail::get_units<CharT>(typename Period::type{}); 8239*1b8b02a4SEd Tanous } 8240*1b8b02a4SEd Tanous 8241*1b8b02a4SEd Tanous } // namespace date 8242*1b8b02a4SEd Tanous 8243*1b8b02a4SEd Tanous #ifdef _MSC_VER 8244*1b8b02a4SEd Tanous # pragma warning(pop) 8245*1b8b02a4SEd Tanous #endif 8246*1b8b02a4SEd Tanous 8247*1b8b02a4SEd Tanous #ifdef __GNUC__ 8248*1b8b02a4SEd Tanous # pragma GCC diagnostic pop 8249*1b8b02a4SEd Tanous #endif 8250*1b8b02a4SEd Tanous 8251*1b8b02a4SEd Tanous // NOLINTEND 8252*1b8b02a4SEd Tanous // clang-format off 8253*1b8b02a4SEd Tanous 8254*1b8b02a4SEd Tanous #endif // DATE_H 8255