1*06a63974SEd Tanous #pragma once 21b8b02a4SEd Tanous // NOLINTBEGIN 31b8b02a4SEd Tanous // clang-format off 41b8b02a4SEd Tanous 51b8b02a4SEd Tanous /* 61b8b02a4SEd Tanous * Originally sourced from 71b8b02a4SEd Tanous * https://github.com/HowardHinnant/date/blob/master/include/date/date.h 81b8b02a4SEd Tanous */ 91b8b02a4SEd Tanous 101b8b02a4SEd Tanous // The MIT License (MIT) 111b8b02a4SEd Tanous // 121b8b02a4SEd Tanous // Copyright (c) 2015, 2016, 2017 Howard Hinnant 131b8b02a4SEd Tanous // Copyright (c) 2016 Adrian Colomitchi 141b8b02a4SEd Tanous // Copyright (c) 2017 Florian Dang 151b8b02a4SEd Tanous // Copyright (c) 2017 Paul Thompson 161b8b02a4SEd Tanous // Copyright (c) 2018, 2019 Tomasz Kamiński 171b8b02a4SEd Tanous // Copyright (c) 2019 Jiangang Zhuang 181b8b02a4SEd Tanous // 191b8b02a4SEd Tanous // Permission is hereby granted, free of charge, to any person obtaining a copy 201b8b02a4SEd Tanous // of this software and associated documentation files (the "Software"), to deal 211b8b02a4SEd Tanous // in the Software without restriction, including without limitation the rights 221b8b02a4SEd Tanous // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 231b8b02a4SEd Tanous // copies of the Software, and to permit persons to whom the Software is 241b8b02a4SEd Tanous // furnished to do so, subject to the following conditions: 251b8b02a4SEd Tanous // 261b8b02a4SEd Tanous // The above copyright notice and this permission notice shall be included in all 271b8b02a4SEd Tanous // copies or substantial portions of the Software. 281b8b02a4SEd Tanous // 291b8b02a4SEd Tanous // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 301b8b02a4SEd Tanous // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 311b8b02a4SEd Tanous // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 321b8b02a4SEd Tanous // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 331b8b02a4SEd Tanous // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 341b8b02a4SEd Tanous // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 351b8b02a4SEd Tanous // SOFTWARE. 361b8b02a4SEd Tanous // 371b8b02a4SEd Tanous // Our apologies. When the previous paragraph was written, lowercase had not yet 381b8b02a4SEd Tanous // been invented (that would involve another several millennia of evolution). 391b8b02a4SEd Tanous // We did not mean to shout. 401b8b02a4SEd Tanous 411b8b02a4SEd Tanous #ifndef HAS_STRING_VIEW 421b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 431b8b02a4SEd Tanous # define HAS_STRING_VIEW 1 441b8b02a4SEd Tanous # else 451b8b02a4SEd Tanous # define HAS_STRING_VIEW 0 461b8b02a4SEd Tanous # endif 471b8b02a4SEd Tanous #endif // HAS_STRING_VIEW 481b8b02a4SEd Tanous 491b8b02a4SEd Tanous #include <cassert> 501b8b02a4SEd Tanous #include <algorithm> 511b8b02a4SEd Tanous #include <cctype> 521b8b02a4SEd Tanous #include <chrono> 531b8b02a4SEd Tanous #include <climits> 541b8b02a4SEd Tanous #include <cmath> 551b8b02a4SEd Tanous #include <cstddef> 561b8b02a4SEd Tanous #include <cstdint> 571b8b02a4SEd Tanous #include <cstdlib> 581b8b02a4SEd Tanous #include <ctime> 591b8b02a4SEd Tanous #include <ios> 601b8b02a4SEd Tanous #include <istream> 611b8b02a4SEd Tanous #include <iterator> 621b8b02a4SEd Tanous #include <limits> 631b8b02a4SEd Tanous #include <locale> 641b8b02a4SEd Tanous #include <memory> 651b8b02a4SEd Tanous #include <ostream> 661b8b02a4SEd Tanous #include <ratio> 671b8b02a4SEd Tanous #include <sstream> 681b8b02a4SEd Tanous #include <stdexcept> 691b8b02a4SEd Tanous #include <string> 701b8b02a4SEd Tanous #if HAS_STRING_VIEW 711b8b02a4SEd Tanous # include <string_view> 721b8b02a4SEd Tanous #endif 731b8b02a4SEd Tanous #include <utility> 741b8b02a4SEd Tanous #include <type_traits> 751b8b02a4SEd Tanous 761b8b02a4SEd Tanous 771b8b02a4SEd Tanous #ifdef __GNUC__ 781b8b02a4SEd Tanous # pragma GCC diagnostic push 791b8b02a4SEd Tanous # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) 801b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wpedantic" 811b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wconversion" 821b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wold-style-cast" 831b8b02a4SEd Tanous # endif 841b8b02a4SEd Tanous # if __GNUC__ < 5 851b8b02a4SEd Tanous // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers 861b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wmissing-field-initializers" 871b8b02a4SEd Tanous # endif 881b8b02a4SEd Tanous #endif 891b8b02a4SEd Tanous 901b8b02a4SEd Tanous #ifdef __clang__ 911b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" 921b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 931b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wold-style-cast" 941b8b02a4SEd Tanous #endif 951b8b02a4SEd Tanous 961b8b02a4SEd Tanous #ifdef _MSC_VER 971b8b02a4SEd Tanous # pragma warning(push) 981b8b02a4SEd Tanous // warning C4127: conditional expression is constant 991b8b02a4SEd Tanous # pragma warning(disable : 4127) 1001b8b02a4SEd Tanous #endif 1011b8b02a4SEd Tanous 1021b8b02a4SEd Tanous namespace date 1031b8b02a4SEd Tanous { 1041b8b02a4SEd Tanous 1051b8b02a4SEd Tanous //---------------+ 1061b8b02a4SEd Tanous // Configuration | 1071b8b02a4SEd Tanous //---------------+ 1081b8b02a4SEd Tanous 1091b8b02a4SEd Tanous #ifndef ONLY_C_LOCALE 1101b8b02a4SEd Tanous # define ONLY_C_LOCALE 1 1111b8b02a4SEd Tanous #endif 1121b8b02a4SEd Tanous 1131b8b02a4SEd Tanous #if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910)) 1141b8b02a4SEd Tanous // MSVC 1151b8b02a4SEd Tanous # ifndef _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 1161b8b02a4SEd Tanous # define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 1171b8b02a4SEd Tanous # endif 1181b8b02a4SEd Tanous # if _MSC_VER < 1910 1191b8b02a4SEd Tanous // before VS2017 1201b8b02a4SEd Tanous # define CONSTDATA const 1211b8b02a4SEd Tanous # define CONSTCD11 1221b8b02a4SEd Tanous # define CONSTCD14 1231b8b02a4SEd Tanous # define NOEXCEPT _NOEXCEPT 1241b8b02a4SEd Tanous # else 1251b8b02a4SEd Tanous // VS2017 and later 1261b8b02a4SEd Tanous # define CONSTDATA constexpr const 1271b8b02a4SEd Tanous # define CONSTCD11 constexpr 1281b8b02a4SEd Tanous # define CONSTCD14 constexpr 1291b8b02a4SEd Tanous # define NOEXCEPT noexcept 1301b8b02a4SEd Tanous # endif 1311b8b02a4SEd Tanous 1321b8b02a4SEd Tanous #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 1331b8b02a4SEd Tanous // Oracle Developer Studio 12.6 and earlier 1341b8b02a4SEd Tanous # define CONSTDATA constexpr const 1351b8b02a4SEd Tanous # define CONSTCD11 constexpr 1361b8b02a4SEd Tanous # define CONSTCD14 1371b8b02a4SEd Tanous # define NOEXCEPT noexcept 1381b8b02a4SEd Tanous 1391b8b02a4SEd Tanous #elif __cplusplus >= 201402 1401b8b02a4SEd Tanous // C++14 1411b8b02a4SEd Tanous # define CONSTDATA constexpr const 1421b8b02a4SEd Tanous # define CONSTCD11 constexpr 1431b8b02a4SEd Tanous # define CONSTCD14 constexpr 1441b8b02a4SEd Tanous # define NOEXCEPT noexcept 1451b8b02a4SEd Tanous #else 1461b8b02a4SEd Tanous // C++11 1471b8b02a4SEd Tanous # define CONSTDATA constexpr const 1481b8b02a4SEd Tanous # define CONSTCD11 constexpr 1491b8b02a4SEd Tanous # define CONSTCD14 1501b8b02a4SEd Tanous # define NOEXCEPT noexcept 1511b8b02a4SEd Tanous #endif 1521b8b02a4SEd Tanous 1531b8b02a4SEd Tanous #ifndef HAS_UNCAUGHT_EXCEPTIONS 1541b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 1551b8b02a4SEd Tanous # define HAS_UNCAUGHT_EXCEPTIONS 1 1561b8b02a4SEd Tanous # else 1571b8b02a4SEd Tanous # define HAS_UNCAUGHT_EXCEPTIONS 0 1581b8b02a4SEd Tanous # endif 1591b8b02a4SEd Tanous #endif // HAS_UNCAUGHT_EXCEPTIONS 1601b8b02a4SEd Tanous 1611b8b02a4SEd Tanous #ifndef HAS_VOID_T 1621b8b02a4SEd Tanous # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 1631b8b02a4SEd Tanous # define HAS_VOID_T 1 1641b8b02a4SEd Tanous # else 1651b8b02a4SEd Tanous # define HAS_VOID_T 0 1661b8b02a4SEd Tanous # endif 1671b8b02a4SEd Tanous #endif // HAS_VOID_T 1681b8b02a4SEd Tanous 1691b8b02a4SEd Tanous // Protect from Oracle sun macro 1701b8b02a4SEd Tanous #ifdef sun 1711b8b02a4SEd Tanous # undef sun 1721b8b02a4SEd Tanous #endif 1731b8b02a4SEd Tanous 1741b8b02a4SEd Tanous // Work around for a NVCC compiler bug which causes it to fail 1751b8b02a4SEd Tanous // to compile std::ratio_{multiply,divide} when used directly 1761b8b02a4SEd Tanous // in the std::chrono::duration template instantiations below 1771b8b02a4SEd Tanous namespace detail { 1781b8b02a4SEd Tanous template <typename R1, typename R2> 1791b8b02a4SEd Tanous using ratio_multiply = decltype(std::ratio_multiply<R1, R2>{}); 1801b8b02a4SEd Tanous 1811b8b02a4SEd Tanous template <typename R1, typename R2> 1821b8b02a4SEd Tanous using ratio_divide = decltype(std::ratio_divide<R1, R2>{}); 1831b8b02a4SEd Tanous } // namespace detail 1841b8b02a4SEd Tanous 1851b8b02a4SEd Tanous //-----------+ 1861b8b02a4SEd Tanous // Interface | 1871b8b02a4SEd Tanous //-----------+ 1881b8b02a4SEd Tanous 1891b8b02a4SEd Tanous // durations 1901b8b02a4SEd Tanous 1911b8b02a4SEd Tanous using days = std::chrono::duration 1921b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>; 1931b8b02a4SEd Tanous 1941b8b02a4SEd Tanous using weeks = std::chrono::duration 1951b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<7>, days::period>>; 1961b8b02a4SEd Tanous 1971b8b02a4SEd Tanous using years = std::chrono::duration 1981b8b02a4SEd Tanous <int, detail::ratio_multiply<std::ratio<146097, 400>, days::period>>; 1991b8b02a4SEd Tanous 2001b8b02a4SEd Tanous using months = std::chrono::duration 2011b8b02a4SEd Tanous <int, detail::ratio_divide<years::period, std::ratio<12>>>; 2021b8b02a4SEd Tanous 2031b8b02a4SEd Tanous // time_point 2041b8b02a4SEd Tanous 2051b8b02a4SEd Tanous template <class Duration> 2061b8b02a4SEd Tanous using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>; 2071b8b02a4SEd Tanous 2081b8b02a4SEd Tanous using sys_days = sys_time<days>; 2091b8b02a4SEd Tanous using sys_seconds = sys_time<std::chrono::seconds>; 2101b8b02a4SEd Tanous 2111b8b02a4SEd Tanous struct local_t {}; 2121b8b02a4SEd Tanous 2131b8b02a4SEd Tanous template <class Duration> 2141b8b02a4SEd Tanous using local_time = std::chrono::time_point<local_t, Duration>; 2151b8b02a4SEd Tanous 2161b8b02a4SEd Tanous using local_seconds = local_time<std::chrono::seconds>; 2171b8b02a4SEd Tanous using local_days = local_time<days>; 2181b8b02a4SEd Tanous 2191b8b02a4SEd Tanous // types 2201b8b02a4SEd Tanous 2211b8b02a4SEd Tanous struct last_spec 2221b8b02a4SEd Tanous { 2231b8b02a4SEd Tanous explicit last_spec() = default; 2241b8b02a4SEd Tanous }; 2251b8b02a4SEd Tanous 2261b8b02a4SEd Tanous class day; 2271b8b02a4SEd Tanous class month; 2281b8b02a4SEd Tanous class year; 2291b8b02a4SEd Tanous 2301b8b02a4SEd Tanous class weekday; 2311b8b02a4SEd Tanous class weekday_indexed; 2321b8b02a4SEd Tanous class weekday_last; 2331b8b02a4SEd Tanous 2341b8b02a4SEd Tanous class month_day; 2351b8b02a4SEd Tanous class month_day_last; 2361b8b02a4SEd Tanous class month_weekday; 2371b8b02a4SEd Tanous class month_weekday_last; 2381b8b02a4SEd Tanous 2391b8b02a4SEd Tanous class year_month; 2401b8b02a4SEd Tanous 2411b8b02a4SEd Tanous class year_month_day; 2421b8b02a4SEd Tanous class year_month_day_last; 2431b8b02a4SEd Tanous class year_month_weekday; 2441b8b02a4SEd Tanous class year_month_weekday_last; 2451b8b02a4SEd Tanous 2461b8b02a4SEd Tanous // date composition operators 2471b8b02a4SEd Tanous 2481b8b02a4SEd Tanous CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; 2491b8b02a4SEd Tanous CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; 2501b8b02a4SEd Tanous 2511b8b02a4SEd Tanous CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; 2521b8b02a4SEd Tanous CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; 2531b8b02a4SEd Tanous CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; 2541b8b02a4SEd Tanous CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; 2551b8b02a4SEd Tanous CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; 2561b8b02a4SEd Tanous 2571b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; 2581b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; 2591b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; 2601b8b02a4SEd Tanous CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; 2611b8b02a4SEd Tanous 2621b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; 2631b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; 2641b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; 2651b8b02a4SEd Tanous CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; 2661b8b02a4SEd Tanous 2671b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; 2681b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; 2691b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; 2701b8b02a4SEd Tanous CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; 2711b8b02a4SEd Tanous 2721b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; 2731b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; 2741b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; 2751b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; 2761b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; 2771b8b02a4SEd Tanous CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; 2781b8b02a4SEd Tanous 2791b8b02a4SEd Tanous CONSTCD11 2801b8b02a4SEd Tanous year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; 2811b8b02a4SEd Tanous CONSTCD11 2821b8b02a4SEd Tanous year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; 2831b8b02a4SEd Tanous CONSTCD11 2841b8b02a4SEd Tanous year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; 2851b8b02a4SEd Tanous CONSTCD11 2861b8b02a4SEd Tanous year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; 2871b8b02a4SEd Tanous CONSTCD11 2881b8b02a4SEd Tanous year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; 2891b8b02a4SEd Tanous 2901b8b02a4SEd Tanous CONSTCD11 2911b8b02a4SEd Tanous year_month_weekday 2921b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; 2931b8b02a4SEd Tanous 2941b8b02a4SEd Tanous CONSTCD11 2951b8b02a4SEd Tanous year_month_weekday 2961b8b02a4SEd Tanous operator/(const year& y, const month_weekday& mwd) NOEXCEPT; 2971b8b02a4SEd Tanous 2981b8b02a4SEd Tanous CONSTCD11 2991b8b02a4SEd Tanous year_month_weekday 3001b8b02a4SEd Tanous operator/(int y, const month_weekday& mwd) NOEXCEPT; 3011b8b02a4SEd Tanous 3021b8b02a4SEd Tanous CONSTCD11 3031b8b02a4SEd Tanous year_month_weekday 3041b8b02a4SEd Tanous operator/(const month_weekday& mwd, const year& y) NOEXCEPT; 3051b8b02a4SEd Tanous 3061b8b02a4SEd Tanous CONSTCD11 3071b8b02a4SEd Tanous year_month_weekday 3081b8b02a4SEd Tanous operator/(const month_weekday& mwd, int y) NOEXCEPT; 3091b8b02a4SEd Tanous 3101b8b02a4SEd Tanous CONSTCD11 3111b8b02a4SEd Tanous year_month_weekday_last 3121b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; 3131b8b02a4SEd Tanous 3141b8b02a4SEd Tanous CONSTCD11 3151b8b02a4SEd Tanous year_month_weekday_last 3161b8b02a4SEd Tanous operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; 3171b8b02a4SEd Tanous 3181b8b02a4SEd Tanous CONSTCD11 3191b8b02a4SEd Tanous year_month_weekday_last 3201b8b02a4SEd Tanous operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; 3211b8b02a4SEd Tanous 3221b8b02a4SEd Tanous CONSTCD11 3231b8b02a4SEd Tanous year_month_weekday_last 3241b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; 3251b8b02a4SEd Tanous 3261b8b02a4SEd Tanous CONSTCD11 3271b8b02a4SEd Tanous year_month_weekday_last 3281b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; 3291b8b02a4SEd Tanous 3301b8b02a4SEd Tanous // Detailed interface 3311b8b02a4SEd Tanous 3321b8b02a4SEd Tanous // day 3331b8b02a4SEd Tanous 3341b8b02a4SEd Tanous class day 3351b8b02a4SEd Tanous { 3361b8b02a4SEd Tanous unsigned char d_; 3371b8b02a4SEd Tanous 3381b8b02a4SEd Tanous public: 3391b8b02a4SEd Tanous day() = default; 3401b8b02a4SEd Tanous explicit CONSTCD11 day(unsigned d) NOEXCEPT; 3411b8b02a4SEd Tanous 3421b8b02a4SEd Tanous CONSTCD14 day& operator++() NOEXCEPT; 3431b8b02a4SEd Tanous CONSTCD14 day operator++(int) NOEXCEPT; 3441b8b02a4SEd Tanous CONSTCD14 day& operator--() NOEXCEPT; 3451b8b02a4SEd Tanous CONSTCD14 day operator--(int) NOEXCEPT; 3461b8b02a4SEd Tanous 3471b8b02a4SEd Tanous CONSTCD14 day& operator+=(const days& d) NOEXCEPT; 3481b8b02a4SEd Tanous CONSTCD14 day& operator-=(const days& d) NOEXCEPT; 3491b8b02a4SEd Tanous 3501b8b02a4SEd Tanous CONSTCD11 explicit operator unsigned() const NOEXCEPT; 3511b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 3521b8b02a4SEd Tanous }; 3531b8b02a4SEd Tanous 3541b8b02a4SEd Tanous CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; 3551b8b02a4SEd Tanous CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; 3561b8b02a4SEd Tanous CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; 3571b8b02a4SEd Tanous CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; 3581b8b02a4SEd Tanous CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; 3591b8b02a4SEd Tanous CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; 3601b8b02a4SEd Tanous 3611b8b02a4SEd Tanous CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; 3621b8b02a4SEd Tanous CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; 3631b8b02a4SEd Tanous CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; 3641b8b02a4SEd Tanous CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; 3651b8b02a4SEd Tanous 3661b8b02a4SEd Tanous template<class CharT, class Traits> 3671b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 3681b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const day& d); 3691b8b02a4SEd Tanous 3701b8b02a4SEd Tanous // month 3711b8b02a4SEd Tanous 3721b8b02a4SEd Tanous class month 3731b8b02a4SEd Tanous { 3741b8b02a4SEd Tanous unsigned char m_; 3751b8b02a4SEd Tanous 3761b8b02a4SEd Tanous public: 3771b8b02a4SEd Tanous month() = default; 3781b8b02a4SEd Tanous explicit CONSTCD11 month(unsigned m) NOEXCEPT; 3791b8b02a4SEd Tanous 3801b8b02a4SEd Tanous CONSTCD14 month& operator++() NOEXCEPT; 3811b8b02a4SEd Tanous CONSTCD14 month operator++(int) NOEXCEPT; 3821b8b02a4SEd Tanous CONSTCD14 month& operator--() NOEXCEPT; 3831b8b02a4SEd Tanous CONSTCD14 month operator--(int) NOEXCEPT; 3841b8b02a4SEd Tanous 3851b8b02a4SEd Tanous CONSTCD14 month& operator+=(const months& m) NOEXCEPT; 3861b8b02a4SEd Tanous CONSTCD14 month& operator-=(const months& m) NOEXCEPT; 3871b8b02a4SEd Tanous 3881b8b02a4SEd Tanous CONSTCD11 explicit operator unsigned() const NOEXCEPT; 3891b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 3901b8b02a4SEd Tanous }; 3911b8b02a4SEd Tanous 3921b8b02a4SEd Tanous CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; 3931b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; 3941b8b02a4SEd Tanous CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; 3951b8b02a4SEd Tanous CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; 3961b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; 3971b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; 3981b8b02a4SEd Tanous 3991b8b02a4SEd Tanous CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; 4001b8b02a4SEd Tanous CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; 4011b8b02a4SEd Tanous CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; 4021b8b02a4SEd Tanous CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; 4031b8b02a4SEd Tanous 4041b8b02a4SEd Tanous template<class CharT, class Traits> 4051b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4061b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month& m); 4071b8b02a4SEd Tanous 4081b8b02a4SEd Tanous // year 4091b8b02a4SEd Tanous 4101b8b02a4SEd Tanous class year 4111b8b02a4SEd Tanous { 4121b8b02a4SEd Tanous short y_; 4131b8b02a4SEd Tanous 4141b8b02a4SEd Tanous public: 4151b8b02a4SEd Tanous year() = default; 4161b8b02a4SEd Tanous explicit CONSTCD11 year(int y) NOEXCEPT; 4171b8b02a4SEd Tanous 4181b8b02a4SEd Tanous CONSTCD14 year& operator++() NOEXCEPT; 4191b8b02a4SEd Tanous CONSTCD14 year operator++(int) NOEXCEPT; 4201b8b02a4SEd Tanous CONSTCD14 year& operator--() NOEXCEPT; 4211b8b02a4SEd Tanous CONSTCD14 year operator--(int) NOEXCEPT; 4221b8b02a4SEd Tanous 4231b8b02a4SEd Tanous CONSTCD14 year& operator+=(const years& y) NOEXCEPT; 4241b8b02a4SEd Tanous CONSTCD14 year& operator-=(const years& y) NOEXCEPT; 4251b8b02a4SEd Tanous 4261b8b02a4SEd Tanous CONSTCD11 year operator-() const NOEXCEPT; 4271b8b02a4SEd Tanous CONSTCD11 year operator+() const NOEXCEPT; 4281b8b02a4SEd Tanous 4291b8b02a4SEd Tanous CONSTCD11 bool is_leap() const NOEXCEPT; 4301b8b02a4SEd Tanous 4311b8b02a4SEd Tanous CONSTCD11 explicit operator int() const NOEXCEPT; 4321b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 4331b8b02a4SEd Tanous 4341b8b02a4SEd Tanous static CONSTCD11 year min() NOEXCEPT { return year{-32767}; } 4351b8b02a4SEd Tanous static CONSTCD11 year max() NOEXCEPT { return year{32767}; } 4361b8b02a4SEd Tanous }; 4371b8b02a4SEd Tanous 4381b8b02a4SEd Tanous CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; 4391b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; 4401b8b02a4SEd Tanous CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; 4411b8b02a4SEd Tanous CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; 4421b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; 4431b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; 4441b8b02a4SEd Tanous 4451b8b02a4SEd Tanous CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; 4461b8b02a4SEd Tanous CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; 4471b8b02a4SEd Tanous CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; 4481b8b02a4SEd Tanous CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; 4491b8b02a4SEd Tanous 4501b8b02a4SEd Tanous template<class CharT, class Traits> 4511b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 4521b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year& y); 4531b8b02a4SEd Tanous 4541b8b02a4SEd Tanous // weekday 4551b8b02a4SEd Tanous 4561b8b02a4SEd Tanous class weekday 4571b8b02a4SEd Tanous { 4581b8b02a4SEd Tanous unsigned char wd_; 4591b8b02a4SEd Tanous public: 4601b8b02a4SEd Tanous weekday() = default; 4611b8b02a4SEd Tanous explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; 4621b8b02a4SEd Tanous CONSTCD14 weekday(const sys_days& dp) NOEXCEPT; 4631b8b02a4SEd Tanous CONSTCD14 explicit weekday(const local_days& dp) NOEXCEPT; 4641b8b02a4SEd Tanous 4651b8b02a4SEd Tanous CONSTCD14 weekday& operator++() NOEXCEPT; 4661b8b02a4SEd Tanous CONSTCD14 weekday operator++(int) NOEXCEPT; 4671b8b02a4SEd Tanous CONSTCD14 weekday& operator--() NOEXCEPT; 4681b8b02a4SEd Tanous CONSTCD14 weekday operator--(int) NOEXCEPT; 4691b8b02a4SEd Tanous 4701b8b02a4SEd Tanous CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; 4711b8b02a4SEd Tanous CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; 4721b8b02a4SEd Tanous 4731b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 4741b8b02a4SEd Tanous 4751b8b02a4SEd Tanous CONSTCD11 unsigned c_encoding() const NOEXCEPT; 4761b8b02a4SEd Tanous CONSTCD11 unsigned iso_encoding() const NOEXCEPT; 4771b8b02a4SEd Tanous 4781b8b02a4SEd Tanous CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; 4791b8b02a4SEd Tanous CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; 4801b8b02a4SEd Tanous 4811b8b02a4SEd Tanous private: 4821b8b02a4SEd Tanous static CONSTCD14 unsigned char weekday_from_days(int z) NOEXCEPT; 4831b8b02a4SEd Tanous 4841b8b02a4SEd Tanous friend CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; 4851b8b02a4SEd Tanous friend CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; 4861b8b02a4SEd Tanous friend CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; 4871b8b02a4SEd Tanous template<class CharT, class Traits> 4881b8b02a4SEd Tanous friend std::basic_ostream<CharT, Traits>& 4891b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd); 4901b8b02a4SEd Tanous friend class weekday_indexed; 4911b8b02a4SEd Tanous }; 4921b8b02a4SEd Tanous 4931b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; 4941b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; 4951b8b02a4SEd Tanous 4961b8b02a4SEd Tanous CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; 4971b8b02a4SEd Tanous CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; 4981b8b02a4SEd Tanous CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; 4991b8b02a4SEd Tanous CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; 5001b8b02a4SEd Tanous 5011b8b02a4SEd Tanous template<class CharT, class Traits> 5021b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 5031b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd); 5041b8b02a4SEd Tanous 5051b8b02a4SEd Tanous // weekday_indexed 5061b8b02a4SEd Tanous 5071b8b02a4SEd Tanous class weekday_indexed 5081b8b02a4SEd Tanous { 5091b8b02a4SEd Tanous unsigned char wd_ : 4; 5101b8b02a4SEd Tanous unsigned char index_ : 4; 5111b8b02a4SEd Tanous 5121b8b02a4SEd Tanous public: 5131b8b02a4SEd Tanous weekday_indexed() = default; 5141b8b02a4SEd Tanous CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT; 5151b8b02a4SEd Tanous 5161b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 5171b8b02a4SEd Tanous CONSTCD11 unsigned index() const NOEXCEPT; 5181b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 5191b8b02a4SEd Tanous }; 5201b8b02a4SEd Tanous 5211b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; 5221b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; 5231b8b02a4SEd Tanous 5241b8b02a4SEd Tanous template<class CharT, class Traits> 5251b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 5261b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi); 5271b8b02a4SEd Tanous 5281b8b02a4SEd Tanous // weekday_last 5291b8b02a4SEd Tanous 5301b8b02a4SEd Tanous class weekday_last 5311b8b02a4SEd Tanous { 5321b8b02a4SEd Tanous date::weekday wd_; 5331b8b02a4SEd Tanous 5341b8b02a4SEd Tanous public: 5351b8b02a4SEd Tanous explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT; 5361b8b02a4SEd Tanous 5371b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 5381b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 5391b8b02a4SEd Tanous }; 5401b8b02a4SEd Tanous 5411b8b02a4SEd Tanous CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; 5421b8b02a4SEd Tanous CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; 5431b8b02a4SEd Tanous 5441b8b02a4SEd Tanous template<class CharT, class Traits> 5451b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 5461b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl); 5471b8b02a4SEd Tanous 5481b8b02a4SEd Tanous namespace detail 5491b8b02a4SEd Tanous { 5501b8b02a4SEd Tanous 5511b8b02a4SEd Tanous struct unspecified_month_disambiguator {}; 5521b8b02a4SEd Tanous 5531b8b02a4SEd Tanous } // namespace detail 5541b8b02a4SEd Tanous 5551b8b02a4SEd Tanous // year_month 5561b8b02a4SEd Tanous 5571b8b02a4SEd Tanous class year_month 5581b8b02a4SEd Tanous { 5591b8b02a4SEd Tanous date::year y_; 5601b8b02a4SEd Tanous date::month m_; 5611b8b02a4SEd Tanous 5621b8b02a4SEd Tanous public: 5631b8b02a4SEd Tanous year_month() = default; 5641b8b02a4SEd Tanous CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT; 5651b8b02a4SEd Tanous 5661b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 5671b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 5681b8b02a4SEd Tanous 5691b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 5701b8b02a4SEd Tanous CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; 5711b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 5721b8b02a4SEd Tanous CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; 5731b8b02a4SEd Tanous CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; 5741b8b02a4SEd Tanous CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; 5751b8b02a4SEd Tanous 5761b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 5771b8b02a4SEd Tanous }; 5781b8b02a4SEd Tanous 5791b8b02a4SEd Tanous CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; 5801b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; 5811b8b02a4SEd Tanous CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; 5821b8b02a4SEd Tanous CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; 5831b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; 5841b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; 5851b8b02a4SEd Tanous 5861b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 5871b8b02a4SEd Tanous CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; 5881b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 5891b8b02a4SEd Tanous CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; 5901b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 5911b8b02a4SEd Tanous CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; 5921b8b02a4SEd Tanous 5931b8b02a4SEd Tanous CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; 5941b8b02a4SEd Tanous CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; 5951b8b02a4SEd Tanous CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; 5961b8b02a4SEd Tanous CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; 5971b8b02a4SEd Tanous 5981b8b02a4SEd Tanous template<class CharT, class Traits> 5991b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6001b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym); 6011b8b02a4SEd Tanous 6021b8b02a4SEd Tanous // month_day 6031b8b02a4SEd Tanous 6041b8b02a4SEd Tanous class month_day 6051b8b02a4SEd Tanous { 6061b8b02a4SEd Tanous date::month m_; 6071b8b02a4SEd Tanous date::day d_; 6081b8b02a4SEd Tanous 6091b8b02a4SEd Tanous public: 6101b8b02a4SEd Tanous month_day() = default; 6111b8b02a4SEd Tanous CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT; 6121b8b02a4SEd Tanous 6131b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 6141b8b02a4SEd Tanous CONSTCD11 date::day day() const NOEXCEPT; 6151b8b02a4SEd Tanous 6161b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 6171b8b02a4SEd Tanous }; 6181b8b02a4SEd Tanous 6191b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; 6201b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; 6211b8b02a4SEd Tanous CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; 6221b8b02a4SEd Tanous CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; 6231b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; 6241b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; 6251b8b02a4SEd Tanous 6261b8b02a4SEd Tanous template<class CharT, class Traits> 6271b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6281b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md); 6291b8b02a4SEd Tanous 6301b8b02a4SEd Tanous // month_day_last 6311b8b02a4SEd Tanous 6321b8b02a4SEd Tanous class month_day_last 6331b8b02a4SEd Tanous { 6341b8b02a4SEd Tanous date::month m_; 6351b8b02a4SEd Tanous 6361b8b02a4SEd Tanous public: 6371b8b02a4SEd Tanous CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT; 6381b8b02a4SEd Tanous 6391b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 6401b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 6411b8b02a4SEd Tanous }; 6421b8b02a4SEd Tanous 6431b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; 6441b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 6451b8b02a4SEd Tanous CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; 6461b8b02a4SEd Tanous CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; 6471b8b02a4SEd Tanous CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 6481b8b02a4SEd Tanous CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; 6491b8b02a4SEd Tanous 6501b8b02a4SEd Tanous template<class CharT, class Traits> 6511b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6521b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl); 6531b8b02a4SEd Tanous 6541b8b02a4SEd Tanous // month_weekday 6551b8b02a4SEd Tanous 6561b8b02a4SEd Tanous class month_weekday 6571b8b02a4SEd Tanous { 6581b8b02a4SEd Tanous date::month m_; 6591b8b02a4SEd Tanous date::weekday_indexed wdi_; 6601b8b02a4SEd Tanous public: 6611b8b02a4SEd Tanous CONSTCD11 month_weekday(const date::month& m, 6621b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT; 6631b8b02a4SEd Tanous 6641b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 6651b8b02a4SEd Tanous CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; 6661b8b02a4SEd Tanous 6671b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 6681b8b02a4SEd Tanous }; 6691b8b02a4SEd Tanous 6701b8b02a4SEd Tanous CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; 6711b8b02a4SEd Tanous CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; 6721b8b02a4SEd Tanous 6731b8b02a4SEd Tanous template<class CharT, class Traits> 6741b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 6751b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd); 6761b8b02a4SEd Tanous 6771b8b02a4SEd Tanous // month_weekday_last 6781b8b02a4SEd Tanous 6791b8b02a4SEd Tanous class month_weekday_last 6801b8b02a4SEd Tanous { 6811b8b02a4SEd Tanous date::month m_; 6821b8b02a4SEd Tanous date::weekday_last wdl_; 6831b8b02a4SEd Tanous 6841b8b02a4SEd Tanous public: 6851b8b02a4SEd Tanous CONSTCD11 month_weekday_last(const date::month& m, 6861b8b02a4SEd Tanous const date::weekday_last& wd) NOEXCEPT; 6871b8b02a4SEd Tanous 6881b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 6891b8b02a4SEd Tanous CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; 6901b8b02a4SEd Tanous 6911b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 6921b8b02a4SEd Tanous }; 6931b8b02a4SEd Tanous 6941b8b02a4SEd Tanous CONSTCD11 6951b8b02a4SEd Tanous bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; 6961b8b02a4SEd Tanous CONSTCD11 6971b8b02a4SEd Tanous bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; 6981b8b02a4SEd Tanous 6991b8b02a4SEd Tanous template<class CharT, class Traits> 7001b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 7011b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl); 7021b8b02a4SEd Tanous 7031b8b02a4SEd Tanous // class year_month_day 7041b8b02a4SEd Tanous 7051b8b02a4SEd Tanous class year_month_day 7061b8b02a4SEd Tanous { 7071b8b02a4SEd Tanous date::year y_; 7081b8b02a4SEd Tanous date::month m_; 7091b8b02a4SEd Tanous date::day d_; 7101b8b02a4SEd Tanous 7111b8b02a4SEd Tanous public: 7121b8b02a4SEd Tanous year_month_day() = default; 7131b8b02a4SEd Tanous CONSTCD11 year_month_day(const date::year& y, const date::month& m, 7141b8b02a4SEd Tanous const date::day& d) NOEXCEPT; 7151b8b02a4SEd Tanous CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; 7161b8b02a4SEd Tanous 7171b8b02a4SEd Tanous CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; 7181b8b02a4SEd Tanous CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; 7191b8b02a4SEd Tanous 7201b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7211b8b02a4SEd Tanous CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; 7221b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7231b8b02a4SEd Tanous CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; 7241b8b02a4SEd Tanous CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; 7251b8b02a4SEd Tanous CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; 7261b8b02a4SEd Tanous 7271b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 7281b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 7291b8b02a4SEd Tanous CONSTCD11 date::day day() const NOEXCEPT; 7301b8b02a4SEd Tanous 7311b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 7321b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 7331b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 7341b8b02a4SEd Tanous 7351b8b02a4SEd Tanous private: 7361b8b02a4SEd Tanous static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; 7371b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 7381b8b02a4SEd Tanous }; 7391b8b02a4SEd Tanous 7401b8b02a4SEd Tanous CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; 7411b8b02a4SEd Tanous CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 7421b8b02a4SEd Tanous CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; 7431b8b02a4SEd Tanous CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; 7441b8b02a4SEd Tanous CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 7451b8b02a4SEd Tanous CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; 7461b8b02a4SEd Tanous 7471b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7481b8b02a4SEd Tanous CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; 7491b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7501b8b02a4SEd Tanous CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; 7511b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7521b8b02a4SEd Tanous CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; 7531b8b02a4SEd Tanous CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; 7541b8b02a4SEd Tanous CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; 7551b8b02a4SEd Tanous CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; 7561b8b02a4SEd Tanous 7571b8b02a4SEd Tanous template<class CharT, class Traits> 7581b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 7591b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd); 7601b8b02a4SEd Tanous 7611b8b02a4SEd Tanous // year_month_day_last 7621b8b02a4SEd Tanous 7631b8b02a4SEd Tanous class year_month_day_last 7641b8b02a4SEd Tanous { 7651b8b02a4SEd Tanous date::year y_; 7661b8b02a4SEd Tanous date::month_day_last mdl_; 7671b8b02a4SEd Tanous 7681b8b02a4SEd Tanous public: 7691b8b02a4SEd Tanous CONSTCD11 year_month_day_last(const date::year& y, 7701b8b02a4SEd Tanous const date::month_day_last& mdl) NOEXCEPT; 7711b8b02a4SEd Tanous 7721b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7731b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; 7741b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 7751b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; 7761b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; 7771b8b02a4SEd Tanous CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; 7781b8b02a4SEd Tanous 7791b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 7801b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 7811b8b02a4SEd Tanous CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; 7821b8b02a4SEd Tanous CONSTCD14 date::day day() const NOEXCEPT; 7831b8b02a4SEd Tanous 7841b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 7851b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 7861b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 7871b8b02a4SEd Tanous }; 7881b8b02a4SEd Tanous 7891b8b02a4SEd Tanous CONSTCD11 7901b8b02a4SEd Tanous bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 7911b8b02a4SEd Tanous CONSTCD11 7921b8b02a4SEd Tanous bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 7931b8b02a4SEd Tanous CONSTCD11 7941b8b02a4SEd Tanous bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 7951b8b02a4SEd Tanous CONSTCD11 7961b8b02a4SEd Tanous bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 7971b8b02a4SEd Tanous CONSTCD11 7981b8b02a4SEd Tanous bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 7991b8b02a4SEd Tanous CONSTCD11 8001b8b02a4SEd Tanous bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; 8011b8b02a4SEd Tanous 8021b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8031b8b02a4SEd Tanous CONSTCD14 8041b8b02a4SEd Tanous year_month_day_last 8051b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; 8061b8b02a4SEd Tanous 8071b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8081b8b02a4SEd Tanous CONSTCD14 8091b8b02a4SEd Tanous year_month_day_last 8101b8b02a4SEd Tanous operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; 8111b8b02a4SEd Tanous 8121b8b02a4SEd Tanous CONSTCD11 8131b8b02a4SEd Tanous year_month_day_last 8141b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; 8151b8b02a4SEd Tanous 8161b8b02a4SEd Tanous CONSTCD11 8171b8b02a4SEd Tanous year_month_day_last 8181b8b02a4SEd Tanous operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; 8191b8b02a4SEd Tanous 8201b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8211b8b02a4SEd Tanous CONSTCD14 8221b8b02a4SEd Tanous year_month_day_last 8231b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; 8241b8b02a4SEd Tanous 8251b8b02a4SEd Tanous CONSTCD11 8261b8b02a4SEd Tanous year_month_day_last 8271b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; 8281b8b02a4SEd Tanous 8291b8b02a4SEd Tanous template<class CharT, class Traits> 8301b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 8311b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl); 8321b8b02a4SEd Tanous 8331b8b02a4SEd Tanous // year_month_weekday 8341b8b02a4SEd Tanous 8351b8b02a4SEd Tanous class year_month_weekday 8361b8b02a4SEd Tanous { 8371b8b02a4SEd Tanous date::year y_; 8381b8b02a4SEd Tanous date::month m_; 8391b8b02a4SEd Tanous date::weekday_indexed wdi_; 8401b8b02a4SEd Tanous 8411b8b02a4SEd Tanous public: 8421b8b02a4SEd Tanous year_month_weekday() = default; 8431b8b02a4SEd Tanous CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, 8441b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT; 8451b8b02a4SEd Tanous CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; 8461b8b02a4SEd Tanous CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; 8471b8b02a4SEd Tanous 8481b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8491b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; 8501b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8511b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; 8521b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; 8531b8b02a4SEd Tanous CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; 8541b8b02a4SEd Tanous 8551b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 8561b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 8571b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 8581b8b02a4SEd Tanous CONSTCD11 unsigned index() const NOEXCEPT; 8591b8b02a4SEd Tanous CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; 8601b8b02a4SEd Tanous 8611b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 8621b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 8631b8b02a4SEd Tanous CONSTCD14 bool ok() const NOEXCEPT; 8641b8b02a4SEd Tanous 8651b8b02a4SEd Tanous private: 8661b8b02a4SEd Tanous static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; 8671b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 8681b8b02a4SEd Tanous }; 8691b8b02a4SEd Tanous 8701b8b02a4SEd Tanous CONSTCD11 8711b8b02a4SEd Tanous bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; 8721b8b02a4SEd Tanous CONSTCD11 8731b8b02a4SEd Tanous bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; 8741b8b02a4SEd Tanous 8751b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8761b8b02a4SEd Tanous CONSTCD14 8771b8b02a4SEd Tanous year_month_weekday 8781b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; 8791b8b02a4SEd Tanous 8801b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8811b8b02a4SEd Tanous CONSTCD14 8821b8b02a4SEd Tanous year_month_weekday 8831b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; 8841b8b02a4SEd Tanous 8851b8b02a4SEd Tanous CONSTCD11 8861b8b02a4SEd Tanous year_month_weekday 8871b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; 8881b8b02a4SEd Tanous 8891b8b02a4SEd Tanous CONSTCD11 8901b8b02a4SEd Tanous year_month_weekday 8911b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; 8921b8b02a4SEd Tanous 8931b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 8941b8b02a4SEd Tanous CONSTCD14 8951b8b02a4SEd Tanous year_month_weekday 8961b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; 8971b8b02a4SEd Tanous 8981b8b02a4SEd Tanous CONSTCD11 8991b8b02a4SEd Tanous year_month_weekday 9001b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; 9011b8b02a4SEd Tanous 9021b8b02a4SEd Tanous template<class CharT, class Traits> 9031b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 9041b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi); 9051b8b02a4SEd Tanous 9061b8b02a4SEd Tanous // year_month_weekday_last 9071b8b02a4SEd Tanous 9081b8b02a4SEd Tanous class year_month_weekday_last 9091b8b02a4SEd Tanous { 9101b8b02a4SEd Tanous date::year y_; 9111b8b02a4SEd Tanous date::month m_; 9121b8b02a4SEd Tanous date::weekday_last wdl_; 9131b8b02a4SEd Tanous 9141b8b02a4SEd Tanous public: 9151b8b02a4SEd Tanous CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, 9161b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT; 9171b8b02a4SEd Tanous 9181b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 9191b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; 9201b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 9211b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; 9221b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; 9231b8b02a4SEd Tanous CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; 9241b8b02a4SEd Tanous 9251b8b02a4SEd Tanous CONSTCD11 date::year year() const NOEXCEPT; 9261b8b02a4SEd Tanous CONSTCD11 date::month month() const NOEXCEPT; 9271b8b02a4SEd Tanous CONSTCD11 date::weekday weekday() const NOEXCEPT; 9281b8b02a4SEd Tanous CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; 9291b8b02a4SEd Tanous 9301b8b02a4SEd Tanous CONSTCD14 operator sys_days() const NOEXCEPT; 9311b8b02a4SEd Tanous CONSTCD14 explicit operator local_days() const NOEXCEPT; 9321b8b02a4SEd Tanous CONSTCD11 bool ok() const NOEXCEPT; 9331b8b02a4SEd Tanous 9341b8b02a4SEd Tanous private: 9351b8b02a4SEd Tanous CONSTCD14 days to_days() const NOEXCEPT; 9361b8b02a4SEd Tanous }; 9371b8b02a4SEd Tanous 9381b8b02a4SEd Tanous CONSTCD11 9391b8b02a4SEd Tanous bool 9401b8b02a4SEd Tanous operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; 9411b8b02a4SEd Tanous 9421b8b02a4SEd Tanous CONSTCD11 9431b8b02a4SEd Tanous bool 9441b8b02a4SEd Tanous operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; 9451b8b02a4SEd Tanous 9461b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 9471b8b02a4SEd Tanous CONSTCD14 9481b8b02a4SEd Tanous year_month_weekday_last 9491b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; 9501b8b02a4SEd Tanous 9511b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 9521b8b02a4SEd Tanous CONSTCD14 9531b8b02a4SEd Tanous year_month_weekday_last 9541b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; 9551b8b02a4SEd Tanous 9561b8b02a4SEd Tanous CONSTCD11 9571b8b02a4SEd Tanous year_month_weekday_last 9581b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; 9591b8b02a4SEd Tanous 9601b8b02a4SEd Tanous CONSTCD11 9611b8b02a4SEd Tanous year_month_weekday_last 9621b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; 9631b8b02a4SEd Tanous 9641b8b02a4SEd Tanous template<class = detail::unspecified_month_disambiguator> 9651b8b02a4SEd Tanous CONSTCD14 9661b8b02a4SEd Tanous year_month_weekday_last 9671b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; 9681b8b02a4SEd Tanous 9691b8b02a4SEd Tanous CONSTCD11 9701b8b02a4SEd Tanous year_month_weekday_last 9711b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; 9721b8b02a4SEd Tanous 9731b8b02a4SEd Tanous template<class CharT, class Traits> 9741b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 9751b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl); 9761b8b02a4SEd Tanous 9771b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 9781b8b02a4SEd Tanous inline namespace literals 9791b8b02a4SEd Tanous { 9801b8b02a4SEd Tanous 9811b8b02a4SEd Tanous CONSTCD11 date::day operator ""_d(unsigned long long d) NOEXCEPT; 9821b8b02a4SEd Tanous CONSTCD11 date::year operator ""_y(unsigned long long y) NOEXCEPT; 9831b8b02a4SEd Tanous 9841b8b02a4SEd Tanous } // inline namespace literals 9851b8b02a4SEd Tanous #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) 9861b8b02a4SEd Tanous 9871b8b02a4SEd Tanous // CONSTDATA date::month January{1}; 9881b8b02a4SEd Tanous // CONSTDATA date::month February{2}; 9891b8b02a4SEd Tanous // CONSTDATA date::month March{3}; 9901b8b02a4SEd Tanous // CONSTDATA date::month April{4}; 9911b8b02a4SEd Tanous // CONSTDATA date::month May{5}; 9921b8b02a4SEd Tanous // CONSTDATA date::month June{6}; 9931b8b02a4SEd Tanous // CONSTDATA date::month July{7}; 9941b8b02a4SEd Tanous // CONSTDATA date::month August{8}; 9951b8b02a4SEd Tanous // CONSTDATA date::month September{9}; 9961b8b02a4SEd Tanous // CONSTDATA date::month October{10}; 9971b8b02a4SEd Tanous // CONSTDATA date::month November{11}; 9981b8b02a4SEd Tanous // CONSTDATA date::month December{12}; 9991b8b02a4SEd Tanous // 10001b8b02a4SEd Tanous // CONSTDATA date::weekday Sunday{0u}; 10011b8b02a4SEd Tanous // CONSTDATA date::weekday Monday{1u}; 10021b8b02a4SEd Tanous // CONSTDATA date::weekday Tuesday{2u}; 10031b8b02a4SEd Tanous // CONSTDATA date::weekday Wednesday{3u}; 10041b8b02a4SEd Tanous // CONSTDATA date::weekday Thursday{4u}; 10051b8b02a4SEd Tanous // CONSTDATA date::weekday Friday{5u}; 10061b8b02a4SEd Tanous // CONSTDATA date::weekday Saturday{6u}; 10071b8b02a4SEd Tanous 10081b8b02a4SEd Tanous #if HAS_VOID_T 10091b8b02a4SEd Tanous 10101b8b02a4SEd Tanous template <class T, class = std::void_t<>> 10111b8b02a4SEd Tanous struct is_clock 10121b8b02a4SEd Tanous : std::false_type 10131b8b02a4SEd Tanous {}; 10141b8b02a4SEd Tanous 10151b8b02a4SEd Tanous template <class T> 10161b8b02a4SEd Tanous struct is_clock<T, std::void_t<decltype(T::now()), typename T::rep, typename T::period, 10171b8b02a4SEd Tanous typename T::duration, typename T::time_point, 10181b8b02a4SEd Tanous decltype(T::is_steady)>> 10191b8b02a4SEd Tanous : std::true_type 10201b8b02a4SEd Tanous {}; 10211b8b02a4SEd Tanous 10221b8b02a4SEd Tanous template<class T> inline constexpr bool is_clock_v = is_clock<T>::value; 10231b8b02a4SEd Tanous 10241b8b02a4SEd Tanous #endif // HAS_VOID_T 10251b8b02a4SEd Tanous 10261b8b02a4SEd Tanous //----------------+ 10271b8b02a4SEd Tanous // Implementation | 10281b8b02a4SEd Tanous //----------------+ 10291b8b02a4SEd Tanous 10301b8b02a4SEd Tanous // utilities 10311b8b02a4SEd Tanous namespace detail { 10321b8b02a4SEd Tanous 10331b8b02a4SEd Tanous template<class CharT, class Traits = std::char_traits<CharT>> 10341b8b02a4SEd Tanous class save_istream 10351b8b02a4SEd Tanous { 10361b8b02a4SEd Tanous protected: 10371b8b02a4SEd Tanous std::basic_ios<CharT, Traits>& is_; 10381b8b02a4SEd Tanous CharT fill_; 10391b8b02a4SEd Tanous std::ios::fmtflags flags_; 10401b8b02a4SEd Tanous std::streamsize precision_; 10411b8b02a4SEd Tanous std::streamsize width_; 10421b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>* tie_; 10431b8b02a4SEd Tanous std::locale loc_; 10441b8b02a4SEd Tanous 10451b8b02a4SEd Tanous public: 10461b8b02a4SEd Tanous ~save_istream() 10471b8b02a4SEd Tanous { 10481b8b02a4SEd Tanous is_.fill(fill_); 10491b8b02a4SEd Tanous is_.flags(flags_); 10501b8b02a4SEd Tanous is_.precision(precision_); 10511b8b02a4SEd Tanous is_.width(width_); 10521b8b02a4SEd Tanous is_.imbue(loc_); 10531b8b02a4SEd Tanous is_.tie(tie_); 10541b8b02a4SEd Tanous } 10551b8b02a4SEd Tanous 10561b8b02a4SEd Tanous save_istream(const save_istream&) = delete; 10571b8b02a4SEd Tanous save_istream& operator=(const save_istream&) = delete; 10581b8b02a4SEd Tanous 10591b8b02a4SEd Tanous explicit save_istream(std::basic_ios<CharT, Traits>& is) 10601b8b02a4SEd Tanous : is_(is) 10611b8b02a4SEd Tanous , fill_(is.fill()) 10621b8b02a4SEd Tanous , flags_(is.flags()) 10631b8b02a4SEd Tanous , precision_(is.precision()) 10641b8b02a4SEd Tanous , width_(is.width(0)) 10651b8b02a4SEd Tanous , tie_(is.tie(nullptr)) 10661b8b02a4SEd Tanous , loc_(is.getloc()) 10671b8b02a4SEd Tanous { 10681b8b02a4SEd Tanous if (tie_ != nullptr) 10691b8b02a4SEd Tanous tie_->flush(); 10701b8b02a4SEd Tanous } 10711b8b02a4SEd Tanous }; 10721b8b02a4SEd Tanous 10731b8b02a4SEd Tanous template<class CharT, class Traits = std::char_traits<CharT>> 10741b8b02a4SEd Tanous class save_ostream 10751b8b02a4SEd Tanous : private save_istream<CharT, Traits> 10761b8b02a4SEd Tanous { 10771b8b02a4SEd Tanous public: 10781b8b02a4SEd Tanous ~save_ostream() 10791b8b02a4SEd Tanous { 10801b8b02a4SEd Tanous if ((this->flags_ & std::ios::unitbuf) && 10811b8b02a4SEd Tanous #if HAS_UNCAUGHT_EXCEPTIONS 10821b8b02a4SEd Tanous std::uncaught_exceptions() == 0 && 10831b8b02a4SEd Tanous #else 10841b8b02a4SEd Tanous !std::uncaught_exception() && 10851b8b02a4SEd Tanous #endif 10861b8b02a4SEd Tanous this->is_.good()) 10871b8b02a4SEd Tanous this->is_.rdbuf()->pubsync(); 10881b8b02a4SEd Tanous } 10891b8b02a4SEd Tanous 10901b8b02a4SEd Tanous save_ostream(const save_ostream&) = delete; 10911b8b02a4SEd Tanous save_ostream& operator=(const save_ostream&) = delete; 10921b8b02a4SEd Tanous 10931b8b02a4SEd Tanous explicit save_ostream(std::basic_ios<CharT, Traits>& os) 10941b8b02a4SEd Tanous : save_istream<CharT, Traits>(os) 10951b8b02a4SEd Tanous { 10961b8b02a4SEd Tanous } 10971b8b02a4SEd Tanous }; 10981b8b02a4SEd Tanous 10991b8b02a4SEd Tanous template <class T> 11001b8b02a4SEd Tanous struct choose_trunc_type 11011b8b02a4SEd Tanous { 11021b8b02a4SEd Tanous static const int digits = std::numeric_limits<T>::digits; 11031b8b02a4SEd Tanous using type = typename std::conditional 11041b8b02a4SEd Tanous < 11051b8b02a4SEd Tanous digits < 32, 11061b8b02a4SEd Tanous std::int32_t, 11071b8b02a4SEd Tanous typename std::conditional 11081b8b02a4SEd Tanous < 11091b8b02a4SEd Tanous digits < 64, 11101b8b02a4SEd Tanous std::int64_t, 11111b8b02a4SEd Tanous #ifdef __SIZEOF_INT128__ 11121b8b02a4SEd Tanous __int128 11131b8b02a4SEd Tanous #else 11141b8b02a4SEd Tanous std::int64_t 11151b8b02a4SEd Tanous #endif 11161b8b02a4SEd Tanous >::type 11171b8b02a4SEd Tanous >::type; 11181b8b02a4SEd Tanous }; 11191b8b02a4SEd Tanous 11201b8b02a4SEd Tanous template <class T> 11211b8b02a4SEd Tanous CONSTCD11 11221b8b02a4SEd Tanous inline 11231b8b02a4SEd Tanous typename std::enable_if 11241b8b02a4SEd Tanous < 11251b8b02a4SEd Tanous !std::chrono::treat_as_floating_point<T>::value, 11261b8b02a4SEd Tanous T 11271b8b02a4SEd Tanous >::type 11281b8b02a4SEd Tanous trunc(T t) NOEXCEPT 11291b8b02a4SEd Tanous { 11301b8b02a4SEd Tanous return t; 11311b8b02a4SEd Tanous } 11321b8b02a4SEd Tanous 11331b8b02a4SEd Tanous template <class T> 11341b8b02a4SEd Tanous CONSTCD14 11351b8b02a4SEd Tanous inline 11361b8b02a4SEd Tanous typename std::enable_if 11371b8b02a4SEd Tanous < 11381b8b02a4SEd Tanous std::chrono::treat_as_floating_point<T>::value, 11391b8b02a4SEd Tanous T 11401b8b02a4SEd Tanous >::type 11411b8b02a4SEd Tanous trunc(T t) NOEXCEPT 11421b8b02a4SEd Tanous { 11431b8b02a4SEd Tanous using std::numeric_limits; 11441b8b02a4SEd Tanous using I = typename choose_trunc_type<T>::type; 11451b8b02a4SEd Tanous CONSTDATA auto digits = numeric_limits<T>::digits; 11461b8b02a4SEd Tanous static_assert(digits < numeric_limits<I>::digits, ""); 11471b8b02a4SEd Tanous CONSTDATA auto max = I{1} << (digits-1); 11481b8b02a4SEd Tanous CONSTDATA auto min = -max; 11491b8b02a4SEd Tanous const auto negative = t < T{0}; 11501b8b02a4SEd Tanous if (min <= t && t <= max && t != 0 && t == t) 11511b8b02a4SEd Tanous { 11521b8b02a4SEd Tanous t = static_cast<T>(static_cast<I>(t)); 11531b8b02a4SEd Tanous if (t == 0 && negative) 11541b8b02a4SEd Tanous t = -t; 11551b8b02a4SEd Tanous } 11561b8b02a4SEd Tanous return t; 11571b8b02a4SEd Tanous } 11581b8b02a4SEd Tanous 11591b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp> 11601b8b02a4SEd Tanous struct static_gcd 11611b8b02a4SEd Tanous { 11621b8b02a4SEd Tanous static const std::intmax_t value = static_gcd<Yp, Xp % Yp>::value; 11631b8b02a4SEd Tanous }; 11641b8b02a4SEd Tanous 11651b8b02a4SEd Tanous template <std::intmax_t Xp> 11661b8b02a4SEd Tanous struct static_gcd<Xp, 0> 11671b8b02a4SEd Tanous { 11681b8b02a4SEd Tanous static const std::intmax_t value = Xp; 11691b8b02a4SEd Tanous }; 11701b8b02a4SEd Tanous 11711b8b02a4SEd Tanous template <> 11721b8b02a4SEd Tanous struct static_gcd<0, 0> 11731b8b02a4SEd Tanous { 11741b8b02a4SEd Tanous static const std::intmax_t value = 1; 11751b8b02a4SEd Tanous }; 11761b8b02a4SEd Tanous 11771b8b02a4SEd Tanous template <class R1, class R2> 11781b8b02a4SEd Tanous struct no_overflow 11791b8b02a4SEd Tanous { 11801b8b02a4SEd Tanous private: 11811b8b02a4SEd Tanous static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value; 11821b8b02a4SEd Tanous static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value; 11831b8b02a4SEd Tanous static const std::intmax_t n1 = R1::num / gcd_n1_n2; 11841b8b02a4SEd Tanous static const std::intmax_t d1 = R1::den / gcd_d1_d2; 11851b8b02a4SEd Tanous static const std::intmax_t n2 = R2::num / gcd_n1_n2; 11861b8b02a4SEd Tanous static const std::intmax_t d2 = R2::den / gcd_d1_d2; 11871b8b02a4SEd Tanous #ifdef __cpp_constexpr 11881b8b02a4SEd Tanous static const std::intmax_t max = std::numeric_limits<std::intmax_t>::max(); 11891b8b02a4SEd Tanous #else 11901b8b02a4SEd Tanous static const std::intmax_t max = LLONG_MAX; 11911b8b02a4SEd Tanous #endif 11921b8b02a4SEd Tanous 11931b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp, bool overflow> 11941b8b02a4SEd Tanous struct mul // overflow == false 11951b8b02a4SEd Tanous { 11961b8b02a4SEd Tanous static const std::intmax_t value = Xp * Yp; 11971b8b02a4SEd Tanous }; 11981b8b02a4SEd Tanous 11991b8b02a4SEd Tanous template <std::intmax_t Xp, std::intmax_t Yp> 12001b8b02a4SEd Tanous struct mul<Xp, Yp, true> 12011b8b02a4SEd Tanous { 12021b8b02a4SEd Tanous static const std::intmax_t value = 1; 12031b8b02a4SEd Tanous }; 12041b8b02a4SEd Tanous 12051b8b02a4SEd Tanous public: 12061b8b02a4SEd Tanous static const bool value = (n1 <= max / d2) && (n2 <= max / d1); 12071b8b02a4SEd Tanous typedef std::ratio<mul<n1, d2, !value>::value, 12081b8b02a4SEd Tanous mul<n2, d1, !value>::value> type; 12091b8b02a4SEd Tanous }; 12101b8b02a4SEd Tanous 12111b8b02a4SEd Tanous } // detail 12121b8b02a4SEd Tanous 12131b8b02a4SEd Tanous // trunc towards zero 12141b8b02a4SEd Tanous template <class To, class Rep, class Period> 12151b8b02a4SEd Tanous CONSTCD11 12161b8b02a4SEd Tanous inline 12171b8b02a4SEd Tanous typename std::enable_if 12181b8b02a4SEd Tanous < 12191b8b02a4SEd Tanous detail::no_overflow<Period, typename To::period>::value, 12201b8b02a4SEd Tanous To 12211b8b02a4SEd Tanous >::type 12221b8b02a4SEd Tanous trunc(const std::chrono::duration<Rep, Period>& d) 12231b8b02a4SEd Tanous { 12241b8b02a4SEd Tanous return To{detail::trunc(std::chrono::duration_cast<To>(d).count())}; 12251b8b02a4SEd Tanous } 12261b8b02a4SEd Tanous 12271b8b02a4SEd Tanous template <class To, class Rep, class Period> 12281b8b02a4SEd Tanous CONSTCD11 12291b8b02a4SEd Tanous inline 12301b8b02a4SEd Tanous typename std::enable_if 12311b8b02a4SEd Tanous < 12321b8b02a4SEd Tanous !detail::no_overflow<Period, typename To::period>::value, 12331b8b02a4SEd Tanous To 12341b8b02a4SEd Tanous >::type 12351b8b02a4SEd Tanous trunc(const std::chrono::duration<Rep, Period>& d) 12361b8b02a4SEd Tanous { 12371b8b02a4SEd Tanous using std::chrono::duration_cast; 12381b8b02a4SEd Tanous using std::chrono::duration; 12391b8b02a4SEd Tanous using rep = typename std::common_type<Rep, typename To::rep>::type; 12401b8b02a4SEd Tanous return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())}; 12411b8b02a4SEd Tanous } 12421b8b02a4SEd Tanous 12431b8b02a4SEd Tanous #ifndef HAS_CHRONO_ROUNDING 12441b8b02a4SEd Tanous # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__))) 12451b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 12461b8b02a4SEd Tanous # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510 12471b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 12481b8b02a4SEd Tanous # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800 12491b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 1 12501b8b02a4SEd Tanous # else 12511b8b02a4SEd Tanous # define HAS_CHRONO_ROUNDING 0 12521b8b02a4SEd Tanous # endif 12531b8b02a4SEd Tanous #endif // HAS_CHRONO_ROUNDING 12541b8b02a4SEd Tanous 12551b8b02a4SEd Tanous #if HAS_CHRONO_ROUNDING == 0 12561b8b02a4SEd Tanous 12571b8b02a4SEd Tanous // round down 12581b8b02a4SEd Tanous template <class To, class Rep, class Period> 12591b8b02a4SEd Tanous CONSTCD14 12601b8b02a4SEd Tanous inline 12611b8b02a4SEd Tanous typename std::enable_if 12621b8b02a4SEd Tanous < 12631b8b02a4SEd Tanous detail::no_overflow<Period, typename To::period>::value, 12641b8b02a4SEd Tanous To 12651b8b02a4SEd Tanous >::type 12661b8b02a4SEd Tanous floor(const std::chrono::duration<Rep, Period>& d) 12671b8b02a4SEd Tanous { 12681b8b02a4SEd Tanous auto t = trunc<To>(d); 12691b8b02a4SEd Tanous if (t > d) 12701b8b02a4SEd Tanous return t - To{1}; 12711b8b02a4SEd Tanous return t; 12721b8b02a4SEd Tanous } 12731b8b02a4SEd Tanous 12741b8b02a4SEd Tanous template <class To, class Rep, class Period> 12751b8b02a4SEd Tanous CONSTCD14 12761b8b02a4SEd Tanous inline 12771b8b02a4SEd Tanous typename std::enable_if 12781b8b02a4SEd Tanous < 12791b8b02a4SEd Tanous !detail::no_overflow<Period, typename To::period>::value, 12801b8b02a4SEd Tanous To 12811b8b02a4SEd Tanous >::type 12821b8b02a4SEd Tanous floor(const std::chrono::duration<Rep, Period>& d) 12831b8b02a4SEd Tanous { 12841b8b02a4SEd Tanous using rep = typename std::common_type<Rep, typename To::rep>::type; 12851b8b02a4SEd Tanous return floor<To>(floor<std::chrono::duration<rep>>(d)); 12861b8b02a4SEd Tanous } 12871b8b02a4SEd Tanous 12881b8b02a4SEd Tanous // round to nearest, to even on tie 12891b8b02a4SEd Tanous template <class To, class Rep, class Period> 12901b8b02a4SEd Tanous CONSTCD14 12911b8b02a4SEd Tanous inline 12921b8b02a4SEd Tanous To 12931b8b02a4SEd Tanous round(const std::chrono::duration<Rep, Period>& d) 12941b8b02a4SEd Tanous { 12951b8b02a4SEd Tanous auto t0 = floor<To>(d); 12961b8b02a4SEd Tanous auto t1 = t0 + To{1}; 12971b8b02a4SEd Tanous if (t1 == To{0} && t0 < To{0}) 12981b8b02a4SEd Tanous t1 = -t1; 12991b8b02a4SEd Tanous auto diff0 = d - t0; 13001b8b02a4SEd Tanous auto diff1 = t1 - d; 13011b8b02a4SEd Tanous if (diff0 == diff1) 13021b8b02a4SEd Tanous { 13031b8b02a4SEd Tanous if (t0 - trunc<To>(t0/2)*2 == To{0}) 13041b8b02a4SEd Tanous return t0; 13051b8b02a4SEd Tanous return t1; 13061b8b02a4SEd Tanous } 13071b8b02a4SEd Tanous if (diff0 < diff1) 13081b8b02a4SEd Tanous return t0; 13091b8b02a4SEd Tanous return t1; 13101b8b02a4SEd Tanous } 13111b8b02a4SEd Tanous 13121b8b02a4SEd Tanous // round up 13131b8b02a4SEd Tanous template <class To, class Rep, class Period> 13141b8b02a4SEd Tanous CONSTCD14 13151b8b02a4SEd Tanous inline 13161b8b02a4SEd Tanous To 13171b8b02a4SEd Tanous ceil(const std::chrono::duration<Rep, Period>& d) 13181b8b02a4SEd Tanous { 13191b8b02a4SEd Tanous auto t = trunc<To>(d); 13201b8b02a4SEd Tanous if (t < d) 13211b8b02a4SEd Tanous return t + To{1}; 13221b8b02a4SEd Tanous return t; 13231b8b02a4SEd Tanous } 13241b8b02a4SEd Tanous 13251b8b02a4SEd Tanous template <class Rep, class Period, 13261b8b02a4SEd Tanous class = typename std::enable_if 13271b8b02a4SEd Tanous < 13281b8b02a4SEd Tanous std::numeric_limits<Rep>::is_signed 13291b8b02a4SEd Tanous >::type> 13301b8b02a4SEd Tanous CONSTCD11 13311b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 13321b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 13331b8b02a4SEd Tanous { 13341b8b02a4SEd Tanous return d >= d.zero() ? d : static_cast<decltype(d)>(-d); 13351b8b02a4SEd Tanous } 13361b8b02a4SEd Tanous 13371b8b02a4SEd Tanous // round down 13381b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 13391b8b02a4SEd Tanous CONSTCD11 13401b8b02a4SEd Tanous inline 13411b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 13421b8b02a4SEd Tanous floor(const std::chrono::time_point<Clock, FromDuration>& tp) 13431b8b02a4SEd Tanous { 13441b8b02a4SEd Tanous using std::chrono::time_point; 13451b8b02a4SEd Tanous return time_point<Clock, To>{date::floor<To>(tp.time_since_epoch())}; 13461b8b02a4SEd Tanous } 13471b8b02a4SEd Tanous 13481b8b02a4SEd Tanous // round to nearest, to even on tie 13491b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 13501b8b02a4SEd Tanous CONSTCD11 13511b8b02a4SEd Tanous inline 13521b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 13531b8b02a4SEd Tanous round(const std::chrono::time_point<Clock, FromDuration>& tp) 13541b8b02a4SEd Tanous { 13551b8b02a4SEd Tanous using std::chrono::time_point; 13561b8b02a4SEd Tanous return time_point<Clock, To>{round<To>(tp.time_since_epoch())}; 13571b8b02a4SEd Tanous } 13581b8b02a4SEd Tanous 13591b8b02a4SEd Tanous // round up 13601b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 13611b8b02a4SEd Tanous CONSTCD11 13621b8b02a4SEd Tanous inline 13631b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 13641b8b02a4SEd Tanous ceil(const std::chrono::time_point<Clock, FromDuration>& tp) 13651b8b02a4SEd Tanous { 13661b8b02a4SEd Tanous using std::chrono::time_point; 13671b8b02a4SEd Tanous return time_point<Clock, To>{ceil<To>(tp.time_since_epoch())}; 13681b8b02a4SEd Tanous } 13691b8b02a4SEd Tanous 13701b8b02a4SEd Tanous #else // HAS_CHRONO_ROUNDING == 1 13711b8b02a4SEd Tanous 13721b8b02a4SEd Tanous using std::chrono::floor; 13731b8b02a4SEd Tanous using std::chrono::ceil; 13741b8b02a4SEd Tanous using std::chrono::round; 13751b8b02a4SEd Tanous using std::chrono::abs; 13761b8b02a4SEd Tanous 13771b8b02a4SEd Tanous #endif // HAS_CHRONO_ROUNDING 13781b8b02a4SEd Tanous 13791b8b02a4SEd Tanous namespace detail 13801b8b02a4SEd Tanous { 13811b8b02a4SEd Tanous 13821b8b02a4SEd Tanous template <class To, class Rep, class Period> 13831b8b02a4SEd Tanous CONSTCD14 13841b8b02a4SEd Tanous inline 13851b8b02a4SEd Tanous typename std::enable_if 13861b8b02a4SEd Tanous < 13871b8b02a4SEd Tanous !std::chrono::treat_as_floating_point<typename To::rep>::value, 13881b8b02a4SEd Tanous To 13891b8b02a4SEd Tanous >::type 13901b8b02a4SEd Tanous round_i(const std::chrono::duration<Rep, Period>& d) 13911b8b02a4SEd Tanous { 13921b8b02a4SEd Tanous return round<To>(d); 13931b8b02a4SEd Tanous } 13941b8b02a4SEd Tanous 13951b8b02a4SEd Tanous template <class To, class Rep, class Period> 13961b8b02a4SEd Tanous CONSTCD14 13971b8b02a4SEd Tanous inline 13981b8b02a4SEd Tanous typename std::enable_if 13991b8b02a4SEd Tanous < 14001b8b02a4SEd Tanous std::chrono::treat_as_floating_point<typename To::rep>::value, 14011b8b02a4SEd Tanous To 14021b8b02a4SEd Tanous >::type 14031b8b02a4SEd Tanous round_i(const std::chrono::duration<Rep, Period>& d) 14041b8b02a4SEd Tanous { 14051b8b02a4SEd Tanous return d; 14061b8b02a4SEd Tanous } 14071b8b02a4SEd Tanous 14081b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 14091b8b02a4SEd Tanous CONSTCD11 14101b8b02a4SEd Tanous inline 14111b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 14121b8b02a4SEd Tanous round_i(const std::chrono::time_point<Clock, FromDuration>& tp) 14131b8b02a4SEd Tanous { 14141b8b02a4SEd Tanous using std::chrono::time_point; 14151b8b02a4SEd Tanous return time_point<Clock, To>{round_i<To>(tp.time_since_epoch())}; 14161b8b02a4SEd Tanous } 14171b8b02a4SEd Tanous 14181b8b02a4SEd Tanous } // detail 14191b8b02a4SEd Tanous 14201b8b02a4SEd Tanous // trunc towards zero 14211b8b02a4SEd Tanous template <class To, class Clock, class FromDuration> 14221b8b02a4SEd Tanous CONSTCD11 14231b8b02a4SEd Tanous inline 14241b8b02a4SEd Tanous std::chrono::time_point<Clock, To> 14251b8b02a4SEd Tanous trunc(const std::chrono::time_point<Clock, FromDuration>& tp) 14261b8b02a4SEd Tanous { 14271b8b02a4SEd Tanous using std::chrono::time_point; 14281b8b02a4SEd Tanous return time_point<Clock, To>{trunc<To>(tp.time_since_epoch())}; 14291b8b02a4SEd Tanous } 14301b8b02a4SEd Tanous 14311b8b02a4SEd Tanous // day 14321b8b02a4SEd Tanous 14331b8b02a4SEd Tanous CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast<decltype(d_)>(d)) {} 14341b8b02a4SEd Tanous CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} 14351b8b02a4SEd Tanous CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 14361b8b02a4SEd Tanous CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} 14371b8b02a4SEd Tanous CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 14381b8b02a4SEd Tanous CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} 14391b8b02a4SEd Tanous CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} 14401b8b02a4SEd Tanous CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} 14411b8b02a4SEd Tanous CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} 14421b8b02a4SEd Tanous 14431b8b02a4SEd Tanous CONSTCD11 14441b8b02a4SEd Tanous inline 14451b8b02a4SEd Tanous bool 14461b8b02a4SEd Tanous operator==(const day& x, const day& y) NOEXCEPT 14471b8b02a4SEd Tanous { 14481b8b02a4SEd Tanous return static_cast<unsigned>(x) == static_cast<unsigned>(y); 14491b8b02a4SEd Tanous } 14501b8b02a4SEd Tanous 14511b8b02a4SEd Tanous CONSTCD11 14521b8b02a4SEd Tanous inline 14531b8b02a4SEd Tanous bool 14541b8b02a4SEd Tanous operator!=(const day& x, const day& y) NOEXCEPT 14551b8b02a4SEd Tanous { 14561b8b02a4SEd Tanous return !(x == y); 14571b8b02a4SEd Tanous } 14581b8b02a4SEd Tanous 14591b8b02a4SEd Tanous CONSTCD11 14601b8b02a4SEd Tanous inline 14611b8b02a4SEd Tanous bool 14621b8b02a4SEd Tanous operator<(const day& x, const day& y) NOEXCEPT 14631b8b02a4SEd Tanous { 14641b8b02a4SEd Tanous return static_cast<unsigned>(x) < static_cast<unsigned>(y); 14651b8b02a4SEd Tanous } 14661b8b02a4SEd Tanous 14671b8b02a4SEd Tanous CONSTCD11 14681b8b02a4SEd Tanous inline 14691b8b02a4SEd Tanous bool 14701b8b02a4SEd Tanous operator>(const day& x, const day& y) NOEXCEPT 14711b8b02a4SEd Tanous { 14721b8b02a4SEd Tanous return y < x; 14731b8b02a4SEd Tanous } 14741b8b02a4SEd Tanous 14751b8b02a4SEd Tanous CONSTCD11 14761b8b02a4SEd Tanous inline 14771b8b02a4SEd Tanous bool 14781b8b02a4SEd Tanous operator<=(const day& x, const day& y) NOEXCEPT 14791b8b02a4SEd Tanous { 14801b8b02a4SEd Tanous return !(y < x); 14811b8b02a4SEd Tanous } 14821b8b02a4SEd Tanous 14831b8b02a4SEd Tanous CONSTCD11 14841b8b02a4SEd Tanous inline 14851b8b02a4SEd Tanous bool 14861b8b02a4SEd Tanous operator>=(const day& x, const day& y) NOEXCEPT 14871b8b02a4SEd Tanous { 14881b8b02a4SEd Tanous return !(x < y); 14891b8b02a4SEd Tanous } 14901b8b02a4SEd Tanous 14911b8b02a4SEd Tanous CONSTCD11 14921b8b02a4SEd Tanous inline 14931b8b02a4SEd Tanous days 14941b8b02a4SEd Tanous operator-(const day& x, const day& y) NOEXCEPT 14951b8b02a4SEd Tanous { 14961b8b02a4SEd Tanous return days{static_cast<days::rep>(static_cast<unsigned>(x) 14971b8b02a4SEd Tanous - static_cast<unsigned>(y))}; 14981b8b02a4SEd Tanous } 14991b8b02a4SEd Tanous 15001b8b02a4SEd Tanous CONSTCD11 15011b8b02a4SEd Tanous inline 15021b8b02a4SEd Tanous day 15031b8b02a4SEd Tanous operator+(const day& x, const days& y) NOEXCEPT 15041b8b02a4SEd Tanous { 15051b8b02a4SEd Tanous return day{static_cast<unsigned>(x) + static_cast<unsigned>(y.count())}; 15061b8b02a4SEd Tanous } 15071b8b02a4SEd Tanous 15081b8b02a4SEd Tanous CONSTCD11 15091b8b02a4SEd Tanous inline 15101b8b02a4SEd Tanous day 15111b8b02a4SEd Tanous operator+(const days& x, const day& y) NOEXCEPT 15121b8b02a4SEd Tanous { 15131b8b02a4SEd Tanous return y + x; 15141b8b02a4SEd Tanous } 15151b8b02a4SEd Tanous 15161b8b02a4SEd Tanous CONSTCD11 15171b8b02a4SEd Tanous inline 15181b8b02a4SEd Tanous day 15191b8b02a4SEd Tanous operator-(const day& x, const days& y) NOEXCEPT 15201b8b02a4SEd Tanous { 15211b8b02a4SEd Tanous return x + -y; 15221b8b02a4SEd Tanous } 15231b8b02a4SEd Tanous 15241b8b02a4SEd Tanous namespace detail 15251b8b02a4SEd Tanous { 15261b8b02a4SEd Tanous 15271b8b02a4SEd Tanous template<class CharT, class Traits> 15281b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 15291b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const day& d) 15301b8b02a4SEd Tanous { 15311b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 15321b8b02a4SEd Tanous os.fill('0'); 15331b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 15341b8b02a4SEd Tanous os.width(2); 15351b8b02a4SEd Tanous os << static_cast<unsigned>(d); 15361b8b02a4SEd Tanous return os; 15371b8b02a4SEd Tanous } 15381b8b02a4SEd Tanous 15391b8b02a4SEd Tanous } // namespace detail 15401b8b02a4SEd Tanous 15411b8b02a4SEd Tanous template<class CharT, class Traits> 15421b8b02a4SEd Tanous inline 15431b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 15441b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const day& d) 15451b8b02a4SEd Tanous { 15461b8b02a4SEd Tanous detail::low_level_fmt(os, d); 15471b8b02a4SEd Tanous if (!d.ok()) 15481b8b02a4SEd Tanous os << " is not a valid day"; 15491b8b02a4SEd Tanous return os; 15501b8b02a4SEd Tanous } 15511b8b02a4SEd Tanous 15521b8b02a4SEd Tanous // month 15531b8b02a4SEd Tanous 15541b8b02a4SEd Tanous CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast<decltype(m_)>(m)) {} 15551b8b02a4SEd Tanous CONSTCD14 inline month& month::operator++() NOEXCEPT {*this += months{1}; return *this;} 15561b8b02a4SEd Tanous CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 15571b8b02a4SEd Tanous CONSTCD14 inline month& month::operator--() NOEXCEPT {*this -= months{1}; return *this;} 15581b8b02a4SEd Tanous CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 15591b8b02a4SEd Tanous 15601b8b02a4SEd Tanous CONSTCD14 15611b8b02a4SEd Tanous inline 15621b8b02a4SEd Tanous month& 15631b8b02a4SEd Tanous month::operator+=(const months& m) NOEXCEPT 15641b8b02a4SEd Tanous { 15651b8b02a4SEd Tanous *this = *this + m; 15661b8b02a4SEd Tanous return *this; 15671b8b02a4SEd Tanous } 15681b8b02a4SEd Tanous 15691b8b02a4SEd Tanous CONSTCD14 15701b8b02a4SEd Tanous inline 15711b8b02a4SEd Tanous month& 15721b8b02a4SEd Tanous month::operator-=(const months& m) NOEXCEPT 15731b8b02a4SEd Tanous { 15741b8b02a4SEd Tanous *this = *this - m; 15751b8b02a4SEd Tanous return *this; 15761b8b02a4SEd Tanous } 15771b8b02a4SEd Tanous 15781b8b02a4SEd Tanous CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} 15791b8b02a4SEd Tanous CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} 15801b8b02a4SEd Tanous 15811b8b02a4SEd Tanous CONSTCD11 15821b8b02a4SEd Tanous inline 15831b8b02a4SEd Tanous bool 15841b8b02a4SEd Tanous operator==(const month& x, const month& y) NOEXCEPT 15851b8b02a4SEd Tanous { 15861b8b02a4SEd Tanous return static_cast<unsigned>(x) == static_cast<unsigned>(y); 15871b8b02a4SEd Tanous } 15881b8b02a4SEd Tanous 15891b8b02a4SEd Tanous CONSTCD11 15901b8b02a4SEd Tanous inline 15911b8b02a4SEd Tanous bool 15921b8b02a4SEd Tanous operator!=(const month& x, const month& y) NOEXCEPT 15931b8b02a4SEd Tanous { 15941b8b02a4SEd Tanous return !(x == y); 15951b8b02a4SEd Tanous } 15961b8b02a4SEd Tanous 15971b8b02a4SEd Tanous CONSTCD11 15981b8b02a4SEd Tanous inline 15991b8b02a4SEd Tanous bool 16001b8b02a4SEd Tanous operator<(const month& x, const month& y) NOEXCEPT 16011b8b02a4SEd Tanous { 16021b8b02a4SEd Tanous return static_cast<unsigned>(x) < static_cast<unsigned>(y); 16031b8b02a4SEd Tanous } 16041b8b02a4SEd Tanous 16051b8b02a4SEd Tanous CONSTCD11 16061b8b02a4SEd Tanous inline 16071b8b02a4SEd Tanous bool 16081b8b02a4SEd Tanous operator>(const month& x, const month& y) NOEXCEPT 16091b8b02a4SEd Tanous { 16101b8b02a4SEd Tanous return y < x; 16111b8b02a4SEd Tanous } 16121b8b02a4SEd Tanous 16131b8b02a4SEd Tanous CONSTCD11 16141b8b02a4SEd Tanous inline 16151b8b02a4SEd Tanous bool 16161b8b02a4SEd Tanous operator<=(const month& x, const month& y) NOEXCEPT 16171b8b02a4SEd Tanous { 16181b8b02a4SEd Tanous return !(y < x); 16191b8b02a4SEd Tanous } 16201b8b02a4SEd Tanous 16211b8b02a4SEd Tanous CONSTCD11 16221b8b02a4SEd Tanous inline 16231b8b02a4SEd Tanous bool 16241b8b02a4SEd Tanous operator>=(const month& x, const month& y) NOEXCEPT 16251b8b02a4SEd Tanous { 16261b8b02a4SEd Tanous return !(x < y); 16271b8b02a4SEd Tanous } 16281b8b02a4SEd Tanous 16291b8b02a4SEd Tanous CONSTCD14 16301b8b02a4SEd Tanous inline 16311b8b02a4SEd Tanous months 16321b8b02a4SEd Tanous operator-(const month& x, const month& y) NOEXCEPT 16331b8b02a4SEd Tanous { 16341b8b02a4SEd Tanous auto const d = static_cast<unsigned>(x) - static_cast<unsigned>(y); 16351b8b02a4SEd Tanous return months(d <= 11 ? d : d + 12); 16361b8b02a4SEd Tanous } 16371b8b02a4SEd Tanous 16381b8b02a4SEd Tanous CONSTCD14 16391b8b02a4SEd Tanous inline 16401b8b02a4SEd Tanous month 16411b8b02a4SEd Tanous operator+(const month& x, const months& y) NOEXCEPT 16421b8b02a4SEd Tanous { 16431b8b02a4SEd Tanous auto const mu = static_cast<long long>(static_cast<unsigned>(x)) + y.count() - 1; 16441b8b02a4SEd Tanous auto const yr = (mu >= 0 ? mu : mu-11) / 12; 16451b8b02a4SEd Tanous return month{static_cast<unsigned>(mu - yr * 12 + 1)}; 16461b8b02a4SEd Tanous } 16471b8b02a4SEd Tanous 16481b8b02a4SEd Tanous CONSTCD14 16491b8b02a4SEd Tanous inline 16501b8b02a4SEd Tanous month 16511b8b02a4SEd Tanous operator+(const months& x, const month& y) NOEXCEPT 16521b8b02a4SEd Tanous { 16531b8b02a4SEd Tanous return y + x; 16541b8b02a4SEd Tanous } 16551b8b02a4SEd Tanous 16561b8b02a4SEd Tanous CONSTCD14 16571b8b02a4SEd Tanous inline 16581b8b02a4SEd Tanous month 16591b8b02a4SEd Tanous operator-(const month& x, const months& y) NOEXCEPT 16601b8b02a4SEd Tanous { 16611b8b02a4SEd Tanous return x + -y; 16621b8b02a4SEd Tanous } 16631b8b02a4SEd Tanous 16641b8b02a4SEd Tanous namespace detail 16651b8b02a4SEd Tanous { 16661b8b02a4SEd Tanous 16671b8b02a4SEd Tanous template<class CharT, class Traits> 16681b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 16691b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month& m) 16701b8b02a4SEd Tanous { 16711b8b02a4SEd Tanous if (m.ok()) 16721b8b02a4SEd Tanous { 16731b8b02a4SEd Tanous CharT fmt[] = {'%', 'b', 0}; 16741b8b02a4SEd Tanous os << format(os.getloc(), fmt, m); 16751b8b02a4SEd Tanous } 16761b8b02a4SEd Tanous else 16771b8b02a4SEd Tanous os << static_cast<unsigned>(m); 16781b8b02a4SEd Tanous return os; 16791b8b02a4SEd Tanous } 16801b8b02a4SEd Tanous 16811b8b02a4SEd Tanous } // namespace detail 16821b8b02a4SEd Tanous 16831b8b02a4SEd Tanous template<class CharT, class Traits> 16841b8b02a4SEd Tanous inline 16851b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 16861b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month& m) 16871b8b02a4SEd Tanous { 16881b8b02a4SEd Tanous detail::low_level_fmt(os, m); 16891b8b02a4SEd Tanous if (!m.ok()) 16901b8b02a4SEd Tanous os << " is not a valid month"; 16911b8b02a4SEd Tanous return os; 16921b8b02a4SEd Tanous } 16931b8b02a4SEd Tanous 16941b8b02a4SEd Tanous // year 16951b8b02a4SEd Tanous 16961b8b02a4SEd Tanous CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast<decltype(y_)>(y)) {} 16971b8b02a4SEd Tanous CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} 16981b8b02a4SEd Tanous CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 16991b8b02a4SEd Tanous CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} 17001b8b02a4SEd Tanous CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 17011b8b02a4SEd Tanous CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} 17021b8b02a4SEd Tanous CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} 17031b8b02a4SEd Tanous CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};} 17041b8b02a4SEd Tanous CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;} 17051b8b02a4SEd Tanous 17061b8b02a4SEd Tanous CONSTCD11 17071b8b02a4SEd Tanous inline 17081b8b02a4SEd Tanous bool 17091b8b02a4SEd Tanous year::is_leap() const NOEXCEPT 17101b8b02a4SEd Tanous { 17111b8b02a4SEd Tanous return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0); 17121b8b02a4SEd Tanous } 17131b8b02a4SEd Tanous 17141b8b02a4SEd Tanous CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} 17151b8b02a4SEd Tanous 17161b8b02a4SEd Tanous CONSTCD11 17171b8b02a4SEd Tanous inline 17181b8b02a4SEd Tanous bool 17191b8b02a4SEd Tanous year::ok() const NOEXCEPT 17201b8b02a4SEd Tanous { 17211b8b02a4SEd Tanous return y_ != std::numeric_limits<short>::min(); 17221b8b02a4SEd Tanous } 17231b8b02a4SEd Tanous 17241b8b02a4SEd Tanous CONSTCD11 17251b8b02a4SEd Tanous inline 17261b8b02a4SEd Tanous bool 17271b8b02a4SEd Tanous operator==(const year& x, const year& y) NOEXCEPT 17281b8b02a4SEd Tanous { 17291b8b02a4SEd Tanous return static_cast<int>(x) == static_cast<int>(y); 17301b8b02a4SEd Tanous } 17311b8b02a4SEd Tanous 17321b8b02a4SEd Tanous CONSTCD11 17331b8b02a4SEd Tanous inline 17341b8b02a4SEd Tanous bool 17351b8b02a4SEd Tanous operator!=(const year& x, const year& y) NOEXCEPT 17361b8b02a4SEd Tanous { 17371b8b02a4SEd Tanous return !(x == y); 17381b8b02a4SEd Tanous } 17391b8b02a4SEd Tanous 17401b8b02a4SEd Tanous CONSTCD11 17411b8b02a4SEd Tanous inline 17421b8b02a4SEd Tanous bool 17431b8b02a4SEd Tanous operator<(const year& x, const year& y) NOEXCEPT 17441b8b02a4SEd Tanous { 17451b8b02a4SEd Tanous return static_cast<int>(x) < static_cast<int>(y); 17461b8b02a4SEd Tanous } 17471b8b02a4SEd Tanous 17481b8b02a4SEd Tanous CONSTCD11 17491b8b02a4SEd Tanous inline 17501b8b02a4SEd Tanous bool 17511b8b02a4SEd Tanous operator>(const year& x, const year& y) NOEXCEPT 17521b8b02a4SEd Tanous { 17531b8b02a4SEd Tanous return y < x; 17541b8b02a4SEd Tanous } 17551b8b02a4SEd Tanous 17561b8b02a4SEd Tanous CONSTCD11 17571b8b02a4SEd Tanous inline 17581b8b02a4SEd Tanous bool 17591b8b02a4SEd Tanous operator<=(const year& x, const year& y) NOEXCEPT 17601b8b02a4SEd Tanous { 17611b8b02a4SEd Tanous return !(y < x); 17621b8b02a4SEd Tanous } 17631b8b02a4SEd Tanous 17641b8b02a4SEd Tanous CONSTCD11 17651b8b02a4SEd Tanous inline 17661b8b02a4SEd Tanous bool 17671b8b02a4SEd Tanous operator>=(const year& x, const year& y) NOEXCEPT 17681b8b02a4SEd Tanous { 17691b8b02a4SEd Tanous return !(x < y); 17701b8b02a4SEd Tanous } 17711b8b02a4SEd Tanous 17721b8b02a4SEd Tanous CONSTCD11 17731b8b02a4SEd Tanous inline 17741b8b02a4SEd Tanous years 17751b8b02a4SEd Tanous operator-(const year& x, const year& y) NOEXCEPT 17761b8b02a4SEd Tanous { 17771b8b02a4SEd Tanous return years{static_cast<int>(x) - static_cast<int>(y)}; 17781b8b02a4SEd Tanous } 17791b8b02a4SEd Tanous 17801b8b02a4SEd Tanous CONSTCD11 17811b8b02a4SEd Tanous inline 17821b8b02a4SEd Tanous year 17831b8b02a4SEd Tanous operator+(const year& x, const years& y) NOEXCEPT 17841b8b02a4SEd Tanous { 17851b8b02a4SEd Tanous return year{static_cast<int>(x) + y.count()}; 17861b8b02a4SEd Tanous } 17871b8b02a4SEd Tanous 17881b8b02a4SEd Tanous CONSTCD11 17891b8b02a4SEd Tanous inline 17901b8b02a4SEd Tanous year 17911b8b02a4SEd Tanous operator+(const years& x, const year& y) NOEXCEPT 17921b8b02a4SEd Tanous { 17931b8b02a4SEd Tanous return y + x; 17941b8b02a4SEd Tanous } 17951b8b02a4SEd Tanous 17961b8b02a4SEd Tanous CONSTCD11 17971b8b02a4SEd Tanous inline 17981b8b02a4SEd Tanous year 17991b8b02a4SEd Tanous operator-(const year& x, const years& y) NOEXCEPT 18001b8b02a4SEd Tanous { 18011b8b02a4SEd Tanous return year{static_cast<int>(x) - y.count()}; 18021b8b02a4SEd Tanous } 18031b8b02a4SEd Tanous 18041b8b02a4SEd Tanous namespace detail 18051b8b02a4SEd Tanous { 18061b8b02a4SEd Tanous 18071b8b02a4SEd Tanous template<class CharT, class Traits> 18081b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 18091b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year& y) 18101b8b02a4SEd Tanous { 18111b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 18121b8b02a4SEd Tanous os.fill('0'); 18131b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::internal); 18141b8b02a4SEd Tanous os.width(4 + (y < year{0})); 18151b8b02a4SEd Tanous os.imbue(std::locale::classic()); 18161b8b02a4SEd Tanous os << static_cast<int>(y); 18171b8b02a4SEd Tanous return os; 18181b8b02a4SEd Tanous } 18191b8b02a4SEd Tanous 18201b8b02a4SEd Tanous } // namespace detail 18211b8b02a4SEd Tanous 18221b8b02a4SEd Tanous template<class CharT, class Traits> 18231b8b02a4SEd Tanous inline 18241b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 18251b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year& y) 18261b8b02a4SEd Tanous { 18271b8b02a4SEd Tanous detail::low_level_fmt(os, y); 18281b8b02a4SEd Tanous if (!y.ok()) 18291b8b02a4SEd Tanous os << " is not a valid year"; 18301b8b02a4SEd Tanous return os; 18311b8b02a4SEd Tanous } 18321b8b02a4SEd Tanous 18331b8b02a4SEd Tanous // weekday 18341b8b02a4SEd Tanous 18351b8b02a4SEd Tanous CONSTCD14 18361b8b02a4SEd Tanous inline 18371b8b02a4SEd Tanous unsigned char 18381b8b02a4SEd Tanous weekday::weekday_from_days(int z) NOEXCEPT 18391b8b02a4SEd Tanous { 18401b8b02a4SEd Tanous auto u = static_cast<unsigned>(z); 18411b8b02a4SEd Tanous return static_cast<unsigned char>(z >= -4 ? (u+4) % 7 : u % 7); 18421b8b02a4SEd Tanous } 18431b8b02a4SEd Tanous 18441b8b02a4SEd Tanous CONSTCD11 18451b8b02a4SEd Tanous inline 18461b8b02a4SEd Tanous weekday::weekday(unsigned wd) NOEXCEPT 18471b8b02a4SEd Tanous : wd_(static_cast<decltype(wd_)>(wd != 7 ? wd : 0)) 18481b8b02a4SEd Tanous {} 18491b8b02a4SEd Tanous 18501b8b02a4SEd Tanous CONSTCD14 18511b8b02a4SEd Tanous inline 18521b8b02a4SEd Tanous weekday::weekday(const sys_days& dp) NOEXCEPT 18531b8b02a4SEd Tanous : wd_(weekday_from_days(dp.time_since_epoch().count())) 18541b8b02a4SEd Tanous {} 18551b8b02a4SEd Tanous 18561b8b02a4SEd Tanous CONSTCD14 18571b8b02a4SEd Tanous inline 18581b8b02a4SEd Tanous weekday::weekday(const local_days& dp) NOEXCEPT 18591b8b02a4SEd Tanous : wd_(weekday_from_days(dp.time_since_epoch().count())) 18601b8b02a4SEd Tanous {} 18611b8b02a4SEd Tanous 18621b8b02a4SEd Tanous CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {*this += days{1}; return *this;} 18631b8b02a4SEd Tanous CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} 18641b8b02a4SEd Tanous CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {*this -= days{1}; return *this;} 18651b8b02a4SEd Tanous CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} 18661b8b02a4SEd Tanous 18671b8b02a4SEd Tanous CONSTCD14 18681b8b02a4SEd Tanous inline 18691b8b02a4SEd Tanous weekday& 18701b8b02a4SEd Tanous weekday::operator+=(const days& d) NOEXCEPT 18711b8b02a4SEd Tanous { 18721b8b02a4SEd Tanous *this = *this + d; 18731b8b02a4SEd Tanous return *this; 18741b8b02a4SEd Tanous } 18751b8b02a4SEd Tanous 18761b8b02a4SEd Tanous CONSTCD14 18771b8b02a4SEd Tanous inline 18781b8b02a4SEd Tanous weekday& 18791b8b02a4SEd Tanous weekday::operator-=(const days& d) NOEXCEPT 18801b8b02a4SEd Tanous { 18811b8b02a4SEd Tanous *this = *this - d; 18821b8b02a4SEd Tanous return *this; 18831b8b02a4SEd Tanous } 18841b8b02a4SEd Tanous 18851b8b02a4SEd Tanous CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} 18861b8b02a4SEd Tanous 18871b8b02a4SEd Tanous CONSTCD11 18881b8b02a4SEd Tanous inline 18891b8b02a4SEd Tanous unsigned weekday::c_encoding() const NOEXCEPT 18901b8b02a4SEd Tanous { 18911b8b02a4SEd Tanous return unsigned{wd_}; 18921b8b02a4SEd Tanous } 18931b8b02a4SEd Tanous 18941b8b02a4SEd Tanous CONSTCD11 18951b8b02a4SEd Tanous inline 18961b8b02a4SEd Tanous unsigned weekday::iso_encoding() const NOEXCEPT 18971b8b02a4SEd Tanous { 18981b8b02a4SEd Tanous return unsigned{((wd_ == 0u) ? 7u : wd_)}; 18991b8b02a4SEd Tanous } 19001b8b02a4SEd Tanous 19011b8b02a4SEd Tanous CONSTCD11 19021b8b02a4SEd Tanous inline 19031b8b02a4SEd Tanous bool 19041b8b02a4SEd Tanous operator==(const weekday& x, const weekday& y) NOEXCEPT 19051b8b02a4SEd Tanous { 19061b8b02a4SEd Tanous return x.wd_ == y.wd_; 19071b8b02a4SEd Tanous } 19081b8b02a4SEd Tanous 19091b8b02a4SEd Tanous CONSTCD11 19101b8b02a4SEd Tanous inline 19111b8b02a4SEd Tanous bool 19121b8b02a4SEd Tanous operator!=(const weekday& x, const weekday& y) NOEXCEPT 19131b8b02a4SEd Tanous { 19141b8b02a4SEd Tanous return !(x == y); 19151b8b02a4SEd Tanous } 19161b8b02a4SEd Tanous 19171b8b02a4SEd Tanous CONSTCD14 19181b8b02a4SEd Tanous inline 19191b8b02a4SEd Tanous days 19201b8b02a4SEd Tanous operator-(const weekday& x, const weekday& y) NOEXCEPT 19211b8b02a4SEd Tanous { 19221b8b02a4SEd Tanous auto const wdu = x.wd_ - y.wd_; 19231b8b02a4SEd Tanous auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; 19241b8b02a4SEd Tanous return days{wdu - wk * 7}; 19251b8b02a4SEd Tanous } 19261b8b02a4SEd Tanous 19271b8b02a4SEd Tanous CONSTCD14 19281b8b02a4SEd Tanous inline 19291b8b02a4SEd Tanous weekday 19301b8b02a4SEd Tanous operator+(const weekday& x, const days& y) NOEXCEPT 19311b8b02a4SEd Tanous { 19321b8b02a4SEd Tanous auto const wdu = static_cast<long long>(static_cast<unsigned>(x.wd_)) + y.count(); 19331b8b02a4SEd Tanous auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; 19341b8b02a4SEd Tanous return weekday{static_cast<unsigned>(wdu - wk * 7)}; 19351b8b02a4SEd Tanous } 19361b8b02a4SEd Tanous 19371b8b02a4SEd Tanous CONSTCD14 19381b8b02a4SEd Tanous inline 19391b8b02a4SEd Tanous weekday 19401b8b02a4SEd Tanous operator+(const days& x, const weekday& y) NOEXCEPT 19411b8b02a4SEd Tanous { 19421b8b02a4SEd Tanous return y + x; 19431b8b02a4SEd Tanous } 19441b8b02a4SEd Tanous 19451b8b02a4SEd Tanous CONSTCD14 19461b8b02a4SEd Tanous inline 19471b8b02a4SEd Tanous weekday 19481b8b02a4SEd Tanous operator-(const weekday& x, const days& y) NOEXCEPT 19491b8b02a4SEd Tanous { 19501b8b02a4SEd Tanous return x + -y; 19511b8b02a4SEd Tanous } 19521b8b02a4SEd Tanous 19531b8b02a4SEd Tanous namespace detail 19541b8b02a4SEd Tanous { 19551b8b02a4SEd Tanous 19561b8b02a4SEd Tanous template<class CharT, class Traits> 19571b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 19581b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday& wd) 19591b8b02a4SEd Tanous { 19601b8b02a4SEd Tanous if (wd.ok()) 19611b8b02a4SEd Tanous { 19621b8b02a4SEd Tanous CharT fmt[] = {'%', 'a', 0}; 19631b8b02a4SEd Tanous os << format(fmt, wd); 19641b8b02a4SEd Tanous } 19651b8b02a4SEd Tanous else 19661b8b02a4SEd Tanous os << wd.c_encoding(); 19671b8b02a4SEd Tanous return os; 19681b8b02a4SEd Tanous } 19691b8b02a4SEd Tanous 19701b8b02a4SEd Tanous } // namespace detail 19711b8b02a4SEd Tanous 19721b8b02a4SEd Tanous template<class CharT, class Traits> 19731b8b02a4SEd Tanous inline 19741b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 19751b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd) 19761b8b02a4SEd Tanous { 19771b8b02a4SEd Tanous detail::low_level_fmt(os, wd); 19781b8b02a4SEd Tanous if (!wd.ok()) 19791b8b02a4SEd Tanous os << " is not a valid weekday"; 19801b8b02a4SEd Tanous return os; 19811b8b02a4SEd Tanous } 19821b8b02a4SEd Tanous 19831b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 19841b8b02a4SEd Tanous inline namespace literals 19851b8b02a4SEd Tanous { 19861b8b02a4SEd Tanous 19871b8b02a4SEd Tanous CONSTCD11 19881b8b02a4SEd Tanous inline 19891b8b02a4SEd Tanous date::day 19901b8b02a4SEd Tanous operator ""_d(unsigned long long d) NOEXCEPT 19911b8b02a4SEd Tanous { 19921b8b02a4SEd Tanous return date::day{static_cast<unsigned>(d)}; 19931b8b02a4SEd Tanous } 19941b8b02a4SEd Tanous 19951b8b02a4SEd Tanous CONSTCD11 19961b8b02a4SEd Tanous inline 19971b8b02a4SEd Tanous date::year 19981b8b02a4SEd Tanous operator ""_y(unsigned long long y) NOEXCEPT 19991b8b02a4SEd Tanous { 20001b8b02a4SEd Tanous return date::year(static_cast<int>(y)); 20011b8b02a4SEd Tanous } 20021b8b02a4SEd Tanous #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) 20031b8b02a4SEd Tanous 20041b8b02a4SEd Tanous CONSTDATA date::last_spec last{}; 20051b8b02a4SEd Tanous 20061b8b02a4SEd Tanous CONSTDATA date::month jan{1}; 20071b8b02a4SEd Tanous CONSTDATA date::month feb{2}; 20081b8b02a4SEd Tanous CONSTDATA date::month mar{3}; 20091b8b02a4SEd Tanous CONSTDATA date::month apr{4}; 20101b8b02a4SEd Tanous CONSTDATA date::month may{5}; 20111b8b02a4SEd Tanous CONSTDATA date::month jun{6}; 20121b8b02a4SEd Tanous CONSTDATA date::month jul{7}; 20131b8b02a4SEd Tanous CONSTDATA date::month aug{8}; 20141b8b02a4SEd Tanous CONSTDATA date::month sep{9}; 20151b8b02a4SEd Tanous CONSTDATA date::month oct{10}; 20161b8b02a4SEd Tanous CONSTDATA date::month nov{11}; 20171b8b02a4SEd Tanous CONSTDATA date::month dec{12}; 20181b8b02a4SEd Tanous 20191b8b02a4SEd Tanous CONSTDATA date::weekday sun{0u}; 20201b8b02a4SEd Tanous CONSTDATA date::weekday mon{1u}; 20211b8b02a4SEd Tanous CONSTDATA date::weekday tue{2u}; 20221b8b02a4SEd Tanous CONSTDATA date::weekday wed{3u}; 20231b8b02a4SEd Tanous CONSTDATA date::weekday thu{4u}; 20241b8b02a4SEd Tanous CONSTDATA date::weekday fri{5u}; 20251b8b02a4SEd Tanous CONSTDATA date::weekday sat{6u}; 20261b8b02a4SEd Tanous 20271b8b02a4SEd Tanous #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 20281b8b02a4SEd Tanous } // inline namespace literals 20291b8b02a4SEd Tanous #endif 20301b8b02a4SEd Tanous 20311b8b02a4SEd Tanous CONSTDATA date::month January{1}; 20321b8b02a4SEd Tanous CONSTDATA date::month February{2}; 20331b8b02a4SEd Tanous CONSTDATA date::month March{3}; 20341b8b02a4SEd Tanous CONSTDATA date::month April{4}; 20351b8b02a4SEd Tanous CONSTDATA date::month May{5}; 20361b8b02a4SEd Tanous CONSTDATA date::month June{6}; 20371b8b02a4SEd Tanous CONSTDATA date::month July{7}; 20381b8b02a4SEd Tanous CONSTDATA date::month August{8}; 20391b8b02a4SEd Tanous CONSTDATA date::month September{9}; 20401b8b02a4SEd Tanous CONSTDATA date::month October{10}; 20411b8b02a4SEd Tanous CONSTDATA date::month November{11}; 20421b8b02a4SEd Tanous CONSTDATA date::month December{12}; 20431b8b02a4SEd Tanous 20441b8b02a4SEd Tanous CONSTDATA date::weekday Monday{1}; 20451b8b02a4SEd Tanous CONSTDATA date::weekday Tuesday{2}; 20461b8b02a4SEd Tanous CONSTDATA date::weekday Wednesday{3}; 20471b8b02a4SEd Tanous CONSTDATA date::weekday Thursday{4}; 20481b8b02a4SEd Tanous CONSTDATA date::weekday Friday{5}; 20491b8b02a4SEd Tanous CONSTDATA date::weekday Saturday{6}; 20501b8b02a4SEd Tanous CONSTDATA date::weekday Sunday{7}; 20511b8b02a4SEd Tanous 20521b8b02a4SEd Tanous // weekday_indexed 20531b8b02a4SEd Tanous 20541b8b02a4SEd Tanous CONSTCD11 20551b8b02a4SEd Tanous inline 20561b8b02a4SEd Tanous weekday 20571b8b02a4SEd Tanous weekday_indexed::weekday() const NOEXCEPT 20581b8b02a4SEd Tanous { 20591b8b02a4SEd Tanous return date::weekday{static_cast<unsigned>(wd_)}; 20601b8b02a4SEd Tanous } 20611b8b02a4SEd Tanous 20621b8b02a4SEd Tanous CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} 20631b8b02a4SEd Tanous 20641b8b02a4SEd Tanous CONSTCD11 20651b8b02a4SEd Tanous inline 20661b8b02a4SEd Tanous bool 20671b8b02a4SEd Tanous weekday_indexed::ok() const NOEXCEPT 20681b8b02a4SEd Tanous { 20691b8b02a4SEd Tanous return weekday().ok() && 1 <= index_ && index_ <= 5; 20701b8b02a4SEd Tanous } 20711b8b02a4SEd Tanous 20721b8b02a4SEd Tanous #ifdef __GNUC__ 20731b8b02a4SEd Tanous # pragma GCC diagnostic push 20741b8b02a4SEd Tanous # pragma GCC diagnostic ignored "-Wconversion" 20751b8b02a4SEd Tanous #endif // __GNUC__ 20761b8b02a4SEd Tanous 20771b8b02a4SEd Tanous CONSTCD11 20781b8b02a4SEd Tanous inline 20791b8b02a4SEd Tanous weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT 20801b8b02a4SEd Tanous : wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd.wd_))) 20811b8b02a4SEd Tanous , index_(static_cast<decltype(index_)>(index)) 20821b8b02a4SEd Tanous {} 20831b8b02a4SEd Tanous 20841b8b02a4SEd Tanous #ifdef __GNUC__ 20851b8b02a4SEd Tanous # pragma GCC diagnostic pop 20861b8b02a4SEd Tanous #endif // __GNUC__ 20871b8b02a4SEd Tanous 20881b8b02a4SEd Tanous namespace detail 20891b8b02a4SEd Tanous { 20901b8b02a4SEd Tanous 20911b8b02a4SEd Tanous template<class CharT, class Traits> 20921b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 20931b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi) 20941b8b02a4SEd Tanous { 20951b8b02a4SEd Tanous return low_level_fmt(os, wdi.weekday()) << '[' << wdi.index() << ']'; 20961b8b02a4SEd Tanous } 20971b8b02a4SEd Tanous 20981b8b02a4SEd Tanous } // namespace detail 20991b8b02a4SEd Tanous 21001b8b02a4SEd Tanous template<class CharT, class Traits> 21011b8b02a4SEd Tanous inline 21021b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 21031b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi) 21041b8b02a4SEd Tanous { 21051b8b02a4SEd Tanous detail::low_level_fmt(os, wdi); 21061b8b02a4SEd Tanous if (!wdi.ok()) 21071b8b02a4SEd Tanous os << " is not a valid weekday_indexed"; 21081b8b02a4SEd Tanous return os; 21091b8b02a4SEd Tanous } 21101b8b02a4SEd Tanous 21111b8b02a4SEd Tanous CONSTCD11 21121b8b02a4SEd Tanous inline 21131b8b02a4SEd Tanous weekday_indexed 21141b8b02a4SEd Tanous weekday::operator[](unsigned index) const NOEXCEPT 21151b8b02a4SEd Tanous { 21161b8b02a4SEd Tanous return {*this, index}; 21171b8b02a4SEd Tanous } 21181b8b02a4SEd Tanous 21191b8b02a4SEd Tanous CONSTCD11 21201b8b02a4SEd Tanous inline 21211b8b02a4SEd Tanous bool 21221b8b02a4SEd Tanous operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT 21231b8b02a4SEd Tanous { 21241b8b02a4SEd Tanous return x.weekday() == y.weekday() && x.index() == y.index(); 21251b8b02a4SEd Tanous } 21261b8b02a4SEd Tanous 21271b8b02a4SEd Tanous CONSTCD11 21281b8b02a4SEd Tanous inline 21291b8b02a4SEd Tanous bool 21301b8b02a4SEd Tanous operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT 21311b8b02a4SEd Tanous { 21321b8b02a4SEd Tanous return !(x == y); 21331b8b02a4SEd Tanous } 21341b8b02a4SEd Tanous 21351b8b02a4SEd Tanous // weekday_last 21361b8b02a4SEd Tanous 21371b8b02a4SEd Tanous CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} 21381b8b02a4SEd Tanous CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} 21391b8b02a4SEd Tanous CONSTCD11 inline weekday_last::weekday_last(const date::weekday& wd) NOEXCEPT : wd_(wd) {} 21401b8b02a4SEd Tanous 21411b8b02a4SEd Tanous CONSTCD11 21421b8b02a4SEd Tanous inline 21431b8b02a4SEd Tanous bool 21441b8b02a4SEd Tanous operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT 21451b8b02a4SEd Tanous { 21461b8b02a4SEd Tanous return x.weekday() == y.weekday(); 21471b8b02a4SEd Tanous } 21481b8b02a4SEd Tanous 21491b8b02a4SEd Tanous CONSTCD11 21501b8b02a4SEd Tanous inline 21511b8b02a4SEd Tanous bool 21521b8b02a4SEd Tanous operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT 21531b8b02a4SEd Tanous { 21541b8b02a4SEd Tanous return !(x == y); 21551b8b02a4SEd Tanous } 21561b8b02a4SEd Tanous 21571b8b02a4SEd Tanous namespace detail 21581b8b02a4SEd Tanous { 21591b8b02a4SEd Tanous 21601b8b02a4SEd Tanous template<class CharT, class Traits> 21611b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 21621b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl) 21631b8b02a4SEd Tanous { 21641b8b02a4SEd Tanous return low_level_fmt(os, wdl.weekday()) << "[last]"; 21651b8b02a4SEd Tanous } 21661b8b02a4SEd Tanous 21671b8b02a4SEd Tanous } // namespace detail 21681b8b02a4SEd Tanous 21691b8b02a4SEd Tanous template<class CharT, class Traits> 21701b8b02a4SEd Tanous inline 21711b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 21721b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl) 21731b8b02a4SEd Tanous { 21741b8b02a4SEd Tanous detail::low_level_fmt(os, wdl); 21751b8b02a4SEd Tanous if (!wdl.ok()) 21761b8b02a4SEd Tanous os << " is not a valid weekday_last"; 21771b8b02a4SEd Tanous return os; 21781b8b02a4SEd Tanous } 21791b8b02a4SEd Tanous 21801b8b02a4SEd Tanous CONSTCD11 21811b8b02a4SEd Tanous inline 21821b8b02a4SEd Tanous weekday_last 21831b8b02a4SEd Tanous weekday::operator[](last_spec) const NOEXCEPT 21841b8b02a4SEd Tanous { 21851b8b02a4SEd Tanous return weekday_last{*this}; 21861b8b02a4SEd Tanous } 21871b8b02a4SEd Tanous 21881b8b02a4SEd Tanous // year_month 21891b8b02a4SEd Tanous 21901b8b02a4SEd Tanous CONSTCD11 21911b8b02a4SEd Tanous inline 21921b8b02a4SEd Tanous year_month::year_month(const date::year& y, const date::month& m) NOEXCEPT 21931b8b02a4SEd Tanous : y_(y) 21941b8b02a4SEd Tanous , m_(m) 21951b8b02a4SEd Tanous {} 21961b8b02a4SEd Tanous 21971b8b02a4SEd Tanous CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} 21981b8b02a4SEd Tanous CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} 21991b8b02a4SEd Tanous CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} 22001b8b02a4SEd Tanous 22011b8b02a4SEd Tanous template<class> 22021b8b02a4SEd Tanous CONSTCD14 22031b8b02a4SEd Tanous inline 22041b8b02a4SEd Tanous year_month& 22051b8b02a4SEd Tanous year_month::operator+=(const months& dm) NOEXCEPT 22061b8b02a4SEd Tanous { 22071b8b02a4SEd Tanous *this = *this + dm; 22081b8b02a4SEd Tanous return *this; 22091b8b02a4SEd Tanous } 22101b8b02a4SEd Tanous 22111b8b02a4SEd Tanous template<class> 22121b8b02a4SEd Tanous CONSTCD14 22131b8b02a4SEd Tanous inline 22141b8b02a4SEd Tanous year_month& 22151b8b02a4SEd Tanous year_month::operator-=(const months& dm) NOEXCEPT 22161b8b02a4SEd Tanous { 22171b8b02a4SEd Tanous *this = *this - dm; 22181b8b02a4SEd Tanous return *this; 22191b8b02a4SEd Tanous } 22201b8b02a4SEd Tanous 22211b8b02a4SEd Tanous CONSTCD14 22221b8b02a4SEd Tanous inline 22231b8b02a4SEd Tanous year_month& 22241b8b02a4SEd Tanous year_month::operator+=(const years& dy) NOEXCEPT 22251b8b02a4SEd Tanous { 22261b8b02a4SEd Tanous *this = *this + dy; 22271b8b02a4SEd Tanous return *this; 22281b8b02a4SEd Tanous } 22291b8b02a4SEd Tanous 22301b8b02a4SEd Tanous CONSTCD14 22311b8b02a4SEd Tanous inline 22321b8b02a4SEd Tanous year_month& 22331b8b02a4SEd Tanous year_month::operator-=(const years& dy) NOEXCEPT 22341b8b02a4SEd Tanous { 22351b8b02a4SEd Tanous *this = *this - dy; 22361b8b02a4SEd Tanous return *this; 22371b8b02a4SEd Tanous } 22381b8b02a4SEd Tanous 22391b8b02a4SEd Tanous CONSTCD11 22401b8b02a4SEd Tanous inline 22411b8b02a4SEd Tanous bool 22421b8b02a4SEd Tanous operator==(const year_month& x, const year_month& y) NOEXCEPT 22431b8b02a4SEd Tanous { 22441b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month(); 22451b8b02a4SEd Tanous } 22461b8b02a4SEd Tanous 22471b8b02a4SEd Tanous CONSTCD11 22481b8b02a4SEd Tanous inline 22491b8b02a4SEd Tanous bool 22501b8b02a4SEd Tanous operator!=(const year_month& x, const year_month& y) NOEXCEPT 22511b8b02a4SEd Tanous { 22521b8b02a4SEd Tanous return !(x == y); 22531b8b02a4SEd Tanous } 22541b8b02a4SEd Tanous 22551b8b02a4SEd Tanous CONSTCD11 22561b8b02a4SEd Tanous inline 22571b8b02a4SEd Tanous bool 22581b8b02a4SEd Tanous operator<(const year_month& x, const year_month& y) NOEXCEPT 22591b8b02a4SEd Tanous { 22601b8b02a4SEd Tanous return x.year() < y.year() ? true 22611b8b02a4SEd Tanous : (x.year() > y.year() ? false 22621b8b02a4SEd Tanous : (x.month() < y.month())); 22631b8b02a4SEd Tanous } 22641b8b02a4SEd Tanous 22651b8b02a4SEd Tanous CONSTCD11 22661b8b02a4SEd Tanous inline 22671b8b02a4SEd Tanous bool 22681b8b02a4SEd Tanous operator>(const year_month& x, const year_month& y) NOEXCEPT 22691b8b02a4SEd Tanous { 22701b8b02a4SEd Tanous return y < x; 22711b8b02a4SEd Tanous } 22721b8b02a4SEd Tanous 22731b8b02a4SEd Tanous CONSTCD11 22741b8b02a4SEd Tanous inline 22751b8b02a4SEd Tanous bool 22761b8b02a4SEd Tanous operator<=(const year_month& x, const year_month& y) NOEXCEPT 22771b8b02a4SEd Tanous { 22781b8b02a4SEd Tanous return !(y < x); 22791b8b02a4SEd Tanous } 22801b8b02a4SEd Tanous 22811b8b02a4SEd Tanous CONSTCD11 22821b8b02a4SEd Tanous inline 22831b8b02a4SEd Tanous bool 22841b8b02a4SEd Tanous operator>=(const year_month& x, const year_month& y) NOEXCEPT 22851b8b02a4SEd Tanous { 22861b8b02a4SEd Tanous return !(x < y); 22871b8b02a4SEd Tanous } 22881b8b02a4SEd Tanous 22891b8b02a4SEd Tanous template<class> 22901b8b02a4SEd Tanous CONSTCD14 22911b8b02a4SEd Tanous inline 22921b8b02a4SEd Tanous year_month 22931b8b02a4SEd Tanous operator+(const year_month& ym, const months& dm) NOEXCEPT 22941b8b02a4SEd Tanous { 22951b8b02a4SEd Tanous auto dmi = static_cast<int>(static_cast<unsigned>(ym.month())) - 1 + dm.count(); 22961b8b02a4SEd Tanous auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; 22971b8b02a4SEd Tanous dmi = dmi - dy * 12 + 1; 22981b8b02a4SEd Tanous return (ym.year() + years(dy)) / month(static_cast<unsigned>(dmi)); 22991b8b02a4SEd Tanous } 23001b8b02a4SEd Tanous 23011b8b02a4SEd Tanous template<class> 23021b8b02a4SEd Tanous CONSTCD14 23031b8b02a4SEd Tanous inline 23041b8b02a4SEd Tanous year_month 23051b8b02a4SEd Tanous operator+(const months& dm, const year_month& ym) NOEXCEPT 23061b8b02a4SEd Tanous { 23071b8b02a4SEd Tanous return ym + dm; 23081b8b02a4SEd Tanous } 23091b8b02a4SEd Tanous 23101b8b02a4SEd Tanous template<class> 23111b8b02a4SEd Tanous CONSTCD14 23121b8b02a4SEd Tanous inline 23131b8b02a4SEd Tanous year_month 23141b8b02a4SEd Tanous operator-(const year_month& ym, const months& dm) NOEXCEPT 23151b8b02a4SEd Tanous { 23161b8b02a4SEd Tanous return ym + -dm; 23171b8b02a4SEd Tanous } 23181b8b02a4SEd Tanous 23191b8b02a4SEd Tanous CONSTCD11 23201b8b02a4SEd Tanous inline 23211b8b02a4SEd Tanous months 23221b8b02a4SEd Tanous operator-(const year_month& x, const year_month& y) NOEXCEPT 23231b8b02a4SEd Tanous { 23241b8b02a4SEd Tanous return (x.year() - y.year()) + 23251b8b02a4SEd Tanous months(static_cast<unsigned>(x.month()) - static_cast<unsigned>(y.month())); 23261b8b02a4SEd Tanous } 23271b8b02a4SEd Tanous 23281b8b02a4SEd Tanous CONSTCD11 23291b8b02a4SEd Tanous inline 23301b8b02a4SEd Tanous year_month 23311b8b02a4SEd Tanous operator+(const year_month& ym, const years& dy) NOEXCEPT 23321b8b02a4SEd Tanous { 23331b8b02a4SEd Tanous return (ym.year() + dy) / ym.month(); 23341b8b02a4SEd Tanous } 23351b8b02a4SEd Tanous 23361b8b02a4SEd Tanous CONSTCD11 23371b8b02a4SEd Tanous inline 23381b8b02a4SEd Tanous year_month 23391b8b02a4SEd Tanous operator+(const years& dy, const year_month& ym) NOEXCEPT 23401b8b02a4SEd Tanous { 23411b8b02a4SEd Tanous return ym + dy; 23421b8b02a4SEd Tanous } 23431b8b02a4SEd Tanous 23441b8b02a4SEd Tanous CONSTCD11 23451b8b02a4SEd Tanous inline 23461b8b02a4SEd Tanous year_month 23471b8b02a4SEd Tanous operator-(const year_month& ym, const years& dy) NOEXCEPT 23481b8b02a4SEd Tanous { 23491b8b02a4SEd Tanous return ym + -dy; 23501b8b02a4SEd Tanous } 23511b8b02a4SEd Tanous 23521b8b02a4SEd Tanous namespace detail 23531b8b02a4SEd Tanous { 23541b8b02a4SEd Tanous 23551b8b02a4SEd Tanous template<class CharT, class Traits> 23561b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 23571b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year_month& ym) 23581b8b02a4SEd Tanous { 23591b8b02a4SEd Tanous low_level_fmt(os, ym.year()) << '/'; 23601b8b02a4SEd Tanous return low_level_fmt(os, ym.month()); 23611b8b02a4SEd Tanous } 23621b8b02a4SEd Tanous 23631b8b02a4SEd Tanous } // namespace detail 23641b8b02a4SEd Tanous 23651b8b02a4SEd Tanous template<class CharT, class Traits> 23661b8b02a4SEd Tanous inline 23671b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 23681b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym) 23691b8b02a4SEd Tanous { 23701b8b02a4SEd Tanous detail::low_level_fmt(os, ym); 23711b8b02a4SEd Tanous if (!ym.ok()) 23721b8b02a4SEd Tanous os << " is not a valid year_month"; 23731b8b02a4SEd Tanous return os; 23741b8b02a4SEd Tanous } 23751b8b02a4SEd Tanous 23761b8b02a4SEd Tanous // month_day 23771b8b02a4SEd Tanous 23781b8b02a4SEd Tanous CONSTCD11 23791b8b02a4SEd Tanous inline 23801b8b02a4SEd Tanous month_day::month_day(const date::month& m, const date::day& d) NOEXCEPT 23811b8b02a4SEd Tanous : m_(m) 23821b8b02a4SEd Tanous , d_(d) 23831b8b02a4SEd Tanous {} 23841b8b02a4SEd Tanous 23851b8b02a4SEd Tanous CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;} 23861b8b02a4SEd Tanous CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;} 23871b8b02a4SEd Tanous 23881b8b02a4SEd Tanous CONSTCD14 23891b8b02a4SEd Tanous inline 23901b8b02a4SEd Tanous bool 23911b8b02a4SEd Tanous month_day::ok() const NOEXCEPT 23921b8b02a4SEd Tanous { 23931b8b02a4SEd Tanous CONSTDATA date::day d[] = 23941b8b02a4SEd Tanous { 23951b8b02a4SEd Tanous date::day(31), date::day(29), date::day(31), 23961b8b02a4SEd Tanous date::day(30), date::day(31), date::day(30), 23971b8b02a4SEd Tanous date::day(31), date::day(31), date::day(30), 23981b8b02a4SEd Tanous date::day(31), date::day(30), date::day(31) 23991b8b02a4SEd Tanous }; 24001b8b02a4SEd Tanous return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast<unsigned>(m_)-1]; 24011b8b02a4SEd Tanous } 24021b8b02a4SEd Tanous 24031b8b02a4SEd Tanous CONSTCD11 24041b8b02a4SEd Tanous inline 24051b8b02a4SEd Tanous bool 24061b8b02a4SEd Tanous operator==(const month_day& x, const month_day& y) NOEXCEPT 24071b8b02a4SEd Tanous { 24081b8b02a4SEd Tanous return x.month() == y.month() && x.day() == y.day(); 24091b8b02a4SEd Tanous } 24101b8b02a4SEd Tanous 24111b8b02a4SEd Tanous CONSTCD11 24121b8b02a4SEd Tanous inline 24131b8b02a4SEd Tanous bool 24141b8b02a4SEd Tanous operator!=(const month_day& x, const month_day& y) NOEXCEPT 24151b8b02a4SEd Tanous { 24161b8b02a4SEd Tanous return !(x == y); 24171b8b02a4SEd Tanous } 24181b8b02a4SEd Tanous 24191b8b02a4SEd Tanous CONSTCD11 24201b8b02a4SEd Tanous inline 24211b8b02a4SEd Tanous bool 24221b8b02a4SEd Tanous operator<(const month_day& x, const month_day& y) NOEXCEPT 24231b8b02a4SEd Tanous { 24241b8b02a4SEd Tanous return x.month() < y.month() ? true 24251b8b02a4SEd Tanous : (x.month() > y.month() ? false 24261b8b02a4SEd Tanous : (x.day() < y.day())); 24271b8b02a4SEd Tanous } 24281b8b02a4SEd Tanous 24291b8b02a4SEd Tanous CONSTCD11 24301b8b02a4SEd Tanous inline 24311b8b02a4SEd Tanous bool 24321b8b02a4SEd Tanous operator>(const month_day& x, const month_day& y) NOEXCEPT 24331b8b02a4SEd Tanous { 24341b8b02a4SEd Tanous return y < x; 24351b8b02a4SEd Tanous } 24361b8b02a4SEd Tanous 24371b8b02a4SEd Tanous CONSTCD11 24381b8b02a4SEd Tanous inline 24391b8b02a4SEd Tanous bool 24401b8b02a4SEd Tanous operator<=(const month_day& x, const month_day& y) NOEXCEPT 24411b8b02a4SEd Tanous { 24421b8b02a4SEd Tanous return !(y < x); 24431b8b02a4SEd Tanous } 24441b8b02a4SEd Tanous 24451b8b02a4SEd Tanous CONSTCD11 24461b8b02a4SEd Tanous inline 24471b8b02a4SEd Tanous bool 24481b8b02a4SEd Tanous operator>=(const month_day& x, const month_day& y) NOEXCEPT 24491b8b02a4SEd Tanous { 24501b8b02a4SEd Tanous return !(x < y); 24511b8b02a4SEd Tanous } 24521b8b02a4SEd Tanous 24531b8b02a4SEd Tanous namespace detail 24541b8b02a4SEd Tanous { 24551b8b02a4SEd Tanous 24561b8b02a4SEd Tanous template<class CharT, class Traits> 24571b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 24581b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_day& md) 24591b8b02a4SEd Tanous { 24601b8b02a4SEd Tanous low_level_fmt(os, md.month()) << '/'; 24611b8b02a4SEd Tanous return low_level_fmt(os, md.day()); 24621b8b02a4SEd Tanous } 24631b8b02a4SEd Tanous 24641b8b02a4SEd Tanous } // namespace detail 24651b8b02a4SEd Tanous 24661b8b02a4SEd Tanous template<class CharT, class Traits> 24671b8b02a4SEd Tanous inline 24681b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 24691b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md) 24701b8b02a4SEd Tanous { 24711b8b02a4SEd Tanous detail::low_level_fmt(os, md); 24721b8b02a4SEd Tanous if (!md.ok()) 24731b8b02a4SEd Tanous os << " is not a valid month_day"; 24741b8b02a4SEd Tanous return os; 24751b8b02a4SEd Tanous } 24761b8b02a4SEd Tanous 24771b8b02a4SEd Tanous // month_day_last 24781b8b02a4SEd Tanous 24791b8b02a4SEd Tanous CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} 24801b8b02a4SEd Tanous CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} 24811b8b02a4SEd Tanous CONSTCD11 inline month_day_last::month_day_last(const date::month& m) NOEXCEPT : m_(m) {} 24821b8b02a4SEd Tanous 24831b8b02a4SEd Tanous CONSTCD11 24841b8b02a4SEd Tanous inline 24851b8b02a4SEd Tanous bool 24861b8b02a4SEd Tanous operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT 24871b8b02a4SEd Tanous { 24881b8b02a4SEd Tanous return x.month() == y.month(); 24891b8b02a4SEd Tanous } 24901b8b02a4SEd Tanous 24911b8b02a4SEd Tanous CONSTCD11 24921b8b02a4SEd Tanous inline 24931b8b02a4SEd Tanous bool 24941b8b02a4SEd Tanous operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT 24951b8b02a4SEd Tanous { 24961b8b02a4SEd Tanous return !(x == y); 24971b8b02a4SEd Tanous } 24981b8b02a4SEd Tanous 24991b8b02a4SEd Tanous CONSTCD11 25001b8b02a4SEd Tanous inline 25011b8b02a4SEd Tanous bool 25021b8b02a4SEd Tanous operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT 25031b8b02a4SEd Tanous { 25041b8b02a4SEd Tanous return x.month() < y.month(); 25051b8b02a4SEd Tanous } 25061b8b02a4SEd Tanous 25071b8b02a4SEd Tanous CONSTCD11 25081b8b02a4SEd Tanous inline 25091b8b02a4SEd Tanous bool 25101b8b02a4SEd Tanous operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT 25111b8b02a4SEd Tanous { 25121b8b02a4SEd Tanous return y < x; 25131b8b02a4SEd Tanous } 25141b8b02a4SEd Tanous 25151b8b02a4SEd Tanous CONSTCD11 25161b8b02a4SEd Tanous inline 25171b8b02a4SEd Tanous bool 25181b8b02a4SEd Tanous operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT 25191b8b02a4SEd Tanous { 25201b8b02a4SEd Tanous return !(y < x); 25211b8b02a4SEd Tanous } 25221b8b02a4SEd Tanous 25231b8b02a4SEd Tanous CONSTCD11 25241b8b02a4SEd Tanous inline 25251b8b02a4SEd Tanous bool 25261b8b02a4SEd Tanous operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT 25271b8b02a4SEd Tanous { 25281b8b02a4SEd Tanous return !(x < y); 25291b8b02a4SEd Tanous } 25301b8b02a4SEd Tanous 25311b8b02a4SEd Tanous namespace detail 25321b8b02a4SEd Tanous { 25331b8b02a4SEd Tanous 25341b8b02a4SEd Tanous template<class CharT, class Traits> 25351b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 25361b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl) 25371b8b02a4SEd Tanous { 25381b8b02a4SEd Tanous return low_level_fmt(os, mdl.month()) << "/last"; 25391b8b02a4SEd Tanous } 25401b8b02a4SEd Tanous 25411b8b02a4SEd Tanous } // namespace detail 25421b8b02a4SEd Tanous 25431b8b02a4SEd Tanous template<class CharT, class Traits> 25441b8b02a4SEd Tanous inline 25451b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 25461b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl) 25471b8b02a4SEd Tanous { 25481b8b02a4SEd Tanous detail::low_level_fmt(os, mdl); 25491b8b02a4SEd Tanous if (!mdl.ok()) 25501b8b02a4SEd Tanous os << " is not a valid month_day_last"; 25511b8b02a4SEd Tanous return os; 25521b8b02a4SEd Tanous } 25531b8b02a4SEd Tanous 25541b8b02a4SEd Tanous // month_weekday 25551b8b02a4SEd Tanous 25561b8b02a4SEd Tanous CONSTCD11 25571b8b02a4SEd Tanous inline 25581b8b02a4SEd Tanous month_weekday::month_weekday(const date::month& m, 25591b8b02a4SEd Tanous const date::weekday_indexed& wdi) NOEXCEPT 25601b8b02a4SEd Tanous : m_(m) 25611b8b02a4SEd Tanous , wdi_(wdi) 25621b8b02a4SEd Tanous {} 25631b8b02a4SEd Tanous 25641b8b02a4SEd Tanous CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} 25651b8b02a4SEd Tanous 25661b8b02a4SEd Tanous CONSTCD11 25671b8b02a4SEd Tanous inline 25681b8b02a4SEd Tanous weekday_indexed 25691b8b02a4SEd Tanous month_weekday::weekday_indexed() const NOEXCEPT 25701b8b02a4SEd Tanous { 25711b8b02a4SEd Tanous return wdi_; 25721b8b02a4SEd Tanous } 25731b8b02a4SEd Tanous 25741b8b02a4SEd Tanous CONSTCD11 25751b8b02a4SEd Tanous inline 25761b8b02a4SEd Tanous bool 25771b8b02a4SEd Tanous month_weekday::ok() const NOEXCEPT 25781b8b02a4SEd Tanous { 25791b8b02a4SEd Tanous return m_.ok() && wdi_.ok(); 25801b8b02a4SEd Tanous } 25811b8b02a4SEd Tanous 25821b8b02a4SEd Tanous CONSTCD11 25831b8b02a4SEd Tanous inline 25841b8b02a4SEd Tanous bool 25851b8b02a4SEd Tanous operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT 25861b8b02a4SEd Tanous { 25871b8b02a4SEd Tanous return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); 25881b8b02a4SEd Tanous } 25891b8b02a4SEd Tanous 25901b8b02a4SEd Tanous CONSTCD11 25911b8b02a4SEd Tanous inline 25921b8b02a4SEd Tanous bool 25931b8b02a4SEd Tanous operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT 25941b8b02a4SEd Tanous { 25951b8b02a4SEd Tanous return !(x == y); 25961b8b02a4SEd Tanous } 25971b8b02a4SEd Tanous 25981b8b02a4SEd Tanous namespace detail 25991b8b02a4SEd Tanous { 26001b8b02a4SEd Tanous 26011b8b02a4SEd Tanous template<class CharT, class Traits> 26021b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 26031b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd) 26041b8b02a4SEd Tanous { 26051b8b02a4SEd Tanous low_level_fmt(os, mwd.month()) << '/'; 26061b8b02a4SEd Tanous return low_level_fmt(os, mwd.weekday_indexed()); 26071b8b02a4SEd Tanous } 26081b8b02a4SEd Tanous 26091b8b02a4SEd Tanous } // namespace detail 26101b8b02a4SEd Tanous 26111b8b02a4SEd Tanous template<class CharT, class Traits> 26121b8b02a4SEd Tanous inline 26131b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 26141b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd) 26151b8b02a4SEd Tanous { 26161b8b02a4SEd Tanous detail::low_level_fmt(os, mwd); 26171b8b02a4SEd Tanous if (!mwd.ok()) 26181b8b02a4SEd Tanous os << " is not a valid month_weekday"; 26191b8b02a4SEd Tanous return os; 26201b8b02a4SEd Tanous } 26211b8b02a4SEd Tanous 26221b8b02a4SEd Tanous // month_weekday_last 26231b8b02a4SEd Tanous 26241b8b02a4SEd Tanous CONSTCD11 26251b8b02a4SEd Tanous inline 26261b8b02a4SEd Tanous month_weekday_last::month_weekday_last(const date::month& m, 26271b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT 26281b8b02a4SEd Tanous : m_(m) 26291b8b02a4SEd Tanous , wdl_(wdl) 26301b8b02a4SEd Tanous {} 26311b8b02a4SEd Tanous 26321b8b02a4SEd Tanous CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} 26331b8b02a4SEd Tanous 26341b8b02a4SEd Tanous CONSTCD11 26351b8b02a4SEd Tanous inline 26361b8b02a4SEd Tanous weekday_last 26371b8b02a4SEd Tanous month_weekday_last::weekday_last() const NOEXCEPT 26381b8b02a4SEd Tanous { 26391b8b02a4SEd Tanous return wdl_; 26401b8b02a4SEd Tanous } 26411b8b02a4SEd Tanous 26421b8b02a4SEd Tanous CONSTCD11 26431b8b02a4SEd Tanous inline 26441b8b02a4SEd Tanous bool 26451b8b02a4SEd Tanous month_weekday_last::ok() const NOEXCEPT 26461b8b02a4SEd Tanous { 26471b8b02a4SEd Tanous return m_.ok() && wdl_.ok(); 26481b8b02a4SEd Tanous } 26491b8b02a4SEd Tanous 26501b8b02a4SEd Tanous CONSTCD11 26511b8b02a4SEd Tanous inline 26521b8b02a4SEd Tanous bool 26531b8b02a4SEd Tanous operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT 26541b8b02a4SEd Tanous { 26551b8b02a4SEd Tanous return x.month() == y.month() && x.weekday_last() == y.weekday_last(); 26561b8b02a4SEd Tanous } 26571b8b02a4SEd Tanous 26581b8b02a4SEd Tanous CONSTCD11 26591b8b02a4SEd Tanous inline 26601b8b02a4SEd Tanous bool 26611b8b02a4SEd Tanous operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT 26621b8b02a4SEd Tanous { 26631b8b02a4SEd Tanous return !(x == y); 26641b8b02a4SEd Tanous } 26651b8b02a4SEd Tanous 26661b8b02a4SEd Tanous namespace detail 26671b8b02a4SEd Tanous { 26681b8b02a4SEd Tanous 26691b8b02a4SEd Tanous template<class CharT, class Traits> 26701b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 26711b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl) 26721b8b02a4SEd Tanous { 26731b8b02a4SEd Tanous low_level_fmt(os, mwdl.month()) << '/'; 26741b8b02a4SEd Tanous return low_level_fmt(os, mwdl.weekday_last()); 26751b8b02a4SEd Tanous } 26761b8b02a4SEd Tanous 26771b8b02a4SEd Tanous } // namespace detail 26781b8b02a4SEd Tanous 26791b8b02a4SEd Tanous template<class CharT, class Traits> 26801b8b02a4SEd Tanous inline 26811b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 26821b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl) 26831b8b02a4SEd Tanous { 26841b8b02a4SEd Tanous detail::low_level_fmt(os, mwdl); 26851b8b02a4SEd Tanous if (!mwdl.ok()) 26861b8b02a4SEd Tanous os << " is not a valid month_weekday_last"; 26871b8b02a4SEd Tanous return os; 26881b8b02a4SEd Tanous } 26891b8b02a4SEd Tanous 26901b8b02a4SEd Tanous // year_month_day_last 26911b8b02a4SEd Tanous 26921b8b02a4SEd Tanous CONSTCD11 26931b8b02a4SEd Tanous inline 26941b8b02a4SEd Tanous year_month_day_last::year_month_day_last(const date::year& y, 26951b8b02a4SEd Tanous const date::month_day_last& mdl) NOEXCEPT 26961b8b02a4SEd Tanous : y_(y) 26971b8b02a4SEd Tanous , mdl_(mdl) 26981b8b02a4SEd Tanous {} 26991b8b02a4SEd Tanous 27001b8b02a4SEd Tanous template<class> 27011b8b02a4SEd Tanous CONSTCD14 27021b8b02a4SEd Tanous inline 27031b8b02a4SEd Tanous year_month_day_last& 27041b8b02a4SEd Tanous year_month_day_last::operator+=(const months& m) NOEXCEPT 27051b8b02a4SEd Tanous { 27061b8b02a4SEd Tanous *this = *this + m; 27071b8b02a4SEd Tanous return *this; 27081b8b02a4SEd Tanous } 27091b8b02a4SEd Tanous 27101b8b02a4SEd Tanous template<class> 27111b8b02a4SEd Tanous CONSTCD14 27121b8b02a4SEd Tanous inline 27131b8b02a4SEd Tanous year_month_day_last& 27141b8b02a4SEd Tanous year_month_day_last::operator-=(const months& m) NOEXCEPT 27151b8b02a4SEd Tanous { 27161b8b02a4SEd Tanous *this = *this - m; 27171b8b02a4SEd Tanous return *this; 27181b8b02a4SEd Tanous } 27191b8b02a4SEd Tanous 27201b8b02a4SEd Tanous CONSTCD14 27211b8b02a4SEd Tanous inline 27221b8b02a4SEd Tanous year_month_day_last& 27231b8b02a4SEd Tanous year_month_day_last::operator+=(const years& y) NOEXCEPT 27241b8b02a4SEd Tanous { 27251b8b02a4SEd Tanous *this = *this + y; 27261b8b02a4SEd Tanous return *this; 27271b8b02a4SEd Tanous } 27281b8b02a4SEd Tanous 27291b8b02a4SEd Tanous CONSTCD14 27301b8b02a4SEd Tanous inline 27311b8b02a4SEd Tanous year_month_day_last& 27321b8b02a4SEd Tanous year_month_day_last::operator-=(const years& y) NOEXCEPT 27331b8b02a4SEd Tanous { 27341b8b02a4SEd Tanous *this = *this - y; 27351b8b02a4SEd Tanous return *this; 27361b8b02a4SEd Tanous } 27371b8b02a4SEd Tanous 27381b8b02a4SEd Tanous CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} 27391b8b02a4SEd Tanous CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} 27401b8b02a4SEd Tanous 27411b8b02a4SEd Tanous CONSTCD11 27421b8b02a4SEd Tanous inline 27431b8b02a4SEd Tanous month_day_last 27441b8b02a4SEd Tanous year_month_day_last::month_day_last() const NOEXCEPT 27451b8b02a4SEd Tanous { 27461b8b02a4SEd Tanous return mdl_; 27471b8b02a4SEd Tanous } 27481b8b02a4SEd Tanous 27491b8b02a4SEd Tanous CONSTCD14 27501b8b02a4SEd Tanous inline 27511b8b02a4SEd Tanous day 27521b8b02a4SEd Tanous year_month_day_last::day() const NOEXCEPT 27531b8b02a4SEd Tanous { 27541b8b02a4SEd Tanous CONSTDATA date::day d[] = 27551b8b02a4SEd Tanous { 27561b8b02a4SEd Tanous date::day(31), date::day(28), date::day(31), 27571b8b02a4SEd Tanous date::day(30), date::day(31), date::day(30), 27581b8b02a4SEd Tanous date::day(31), date::day(31), date::day(30), 27591b8b02a4SEd Tanous date::day(31), date::day(30), date::day(31) 27601b8b02a4SEd Tanous }; 27611b8b02a4SEd Tanous return (month() != February || !y_.is_leap()) && mdl_.ok() ? 27621b8b02a4SEd Tanous d[static_cast<unsigned>(month()) - 1] : date::day{29}; 27631b8b02a4SEd Tanous } 27641b8b02a4SEd Tanous 27651b8b02a4SEd Tanous CONSTCD14 27661b8b02a4SEd Tanous inline 27671b8b02a4SEd Tanous year_month_day_last::operator sys_days() const NOEXCEPT 27681b8b02a4SEd Tanous { 27691b8b02a4SEd Tanous return sys_days(year()/month()/day()); 27701b8b02a4SEd Tanous } 27711b8b02a4SEd Tanous 27721b8b02a4SEd Tanous CONSTCD14 27731b8b02a4SEd Tanous inline 27741b8b02a4SEd Tanous year_month_day_last::operator local_days() const NOEXCEPT 27751b8b02a4SEd Tanous { 27761b8b02a4SEd Tanous return local_days(year()/month()/day()); 27771b8b02a4SEd Tanous } 27781b8b02a4SEd Tanous 27791b8b02a4SEd Tanous CONSTCD11 27801b8b02a4SEd Tanous inline 27811b8b02a4SEd Tanous bool 27821b8b02a4SEd Tanous year_month_day_last::ok() const NOEXCEPT 27831b8b02a4SEd Tanous { 27841b8b02a4SEd Tanous return y_.ok() && mdl_.ok(); 27851b8b02a4SEd Tanous } 27861b8b02a4SEd Tanous 27871b8b02a4SEd Tanous CONSTCD11 27881b8b02a4SEd Tanous inline 27891b8b02a4SEd Tanous bool 27901b8b02a4SEd Tanous operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 27911b8b02a4SEd Tanous { 27921b8b02a4SEd Tanous return x.year() == y.year() && x.month_day_last() == y.month_day_last(); 27931b8b02a4SEd Tanous } 27941b8b02a4SEd Tanous 27951b8b02a4SEd Tanous CONSTCD11 27961b8b02a4SEd Tanous inline 27971b8b02a4SEd Tanous bool 27981b8b02a4SEd Tanous operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 27991b8b02a4SEd Tanous { 28001b8b02a4SEd Tanous return !(x == y); 28011b8b02a4SEd Tanous } 28021b8b02a4SEd Tanous 28031b8b02a4SEd Tanous CONSTCD11 28041b8b02a4SEd Tanous inline 28051b8b02a4SEd Tanous bool 28061b8b02a4SEd Tanous operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 28071b8b02a4SEd Tanous { 28081b8b02a4SEd Tanous return x.year() < y.year() ? true 28091b8b02a4SEd Tanous : (x.year() > y.year() ? false 28101b8b02a4SEd Tanous : (x.month_day_last() < y.month_day_last())); 28111b8b02a4SEd Tanous } 28121b8b02a4SEd Tanous 28131b8b02a4SEd Tanous CONSTCD11 28141b8b02a4SEd Tanous inline 28151b8b02a4SEd Tanous bool 28161b8b02a4SEd Tanous operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 28171b8b02a4SEd Tanous { 28181b8b02a4SEd Tanous return y < x; 28191b8b02a4SEd Tanous } 28201b8b02a4SEd Tanous 28211b8b02a4SEd Tanous CONSTCD11 28221b8b02a4SEd Tanous inline 28231b8b02a4SEd Tanous bool 28241b8b02a4SEd Tanous operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 28251b8b02a4SEd Tanous { 28261b8b02a4SEd Tanous return !(y < x); 28271b8b02a4SEd Tanous } 28281b8b02a4SEd Tanous 28291b8b02a4SEd Tanous CONSTCD11 28301b8b02a4SEd Tanous inline 28311b8b02a4SEd Tanous bool 28321b8b02a4SEd Tanous operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT 28331b8b02a4SEd Tanous { 28341b8b02a4SEd Tanous return !(x < y); 28351b8b02a4SEd Tanous } 28361b8b02a4SEd Tanous 28371b8b02a4SEd Tanous namespace detail 28381b8b02a4SEd Tanous { 28391b8b02a4SEd Tanous 28401b8b02a4SEd Tanous template<class CharT, class Traits> 28411b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 28421b8b02a4SEd Tanous low_level_fmt(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl) 28431b8b02a4SEd Tanous { 28441b8b02a4SEd Tanous low_level_fmt(os, ymdl.year()) << '/'; 28451b8b02a4SEd Tanous return low_level_fmt(os, ymdl.month_day_last()); 28461b8b02a4SEd Tanous } 28471b8b02a4SEd Tanous 28481b8b02a4SEd Tanous } // namespace detail 28491b8b02a4SEd Tanous 28501b8b02a4SEd Tanous template<class CharT, class Traits> 28511b8b02a4SEd Tanous inline 28521b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 28531b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl) 28541b8b02a4SEd Tanous { 28551b8b02a4SEd Tanous detail::low_level_fmt(os, ymdl); 28561b8b02a4SEd Tanous if (!ymdl.ok()) 28571b8b02a4SEd Tanous os << " is not a valid year_month_day_last"; 28581b8b02a4SEd Tanous return os; 28591b8b02a4SEd Tanous } 28601b8b02a4SEd Tanous 28611b8b02a4SEd Tanous template<class> 28621b8b02a4SEd Tanous CONSTCD14 28631b8b02a4SEd Tanous inline 28641b8b02a4SEd Tanous year_month_day_last 28651b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT 28661b8b02a4SEd Tanous { 28671b8b02a4SEd Tanous return (ymdl.year() / ymdl.month() + dm) / last; 28681b8b02a4SEd Tanous } 28691b8b02a4SEd Tanous 28701b8b02a4SEd Tanous template<class> 28711b8b02a4SEd Tanous CONSTCD14 28721b8b02a4SEd Tanous inline 28731b8b02a4SEd Tanous year_month_day_last 28741b8b02a4SEd Tanous operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT 28751b8b02a4SEd Tanous { 28761b8b02a4SEd Tanous return ymdl + dm; 28771b8b02a4SEd Tanous } 28781b8b02a4SEd Tanous 28791b8b02a4SEd Tanous template<class> 28801b8b02a4SEd Tanous CONSTCD14 28811b8b02a4SEd Tanous inline 28821b8b02a4SEd Tanous year_month_day_last 28831b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT 28841b8b02a4SEd Tanous { 28851b8b02a4SEd Tanous return ymdl + (-dm); 28861b8b02a4SEd Tanous } 28871b8b02a4SEd Tanous 28881b8b02a4SEd Tanous CONSTCD11 28891b8b02a4SEd Tanous inline 28901b8b02a4SEd Tanous year_month_day_last 28911b8b02a4SEd Tanous operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT 28921b8b02a4SEd Tanous { 28931b8b02a4SEd Tanous return {ymdl.year()+dy, ymdl.month_day_last()}; 28941b8b02a4SEd Tanous } 28951b8b02a4SEd Tanous 28961b8b02a4SEd Tanous CONSTCD11 28971b8b02a4SEd Tanous inline 28981b8b02a4SEd Tanous year_month_day_last 28991b8b02a4SEd Tanous operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT 29001b8b02a4SEd Tanous { 29011b8b02a4SEd Tanous return ymdl + dy; 29021b8b02a4SEd Tanous } 29031b8b02a4SEd Tanous 29041b8b02a4SEd Tanous CONSTCD11 29051b8b02a4SEd Tanous inline 29061b8b02a4SEd Tanous year_month_day_last 29071b8b02a4SEd Tanous operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT 29081b8b02a4SEd Tanous { 29091b8b02a4SEd Tanous return ymdl + (-dy); 29101b8b02a4SEd Tanous } 29111b8b02a4SEd Tanous 29121b8b02a4SEd Tanous // year_month_day 29131b8b02a4SEd Tanous 29141b8b02a4SEd Tanous CONSTCD11 29151b8b02a4SEd Tanous inline 29161b8b02a4SEd Tanous year_month_day::year_month_day(const date::year& y, const date::month& m, 29171b8b02a4SEd Tanous const date::day& d) NOEXCEPT 29181b8b02a4SEd Tanous : y_(y) 29191b8b02a4SEd Tanous , m_(m) 29201b8b02a4SEd Tanous , d_(d) 29211b8b02a4SEd Tanous {} 29221b8b02a4SEd Tanous 29231b8b02a4SEd Tanous CONSTCD14 29241b8b02a4SEd Tanous inline 29251b8b02a4SEd Tanous year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT 29261b8b02a4SEd Tanous : y_(ymdl.year()) 29271b8b02a4SEd Tanous , m_(ymdl.month()) 29281b8b02a4SEd Tanous , d_(ymdl.day()) 29291b8b02a4SEd Tanous {} 29301b8b02a4SEd Tanous 29311b8b02a4SEd Tanous CONSTCD14 29321b8b02a4SEd Tanous inline 29331b8b02a4SEd Tanous year_month_day::year_month_day(sys_days dp) NOEXCEPT 29341b8b02a4SEd Tanous : year_month_day(from_days(dp.time_since_epoch())) 29351b8b02a4SEd Tanous {} 29361b8b02a4SEd Tanous 29371b8b02a4SEd Tanous CONSTCD14 29381b8b02a4SEd Tanous inline 29391b8b02a4SEd Tanous year_month_day::year_month_day(local_days dp) NOEXCEPT 29401b8b02a4SEd Tanous : year_month_day(from_days(dp.time_since_epoch())) 29411b8b02a4SEd Tanous {} 29421b8b02a4SEd Tanous 29431b8b02a4SEd Tanous CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} 29441b8b02a4SEd Tanous CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} 29451b8b02a4SEd Tanous CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} 29461b8b02a4SEd Tanous 29471b8b02a4SEd Tanous template<class> 29481b8b02a4SEd Tanous CONSTCD14 29491b8b02a4SEd Tanous inline 29501b8b02a4SEd Tanous year_month_day& 29511b8b02a4SEd Tanous year_month_day::operator+=(const months& m) NOEXCEPT 29521b8b02a4SEd Tanous { 29531b8b02a4SEd Tanous *this = *this + m; 29541b8b02a4SEd Tanous return *this; 29551b8b02a4SEd Tanous } 29561b8b02a4SEd Tanous 29571b8b02a4SEd Tanous template<class> 29581b8b02a4SEd Tanous CONSTCD14 29591b8b02a4SEd Tanous inline 29601b8b02a4SEd Tanous year_month_day& 29611b8b02a4SEd Tanous year_month_day::operator-=(const months& m) NOEXCEPT 29621b8b02a4SEd Tanous { 29631b8b02a4SEd Tanous *this = *this - m; 29641b8b02a4SEd Tanous return *this; 29651b8b02a4SEd Tanous } 29661b8b02a4SEd Tanous 29671b8b02a4SEd Tanous CONSTCD14 29681b8b02a4SEd Tanous inline 29691b8b02a4SEd Tanous year_month_day& 29701b8b02a4SEd Tanous year_month_day::operator+=(const years& y) NOEXCEPT 29711b8b02a4SEd Tanous { 29721b8b02a4SEd Tanous *this = *this + y; 29731b8b02a4SEd Tanous return *this; 29741b8b02a4SEd Tanous } 29751b8b02a4SEd Tanous 29761b8b02a4SEd Tanous CONSTCD14 29771b8b02a4SEd Tanous inline 29781b8b02a4SEd Tanous year_month_day& 29791b8b02a4SEd Tanous year_month_day::operator-=(const years& y) NOEXCEPT 29801b8b02a4SEd Tanous { 29811b8b02a4SEd Tanous *this = *this - y; 29821b8b02a4SEd Tanous return *this; 29831b8b02a4SEd Tanous } 29841b8b02a4SEd Tanous 29851b8b02a4SEd Tanous CONSTCD14 29861b8b02a4SEd Tanous inline 29871b8b02a4SEd Tanous days 29881b8b02a4SEd Tanous year_month_day::to_days() const NOEXCEPT 29891b8b02a4SEd Tanous { 29901b8b02a4SEd Tanous static_assert(std::numeric_limits<unsigned>::digits >= 18, 29911b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit unsigned integer"); 29921b8b02a4SEd Tanous static_assert(std::numeric_limits<int>::digits >= 20, 29931b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit signed integer"); 29941b8b02a4SEd Tanous auto const y = static_cast<int>(y_) - (m_ <= February); 29951b8b02a4SEd Tanous auto const m = static_cast<unsigned>(m_); 29961b8b02a4SEd Tanous auto const d = static_cast<unsigned>(d_); 29971b8b02a4SEd Tanous auto const era = (y >= 0 ? y : y-399) / 400; 29981b8b02a4SEd Tanous auto const yoe = static_cast<unsigned>(y - era * 400); // [0, 399] 29991b8b02a4SEd Tanous auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] 30001b8b02a4SEd Tanous auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] 30011b8b02a4SEd Tanous return days{era * 146097 + static_cast<int>(doe) - 719468}; 30021b8b02a4SEd Tanous } 30031b8b02a4SEd Tanous 30041b8b02a4SEd Tanous CONSTCD14 30051b8b02a4SEd Tanous inline 30061b8b02a4SEd Tanous year_month_day::operator sys_days() const NOEXCEPT 30071b8b02a4SEd Tanous { 30081b8b02a4SEd Tanous return sys_days{to_days()}; 30091b8b02a4SEd Tanous } 30101b8b02a4SEd Tanous 30111b8b02a4SEd Tanous CONSTCD14 30121b8b02a4SEd Tanous inline 30131b8b02a4SEd Tanous year_month_day::operator local_days() const NOEXCEPT 30141b8b02a4SEd Tanous { 30151b8b02a4SEd Tanous return local_days{to_days()}; 30161b8b02a4SEd Tanous } 30171b8b02a4SEd Tanous 30181b8b02a4SEd Tanous CONSTCD14 30191b8b02a4SEd Tanous inline 30201b8b02a4SEd Tanous bool 30211b8b02a4SEd Tanous year_month_day::ok() const NOEXCEPT 30221b8b02a4SEd Tanous { 30231b8b02a4SEd Tanous if (!(y_.ok() && m_.ok())) 30241b8b02a4SEd Tanous return false; 30251b8b02a4SEd Tanous return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); 30261b8b02a4SEd Tanous } 30271b8b02a4SEd Tanous 30281b8b02a4SEd Tanous CONSTCD11 30291b8b02a4SEd Tanous inline 30301b8b02a4SEd Tanous bool 30311b8b02a4SEd Tanous operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT 30321b8b02a4SEd Tanous { 30331b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); 30341b8b02a4SEd Tanous } 30351b8b02a4SEd Tanous 30361b8b02a4SEd Tanous CONSTCD11 30371b8b02a4SEd Tanous inline 30381b8b02a4SEd Tanous bool 30391b8b02a4SEd Tanous operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT 30401b8b02a4SEd Tanous { 30411b8b02a4SEd Tanous return !(x == y); 30421b8b02a4SEd Tanous } 30431b8b02a4SEd Tanous 30441b8b02a4SEd Tanous CONSTCD11 30451b8b02a4SEd Tanous inline 30461b8b02a4SEd Tanous bool 30471b8b02a4SEd Tanous operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT 30481b8b02a4SEd Tanous { 30491b8b02a4SEd Tanous return x.year() < y.year() ? true 30501b8b02a4SEd Tanous : (x.year() > y.year() ? false 30511b8b02a4SEd Tanous : (x.month() < y.month() ? true 30521b8b02a4SEd Tanous : (x.month() > y.month() ? false 30531b8b02a4SEd Tanous : (x.day() < y.day())))); 30541b8b02a4SEd Tanous } 30551b8b02a4SEd Tanous 30561b8b02a4SEd Tanous CONSTCD11 30571b8b02a4SEd Tanous inline 30581b8b02a4SEd Tanous bool 30591b8b02a4SEd Tanous operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT 30601b8b02a4SEd Tanous { 30611b8b02a4SEd Tanous return y < x; 30621b8b02a4SEd Tanous } 30631b8b02a4SEd Tanous 30641b8b02a4SEd Tanous CONSTCD11 30651b8b02a4SEd Tanous inline 30661b8b02a4SEd Tanous bool 30671b8b02a4SEd Tanous operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT 30681b8b02a4SEd Tanous { 30691b8b02a4SEd Tanous return !(y < x); 30701b8b02a4SEd Tanous } 30711b8b02a4SEd Tanous 30721b8b02a4SEd Tanous CONSTCD11 30731b8b02a4SEd Tanous inline 30741b8b02a4SEd Tanous bool 30751b8b02a4SEd Tanous operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT 30761b8b02a4SEd Tanous { 30771b8b02a4SEd Tanous return !(x < y); 30781b8b02a4SEd Tanous } 30791b8b02a4SEd Tanous 30801b8b02a4SEd Tanous template<class CharT, class Traits> 30811b8b02a4SEd Tanous inline 30821b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 30831b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd) 30841b8b02a4SEd Tanous { 30851b8b02a4SEd Tanous detail::save_ostream<CharT, Traits> _(os); 30861b8b02a4SEd Tanous os.fill('0'); 30871b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 30881b8b02a4SEd Tanous os.imbue(std::locale::classic()); 30891b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) << '-'; 30901b8b02a4SEd Tanous os.width(2); 30911b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << '-'; 30921b8b02a4SEd Tanous os.width(2); 30931b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()); 30941b8b02a4SEd Tanous if (!ymd.ok()) 30951b8b02a4SEd Tanous os << " is not a valid year_month_day"; 30961b8b02a4SEd Tanous return os; 30971b8b02a4SEd Tanous } 30981b8b02a4SEd Tanous 30991b8b02a4SEd Tanous CONSTCD14 31001b8b02a4SEd Tanous inline 31011b8b02a4SEd Tanous year_month_day 31021b8b02a4SEd Tanous year_month_day::from_days(days dp) NOEXCEPT 31031b8b02a4SEd Tanous { 31041b8b02a4SEd Tanous static_assert(std::numeric_limits<unsigned>::digits >= 18, 31051b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit unsigned integer"); 31061b8b02a4SEd Tanous static_assert(std::numeric_limits<int>::digits >= 20, 31071b8b02a4SEd Tanous "This algorithm has not been ported to a 16 bit signed integer"); 31081b8b02a4SEd Tanous auto const z = dp.count() + 719468; 31091b8b02a4SEd Tanous auto const era = (z >= 0 ? z : z - 146096) / 146097; 31101b8b02a4SEd Tanous auto const doe = static_cast<unsigned>(z - era * 146097); // [0, 146096] 31111b8b02a4SEd Tanous auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] 31121b8b02a4SEd Tanous auto const y = static_cast<days::rep>(yoe) + era * 400; 31131b8b02a4SEd Tanous auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] 31141b8b02a4SEd Tanous auto const mp = (5*doy + 2)/153; // [0, 11] 31151b8b02a4SEd Tanous auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] 31161b8b02a4SEd Tanous auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] 31171b8b02a4SEd Tanous return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; 31181b8b02a4SEd Tanous } 31191b8b02a4SEd Tanous 31201b8b02a4SEd Tanous template<class> 31211b8b02a4SEd Tanous CONSTCD14 31221b8b02a4SEd Tanous inline 31231b8b02a4SEd Tanous year_month_day 31241b8b02a4SEd Tanous operator+(const year_month_day& ymd, const months& dm) NOEXCEPT 31251b8b02a4SEd Tanous { 31261b8b02a4SEd Tanous return (ymd.year() / ymd.month() + dm) / ymd.day(); 31271b8b02a4SEd Tanous } 31281b8b02a4SEd Tanous 31291b8b02a4SEd Tanous template<class> 31301b8b02a4SEd Tanous CONSTCD14 31311b8b02a4SEd Tanous inline 31321b8b02a4SEd Tanous year_month_day 31331b8b02a4SEd Tanous operator+(const months& dm, const year_month_day& ymd) NOEXCEPT 31341b8b02a4SEd Tanous { 31351b8b02a4SEd Tanous return ymd + dm; 31361b8b02a4SEd Tanous } 31371b8b02a4SEd Tanous 31381b8b02a4SEd Tanous template<class> 31391b8b02a4SEd Tanous CONSTCD14 31401b8b02a4SEd Tanous inline 31411b8b02a4SEd Tanous year_month_day 31421b8b02a4SEd Tanous operator-(const year_month_day& ymd, const months& dm) NOEXCEPT 31431b8b02a4SEd Tanous { 31441b8b02a4SEd Tanous return ymd + (-dm); 31451b8b02a4SEd Tanous } 31461b8b02a4SEd Tanous 31471b8b02a4SEd Tanous CONSTCD11 31481b8b02a4SEd Tanous inline 31491b8b02a4SEd Tanous year_month_day 31501b8b02a4SEd Tanous operator+(const year_month_day& ymd, const years& dy) NOEXCEPT 31511b8b02a4SEd Tanous { 31521b8b02a4SEd Tanous return (ymd.year() + dy) / ymd.month() / ymd.day(); 31531b8b02a4SEd Tanous } 31541b8b02a4SEd Tanous 31551b8b02a4SEd Tanous CONSTCD11 31561b8b02a4SEd Tanous inline 31571b8b02a4SEd Tanous year_month_day 31581b8b02a4SEd Tanous operator+(const years& dy, const year_month_day& ymd) NOEXCEPT 31591b8b02a4SEd Tanous { 31601b8b02a4SEd Tanous return ymd + dy; 31611b8b02a4SEd Tanous } 31621b8b02a4SEd Tanous 31631b8b02a4SEd Tanous CONSTCD11 31641b8b02a4SEd Tanous inline 31651b8b02a4SEd Tanous year_month_day 31661b8b02a4SEd Tanous operator-(const year_month_day& ymd, const years& dy) NOEXCEPT 31671b8b02a4SEd Tanous { 31681b8b02a4SEd Tanous return ymd + (-dy); 31691b8b02a4SEd Tanous } 31701b8b02a4SEd Tanous 31711b8b02a4SEd Tanous // year_month_weekday 31721b8b02a4SEd Tanous 31731b8b02a4SEd Tanous CONSTCD11 31741b8b02a4SEd Tanous inline 31751b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const date::year& y, const date::month& m, 31761b8b02a4SEd Tanous const date::weekday_indexed& wdi) 31771b8b02a4SEd Tanous NOEXCEPT 31781b8b02a4SEd Tanous : y_(y) 31791b8b02a4SEd Tanous , m_(m) 31801b8b02a4SEd Tanous , wdi_(wdi) 31811b8b02a4SEd Tanous {} 31821b8b02a4SEd Tanous 31831b8b02a4SEd Tanous CONSTCD14 31841b8b02a4SEd Tanous inline 31851b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT 31861b8b02a4SEd Tanous : year_month_weekday(from_days(dp.time_since_epoch())) 31871b8b02a4SEd Tanous {} 31881b8b02a4SEd Tanous 31891b8b02a4SEd Tanous CONSTCD14 31901b8b02a4SEd Tanous inline 31911b8b02a4SEd Tanous year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT 31921b8b02a4SEd Tanous : year_month_weekday(from_days(dp.time_since_epoch())) 31931b8b02a4SEd Tanous {} 31941b8b02a4SEd Tanous 31951b8b02a4SEd Tanous template<class> 31961b8b02a4SEd Tanous CONSTCD14 31971b8b02a4SEd Tanous inline 31981b8b02a4SEd Tanous year_month_weekday& 31991b8b02a4SEd Tanous year_month_weekday::operator+=(const months& m) NOEXCEPT 32001b8b02a4SEd Tanous { 32011b8b02a4SEd Tanous *this = *this + m; 32021b8b02a4SEd Tanous return *this; 32031b8b02a4SEd Tanous } 32041b8b02a4SEd Tanous 32051b8b02a4SEd Tanous template<class> 32061b8b02a4SEd Tanous CONSTCD14 32071b8b02a4SEd Tanous inline 32081b8b02a4SEd Tanous year_month_weekday& 32091b8b02a4SEd Tanous year_month_weekday::operator-=(const months& m) NOEXCEPT 32101b8b02a4SEd Tanous { 32111b8b02a4SEd Tanous *this = *this - m; 32121b8b02a4SEd Tanous return *this; 32131b8b02a4SEd Tanous } 32141b8b02a4SEd Tanous 32151b8b02a4SEd Tanous CONSTCD14 32161b8b02a4SEd Tanous inline 32171b8b02a4SEd Tanous year_month_weekday& 32181b8b02a4SEd Tanous year_month_weekday::operator+=(const years& y) NOEXCEPT 32191b8b02a4SEd Tanous { 32201b8b02a4SEd Tanous *this = *this + y; 32211b8b02a4SEd Tanous return *this; 32221b8b02a4SEd Tanous } 32231b8b02a4SEd Tanous 32241b8b02a4SEd Tanous CONSTCD14 32251b8b02a4SEd Tanous inline 32261b8b02a4SEd Tanous year_month_weekday& 32271b8b02a4SEd Tanous year_month_weekday::operator-=(const years& y) NOEXCEPT 32281b8b02a4SEd Tanous { 32291b8b02a4SEd Tanous *this = *this - y; 32301b8b02a4SEd Tanous return *this; 32311b8b02a4SEd Tanous } 32321b8b02a4SEd Tanous 32331b8b02a4SEd Tanous CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} 32341b8b02a4SEd Tanous CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} 32351b8b02a4SEd Tanous 32361b8b02a4SEd Tanous CONSTCD11 32371b8b02a4SEd Tanous inline 32381b8b02a4SEd Tanous weekday 32391b8b02a4SEd Tanous year_month_weekday::weekday() const NOEXCEPT 32401b8b02a4SEd Tanous { 32411b8b02a4SEd Tanous return wdi_.weekday(); 32421b8b02a4SEd Tanous } 32431b8b02a4SEd Tanous 32441b8b02a4SEd Tanous CONSTCD11 32451b8b02a4SEd Tanous inline 32461b8b02a4SEd Tanous unsigned 32471b8b02a4SEd Tanous year_month_weekday::index() const NOEXCEPT 32481b8b02a4SEd Tanous { 32491b8b02a4SEd Tanous return wdi_.index(); 32501b8b02a4SEd Tanous } 32511b8b02a4SEd Tanous 32521b8b02a4SEd Tanous CONSTCD11 32531b8b02a4SEd Tanous inline 32541b8b02a4SEd Tanous weekday_indexed 32551b8b02a4SEd Tanous year_month_weekday::weekday_indexed() const NOEXCEPT 32561b8b02a4SEd Tanous { 32571b8b02a4SEd Tanous return wdi_; 32581b8b02a4SEd Tanous } 32591b8b02a4SEd Tanous 32601b8b02a4SEd Tanous CONSTCD14 32611b8b02a4SEd Tanous inline 32621b8b02a4SEd Tanous year_month_weekday::operator sys_days() const NOEXCEPT 32631b8b02a4SEd Tanous { 32641b8b02a4SEd Tanous return sys_days{to_days()}; 32651b8b02a4SEd Tanous } 32661b8b02a4SEd Tanous 32671b8b02a4SEd Tanous CONSTCD14 32681b8b02a4SEd Tanous inline 32691b8b02a4SEd Tanous year_month_weekday::operator local_days() const NOEXCEPT 32701b8b02a4SEd Tanous { 32711b8b02a4SEd Tanous return local_days{to_days()}; 32721b8b02a4SEd Tanous } 32731b8b02a4SEd Tanous 32741b8b02a4SEd Tanous CONSTCD14 32751b8b02a4SEd Tanous inline 32761b8b02a4SEd Tanous bool 32771b8b02a4SEd Tanous year_month_weekday::ok() const NOEXCEPT 32781b8b02a4SEd Tanous { 32791b8b02a4SEd Tanous if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) 32801b8b02a4SEd Tanous return false; 32811b8b02a4SEd Tanous if (wdi_.index() <= 4) 32821b8b02a4SEd Tanous return true; 32831b8b02a4SEd Tanous auto d2 = wdi_.weekday() - date::weekday(static_cast<sys_days>(y_/m_/1)) + 32841b8b02a4SEd Tanous days((wdi_.index()-1)*7 + 1); 32851b8b02a4SEd Tanous return static_cast<unsigned>(d2.count()) <= static_cast<unsigned>((y_/m_/last).day()); 32861b8b02a4SEd Tanous } 32871b8b02a4SEd Tanous 32881b8b02a4SEd Tanous CONSTCD14 32891b8b02a4SEd Tanous inline 32901b8b02a4SEd Tanous year_month_weekday 32911b8b02a4SEd Tanous year_month_weekday::from_days(days d) NOEXCEPT 32921b8b02a4SEd Tanous { 32931b8b02a4SEd Tanous sys_days dp{d}; 32941b8b02a4SEd Tanous auto const wd = date::weekday(dp); 32951b8b02a4SEd Tanous auto const ymd = year_month_day(dp); 32961b8b02a4SEd Tanous return {ymd.year(), ymd.month(), wd[(static_cast<unsigned>(ymd.day())-1)/7+1]}; 32971b8b02a4SEd Tanous } 32981b8b02a4SEd Tanous 32991b8b02a4SEd Tanous CONSTCD14 33001b8b02a4SEd Tanous inline 33011b8b02a4SEd Tanous days 33021b8b02a4SEd Tanous year_month_weekday::to_days() const NOEXCEPT 33031b8b02a4SEd Tanous { 33041b8b02a4SEd Tanous auto d = sys_days(y_/m_/1); 33051b8b02a4SEd Tanous return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) 33061b8b02a4SEd Tanous ).time_since_epoch(); 33071b8b02a4SEd Tanous } 33081b8b02a4SEd Tanous 33091b8b02a4SEd Tanous CONSTCD11 33101b8b02a4SEd Tanous inline 33111b8b02a4SEd Tanous bool 33121b8b02a4SEd Tanous operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT 33131b8b02a4SEd Tanous { 33141b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && 33151b8b02a4SEd Tanous x.weekday_indexed() == y.weekday_indexed(); 33161b8b02a4SEd Tanous } 33171b8b02a4SEd Tanous 33181b8b02a4SEd Tanous CONSTCD11 33191b8b02a4SEd Tanous inline 33201b8b02a4SEd Tanous bool 33211b8b02a4SEd Tanous operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT 33221b8b02a4SEd Tanous { 33231b8b02a4SEd Tanous return !(x == y); 33241b8b02a4SEd Tanous } 33251b8b02a4SEd Tanous 33261b8b02a4SEd Tanous template<class CharT, class Traits> 33271b8b02a4SEd Tanous inline 33281b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 33291b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi) 33301b8b02a4SEd Tanous { 33311b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.year()) << '/'; 33321b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.month()) << '/'; 33331b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdi.weekday_indexed()); 33341b8b02a4SEd Tanous if (!ymwdi.ok()) 33351b8b02a4SEd Tanous os << " is not a valid year_month_weekday"; 33361b8b02a4SEd Tanous return os; 33371b8b02a4SEd Tanous } 33381b8b02a4SEd Tanous 33391b8b02a4SEd Tanous template<class> 33401b8b02a4SEd Tanous CONSTCD14 33411b8b02a4SEd Tanous inline 33421b8b02a4SEd Tanous year_month_weekday 33431b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT 33441b8b02a4SEd Tanous { 33451b8b02a4SEd Tanous return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); 33461b8b02a4SEd Tanous } 33471b8b02a4SEd Tanous 33481b8b02a4SEd Tanous template<class> 33491b8b02a4SEd Tanous CONSTCD14 33501b8b02a4SEd Tanous inline 33511b8b02a4SEd Tanous year_month_weekday 33521b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT 33531b8b02a4SEd Tanous { 33541b8b02a4SEd Tanous return ymwd + dm; 33551b8b02a4SEd Tanous } 33561b8b02a4SEd Tanous 33571b8b02a4SEd Tanous template<class> 33581b8b02a4SEd Tanous CONSTCD14 33591b8b02a4SEd Tanous inline 33601b8b02a4SEd Tanous year_month_weekday 33611b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT 33621b8b02a4SEd Tanous { 33631b8b02a4SEd Tanous return ymwd + (-dm); 33641b8b02a4SEd Tanous } 33651b8b02a4SEd Tanous 33661b8b02a4SEd Tanous CONSTCD11 33671b8b02a4SEd Tanous inline 33681b8b02a4SEd Tanous year_month_weekday 33691b8b02a4SEd Tanous operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT 33701b8b02a4SEd Tanous { 33711b8b02a4SEd Tanous return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; 33721b8b02a4SEd Tanous } 33731b8b02a4SEd Tanous 33741b8b02a4SEd Tanous CONSTCD11 33751b8b02a4SEd Tanous inline 33761b8b02a4SEd Tanous year_month_weekday 33771b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT 33781b8b02a4SEd Tanous { 33791b8b02a4SEd Tanous return ymwd + dy; 33801b8b02a4SEd Tanous } 33811b8b02a4SEd Tanous 33821b8b02a4SEd Tanous CONSTCD11 33831b8b02a4SEd Tanous inline 33841b8b02a4SEd Tanous year_month_weekday 33851b8b02a4SEd Tanous operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT 33861b8b02a4SEd Tanous { 33871b8b02a4SEd Tanous return ymwd + (-dy); 33881b8b02a4SEd Tanous } 33891b8b02a4SEd Tanous 33901b8b02a4SEd Tanous // year_month_weekday_last 33911b8b02a4SEd Tanous 33921b8b02a4SEd Tanous CONSTCD11 33931b8b02a4SEd Tanous inline 33941b8b02a4SEd Tanous year_month_weekday_last::year_month_weekday_last(const date::year& y, 33951b8b02a4SEd Tanous const date::month& m, 33961b8b02a4SEd Tanous const date::weekday_last& wdl) NOEXCEPT 33971b8b02a4SEd Tanous : y_(y) 33981b8b02a4SEd Tanous , m_(m) 33991b8b02a4SEd Tanous , wdl_(wdl) 34001b8b02a4SEd Tanous {} 34011b8b02a4SEd Tanous 34021b8b02a4SEd Tanous template<class> 34031b8b02a4SEd Tanous CONSTCD14 34041b8b02a4SEd Tanous inline 34051b8b02a4SEd Tanous year_month_weekday_last& 34061b8b02a4SEd Tanous year_month_weekday_last::operator+=(const months& m) NOEXCEPT 34071b8b02a4SEd Tanous { 34081b8b02a4SEd Tanous *this = *this + m; 34091b8b02a4SEd Tanous return *this; 34101b8b02a4SEd Tanous } 34111b8b02a4SEd Tanous 34121b8b02a4SEd Tanous template<class> 34131b8b02a4SEd Tanous CONSTCD14 34141b8b02a4SEd Tanous inline 34151b8b02a4SEd Tanous year_month_weekday_last& 34161b8b02a4SEd Tanous year_month_weekday_last::operator-=(const months& m) NOEXCEPT 34171b8b02a4SEd Tanous { 34181b8b02a4SEd Tanous *this = *this - m; 34191b8b02a4SEd Tanous return *this; 34201b8b02a4SEd Tanous } 34211b8b02a4SEd Tanous 34221b8b02a4SEd Tanous CONSTCD14 34231b8b02a4SEd Tanous inline 34241b8b02a4SEd Tanous year_month_weekday_last& 34251b8b02a4SEd Tanous year_month_weekday_last::operator+=(const years& y) NOEXCEPT 34261b8b02a4SEd Tanous { 34271b8b02a4SEd Tanous *this = *this + y; 34281b8b02a4SEd Tanous return *this; 34291b8b02a4SEd Tanous } 34301b8b02a4SEd Tanous 34311b8b02a4SEd Tanous CONSTCD14 34321b8b02a4SEd Tanous inline 34331b8b02a4SEd Tanous year_month_weekday_last& 34341b8b02a4SEd Tanous year_month_weekday_last::operator-=(const years& y) NOEXCEPT 34351b8b02a4SEd Tanous { 34361b8b02a4SEd Tanous *this = *this - y; 34371b8b02a4SEd Tanous return *this; 34381b8b02a4SEd Tanous } 34391b8b02a4SEd Tanous 34401b8b02a4SEd Tanous CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} 34411b8b02a4SEd Tanous CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} 34421b8b02a4SEd Tanous 34431b8b02a4SEd Tanous CONSTCD11 34441b8b02a4SEd Tanous inline 34451b8b02a4SEd Tanous weekday 34461b8b02a4SEd Tanous year_month_weekday_last::weekday() const NOEXCEPT 34471b8b02a4SEd Tanous { 34481b8b02a4SEd Tanous return wdl_.weekday(); 34491b8b02a4SEd Tanous } 34501b8b02a4SEd Tanous 34511b8b02a4SEd Tanous CONSTCD11 34521b8b02a4SEd Tanous inline 34531b8b02a4SEd Tanous weekday_last 34541b8b02a4SEd Tanous year_month_weekday_last::weekday_last() const NOEXCEPT 34551b8b02a4SEd Tanous { 34561b8b02a4SEd Tanous return wdl_; 34571b8b02a4SEd Tanous } 34581b8b02a4SEd Tanous 34591b8b02a4SEd Tanous CONSTCD14 34601b8b02a4SEd Tanous inline 34611b8b02a4SEd Tanous year_month_weekday_last::operator sys_days() const NOEXCEPT 34621b8b02a4SEd Tanous { 34631b8b02a4SEd Tanous return sys_days{to_days()}; 34641b8b02a4SEd Tanous } 34651b8b02a4SEd Tanous 34661b8b02a4SEd Tanous CONSTCD14 34671b8b02a4SEd Tanous inline 34681b8b02a4SEd Tanous year_month_weekday_last::operator local_days() const NOEXCEPT 34691b8b02a4SEd Tanous { 34701b8b02a4SEd Tanous return local_days{to_days()}; 34711b8b02a4SEd Tanous } 34721b8b02a4SEd Tanous 34731b8b02a4SEd Tanous CONSTCD11 34741b8b02a4SEd Tanous inline 34751b8b02a4SEd Tanous bool 34761b8b02a4SEd Tanous year_month_weekday_last::ok() const NOEXCEPT 34771b8b02a4SEd Tanous { 34781b8b02a4SEd Tanous return y_.ok() && m_.ok() && wdl_.ok(); 34791b8b02a4SEd Tanous } 34801b8b02a4SEd Tanous 34811b8b02a4SEd Tanous CONSTCD14 34821b8b02a4SEd Tanous inline 34831b8b02a4SEd Tanous days 34841b8b02a4SEd Tanous year_month_weekday_last::to_days() const NOEXCEPT 34851b8b02a4SEd Tanous { 34861b8b02a4SEd Tanous auto const d = sys_days(y_/m_/last); 34871b8b02a4SEd Tanous return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); 34881b8b02a4SEd Tanous } 34891b8b02a4SEd Tanous 34901b8b02a4SEd Tanous CONSTCD11 34911b8b02a4SEd Tanous inline 34921b8b02a4SEd Tanous bool 34931b8b02a4SEd Tanous operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT 34941b8b02a4SEd Tanous { 34951b8b02a4SEd Tanous return x.year() == y.year() && x.month() == y.month() && 34961b8b02a4SEd Tanous x.weekday_last() == y.weekday_last(); 34971b8b02a4SEd Tanous } 34981b8b02a4SEd Tanous 34991b8b02a4SEd Tanous CONSTCD11 35001b8b02a4SEd Tanous inline 35011b8b02a4SEd Tanous bool 35021b8b02a4SEd Tanous operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT 35031b8b02a4SEd Tanous { 35041b8b02a4SEd Tanous return !(x == y); 35051b8b02a4SEd Tanous } 35061b8b02a4SEd Tanous 35071b8b02a4SEd Tanous template<class CharT, class Traits> 35081b8b02a4SEd Tanous inline 35091b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 35101b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl) 35111b8b02a4SEd Tanous { 35121b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.year()) << '/'; 35131b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.month()) << '/'; 35141b8b02a4SEd Tanous detail::low_level_fmt(os, ymwdl.weekday_last()); 35151b8b02a4SEd Tanous if (!ymwdl.ok()) 35161b8b02a4SEd Tanous os << " is not a valid year_month_weekday_last"; 35171b8b02a4SEd Tanous return os; 35181b8b02a4SEd Tanous } 35191b8b02a4SEd Tanous 35201b8b02a4SEd Tanous template<class> 35211b8b02a4SEd Tanous CONSTCD14 35221b8b02a4SEd Tanous inline 35231b8b02a4SEd Tanous year_month_weekday_last 35241b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT 35251b8b02a4SEd Tanous { 35261b8b02a4SEd Tanous return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); 35271b8b02a4SEd Tanous } 35281b8b02a4SEd Tanous 35291b8b02a4SEd Tanous template<class> 35301b8b02a4SEd Tanous CONSTCD14 35311b8b02a4SEd Tanous inline 35321b8b02a4SEd Tanous year_month_weekday_last 35331b8b02a4SEd Tanous operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT 35341b8b02a4SEd Tanous { 35351b8b02a4SEd Tanous return ymwdl + dm; 35361b8b02a4SEd Tanous } 35371b8b02a4SEd Tanous 35381b8b02a4SEd Tanous template<class> 35391b8b02a4SEd Tanous CONSTCD14 35401b8b02a4SEd Tanous inline 35411b8b02a4SEd Tanous year_month_weekday_last 35421b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT 35431b8b02a4SEd Tanous { 35441b8b02a4SEd Tanous return ymwdl + (-dm); 35451b8b02a4SEd Tanous } 35461b8b02a4SEd Tanous 35471b8b02a4SEd Tanous CONSTCD11 35481b8b02a4SEd Tanous inline 35491b8b02a4SEd Tanous year_month_weekday_last 35501b8b02a4SEd Tanous operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT 35511b8b02a4SEd Tanous { 35521b8b02a4SEd Tanous return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; 35531b8b02a4SEd Tanous } 35541b8b02a4SEd Tanous 35551b8b02a4SEd Tanous CONSTCD11 35561b8b02a4SEd Tanous inline 35571b8b02a4SEd Tanous year_month_weekday_last 35581b8b02a4SEd Tanous operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT 35591b8b02a4SEd Tanous { 35601b8b02a4SEd Tanous return ymwdl + dy; 35611b8b02a4SEd Tanous } 35621b8b02a4SEd Tanous 35631b8b02a4SEd Tanous CONSTCD11 35641b8b02a4SEd Tanous inline 35651b8b02a4SEd Tanous year_month_weekday_last 35661b8b02a4SEd Tanous operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT 35671b8b02a4SEd Tanous { 35681b8b02a4SEd Tanous return ymwdl + (-dy); 35691b8b02a4SEd Tanous } 35701b8b02a4SEd Tanous 35711b8b02a4SEd Tanous // year_month from operator/() 35721b8b02a4SEd Tanous 35731b8b02a4SEd Tanous CONSTCD11 35741b8b02a4SEd Tanous inline 35751b8b02a4SEd Tanous year_month 35761b8b02a4SEd Tanous operator/(const year& y, const month& m) NOEXCEPT 35771b8b02a4SEd Tanous { 35781b8b02a4SEd Tanous return {y, m}; 35791b8b02a4SEd Tanous } 35801b8b02a4SEd Tanous 35811b8b02a4SEd Tanous CONSTCD11 35821b8b02a4SEd Tanous inline 35831b8b02a4SEd Tanous year_month 35841b8b02a4SEd Tanous operator/(const year& y, int m) NOEXCEPT 35851b8b02a4SEd Tanous { 35861b8b02a4SEd Tanous return y / month(static_cast<unsigned>(m)); 35871b8b02a4SEd Tanous } 35881b8b02a4SEd Tanous 35891b8b02a4SEd Tanous // month_day from operator/() 35901b8b02a4SEd Tanous 35911b8b02a4SEd Tanous CONSTCD11 35921b8b02a4SEd Tanous inline 35931b8b02a4SEd Tanous month_day 35941b8b02a4SEd Tanous operator/(const month& m, const day& d) NOEXCEPT 35951b8b02a4SEd Tanous { 35961b8b02a4SEd Tanous return {m, d}; 35971b8b02a4SEd Tanous } 35981b8b02a4SEd Tanous 35991b8b02a4SEd Tanous CONSTCD11 36001b8b02a4SEd Tanous inline 36011b8b02a4SEd Tanous month_day 36021b8b02a4SEd Tanous operator/(const day& d, const month& m) NOEXCEPT 36031b8b02a4SEd Tanous { 36041b8b02a4SEd Tanous return m / d; 36051b8b02a4SEd Tanous } 36061b8b02a4SEd Tanous 36071b8b02a4SEd Tanous CONSTCD11 36081b8b02a4SEd Tanous inline 36091b8b02a4SEd Tanous month_day 36101b8b02a4SEd Tanous operator/(const month& m, int d) NOEXCEPT 36111b8b02a4SEd Tanous { 36121b8b02a4SEd Tanous return m / day(static_cast<unsigned>(d)); 36131b8b02a4SEd Tanous } 36141b8b02a4SEd Tanous 36151b8b02a4SEd Tanous CONSTCD11 36161b8b02a4SEd Tanous inline 36171b8b02a4SEd Tanous month_day 36181b8b02a4SEd Tanous operator/(int m, const day& d) NOEXCEPT 36191b8b02a4SEd Tanous { 36201b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / d; 36211b8b02a4SEd Tanous } 36221b8b02a4SEd Tanous 36231b8b02a4SEd Tanous CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} 36241b8b02a4SEd Tanous 36251b8b02a4SEd Tanous // month_day_last from operator/() 36261b8b02a4SEd Tanous 36271b8b02a4SEd Tanous CONSTCD11 36281b8b02a4SEd Tanous inline 36291b8b02a4SEd Tanous month_day_last 36301b8b02a4SEd Tanous operator/(const month& m, last_spec) NOEXCEPT 36311b8b02a4SEd Tanous { 36321b8b02a4SEd Tanous return month_day_last{m}; 36331b8b02a4SEd Tanous } 36341b8b02a4SEd Tanous 36351b8b02a4SEd Tanous CONSTCD11 36361b8b02a4SEd Tanous inline 36371b8b02a4SEd Tanous month_day_last 36381b8b02a4SEd Tanous operator/(last_spec, const month& m) NOEXCEPT 36391b8b02a4SEd Tanous { 36401b8b02a4SEd Tanous return m/last; 36411b8b02a4SEd Tanous } 36421b8b02a4SEd Tanous 36431b8b02a4SEd Tanous CONSTCD11 36441b8b02a4SEd Tanous inline 36451b8b02a4SEd Tanous month_day_last 36461b8b02a4SEd Tanous operator/(int m, last_spec) NOEXCEPT 36471b8b02a4SEd Tanous { 36481b8b02a4SEd Tanous return month(static_cast<unsigned>(m))/last; 36491b8b02a4SEd Tanous } 36501b8b02a4SEd Tanous 36511b8b02a4SEd Tanous CONSTCD11 36521b8b02a4SEd Tanous inline 36531b8b02a4SEd Tanous month_day_last 36541b8b02a4SEd Tanous operator/(last_spec, int m) NOEXCEPT 36551b8b02a4SEd Tanous { 36561b8b02a4SEd Tanous return m/last; 36571b8b02a4SEd Tanous } 36581b8b02a4SEd Tanous 36591b8b02a4SEd Tanous // month_weekday from operator/() 36601b8b02a4SEd Tanous 36611b8b02a4SEd Tanous CONSTCD11 36621b8b02a4SEd Tanous inline 36631b8b02a4SEd Tanous month_weekday 36641b8b02a4SEd Tanous operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT 36651b8b02a4SEd Tanous { 36661b8b02a4SEd Tanous return {m, wdi}; 36671b8b02a4SEd Tanous } 36681b8b02a4SEd Tanous 36691b8b02a4SEd Tanous CONSTCD11 36701b8b02a4SEd Tanous inline 36711b8b02a4SEd Tanous month_weekday 36721b8b02a4SEd Tanous operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT 36731b8b02a4SEd Tanous { 36741b8b02a4SEd Tanous return m / wdi; 36751b8b02a4SEd Tanous } 36761b8b02a4SEd Tanous 36771b8b02a4SEd Tanous CONSTCD11 36781b8b02a4SEd Tanous inline 36791b8b02a4SEd Tanous month_weekday 36801b8b02a4SEd Tanous operator/(int m, const weekday_indexed& wdi) NOEXCEPT 36811b8b02a4SEd Tanous { 36821b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / wdi; 36831b8b02a4SEd Tanous } 36841b8b02a4SEd Tanous 36851b8b02a4SEd Tanous CONSTCD11 36861b8b02a4SEd Tanous inline 36871b8b02a4SEd Tanous month_weekday 36881b8b02a4SEd Tanous operator/(const weekday_indexed& wdi, int m) NOEXCEPT 36891b8b02a4SEd Tanous { 36901b8b02a4SEd Tanous return m / wdi; 36911b8b02a4SEd Tanous } 36921b8b02a4SEd Tanous 36931b8b02a4SEd Tanous // month_weekday_last from operator/() 36941b8b02a4SEd Tanous 36951b8b02a4SEd Tanous CONSTCD11 36961b8b02a4SEd Tanous inline 36971b8b02a4SEd Tanous month_weekday_last 36981b8b02a4SEd Tanous operator/(const month& m, const weekday_last& wdl) NOEXCEPT 36991b8b02a4SEd Tanous { 37001b8b02a4SEd Tanous return {m, wdl}; 37011b8b02a4SEd Tanous } 37021b8b02a4SEd Tanous 37031b8b02a4SEd Tanous CONSTCD11 37041b8b02a4SEd Tanous inline 37051b8b02a4SEd Tanous month_weekday_last 37061b8b02a4SEd Tanous operator/(const weekday_last& wdl, const month& m) NOEXCEPT 37071b8b02a4SEd Tanous { 37081b8b02a4SEd Tanous return m / wdl; 37091b8b02a4SEd Tanous } 37101b8b02a4SEd Tanous 37111b8b02a4SEd Tanous CONSTCD11 37121b8b02a4SEd Tanous inline 37131b8b02a4SEd Tanous month_weekday_last 37141b8b02a4SEd Tanous operator/(int m, const weekday_last& wdl) NOEXCEPT 37151b8b02a4SEd Tanous { 37161b8b02a4SEd Tanous return month(static_cast<unsigned>(m)) / wdl; 37171b8b02a4SEd Tanous } 37181b8b02a4SEd Tanous 37191b8b02a4SEd Tanous CONSTCD11 37201b8b02a4SEd Tanous inline 37211b8b02a4SEd Tanous month_weekday_last 37221b8b02a4SEd Tanous operator/(const weekday_last& wdl, int m) NOEXCEPT 37231b8b02a4SEd Tanous { 37241b8b02a4SEd Tanous return m / wdl; 37251b8b02a4SEd Tanous } 37261b8b02a4SEd Tanous 37271b8b02a4SEd Tanous // year_month_day from operator/() 37281b8b02a4SEd Tanous 37291b8b02a4SEd Tanous CONSTCD11 37301b8b02a4SEd Tanous inline 37311b8b02a4SEd Tanous year_month_day 37321b8b02a4SEd Tanous operator/(const year_month& ym, const day& d) NOEXCEPT 37331b8b02a4SEd Tanous { 37341b8b02a4SEd Tanous return {ym.year(), ym.month(), d}; 37351b8b02a4SEd Tanous } 37361b8b02a4SEd Tanous 37371b8b02a4SEd Tanous CONSTCD11 37381b8b02a4SEd Tanous inline 37391b8b02a4SEd Tanous year_month_day 37401b8b02a4SEd Tanous operator/(const year_month& ym, int d) NOEXCEPT 37411b8b02a4SEd Tanous { 37421b8b02a4SEd Tanous return ym / day(static_cast<unsigned>(d)); 37431b8b02a4SEd Tanous } 37441b8b02a4SEd Tanous 37451b8b02a4SEd Tanous CONSTCD11 37461b8b02a4SEd Tanous inline 37471b8b02a4SEd Tanous year_month_day 37481b8b02a4SEd Tanous operator/(const year& y, const month_day& md) NOEXCEPT 37491b8b02a4SEd Tanous { 37501b8b02a4SEd Tanous return y / md.month() / md.day(); 37511b8b02a4SEd Tanous } 37521b8b02a4SEd Tanous 37531b8b02a4SEd Tanous CONSTCD11 37541b8b02a4SEd Tanous inline 37551b8b02a4SEd Tanous year_month_day 37561b8b02a4SEd Tanous operator/(int y, const month_day& md) NOEXCEPT 37571b8b02a4SEd Tanous { 37581b8b02a4SEd Tanous return year(y) / md; 37591b8b02a4SEd Tanous } 37601b8b02a4SEd Tanous 37611b8b02a4SEd Tanous CONSTCD11 37621b8b02a4SEd Tanous inline 37631b8b02a4SEd Tanous year_month_day 37641b8b02a4SEd Tanous operator/(const month_day& md, const year& y) NOEXCEPT 37651b8b02a4SEd Tanous { 37661b8b02a4SEd Tanous return y / md; 37671b8b02a4SEd Tanous } 37681b8b02a4SEd Tanous 37691b8b02a4SEd Tanous CONSTCD11 37701b8b02a4SEd Tanous inline 37711b8b02a4SEd Tanous year_month_day 37721b8b02a4SEd Tanous operator/(const month_day& md, int y) NOEXCEPT 37731b8b02a4SEd Tanous { 37741b8b02a4SEd Tanous return year(y) / md; 37751b8b02a4SEd Tanous } 37761b8b02a4SEd Tanous 37771b8b02a4SEd Tanous // year_month_day_last from operator/() 37781b8b02a4SEd Tanous 37791b8b02a4SEd Tanous CONSTCD11 37801b8b02a4SEd Tanous inline 37811b8b02a4SEd Tanous year_month_day_last 37821b8b02a4SEd Tanous operator/(const year_month& ym, last_spec) NOEXCEPT 37831b8b02a4SEd Tanous { 37841b8b02a4SEd Tanous return {ym.year(), month_day_last{ym.month()}}; 37851b8b02a4SEd Tanous } 37861b8b02a4SEd Tanous 37871b8b02a4SEd Tanous CONSTCD11 37881b8b02a4SEd Tanous inline 37891b8b02a4SEd Tanous year_month_day_last 37901b8b02a4SEd Tanous operator/(const year& y, const month_day_last& mdl) NOEXCEPT 37911b8b02a4SEd Tanous { 37921b8b02a4SEd Tanous return {y, mdl}; 37931b8b02a4SEd Tanous } 37941b8b02a4SEd Tanous 37951b8b02a4SEd Tanous CONSTCD11 37961b8b02a4SEd Tanous inline 37971b8b02a4SEd Tanous year_month_day_last 37981b8b02a4SEd Tanous operator/(int y, const month_day_last& mdl) NOEXCEPT 37991b8b02a4SEd Tanous { 38001b8b02a4SEd Tanous return year(y) / mdl; 38011b8b02a4SEd Tanous } 38021b8b02a4SEd Tanous 38031b8b02a4SEd Tanous CONSTCD11 38041b8b02a4SEd Tanous inline 38051b8b02a4SEd Tanous year_month_day_last 38061b8b02a4SEd Tanous operator/(const month_day_last& mdl, const year& y) NOEXCEPT 38071b8b02a4SEd Tanous { 38081b8b02a4SEd Tanous return y / mdl; 38091b8b02a4SEd Tanous } 38101b8b02a4SEd Tanous 38111b8b02a4SEd Tanous CONSTCD11 38121b8b02a4SEd Tanous inline 38131b8b02a4SEd Tanous year_month_day_last 38141b8b02a4SEd Tanous operator/(const month_day_last& mdl, int y) NOEXCEPT 38151b8b02a4SEd Tanous { 38161b8b02a4SEd Tanous return year(y) / mdl; 38171b8b02a4SEd Tanous } 38181b8b02a4SEd Tanous 38191b8b02a4SEd Tanous // year_month_weekday from operator/() 38201b8b02a4SEd Tanous 38211b8b02a4SEd Tanous CONSTCD11 38221b8b02a4SEd Tanous inline 38231b8b02a4SEd Tanous year_month_weekday 38241b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT 38251b8b02a4SEd Tanous { 38261b8b02a4SEd Tanous return {ym.year(), ym.month(), wdi}; 38271b8b02a4SEd Tanous } 38281b8b02a4SEd Tanous 38291b8b02a4SEd Tanous CONSTCD11 38301b8b02a4SEd Tanous inline 38311b8b02a4SEd Tanous year_month_weekday 38321b8b02a4SEd Tanous operator/(const year& y, const month_weekday& mwd) NOEXCEPT 38331b8b02a4SEd Tanous { 38341b8b02a4SEd Tanous return {y, mwd.month(), mwd.weekday_indexed()}; 38351b8b02a4SEd Tanous } 38361b8b02a4SEd Tanous 38371b8b02a4SEd Tanous CONSTCD11 38381b8b02a4SEd Tanous inline 38391b8b02a4SEd Tanous year_month_weekday 38401b8b02a4SEd Tanous operator/(int y, const month_weekday& mwd) NOEXCEPT 38411b8b02a4SEd Tanous { 38421b8b02a4SEd Tanous return year(y) / mwd; 38431b8b02a4SEd Tanous } 38441b8b02a4SEd Tanous 38451b8b02a4SEd Tanous CONSTCD11 38461b8b02a4SEd Tanous inline 38471b8b02a4SEd Tanous year_month_weekday 38481b8b02a4SEd Tanous operator/(const month_weekday& mwd, const year& y) NOEXCEPT 38491b8b02a4SEd Tanous { 38501b8b02a4SEd Tanous return y / mwd; 38511b8b02a4SEd Tanous } 38521b8b02a4SEd Tanous 38531b8b02a4SEd Tanous CONSTCD11 38541b8b02a4SEd Tanous inline 38551b8b02a4SEd Tanous year_month_weekday 38561b8b02a4SEd Tanous operator/(const month_weekday& mwd, int y) NOEXCEPT 38571b8b02a4SEd Tanous { 38581b8b02a4SEd Tanous return year(y) / mwd; 38591b8b02a4SEd Tanous } 38601b8b02a4SEd Tanous 38611b8b02a4SEd Tanous // year_month_weekday_last from operator/() 38621b8b02a4SEd Tanous 38631b8b02a4SEd Tanous CONSTCD11 38641b8b02a4SEd Tanous inline 38651b8b02a4SEd Tanous year_month_weekday_last 38661b8b02a4SEd Tanous operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT 38671b8b02a4SEd Tanous { 38681b8b02a4SEd Tanous return {ym.year(), ym.month(), wdl}; 38691b8b02a4SEd Tanous } 38701b8b02a4SEd Tanous 38711b8b02a4SEd Tanous CONSTCD11 38721b8b02a4SEd Tanous inline 38731b8b02a4SEd Tanous year_month_weekday_last 38741b8b02a4SEd Tanous operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT 38751b8b02a4SEd Tanous { 38761b8b02a4SEd Tanous return {y, mwdl.month(), mwdl.weekday_last()}; 38771b8b02a4SEd Tanous } 38781b8b02a4SEd Tanous 38791b8b02a4SEd Tanous CONSTCD11 38801b8b02a4SEd Tanous inline 38811b8b02a4SEd Tanous year_month_weekday_last 38821b8b02a4SEd Tanous operator/(int y, const month_weekday_last& mwdl) NOEXCEPT 38831b8b02a4SEd Tanous { 38841b8b02a4SEd Tanous return year(y) / mwdl; 38851b8b02a4SEd Tanous } 38861b8b02a4SEd Tanous 38871b8b02a4SEd Tanous CONSTCD11 38881b8b02a4SEd Tanous inline 38891b8b02a4SEd Tanous year_month_weekday_last 38901b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT 38911b8b02a4SEd Tanous { 38921b8b02a4SEd Tanous return y / mwdl; 38931b8b02a4SEd Tanous } 38941b8b02a4SEd Tanous 38951b8b02a4SEd Tanous CONSTCD11 38961b8b02a4SEd Tanous inline 38971b8b02a4SEd Tanous year_month_weekday_last 38981b8b02a4SEd Tanous operator/(const month_weekday_last& mwdl, int y) NOEXCEPT 38991b8b02a4SEd Tanous { 39001b8b02a4SEd Tanous return year(y) / mwdl; 39011b8b02a4SEd Tanous } 39021b8b02a4SEd Tanous 39031b8b02a4SEd Tanous template <class Duration> 39041b8b02a4SEd Tanous struct fields; 39051b8b02a4SEd Tanous 39061b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 39071b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 39081b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 39091b8b02a4SEd Tanous const fields<Duration>& fds, const std::string* abbrev = nullptr, 39101b8b02a4SEd Tanous const std::chrono::seconds* offset_sec = nullptr); 39111b8b02a4SEd Tanous 39121b8b02a4SEd Tanous template <class CharT, class Traits, class Duration, class Alloc> 39131b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 39141b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 39151b8b02a4SEd Tanous fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 39161b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr); 39171b8b02a4SEd Tanous 39181b8b02a4SEd Tanous // hh_mm_ss 39191b8b02a4SEd Tanous 39201b8b02a4SEd Tanous namespace detail 39211b8b02a4SEd Tanous { 39221b8b02a4SEd Tanous 39231b8b02a4SEd Tanous struct undocumented {explicit undocumented() = default;}; 39241b8b02a4SEd Tanous 39251b8b02a4SEd Tanous // width<n>::value is the number of fractional decimal digits in 1/n 39261b8b02a4SEd Tanous // width<0>::value and width<1>::value are defined to be 0 39271b8b02a4SEd Tanous // If 1/n takes more than 18 fractional decimal digits, 39281b8b02a4SEd Tanous // the result is truncated to 19. 39291b8b02a4SEd Tanous // Example: width<2>::value == 1 39301b8b02a4SEd Tanous // Example: width<3>::value == 19 39311b8b02a4SEd Tanous // Example: width<4>::value == 2 39321b8b02a4SEd Tanous // Example: width<10>::value == 1 39331b8b02a4SEd Tanous // Example: width<1000>::value == 3 39341b8b02a4SEd Tanous template <std::uint64_t n, std::uint64_t d, unsigned w = 0, 39351b8b02a4SEd Tanous bool should_continue = n%d != 0 && (w < 19)> 39361b8b02a4SEd Tanous struct width 39371b8b02a4SEd Tanous { 39381b8b02a4SEd Tanous static_assert(d > 0, "width called with zero denominator"); 39391b8b02a4SEd Tanous static CONSTDATA unsigned value = 1 + width<n%d*10, d, w+1>::value; 39401b8b02a4SEd Tanous }; 39411b8b02a4SEd Tanous 39421b8b02a4SEd Tanous template <std::uint64_t n, std::uint64_t d, unsigned w> 39431b8b02a4SEd Tanous struct width<n, d, w, false> 39441b8b02a4SEd Tanous { 39451b8b02a4SEd Tanous static CONSTDATA unsigned value = 0; 39461b8b02a4SEd Tanous }; 39471b8b02a4SEd Tanous 39481b8b02a4SEd Tanous template <unsigned exp> 39491b8b02a4SEd Tanous struct static_pow10 39501b8b02a4SEd Tanous { 39511b8b02a4SEd Tanous private: 39521b8b02a4SEd Tanous static CONSTDATA std::uint64_t h = static_pow10<exp/2>::value; 39531b8b02a4SEd Tanous public: 39541b8b02a4SEd Tanous static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1); 39551b8b02a4SEd Tanous }; 39561b8b02a4SEd Tanous 39571b8b02a4SEd Tanous template <> 39581b8b02a4SEd Tanous struct static_pow10<0> 39591b8b02a4SEd Tanous { 39601b8b02a4SEd Tanous static CONSTDATA std::uint64_t value = 1; 39611b8b02a4SEd Tanous }; 39621b8b02a4SEd Tanous 39631b8b02a4SEd Tanous template <class Duration> 39641b8b02a4SEd Tanous class decimal_format_seconds 39651b8b02a4SEd Tanous { 39661b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 39671b8b02a4SEd Tanous using rep = typename CT::rep; 39681b8b02a4SEd Tanous static unsigned CONSTDATA trial_width = 39691b8b02a4SEd Tanous detail::width<CT::period::num, CT::period::den>::value; 39701b8b02a4SEd Tanous public: 39711b8b02a4SEd Tanous static unsigned CONSTDATA width = trial_width < 19 ? trial_width : 6u; 39721b8b02a4SEd Tanous using precision = std::chrono::duration<rep, 39731b8b02a4SEd Tanous std::ratio<1, static_pow10<width>::value>>; 39741b8b02a4SEd Tanous 39751b8b02a4SEd Tanous private: 39761b8b02a4SEd Tanous std::chrono::seconds s_; 39771b8b02a4SEd Tanous precision sub_s_; 39781b8b02a4SEd Tanous 39791b8b02a4SEd Tanous public: 39801b8b02a4SEd Tanous CONSTCD11 decimal_format_seconds() 39811b8b02a4SEd Tanous : s_() 39821b8b02a4SEd Tanous , sub_s_() 39831b8b02a4SEd Tanous {} 39841b8b02a4SEd Tanous 39851b8b02a4SEd Tanous CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT 39861b8b02a4SEd Tanous : s_(std::chrono::duration_cast<std::chrono::seconds>(d)) 39871b8b02a4SEd Tanous , sub_s_(std::chrono::duration_cast<precision>(d - s_)) 39881b8b02a4SEd Tanous {} 39891b8b02a4SEd Tanous 39901b8b02a4SEd Tanous CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} 39911b8b02a4SEd Tanous CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} 39921b8b02a4SEd Tanous CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} 39931b8b02a4SEd Tanous 39941b8b02a4SEd Tanous CONSTCD14 precision to_duration() const NOEXCEPT 39951b8b02a4SEd Tanous { 39961b8b02a4SEd Tanous return s_ + sub_s_; 39971b8b02a4SEd Tanous } 39981b8b02a4SEd Tanous 39991b8b02a4SEd Tanous CONSTCD11 bool in_conventional_range() const NOEXCEPT 40001b8b02a4SEd Tanous { 40011b8b02a4SEd Tanous return sub_s_ < std::chrono::seconds{1} && s_ < std::chrono::minutes{1}; 40021b8b02a4SEd Tanous } 40031b8b02a4SEd Tanous 40041b8b02a4SEd Tanous template <class CharT, class Traits> 40051b8b02a4SEd Tanous friend 40061b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 40071b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x) 40081b8b02a4SEd Tanous { 40091b8b02a4SEd Tanous return x.print(os, std::chrono::treat_as_floating_point<rep>{}); 40101b8b02a4SEd Tanous } 40111b8b02a4SEd Tanous 40121b8b02a4SEd Tanous template <class CharT, class Traits> 40131b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 40141b8b02a4SEd Tanous print(std::basic_ostream<CharT, Traits>& os, std::true_type) const 40151b8b02a4SEd Tanous { 40161b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _(os); 40171b8b02a4SEd Tanous std::chrono::duration<rep> d = s_ + sub_s_; 40181b8b02a4SEd Tanous if (d < std::chrono::seconds{10}) 40191b8b02a4SEd Tanous os << '0'; 40201b8b02a4SEd Tanous os.precision(width+6); 40211b8b02a4SEd Tanous os << std::fixed << d.count(); 40221b8b02a4SEd Tanous return os; 40231b8b02a4SEd Tanous } 40241b8b02a4SEd Tanous 40251b8b02a4SEd Tanous template <class CharT, class Traits> 40261b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 40271b8b02a4SEd Tanous print(std::basic_ostream<CharT, Traits>& os, std::false_type) const 40281b8b02a4SEd Tanous { 40291b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _(os); 40301b8b02a4SEd Tanous os.fill('0'); 40311b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 40321b8b02a4SEd Tanous os.width(2); 40331b8b02a4SEd Tanous os << s_.count(); 40341b8b02a4SEd Tanous if (width > 0) 40351b8b02a4SEd Tanous { 40361b8b02a4SEd Tanous #if !ONLY_C_LOCALE 40371b8b02a4SEd Tanous os << std::use_facet<std::numpunct<CharT>>(os.getloc()).decimal_point(); 40381b8b02a4SEd Tanous #else 40391b8b02a4SEd Tanous os << '.'; 40401b8b02a4SEd Tanous #endif 40411b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> _s(os); 40421b8b02a4SEd Tanous os.imbue(std::locale::classic()); 40431b8b02a4SEd Tanous os.width(width); 40441b8b02a4SEd Tanous os << sub_s_.count(); 40451b8b02a4SEd Tanous } 40461b8b02a4SEd Tanous return os; 40471b8b02a4SEd Tanous } 40481b8b02a4SEd Tanous }; 40491b8b02a4SEd Tanous 40501b8b02a4SEd Tanous template <class Rep, class Period> 40511b8b02a4SEd Tanous inline 40521b8b02a4SEd Tanous CONSTCD11 40531b8b02a4SEd Tanous typename std::enable_if 40541b8b02a4SEd Tanous < 40551b8b02a4SEd Tanous std::numeric_limits<Rep>::is_signed, 40561b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 40571b8b02a4SEd Tanous >::type 40581b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 40591b8b02a4SEd Tanous { 40601b8b02a4SEd Tanous return d >= d.zero() ? +d : -d; 40611b8b02a4SEd Tanous } 40621b8b02a4SEd Tanous 40631b8b02a4SEd Tanous template <class Rep, class Period> 40641b8b02a4SEd Tanous inline 40651b8b02a4SEd Tanous CONSTCD11 40661b8b02a4SEd Tanous typename std::enable_if 40671b8b02a4SEd Tanous < 40681b8b02a4SEd Tanous !std::numeric_limits<Rep>::is_signed, 40691b8b02a4SEd Tanous std::chrono::duration<Rep, Period> 40701b8b02a4SEd Tanous >::type 40711b8b02a4SEd Tanous abs(std::chrono::duration<Rep, Period> d) 40721b8b02a4SEd Tanous { 40731b8b02a4SEd Tanous return d; 40741b8b02a4SEd Tanous } 40751b8b02a4SEd Tanous 40761b8b02a4SEd Tanous } // namespace detail 40771b8b02a4SEd Tanous 40781b8b02a4SEd Tanous template <class Duration> 40791b8b02a4SEd Tanous class hh_mm_ss 40801b8b02a4SEd Tanous { 40811b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<typename std::common_type<Duration, 40821b8b02a4SEd Tanous std::chrono::seconds>::type>; 40831b8b02a4SEd Tanous 40841b8b02a4SEd Tanous std::chrono::hours h_; 40851b8b02a4SEd Tanous std::chrono::minutes m_; 40861b8b02a4SEd Tanous dfs s_; 40871b8b02a4SEd Tanous bool neg_; 40881b8b02a4SEd Tanous 40891b8b02a4SEd Tanous public: 40901b8b02a4SEd Tanous static unsigned CONSTDATA fractional_width = dfs::width; 40911b8b02a4SEd Tanous using precision = typename dfs::precision; 40921b8b02a4SEd Tanous 40931b8b02a4SEd Tanous CONSTCD11 hh_mm_ss() NOEXCEPT 40941b8b02a4SEd Tanous : hh_mm_ss(Duration::zero()) 40951b8b02a4SEd Tanous {} 40961b8b02a4SEd Tanous 40971b8b02a4SEd Tanous CONSTCD11 explicit hh_mm_ss(Duration d) NOEXCEPT 40981b8b02a4SEd Tanous : h_(std::chrono::duration_cast<std::chrono::hours>(detail::abs(d))) 40991b8b02a4SEd Tanous , m_(std::chrono::duration_cast<std::chrono::minutes>(detail::abs(d)) - h_) 41001b8b02a4SEd Tanous , s_(detail::abs(d) - h_ - m_) 41011b8b02a4SEd Tanous , neg_(d < Duration::zero()) 41021b8b02a4SEd Tanous {} 41031b8b02a4SEd Tanous 41041b8b02a4SEd Tanous CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} 41051b8b02a4SEd Tanous CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} 41061b8b02a4SEd Tanous CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} 41071b8b02a4SEd Tanous CONSTCD14 std::chrono::seconds& 41081b8b02a4SEd Tanous seconds(detail::undocumented) NOEXCEPT {return s_.seconds();} 41091b8b02a4SEd Tanous CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();} 41101b8b02a4SEd Tanous CONSTCD11 bool is_negative() const NOEXCEPT {return neg_;} 41111b8b02a4SEd Tanous 41121b8b02a4SEd Tanous CONSTCD11 explicit operator precision() const NOEXCEPT {return to_duration();} 41131b8b02a4SEd Tanous CONSTCD11 precision to_duration() const NOEXCEPT 41141b8b02a4SEd Tanous {return (s_.to_duration() + m_ + h_) * (1-2*neg_);} 41151b8b02a4SEd Tanous 41161b8b02a4SEd Tanous CONSTCD11 bool in_conventional_range() const NOEXCEPT 41171b8b02a4SEd Tanous { 41181b8b02a4SEd Tanous return !neg_ && h_ < days{1} && m_ < std::chrono::hours{1} && 41191b8b02a4SEd Tanous s_.in_conventional_range(); 41201b8b02a4SEd Tanous } 41211b8b02a4SEd Tanous 41221b8b02a4SEd Tanous private: 41231b8b02a4SEd Tanous 41241b8b02a4SEd Tanous template <class charT, class traits> 41251b8b02a4SEd Tanous friend 41261b8b02a4SEd Tanous std::basic_ostream<charT, traits>& 41271b8b02a4SEd Tanous operator<<(std::basic_ostream<charT, traits>& os, hh_mm_ss const& tod) 41281b8b02a4SEd Tanous { 41291b8b02a4SEd Tanous if (tod.is_negative()) 41301b8b02a4SEd Tanous os << '-'; 41311b8b02a4SEd Tanous if (tod.h_ < std::chrono::hours{10}) 41321b8b02a4SEd Tanous os << '0'; 41331b8b02a4SEd Tanous os << tod.h_.count() << ':'; 41341b8b02a4SEd Tanous if (tod.m_ < std::chrono::minutes{10}) 41351b8b02a4SEd Tanous os << '0'; 41361b8b02a4SEd Tanous os << tod.m_.count() << ':' << tod.s_; 41371b8b02a4SEd Tanous return os; 41381b8b02a4SEd Tanous } 41391b8b02a4SEd Tanous 41401b8b02a4SEd Tanous template <class CharT, class Traits, class Duration2> 41411b8b02a4SEd Tanous friend 41421b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 41431b8b02a4SEd Tanous date::to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 41441b8b02a4SEd Tanous const fields<Duration2>& fds, const std::string* abbrev, 41451b8b02a4SEd Tanous const std::chrono::seconds* offset_sec); 41461b8b02a4SEd Tanous 41471b8b02a4SEd Tanous template <class CharT, class Traits, class Duration2, class Alloc> 41481b8b02a4SEd Tanous friend 41491b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 41501b8b02a4SEd Tanous date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 41511b8b02a4SEd Tanous fields<Duration2>& fds, 41521b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev, std::chrono::minutes* offset); 41531b8b02a4SEd Tanous }; 41541b8b02a4SEd Tanous 41551b8b02a4SEd Tanous inline 41561b8b02a4SEd Tanous CONSTCD14 41571b8b02a4SEd Tanous bool 41581b8b02a4SEd Tanous is_am(std::chrono::hours const& h) NOEXCEPT 41591b8b02a4SEd Tanous { 41601b8b02a4SEd Tanous using std::chrono::hours; 41611b8b02a4SEd Tanous return hours{0} <= h && h < hours{12}; 41621b8b02a4SEd Tanous } 41631b8b02a4SEd Tanous 41641b8b02a4SEd Tanous inline 41651b8b02a4SEd Tanous CONSTCD14 41661b8b02a4SEd Tanous bool 41671b8b02a4SEd Tanous is_pm(std::chrono::hours const& h) NOEXCEPT 41681b8b02a4SEd Tanous { 41691b8b02a4SEd Tanous using std::chrono::hours; 41701b8b02a4SEd Tanous return hours{12} <= h && h < hours{24}; 41711b8b02a4SEd Tanous } 41721b8b02a4SEd Tanous 41731b8b02a4SEd Tanous inline 41741b8b02a4SEd Tanous CONSTCD14 41751b8b02a4SEd Tanous std::chrono::hours 41761b8b02a4SEd Tanous make12(std::chrono::hours h) NOEXCEPT 41771b8b02a4SEd Tanous { 41781b8b02a4SEd Tanous using std::chrono::hours; 41791b8b02a4SEd Tanous if (h < hours{12}) 41801b8b02a4SEd Tanous { 41811b8b02a4SEd Tanous if (h == hours{0}) 41821b8b02a4SEd Tanous h = hours{12}; 41831b8b02a4SEd Tanous } 41841b8b02a4SEd Tanous else 41851b8b02a4SEd Tanous { 41861b8b02a4SEd Tanous if (h != hours{12}) 41871b8b02a4SEd Tanous h = h - hours{12}; 41881b8b02a4SEd Tanous } 41891b8b02a4SEd Tanous return h; 41901b8b02a4SEd Tanous } 41911b8b02a4SEd Tanous 41921b8b02a4SEd Tanous inline 41931b8b02a4SEd Tanous CONSTCD14 41941b8b02a4SEd Tanous std::chrono::hours 41951b8b02a4SEd Tanous make24(std::chrono::hours h, bool is_pm) NOEXCEPT 41961b8b02a4SEd Tanous { 41971b8b02a4SEd Tanous using std::chrono::hours; 41981b8b02a4SEd Tanous if (is_pm) 41991b8b02a4SEd Tanous { 42001b8b02a4SEd Tanous if (h != hours{12}) 42011b8b02a4SEd Tanous h = h + hours{12}; 42021b8b02a4SEd Tanous } 42031b8b02a4SEd Tanous else if (h == hours{12}) 42041b8b02a4SEd Tanous h = hours{0}; 42051b8b02a4SEd Tanous return h; 42061b8b02a4SEd Tanous } 42071b8b02a4SEd Tanous 42081b8b02a4SEd Tanous template <class Duration> 42091b8b02a4SEd Tanous using time_of_day = hh_mm_ss<Duration>; 42101b8b02a4SEd Tanous 42111b8b02a4SEd Tanous template <class Rep, class Period> 42121b8b02a4SEd Tanous CONSTCD11 42131b8b02a4SEd Tanous inline 42141b8b02a4SEd Tanous hh_mm_ss<std::chrono::duration<Rep, Period>> 42151b8b02a4SEd Tanous make_time(const std::chrono::duration<Rep, Period>& d) 42161b8b02a4SEd Tanous { 42171b8b02a4SEd Tanous return hh_mm_ss<std::chrono::duration<Rep, Period>>(d); 42181b8b02a4SEd Tanous } 42191b8b02a4SEd Tanous 42201b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 42211b8b02a4SEd Tanous inline 42221b8b02a4SEd Tanous typename std::enable_if 42231b8b02a4SEd Tanous < 42241b8b02a4SEd Tanous !std::is_convertible<Duration, days>::value, 42251b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 42261b8b02a4SEd Tanous >::type 42271b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const sys_time<Duration>& tp) 42281b8b02a4SEd Tanous { 42291b8b02a4SEd Tanous auto const dp = date::floor<days>(tp); 42301b8b02a4SEd Tanous return os << year_month_day(dp) << ' ' << make_time(tp-dp); 42311b8b02a4SEd Tanous } 42321b8b02a4SEd Tanous 42331b8b02a4SEd Tanous template <class CharT, class Traits> 42341b8b02a4SEd Tanous inline 42351b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 42361b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const sys_days& dp) 42371b8b02a4SEd Tanous { 42381b8b02a4SEd Tanous return os << year_month_day(dp); 42391b8b02a4SEd Tanous } 42401b8b02a4SEd Tanous 42411b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 42421b8b02a4SEd Tanous inline 42431b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 42441b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const local_time<Duration>& ut) 42451b8b02a4SEd Tanous { 42461b8b02a4SEd Tanous return (os << sys_time<Duration>{ut.time_since_epoch()}); 42471b8b02a4SEd Tanous } 42481b8b02a4SEd Tanous 42491b8b02a4SEd Tanous namespace detail 42501b8b02a4SEd Tanous { 42511b8b02a4SEd Tanous 42521b8b02a4SEd Tanous template <class CharT, std::size_t N> 42531b8b02a4SEd Tanous class string_literal; 42541b8b02a4SEd Tanous 42551b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 42561b8b02a4SEd Tanous inline 42571b8b02a4SEd Tanous CONSTCD14 42581b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 42591b8b02a4SEd Tanous N1 + N2 - 1> 42601b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT; 42611b8b02a4SEd Tanous 42621b8b02a4SEd Tanous template <class CharT, std::size_t N> 42631b8b02a4SEd Tanous class string_literal 42641b8b02a4SEd Tanous { 42651b8b02a4SEd Tanous CharT p_[N]; 42661b8b02a4SEd Tanous 42671b8b02a4SEd Tanous CONSTCD11 string_literal() NOEXCEPT 42681b8b02a4SEd Tanous : p_{} 42691b8b02a4SEd Tanous {} 42701b8b02a4SEd Tanous 42711b8b02a4SEd Tanous public: 42721b8b02a4SEd Tanous using const_iterator = const CharT*; 42731b8b02a4SEd Tanous 42741b8b02a4SEd Tanous string_literal(string_literal const&) = default; 42751b8b02a4SEd Tanous string_literal& operator=(string_literal const&) = delete; 42761b8b02a4SEd Tanous 42771b8b02a4SEd Tanous template <std::size_t N1 = 2, 42781b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 42791b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c) NOEXCEPT 42801b8b02a4SEd Tanous : p_{c} 42811b8b02a4SEd Tanous { 42821b8b02a4SEd Tanous } 42831b8b02a4SEd Tanous 42841b8b02a4SEd Tanous template <std::size_t N1 = 3, 42851b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 42861b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c1, CharT c2) NOEXCEPT 42871b8b02a4SEd Tanous : p_{c1, c2} 42881b8b02a4SEd Tanous { 42891b8b02a4SEd Tanous } 42901b8b02a4SEd Tanous 42911b8b02a4SEd Tanous template <std::size_t N1 = 4, 42921b8b02a4SEd Tanous class = typename std::enable_if<N1 == N>::type> 42931b8b02a4SEd Tanous CONSTCD11 string_literal(CharT c1, CharT c2, CharT c3) NOEXCEPT 42941b8b02a4SEd Tanous : p_{c1, c2, c3} 42951b8b02a4SEd Tanous { 42961b8b02a4SEd Tanous } 42971b8b02a4SEd Tanous 42981b8b02a4SEd Tanous CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT 42991b8b02a4SEd Tanous : p_{} 43001b8b02a4SEd Tanous { 43011b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 43021b8b02a4SEd Tanous p_[i] = a[i]; 43031b8b02a4SEd Tanous } 43041b8b02a4SEd Tanous 43051b8b02a4SEd Tanous template <class U = CharT, 43061b8b02a4SEd Tanous class = typename std::enable_if<(1 < sizeof(U))>::type> 43071b8b02a4SEd Tanous CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT 43081b8b02a4SEd Tanous : p_{} 43091b8b02a4SEd Tanous { 43101b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 43111b8b02a4SEd Tanous p_[i] = a[i]; 43121b8b02a4SEd Tanous } 43131b8b02a4SEd Tanous 43141b8b02a4SEd Tanous template <class CharT2, 43151b8b02a4SEd Tanous class = typename std::enable_if<!std::is_same<CharT2, CharT>::value>::type> 43161b8b02a4SEd Tanous CONSTCD14 string_literal(string_literal<CharT2, N> const& a) NOEXCEPT 43171b8b02a4SEd Tanous : p_{} 43181b8b02a4SEd Tanous { 43191b8b02a4SEd Tanous for (std::size_t i = 0; i < N; ++i) 43201b8b02a4SEd Tanous p_[i] = a[i]; 43211b8b02a4SEd Tanous } 43221b8b02a4SEd Tanous 43231b8b02a4SEd Tanous CONSTCD11 const CharT* data() const NOEXCEPT {return p_;} 43241b8b02a4SEd Tanous CONSTCD11 std::size_t size() const NOEXCEPT {return N-1;} 43251b8b02a4SEd Tanous 43261b8b02a4SEd Tanous CONSTCD11 const_iterator begin() const NOEXCEPT {return p_;} 43271b8b02a4SEd Tanous CONSTCD11 const_iterator end() const NOEXCEPT {return p_ + N-1;} 43281b8b02a4SEd Tanous 43291b8b02a4SEd Tanous CONSTCD11 CharT const& operator[](std::size_t n) const NOEXCEPT 43301b8b02a4SEd Tanous { 43311b8b02a4SEd Tanous return p_[n]; 43321b8b02a4SEd Tanous } 43331b8b02a4SEd Tanous 43341b8b02a4SEd Tanous template <class Traits> 43351b8b02a4SEd Tanous friend 43361b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 43371b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s) 43381b8b02a4SEd Tanous { 43391b8b02a4SEd Tanous return os << s.p_; 43401b8b02a4SEd Tanous } 43411b8b02a4SEd Tanous 43421b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 43431b8b02a4SEd Tanous friend 43441b8b02a4SEd Tanous CONSTCD14 43451b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 43461b8b02a4SEd Tanous N1 + N2 - 1> 43471b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT; 43481b8b02a4SEd Tanous }; 43491b8b02a4SEd Tanous 43501b8b02a4SEd Tanous template <class CharT> 43511b8b02a4SEd Tanous CONSTCD11 43521b8b02a4SEd Tanous inline 43531b8b02a4SEd Tanous string_literal<CharT, 3> 43541b8b02a4SEd Tanous operator+(const string_literal<CharT, 2>& x, const string_literal<CharT, 2>& y) NOEXCEPT 43551b8b02a4SEd Tanous { 43561b8b02a4SEd Tanous return string_literal<CharT, 3>(x[0], y[0]); 43571b8b02a4SEd Tanous } 43581b8b02a4SEd Tanous 43591b8b02a4SEd Tanous template <class CharT> 43601b8b02a4SEd Tanous CONSTCD11 43611b8b02a4SEd Tanous inline 43621b8b02a4SEd Tanous string_literal<CharT, 4> 43631b8b02a4SEd Tanous operator+(const string_literal<CharT, 3>& x, const string_literal<CharT, 2>& y) NOEXCEPT 43641b8b02a4SEd Tanous { 43651b8b02a4SEd Tanous return string_literal<CharT, 4>(x[0], x[1], y[0]); 43661b8b02a4SEd Tanous } 43671b8b02a4SEd Tanous 43681b8b02a4SEd Tanous template <class CharT1, class CharT2, std::size_t N1, std::size_t N2> 43691b8b02a4SEd Tanous CONSTCD14 43701b8b02a4SEd Tanous inline 43711b8b02a4SEd Tanous string_literal<typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type, 43721b8b02a4SEd Tanous N1 + N2 - 1> 43731b8b02a4SEd Tanous operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT 43741b8b02a4SEd Tanous { 43751b8b02a4SEd Tanous using CT = typename std::conditional<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>::type; 43761b8b02a4SEd Tanous 43771b8b02a4SEd Tanous string_literal<CT, N1 + N2 - 1> r; 43781b8b02a4SEd Tanous std::size_t i = 0; 43791b8b02a4SEd Tanous for (; i < N1-1; ++i) 43801b8b02a4SEd Tanous r.p_[i] = CT(x.p_[i]); 43811b8b02a4SEd Tanous for (std::size_t j = 0; j < N2; ++j, ++i) 43821b8b02a4SEd Tanous r.p_[i] = CT(y.p_[j]); 43831b8b02a4SEd Tanous 43841b8b02a4SEd Tanous return r; 43851b8b02a4SEd Tanous } 43861b8b02a4SEd Tanous 43871b8b02a4SEd Tanous 43881b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, std::size_t N> 43891b8b02a4SEd Tanous inline 43901b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> 43911b8b02a4SEd Tanous operator+(std::basic_string<CharT, Traits, Alloc> x, const string_literal<CharT, N>& y) 43921b8b02a4SEd Tanous { 43931b8b02a4SEd Tanous x.append(y.data(), y.size()); 43941b8b02a4SEd Tanous return x; 43951b8b02a4SEd Tanous } 43961b8b02a4SEd Tanous 43971b8b02a4SEd Tanous #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \ 43981b8b02a4SEd Tanous && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150) 43991b8b02a4SEd Tanous 44001b8b02a4SEd Tanous template <class CharT, 44011b8b02a4SEd Tanous class = std::enable_if_t<std::is_same<CharT, char>::value || 44021b8b02a4SEd Tanous std::is_same<CharT, wchar_t>::value || 44031b8b02a4SEd Tanous std::is_same<CharT, char16_t>::value || 44041b8b02a4SEd Tanous std::is_same<CharT, char32_t>::value>> 44051b8b02a4SEd Tanous CONSTCD14 44061b8b02a4SEd Tanous inline 44071b8b02a4SEd Tanous string_literal<CharT, 2> 44081b8b02a4SEd Tanous msl(CharT c) NOEXCEPT 44091b8b02a4SEd Tanous { 44101b8b02a4SEd Tanous return string_literal<CharT, 2>{c}; 44111b8b02a4SEd Tanous } 44121b8b02a4SEd Tanous 44131b8b02a4SEd Tanous CONSTCD14 44141b8b02a4SEd Tanous inline 44151b8b02a4SEd Tanous std::size_t 44161b8b02a4SEd Tanous to_string_len(std::intmax_t i) 44171b8b02a4SEd Tanous { 44181b8b02a4SEd Tanous std::size_t r = 0; 44191b8b02a4SEd Tanous do 44201b8b02a4SEd Tanous { 44211b8b02a4SEd Tanous i /= 10; 44221b8b02a4SEd Tanous ++r; 44231b8b02a4SEd Tanous } while (i > 0); 44241b8b02a4SEd Tanous return r; 44251b8b02a4SEd Tanous } 44261b8b02a4SEd Tanous 44271b8b02a4SEd Tanous template <std::intmax_t N> 44281b8b02a4SEd Tanous CONSTCD14 44291b8b02a4SEd Tanous inline 44301b8b02a4SEd Tanous std::enable_if_t 44311b8b02a4SEd Tanous < 44321b8b02a4SEd Tanous N < 10, 44331b8b02a4SEd Tanous string_literal<char, to_string_len(N)+1> 44341b8b02a4SEd Tanous > 44351b8b02a4SEd Tanous msl() NOEXCEPT 44361b8b02a4SEd Tanous { 44371b8b02a4SEd Tanous return msl(char(N % 10 + '0')); 44381b8b02a4SEd Tanous } 44391b8b02a4SEd Tanous 44401b8b02a4SEd Tanous template <std::intmax_t N> 44411b8b02a4SEd Tanous CONSTCD14 44421b8b02a4SEd Tanous inline 44431b8b02a4SEd Tanous std::enable_if_t 44441b8b02a4SEd Tanous < 44451b8b02a4SEd Tanous 10 <= N, 44461b8b02a4SEd Tanous string_literal<char, to_string_len(N)+1> 44471b8b02a4SEd Tanous > 44481b8b02a4SEd Tanous msl() NOEXCEPT 44491b8b02a4SEd Tanous { 44501b8b02a4SEd Tanous return msl<N/10>() + msl(char(N % 10 + '0')); 44511b8b02a4SEd Tanous } 44521b8b02a4SEd Tanous 44531b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 44541b8b02a4SEd Tanous CONSTCD14 44551b8b02a4SEd Tanous inline 44561b8b02a4SEd Tanous std::enable_if_t 44571b8b02a4SEd Tanous < 44581b8b02a4SEd Tanous std::ratio<N, D>::type::den != 1, 44591b8b02a4SEd Tanous string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 44601b8b02a4SEd Tanous to_string_len(std::ratio<N, D>::type::den) + 4> 44611b8b02a4SEd Tanous > 44621b8b02a4SEd Tanous msl(std::ratio<N, D>) NOEXCEPT 44631b8b02a4SEd Tanous { 44641b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 44651b8b02a4SEd Tanous return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) + 44661b8b02a4SEd Tanous msl<R::den>() + msl(CharT{']'}); 44671b8b02a4SEd Tanous } 44681b8b02a4SEd Tanous 44691b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 44701b8b02a4SEd Tanous CONSTCD14 44711b8b02a4SEd Tanous inline 44721b8b02a4SEd Tanous std::enable_if_t 44731b8b02a4SEd Tanous < 44741b8b02a4SEd Tanous std::ratio<N, D>::type::den == 1, 44751b8b02a4SEd Tanous string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3> 44761b8b02a4SEd Tanous > 44771b8b02a4SEd Tanous msl(std::ratio<N, D>) NOEXCEPT 44781b8b02a4SEd Tanous { 44791b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 44801b8b02a4SEd Tanous return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'}); 44811b8b02a4SEd Tanous } 44821b8b02a4SEd Tanous 44831b8b02a4SEd Tanous 44841b8b02a4SEd Tanous #else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) 44851b8b02a4SEd Tanous 44861b8b02a4SEd Tanous inline 44871b8b02a4SEd Tanous std::string 44881b8b02a4SEd Tanous to_string(std::uint64_t x) 44891b8b02a4SEd Tanous { 44901b8b02a4SEd Tanous return std::to_string(x); 44911b8b02a4SEd Tanous } 44921b8b02a4SEd Tanous 44931b8b02a4SEd Tanous template <class CharT> 44941b8b02a4SEd Tanous inline 44951b8b02a4SEd Tanous std::basic_string<CharT> 44961b8b02a4SEd Tanous to_string(std::uint64_t x) 44971b8b02a4SEd Tanous { 44981b8b02a4SEd Tanous auto y = std::to_string(x); 44991b8b02a4SEd Tanous return std::basic_string<CharT>(y.begin(), y.end()); 45001b8b02a4SEd Tanous } 45011b8b02a4SEd Tanous 45021b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 45031b8b02a4SEd Tanous inline 45041b8b02a4SEd Tanous typename std::enable_if 45051b8b02a4SEd Tanous < 45061b8b02a4SEd Tanous std::ratio<N, D>::type::den != 1, 45071b8b02a4SEd Tanous std::basic_string<CharT> 45081b8b02a4SEd Tanous >::type 45091b8b02a4SEd Tanous msl(std::ratio<N, D>) 45101b8b02a4SEd Tanous { 45111b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 45121b8b02a4SEd Tanous return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} + 45131b8b02a4SEd Tanous to_string<CharT>(R::den) + CharT{']'}; 45141b8b02a4SEd Tanous } 45151b8b02a4SEd Tanous 45161b8b02a4SEd Tanous template <class CharT, std::intmax_t N, std::intmax_t D> 45171b8b02a4SEd Tanous inline 45181b8b02a4SEd Tanous typename std::enable_if 45191b8b02a4SEd Tanous < 45201b8b02a4SEd Tanous std::ratio<N, D>::type::den == 1, 45211b8b02a4SEd Tanous std::basic_string<CharT> 45221b8b02a4SEd Tanous >::type 45231b8b02a4SEd Tanous msl(std::ratio<N, D>) 45241b8b02a4SEd Tanous { 45251b8b02a4SEd Tanous using R = typename std::ratio<N, D>::type; 45261b8b02a4SEd Tanous return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'}; 45271b8b02a4SEd Tanous } 45281b8b02a4SEd Tanous 45291b8b02a4SEd Tanous #endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) 45301b8b02a4SEd Tanous 45311b8b02a4SEd Tanous template <class CharT> 45321b8b02a4SEd Tanous CONSTCD11 45331b8b02a4SEd Tanous inline 45341b8b02a4SEd Tanous string_literal<CharT, 2> 45351b8b02a4SEd Tanous msl(std::atto) NOEXCEPT 45361b8b02a4SEd Tanous { 45371b8b02a4SEd Tanous return string_literal<CharT, 2>{'a'}; 45381b8b02a4SEd Tanous } 45391b8b02a4SEd Tanous 45401b8b02a4SEd Tanous template <class CharT> 45411b8b02a4SEd Tanous CONSTCD11 45421b8b02a4SEd Tanous inline 45431b8b02a4SEd Tanous string_literal<CharT, 2> 45441b8b02a4SEd Tanous msl(std::femto) NOEXCEPT 45451b8b02a4SEd Tanous { 45461b8b02a4SEd Tanous return string_literal<CharT, 2>{'f'}; 45471b8b02a4SEd Tanous } 45481b8b02a4SEd Tanous 45491b8b02a4SEd Tanous template <class CharT> 45501b8b02a4SEd Tanous CONSTCD11 45511b8b02a4SEd Tanous inline 45521b8b02a4SEd Tanous string_literal<CharT, 2> 45531b8b02a4SEd Tanous msl(std::pico) NOEXCEPT 45541b8b02a4SEd Tanous { 45551b8b02a4SEd Tanous return string_literal<CharT, 2>{'p'}; 45561b8b02a4SEd Tanous } 45571b8b02a4SEd Tanous 45581b8b02a4SEd Tanous template <class CharT> 45591b8b02a4SEd Tanous CONSTCD11 45601b8b02a4SEd Tanous inline 45611b8b02a4SEd Tanous string_literal<CharT, 2> 45621b8b02a4SEd Tanous msl(std::nano) NOEXCEPT 45631b8b02a4SEd Tanous { 45641b8b02a4SEd Tanous return string_literal<CharT, 2>{'n'}; 45651b8b02a4SEd Tanous } 45661b8b02a4SEd Tanous 45671b8b02a4SEd Tanous template <class CharT> 45681b8b02a4SEd Tanous CONSTCD11 45691b8b02a4SEd Tanous inline 45701b8b02a4SEd Tanous typename std::enable_if 45711b8b02a4SEd Tanous < 45721b8b02a4SEd Tanous std::is_same<CharT, char>::value, 45731b8b02a4SEd Tanous string_literal<char, 3> 45741b8b02a4SEd Tanous >::type 45751b8b02a4SEd Tanous msl(std::micro) NOEXCEPT 45761b8b02a4SEd Tanous { 45771b8b02a4SEd Tanous return string_literal<char, 3>{'\xC2', '\xB5'}; 45781b8b02a4SEd Tanous } 45791b8b02a4SEd Tanous 45801b8b02a4SEd Tanous template <class CharT> 45811b8b02a4SEd Tanous CONSTCD11 45821b8b02a4SEd Tanous inline 45831b8b02a4SEd Tanous typename std::enable_if 45841b8b02a4SEd Tanous < 45851b8b02a4SEd Tanous !std::is_same<CharT, char>::value, 45861b8b02a4SEd Tanous string_literal<CharT, 2> 45871b8b02a4SEd Tanous >::type 45881b8b02a4SEd Tanous msl(std::micro) NOEXCEPT 45891b8b02a4SEd Tanous { 45901b8b02a4SEd Tanous return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}}; 45911b8b02a4SEd Tanous } 45921b8b02a4SEd Tanous 45931b8b02a4SEd Tanous template <class CharT> 45941b8b02a4SEd Tanous CONSTCD11 45951b8b02a4SEd Tanous inline 45961b8b02a4SEd Tanous string_literal<CharT, 2> 45971b8b02a4SEd Tanous msl(std::milli) NOEXCEPT 45981b8b02a4SEd Tanous { 45991b8b02a4SEd Tanous return string_literal<CharT, 2>{'m'}; 46001b8b02a4SEd Tanous } 46011b8b02a4SEd Tanous 46021b8b02a4SEd Tanous template <class CharT> 46031b8b02a4SEd Tanous CONSTCD11 46041b8b02a4SEd Tanous inline 46051b8b02a4SEd Tanous string_literal<CharT, 2> 46061b8b02a4SEd Tanous msl(std::centi) NOEXCEPT 46071b8b02a4SEd Tanous { 46081b8b02a4SEd Tanous return string_literal<CharT, 2>{'c'}; 46091b8b02a4SEd Tanous } 46101b8b02a4SEd Tanous 46111b8b02a4SEd Tanous template <class CharT> 46121b8b02a4SEd Tanous CONSTCD11 46131b8b02a4SEd Tanous inline 46141b8b02a4SEd Tanous string_literal<CharT, 3> 46151b8b02a4SEd Tanous msl(std::deca) NOEXCEPT 46161b8b02a4SEd Tanous { 46171b8b02a4SEd Tanous return string_literal<CharT, 3>{'d', 'a'}; 46181b8b02a4SEd Tanous } 46191b8b02a4SEd Tanous 46201b8b02a4SEd Tanous template <class CharT> 46211b8b02a4SEd Tanous CONSTCD11 46221b8b02a4SEd Tanous inline 46231b8b02a4SEd Tanous string_literal<CharT, 2> 46241b8b02a4SEd Tanous msl(std::deci) NOEXCEPT 46251b8b02a4SEd Tanous { 46261b8b02a4SEd Tanous return string_literal<CharT, 2>{'d'}; 46271b8b02a4SEd Tanous } 46281b8b02a4SEd Tanous 46291b8b02a4SEd Tanous template <class CharT> 46301b8b02a4SEd Tanous CONSTCD11 46311b8b02a4SEd Tanous inline 46321b8b02a4SEd Tanous string_literal<CharT, 2> 46331b8b02a4SEd Tanous msl(std::hecto) NOEXCEPT 46341b8b02a4SEd Tanous { 46351b8b02a4SEd Tanous return string_literal<CharT, 2>{'h'}; 46361b8b02a4SEd Tanous } 46371b8b02a4SEd Tanous 46381b8b02a4SEd Tanous template <class CharT> 46391b8b02a4SEd Tanous CONSTCD11 46401b8b02a4SEd Tanous inline 46411b8b02a4SEd Tanous string_literal<CharT, 2> 46421b8b02a4SEd Tanous msl(std::kilo) NOEXCEPT 46431b8b02a4SEd Tanous { 46441b8b02a4SEd Tanous return string_literal<CharT, 2>{'k'}; 46451b8b02a4SEd Tanous } 46461b8b02a4SEd Tanous 46471b8b02a4SEd Tanous template <class CharT> 46481b8b02a4SEd Tanous CONSTCD11 46491b8b02a4SEd Tanous inline 46501b8b02a4SEd Tanous string_literal<CharT, 2> 46511b8b02a4SEd Tanous msl(std::mega) NOEXCEPT 46521b8b02a4SEd Tanous { 46531b8b02a4SEd Tanous return string_literal<CharT, 2>{'M'}; 46541b8b02a4SEd Tanous } 46551b8b02a4SEd Tanous 46561b8b02a4SEd Tanous template <class CharT> 46571b8b02a4SEd Tanous CONSTCD11 46581b8b02a4SEd Tanous inline 46591b8b02a4SEd Tanous string_literal<CharT, 2> 46601b8b02a4SEd Tanous msl(std::giga) NOEXCEPT 46611b8b02a4SEd Tanous { 46621b8b02a4SEd Tanous return string_literal<CharT, 2>{'G'}; 46631b8b02a4SEd Tanous } 46641b8b02a4SEd Tanous 46651b8b02a4SEd Tanous template <class CharT> 46661b8b02a4SEd Tanous CONSTCD11 46671b8b02a4SEd Tanous inline 46681b8b02a4SEd Tanous string_literal<CharT, 2> 46691b8b02a4SEd Tanous msl(std::tera) NOEXCEPT 46701b8b02a4SEd Tanous { 46711b8b02a4SEd Tanous return string_literal<CharT, 2>{'T'}; 46721b8b02a4SEd Tanous } 46731b8b02a4SEd Tanous 46741b8b02a4SEd Tanous template <class CharT> 46751b8b02a4SEd Tanous CONSTCD11 46761b8b02a4SEd Tanous inline 46771b8b02a4SEd Tanous string_literal<CharT, 2> 46781b8b02a4SEd Tanous msl(std::peta) NOEXCEPT 46791b8b02a4SEd Tanous { 46801b8b02a4SEd Tanous return string_literal<CharT, 2>{'P'}; 46811b8b02a4SEd Tanous } 46821b8b02a4SEd Tanous 46831b8b02a4SEd Tanous template <class CharT> 46841b8b02a4SEd Tanous CONSTCD11 46851b8b02a4SEd Tanous inline 46861b8b02a4SEd Tanous string_literal<CharT, 2> 46871b8b02a4SEd Tanous msl(std::exa) NOEXCEPT 46881b8b02a4SEd Tanous { 46891b8b02a4SEd Tanous return string_literal<CharT, 2>{'E'}; 46901b8b02a4SEd Tanous } 46911b8b02a4SEd Tanous 46921b8b02a4SEd Tanous template <class CharT, class Period> 46931b8b02a4SEd Tanous CONSTCD11 46941b8b02a4SEd Tanous inline 46951b8b02a4SEd Tanous auto 46961b8b02a4SEd Tanous get_units(Period p) 46971b8b02a4SEd Tanous -> decltype(msl<CharT>(p) + string_literal<CharT, 2>{'s'}) 46981b8b02a4SEd Tanous { 46991b8b02a4SEd Tanous return msl<CharT>(p) + string_literal<CharT, 2>{'s'}; 47001b8b02a4SEd Tanous } 47011b8b02a4SEd Tanous 47021b8b02a4SEd Tanous template <class CharT> 47031b8b02a4SEd Tanous CONSTCD11 47041b8b02a4SEd Tanous inline 47051b8b02a4SEd Tanous string_literal<CharT, 2> 47061b8b02a4SEd Tanous get_units(std::ratio<1>) 47071b8b02a4SEd Tanous { 47081b8b02a4SEd Tanous return string_literal<CharT, 2>{'s'}; 47091b8b02a4SEd Tanous } 47101b8b02a4SEd Tanous 47111b8b02a4SEd Tanous template <class CharT> 47121b8b02a4SEd Tanous CONSTCD11 47131b8b02a4SEd Tanous inline 47141b8b02a4SEd Tanous string_literal<CharT, 2> 47151b8b02a4SEd Tanous get_units(std::ratio<3600>) 47161b8b02a4SEd Tanous { 47171b8b02a4SEd Tanous return string_literal<CharT, 2>{'h'}; 47181b8b02a4SEd Tanous } 47191b8b02a4SEd Tanous 47201b8b02a4SEd Tanous template <class CharT> 47211b8b02a4SEd Tanous CONSTCD11 47221b8b02a4SEd Tanous inline 47231b8b02a4SEd Tanous string_literal<CharT, 4> 47241b8b02a4SEd Tanous get_units(std::ratio<60>) 47251b8b02a4SEd Tanous { 47261b8b02a4SEd Tanous return string_literal<CharT, 4>{'m', 'i', 'n'}; 47271b8b02a4SEd Tanous } 47281b8b02a4SEd Tanous 47291b8b02a4SEd Tanous template <class CharT> 47301b8b02a4SEd Tanous CONSTCD11 47311b8b02a4SEd Tanous inline 47321b8b02a4SEd Tanous string_literal<CharT, 2> 47331b8b02a4SEd Tanous get_units(std::ratio<86400>) 47341b8b02a4SEd Tanous { 47351b8b02a4SEd Tanous return string_literal<CharT, 2>{'d'}; 47361b8b02a4SEd Tanous } 47371b8b02a4SEd Tanous 47381b8b02a4SEd Tanous template <class CharT, class Traits = std::char_traits<CharT>> 47391b8b02a4SEd Tanous struct make_string; 47401b8b02a4SEd Tanous 47411b8b02a4SEd Tanous template <> 47421b8b02a4SEd Tanous struct make_string<char> 47431b8b02a4SEd Tanous { 47441b8b02a4SEd Tanous template <class Rep> 47451b8b02a4SEd Tanous static 47461b8b02a4SEd Tanous std::string 47471b8b02a4SEd Tanous from(Rep n) 47481b8b02a4SEd Tanous { 47491b8b02a4SEd Tanous return std::to_string(n); 47501b8b02a4SEd Tanous } 47511b8b02a4SEd Tanous }; 47521b8b02a4SEd Tanous 47531b8b02a4SEd Tanous template <class Traits> 47541b8b02a4SEd Tanous struct make_string<char, Traits> 47551b8b02a4SEd Tanous { 47561b8b02a4SEd Tanous template <class Rep> 47571b8b02a4SEd Tanous static 47581b8b02a4SEd Tanous std::basic_string<char, Traits> 47591b8b02a4SEd Tanous from(Rep n) 47601b8b02a4SEd Tanous { 47611b8b02a4SEd Tanous auto s = std::to_string(n); 47621b8b02a4SEd Tanous return std::basic_string<char, Traits>(s.begin(), s.end()); 47631b8b02a4SEd Tanous } 47641b8b02a4SEd Tanous }; 47651b8b02a4SEd Tanous 47661b8b02a4SEd Tanous template <> 47671b8b02a4SEd Tanous struct make_string<wchar_t> 47681b8b02a4SEd Tanous { 47691b8b02a4SEd Tanous template <class Rep> 47701b8b02a4SEd Tanous static 47711b8b02a4SEd Tanous std::wstring 47721b8b02a4SEd Tanous from(Rep n) 47731b8b02a4SEd Tanous { 47741b8b02a4SEd Tanous return std::to_wstring(n); 47751b8b02a4SEd Tanous } 47761b8b02a4SEd Tanous }; 47771b8b02a4SEd Tanous 47781b8b02a4SEd Tanous template <class Traits> 47791b8b02a4SEd Tanous struct make_string<wchar_t, Traits> 47801b8b02a4SEd Tanous { 47811b8b02a4SEd Tanous template <class Rep> 47821b8b02a4SEd Tanous static 47831b8b02a4SEd Tanous std::basic_string<wchar_t, Traits> 47841b8b02a4SEd Tanous from(Rep n) 47851b8b02a4SEd Tanous { 47861b8b02a4SEd Tanous auto s = std::to_wstring(n); 47871b8b02a4SEd Tanous return std::basic_string<wchar_t, Traits>(s.begin(), s.end()); 47881b8b02a4SEd Tanous } 47891b8b02a4SEd Tanous }; 47901b8b02a4SEd Tanous 47911b8b02a4SEd Tanous } // namespace detail 47921b8b02a4SEd Tanous 47931b8b02a4SEd Tanous // to_stream 47941b8b02a4SEd Tanous 47951b8b02a4SEd Tanous CONSTDATA year nanyear{-32768}; 47961b8b02a4SEd Tanous 47971b8b02a4SEd Tanous template <class Duration> 47981b8b02a4SEd Tanous struct fields 47991b8b02a4SEd Tanous { 48001b8b02a4SEd Tanous year_month_day ymd{nanyear/0/0}; 48011b8b02a4SEd Tanous weekday wd{8u}; 48021b8b02a4SEd Tanous hh_mm_ss<Duration> tod{}; 48031b8b02a4SEd Tanous bool has_tod = false; 48041b8b02a4SEd Tanous 48051b8b02a4SEd Tanous #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ <= 409) 48061b8b02a4SEd Tanous fields() : ymd{nanyear/0/0}, wd{8u}, tod{}, has_tod{false} {} 48071b8b02a4SEd Tanous #else 48081b8b02a4SEd Tanous fields() = default; 48091b8b02a4SEd Tanous #endif 48101b8b02a4SEd Tanous 48111b8b02a4SEd Tanous fields(year_month_day ymd_) : ymd(ymd_) {} 48121b8b02a4SEd Tanous fields(weekday wd_) : wd(wd_) {} 48131b8b02a4SEd Tanous fields(hh_mm_ss<Duration> tod_) : tod(tod_), has_tod(true) {} 48141b8b02a4SEd Tanous 48151b8b02a4SEd Tanous fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {} 48161b8b02a4SEd Tanous fields(year_month_day ymd_, hh_mm_ss<Duration> tod_) : ymd(ymd_), tod(tod_), 48171b8b02a4SEd Tanous has_tod(true) {} 48181b8b02a4SEd Tanous 48191b8b02a4SEd Tanous fields(weekday wd_, hh_mm_ss<Duration> tod_) : wd(wd_), tod(tod_), has_tod(true) {} 48201b8b02a4SEd Tanous 48211b8b02a4SEd Tanous fields(year_month_day ymd_, weekday wd_, hh_mm_ss<Duration> tod_) 48221b8b02a4SEd Tanous : ymd(ymd_) 48231b8b02a4SEd Tanous , wd(wd_) 48241b8b02a4SEd Tanous , tod(tod_) 48251b8b02a4SEd Tanous , has_tod(true) 48261b8b02a4SEd Tanous {} 48271b8b02a4SEd Tanous }; 48281b8b02a4SEd Tanous 48291b8b02a4SEd Tanous namespace detail 48301b8b02a4SEd Tanous { 48311b8b02a4SEd Tanous 48321b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 48331b8b02a4SEd Tanous unsigned 48341b8b02a4SEd Tanous extract_weekday(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds) 48351b8b02a4SEd Tanous { 48361b8b02a4SEd Tanous if (!fds.ymd.ok() && !fds.wd.ok()) 48371b8b02a4SEd Tanous { 48381b8b02a4SEd Tanous // fds does not contain a valid weekday 48391b8b02a4SEd Tanous os.setstate(std::ios::failbit); 48401b8b02a4SEd Tanous return 8; 48411b8b02a4SEd Tanous } 48421b8b02a4SEd Tanous weekday wd; 48431b8b02a4SEd Tanous if (fds.ymd.ok()) 48441b8b02a4SEd Tanous { 48451b8b02a4SEd Tanous wd = weekday{sys_days(fds.ymd)}; 48461b8b02a4SEd Tanous if (fds.wd.ok() && wd != fds.wd) 48471b8b02a4SEd Tanous { 48481b8b02a4SEd Tanous // fds.ymd and fds.wd are inconsistent 48491b8b02a4SEd Tanous os.setstate(std::ios::failbit); 48501b8b02a4SEd Tanous return 8; 48511b8b02a4SEd Tanous } 48521b8b02a4SEd Tanous } 48531b8b02a4SEd Tanous else 48541b8b02a4SEd Tanous wd = fds.wd; 48551b8b02a4SEd Tanous return static_cast<unsigned>((wd - Sunday).count()); 48561b8b02a4SEd Tanous } 48571b8b02a4SEd Tanous 48581b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 48591b8b02a4SEd Tanous unsigned 48601b8b02a4SEd Tanous extract_month(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds) 48611b8b02a4SEd Tanous { 48621b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 48631b8b02a4SEd Tanous { 48641b8b02a4SEd Tanous // fds does not contain a valid month 48651b8b02a4SEd Tanous os.setstate(std::ios::failbit); 48661b8b02a4SEd Tanous return 0; 48671b8b02a4SEd Tanous } 48681b8b02a4SEd Tanous return static_cast<unsigned>(fds.ymd.month()); 48691b8b02a4SEd Tanous } 48701b8b02a4SEd Tanous 48711b8b02a4SEd Tanous } // namespace detail 48721b8b02a4SEd Tanous 48731b8b02a4SEd Tanous #if ONLY_C_LOCALE 48741b8b02a4SEd Tanous 48751b8b02a4SEd Tanous namespace detail 48761b8b02a4SEd Tanous { 48771b8b02a4SEd Tanous 48781b8b02a4SEd Tanous inline 48791b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 48801b8b02a4SEd Tanous weekday_names() 48811b8b02a4SEd Tanous { 48821b8b02a4SEd Tanous static const std::string nm[] = 48831b8b02a4SEd Tanous { 48841b8b02a4SEd Tanous "Sunday", 48851b8b02a4SEd Tanous "Monday", 48861b8b02a4SEd Tanous "Tuesday", 48871b8b02a4SEd Tanous "Wednesday", 48881b8b02a4SEd Tanous "Thursday", 48891b8b02a4SEd Tanous "Friday", 48901b8b02a4SEd Tanous "Saturday", 48911b8b02a4SEd Tanous "Sun", 48921b8b02a4SEd Tanous "Mon", 48931b8b02a4SEd Tanous "Tue", 48941b8b02a4SEd Tanous "Wed", 48951b8b02a4SEd Tanous "Thu", 48961b8b02a4SEd Tanous "Fri", 48971b8b02a4SEd Tanous "Sat" 48981b8b02a4SEd Tanous }; 48991b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 49001b8b02a4SEd Tanous } 49011b8b02a4SEd Tanous 49021b8b02a4SEd Tanous inline 49031b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 49041b8b02a4SEd Tanous month_names() 49051b8b02a4SEd Tanous { 49061b8b02a4SEd Tanous static const std::string nm[] = 49071b8b02a4SEd Tanous { 49081b8b02a4SEd Tanous "January", 49091b8b02a4SEd Tanous "February", 49101b8b02a4SEd Tanous "March", 49111b8b02a4SEd Tanous "April", 49121b8b02a4SEd Tanous "May", 49131b8b02a4SEd Tanous "June", 49141b8b02a4SEd Tanous "July", 49151b8b02a4SEd Tanous "August", 49161b8b02a4SEd Tanous "September", 49171b8b02a4SEd Tanous "October", 49181b8b02a4SEd Tanous "November", 49191b8b02a4SEd Tanous "December", 49201b8b02a4SEd Tanous "Jan", 49211b8b02a4SEd Tanous "Feb", 49221b8b02a4SEd Tanous "Mar", 49231b8b02a4SEd Tanous "Apr", 49241b8b02a4SEd Tanous "May", 49251b8b02a4SEd Tanous "Jun", 49261b8b02a4SEd Tanous "Jul", 49271b8b02a4SEd Tanous "Aug", 49281b8b02a4SEd Tanous "Sep", 49291b8b02a4SEd Tanous "Oct", 49301b8b02a4SEd Tanous "Nov", 49311b8b02a4SEd Tanous "Dec" 49321b8b02a4SEd Tanous }; 49331b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 49341b8b02a4SEd Tanous } 49351b8b02a4SEd Tanous 49361b8b02a4SEd Tanous inline 49371b8b02a4SEd Tanous std::pair<const std::string*, const std::string*> 49381b8b02a4SEd Tanous ampm_names() 49391b8b02a4SEd Tanous { 49401b8b02a4SEd Tanous static const std::string nm[] = 49411b8b02a4SEd Tanous { 49421b8b02a4SEd Tanous "AM", 49431b8b02a4SEd Tanous "PM" 49441b8b02a4SEd Tanous }; 49451b8b02a4SEd Tanous return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); 49461b8b02a4SEd Tanous } 49471b8b02a4SEd Tanous 49481b8b02a4SEd Tanous template <class CharT, class Traits, class FwdIter> 49491b8b02a4SEd Tanous FwdIter 49501b8b02a4SEd Tanous scan_keyword(std::basic_istream<CharT, Traits>& is, FwdIter kb, FwdIter ke) 49511b8b02a4SEd Tanous { 49521b8b02a4SEd Tanous size_t nkw = static_cast<size_t>(std::distance(kb, ke)); 49531b8b02a4SEd Tanous const unsigned char doesnt_match = '\0'; 49541b8b02a4SEd Tanous const unsigned char might_match = '\1'; 49551b8b02a4SEd Tanous const unsigned char does_match = '\2'; 49561b8b02a4SEd Tanous unsigned char statbuf[100]; 49571b8b02a4SEd Tanous unsigned char* status = statbuf; 49581b8b02a4SEd Tanous std::unique_ptr<unsigned char, void(*)(void*)> stat_hold(0, free); 49591b8b02a4SEd Tanous if (nkw > sizeof(statbuf)) 49601b8b02a4SEd Tanous { 49611b8b02a4SEd Tanous status = (unsigned char*)std::malloc(nkw); 49621b8b02a4SEd Tanous if (status == nullptr) 49631b8b02a4SEd Tanous std::terminate(); 49641b8b02a4SEd Tanous stat_hold.reset(status); 49651b8b02a4SEd Tanous } 49661b8b02a4SEd Tanous size_t n_might_match = nkw; // At this point, any keyword might match 49671b8b02a4SEd Tanous size_t n_does_match = 0; // but none of them definitely do 49681b8b02a4SEd Tanous // Initialize all statuses to might_match, except for "" keywords are does_match 49691b8b02a4SEd Tanous unsigned char* st = status; 49701b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 49711b8b02a4SEd Tanous { 49721b8b02a4SEd Tanous if (!ky->empty()) 49731b8b02a4SEd Tanous *st = might_match; 49741b8b02a4SEd Tanous else 49751b8b02a4SEd Tanous { 49761b8b02a4SEd Tanous *st = does_match; 49771b8b02a4SEd Tanous --n_might_match; 49781b8b02a4SEd Tanous ++n_does_match; 49791b8b02a4SEd Tanous } 49801b8b02a4SEd Tanous } 49811b8b02a4SEd Tanous // While there might be a match, test keywords against the next CharT 49821b8b02a4SEd Tanous for (size_t indx = 0; is && n_might_match > 0; ++indx) 49831b8b02a4SEd Tanous { 49841b8b02a4SEd Tanous // Peek at the next CharT but don't consume it 49851b8b02a4SEd Tanous auto ic = is.peek(); 49861b8b02a4SEd Tanous if (ic == EOF) 49871b8b02a4SEd Tanous { 49881b8b02a4SEd Tanous is.setstate(std::ios::eofbit); 49891b8b02a4SEd Tanous break; 49901b8b02a4SEd Tanous } 49911b8b02a4SEd Tanous auto c = static_cast<char>(toupper(static_cast<unsigned char>(ic))); 49921b8b02a4SEd Tanous bool consume = false; 49931b8b02a4SEd Tanous // For each keyword which might match, see if the indx character is c 49941b8b02a4SEd Tanous // If a match if found, consume c 49951b8b02a4SEd Tanous // If a match is found, and that is the last character in the keyword, 49961b8b02a4SEd Tanous // then that keyword matches. 49971b8b02a4SEd Tanous // If the keyword doesn't match this character, then change the keyword 49981b8b02a4SEd Tanous // to doesn't match 49991b8b02a4SEd Tanous st = status; 50001b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 50011b8b02a4SEd Tanous { 50021b8b02a4SEd Tanous if (*st == might_match) 50031b8b02a4SEd Tanous { 50041b8b02a4SEd Tanous if (c == static_cast<char>(toupper(static_cast<unsigned char>((*ky)[indx])))) 50051b8b02a4SEd Tanous { 50061b8b02a4SEd Tanous consume = true; 50071b8b02a4SEd Tanous if (ky->size() == indx+1) 50081b8b02a4SEd Tanous { 50091b8b02a4SEd Tanous *st = does_match; 50101b8b02a4SEd Tanous --n_might_match; 50111b8b02a4SEd Tanous ++n_does_match; 50121b8b02a4SEd Tanous } 50131b8b02a4SEd Tanous } 50141b8b02a4SEd Tanous else 50151b8b02a4SEd Tanous { 50161b8b02a4SEd Tanous *st = doesnt_match; 50171b8b02a4SEd Tanous --n_might_match; 50181b8b02a4SEd Tanous } 50191b8b02a4SEd Tanous } 50201b8b02a4SEd Tanous } 50211b8b02a4SEd Tanous // consume if we matched a character 50221b8b02a4SEd Tanous if (consume) 50231b8b02a4SEd Tanous { 50241b8b02a4SEd Tanous (void)is.get(); 50251b8b02a4SEd Tanous // If we consumed a character and there might be a matched keyword that 50261b8b02a4SEd Tanous // was marked matched on a previous iteration, then such keywords 50271b8b02a4SEd Tanous // are now marked as not matching. 50281b8b02a4SEd Tanous if (n_might_match + n_does_match > 1) 50291b8b02a4SEd Tanous { 50301b8b02a4SEd Tanous st = status; 50311b8b02a4SEd Tanous for (auto ky = kb; ky != ke; ++ky, ++st) 50321b8b02a4SEd Tanous { 50331b8b02a4SEd Tanous if (*st == does_match && ky->size() != indx+1) 50341b8b02a4SEd Tanous { 50351b8b02a4SEd Tanous *st = doesnt_match; 50361b8b02a4SEd Tanous --n_does_match; 50371b8b02a4SEd Tanous } 50381b8b02a4SEd Tanous } 50391b8b02a4SEd Tanous } 50401b8b02a4SEd Tanous } 50411b8b02a4SEd Tanous } 50421b8b02a4SEd Tanous // We've exited the loop because we hit eof and/or we have no more "might matches". 50431b8b02a4SEd Tanous // Return the first matching result 50441b8b02a4SEd Tanous for (st = status; kb != ke; ++kb, ++st) 50451b8b02a4SEd Tanous if (*st == does_match) 50461b8b02a4SEd Tanous break; 50471b8b02a4SEd Tanous if (kb == ke) 50481b8b02a4SEd Tanous is.setstate(std::ios::failbit); 50491b8b02a4SEd Tanous return kb; 50501b8b02a4SEd Tanous } 50511b8b02a4SEd Tanous 50521b8b02a4SEd Tanous } // namespace detail 50531b8b02a4SEd Tanous 50541b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 50551b8b02a4SEd Tanous 50561b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 50571b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 50581b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 50591b8b02a4SEd Tanous const fields<Duration>& fds, const std::string* abbrev, 50601b8b02a4SEd Tanous const std::chrono::seconds* offset_sec) 50611b8b02a4SEd Tanous { 50621b8b02a4SEd Tanous #if ONLY_C_LOCALE 50631b8b02a4SEd Tanous using detail::weekday_names; 50641b8b02a4SEd Tanous using detail::month_names; 50651b8b02a4SEd Tanous using detail::ampm_names; 50661b8b02a4SEd Tanous #endif 50671b8b02a4SEd Tanous using detail::save_ostream; 50681b8b02a4SEd Tanous using detail::get_units; 50691b8b02a4SEd Tanous using detail::extract_weekday; 50701b8b02a4SEd Tanous using detail::extract_month; 50711b8b02a4SEd Tanous using std::ios; 50721b8b02a4SEd Tanous using std::chrono::duration_cast; 50731b8b02a4SEd Tanous using std::chrono::seconds; 50741b8b02a4SEd Tanous using std::chrono::minutes; 50751b8b02a4SEd Tanous using std::chrono::hours; 50761b8b02a4SEd Tanous date::detail::save_ostream<CharT, Traits> ss(os); 50771b8b02a4SEd Tanous os.fill(' '); 50781b8b02a4SEd Tanous os.flags(std::ios::skipws | std::ios::dec); 50791b8b02a4SEd Tanous os.width(0); 50801b8b02a4SEd Tanous tm tm{}; 50811b8b02a4SEd Tanous bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero(); 50821b8b02a4SEd Tanous #if !ONLY_C_LOCALE 50831b8b02a4SEd Tanous auto& facet = std::use_facet<std::time_put<CharT>>(os.getloc()); 50841b8b02a4SEd Tanous #endif 50851b8b02a4SEd Tanous const CharT* command = nullptr; 50861b8b02a4SEd Tanous CharT modified = CharT{}; 50871b8b02a4SEd Tanous for (; *fmt; ++fmt) 50881b8b02a4SEd Tanous { 50891b8b02a4SEd Tanous switch (*fmt) 50901b8b02a4SEd Tanous { 50911b8b02a4SEd Tanous case 'a': 50921b8b02a4SEd Tanous case 'A': 50931b8b02a4SEd Tanous if (command) 50941b8b02a4SEd Tanous { 50951b8b02a4SEd Tanous if (modified == CharT{}) 50961b8b02a4SEd Tanous { 50971b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 50981b8b02a4SEd Tanous if (os.fail()) 50991b8b02a4SEd Tanous return os; 51001b8b02a4SEd Tanous #if !ONLY_C_LOCALE 51011b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 51021b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 51031b8b02a4SEd Tanous #else // ONLY_C_LOCALE 51041b8b02a4SEd Tanous os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')]; 51051b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 51061b8b02a4SEd Tanous } 51071b8b02a4SEd Tanous else 51081b8b02a4SEd Tanous { 51091b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 51101b8b02a4SEd Tanous modified = CharT{}; 51111b8b02a4SEd Tanous } 51121b8b02a4SEd Tanous command = nullptr; 51131b8b02a4SEd Tanous } 51141b8b02a4SEd Tanous else 51151b8b02a4SEd Tanous os << *fmt; 51161b8b02a4SEd Tanous break; 51171b8b02a4SEd Tanous case 'b': 51181b8b02a4SEd Tanous case 'B': 51191b8b02a4SEd Tanous case 'h': 51201b8b02a4SEd Tanous if (command) 51211b8b02a4SEd Tanous { 51221b8b02a4SEd Tanous if (modified == CharT{}) 51231b8b02a4SEd Tanous { 51241b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(extract_month(os, fds)) - 1; 51251b8b02a4SEd Tanous #if !ONLY_C_LOCALE 51261b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 51271b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 51281b8b02a4SEd Tanous #else // ONLY_C_LOCALE 51291b8b02a4SEd Tanous os << month_names().first[tm.tm_mon+12*(*fmt != 'B')]; 51301b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 51311b8b02a4SEd Tanous } 51321b8b02a4SEd Tanous else 51331b8b02a4SEd Tanous { 51341b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 51351b8b02a4SEd Tanous modified = CharT{}; 51361b8b02a4SEd Tanous } 51371b8b02a4SEd Tanous command = nullptr; 51381b8b02a4SEd Tanous } 51391b8b02a4SEd Tanous else 51401b8b02a4SEd Tanous os << *fmt; 51411b8b02a4SEd Tanous break; 51421b8b02a4SEd Tanous case 'c': 51431b8b02a4SEd Tanous case 'x': 51441b8b02a4SEd Tanous if (command) 51451b8b02a4SEd Tanous { 51461b8b02a4SEd Tanous if (modified == CharT{'O'}) 51471b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 51481b8b02a4SEd Tanous else 51491b8b02a4SEd Tanous { 51501b8b02a4SEd Tanous if (!fds.ymd.ok()) 51511b8b02a4SEd Tanous os.setstate(std::ios::failbit); 51521b8b02a4SEd Tanous if (*fmt == 'c' && !fds.has_tod) 51531b8b02a4SEd Tanous os.setstate(std::ios::failbit); 51541b8b02a4SEd Tanous #if !ONLY_C_LOCALE 51551b8b02a4SEd Tanous tm = std::tm{}; 51561b8b02a4SEd Tanous auto const& ymd = fds.ymd; 51571b8b02a4SEd Tanous auto ld = local_days(ymd); 51581b8b02a4SEd Tanous if (*fmt == 'c') 51591b8b02a4SEd Tanous { 51601b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 51611b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 51621b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 51631b8b02a4SEd Tanous } 51641b8b02a4SEd Tanous tm.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day())); 51651b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(extract_month(os, fds) - 1); 51661b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 51671b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 51681b8b02a4SEd Tanous if (os.fail()) 51691b8b02a4SEd Tanous return os; 51701b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 51711b8b02a4SEd Tanous CharT f[3] = {'%'}; 51721b8b02a4SEd Tanous auto fe = std::begin(f) + 1; 51731b8b02a4SEd Tanous if (modified == CharT{'E'}) 51741b8b02a4SEd Tanous *fe++ = modified; 51751b8b02a4SEd Tanous *fe++ = *fmt; 51761b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), fe); 51771b8b02a4SEd Tanous #else // ONLY_C_LOCALE 51781b8b02a4SEd Tanous if (*fmt == 'c') 51791b8b02a4SEd Tanous { 51801b8b02a4SEd Tanous auto wd = static_cast<int>(extract_weekday(os, fds)); 51811b8b02a4SEd Tanous os << weekday_names().first[static_cast<unsigned>(wd)+7] 51821b8b02a4SEd Tanous << ' '; 51831b8b02a4SEd Tanous os << month_names().first[extract_month(os, fds)-1+12] << ' '; 51841b8b02a4SEd Tanous auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day())); 51851b8b02a4SEd Tanous if (d < 10) 51861b8b02a4SEd Tanous os << ' '; 51871b8b02a4SEd Tanous os << d << ' ' 51881b8b02a4SEd Tanous << make_time(duration_cast<seconds>(fds.tod.to_duration())) 51891b8b02a4SEd Tanous << ' ' << fds.ymd.year(); 51901b8b02a4SEd Tanous 51911b8b02a4SEd Tanous } 51921b8b02a4SEd Tanous else // *fmt == 'x' 51931b8b02a4SEd Tanous { 51941b8b02a4SEd Tanous auto const& ymd = fds.ymd; 51951b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 51961b8b02a4SEd Tanous os.fill('0'); 51971b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 51981b8b02a4SEd Tanous os.width(2); 51991b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'/'}; 52001b8b02a4SEd Tanous os.width(2); 52011b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()) << CharT{'/'}; 52021b8b02a4SEd Tanous os.width(2); 52031b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) % 100; 52041b8b02a4SEd Tanous } 52051b8b02a4SEd Tanous #endif // ONLY_C_LOCALE 52061b8b02a4SEd Tanous } 52071b8b02a4SEd Tanous command = nullptr; 52081b8b02a4SEd Tanous modified = CharT{}; 52091b8b02a4SEd Tanous } 52101b8b02a4SEd Tanous else 52111b8b02a4SEd Tanous os << *fmt; 52121b8b02a4SEd Tanous break; 52131b8b02a4SEd Tanous case 'C': 52141b8b02a4SEd Tanous if (command) 52151b8b02a4SEd Tanous { 52161b8b02a4SEd Tanous if (modified == CharT{'O'}) 52171b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 52181b8b02a4SEd Tanous else 52191b8b02a4SEd Tanous { 52201b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 52211b8b02a4SEd Tanous os.setstate(std::ios::failbit); 52221b8b02a4SEd Tanous auto y = static_cast<int>(fds.ymd.year()); 52231b8b02a4SEd Tanous #if !ONLY_C_LOCALE 52241b8b02a4SEd Tanous if (modified == CharT{}) 52251b8b02a4SEd Tanous #endif 52261b8b02a4SEd Tanous { 52271b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 52281b8b02a4SEd Tanous os.fill('0'); 52291b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 52301b8b02a4SEd Tanous if (y >= 0) 52311b8b02a4SEd Tanous { 52321b8b02a4SEd Tanous os.width(2); 52331b8b02a4SEd Tanous os << y/100; 52341b8b02a4SEd Tanous } 52351b8b02a4SEd Tanous else 52361b8b02a4SEd Tanous { 52371b8b02a4SEd Tanous os << CharT{'-'}; 52381b8b02a4SEd Tanous os.width(2); 52391b8b02a4SEd Tanous os << -(y-99)/100; 52401b8b02a4SEd Tanous } 52411b8b02a4SEd Tanous } 52421b8b02a4SEd Tanous #if !ONLY_C_LOCALE 52431b8b02a4SEd Tanous else if (modified == CharT{'E'}) 52441b8b02a4SEd Tanous { 52451b8b02a4SEd Tanous tm.tm_year = y - 1900; 52461b8b02a4SEd Tanous CharT f[3] = {'%', 'E', 'C'}; 52471b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 52481b8b02a4SEd Tanous } 52491b8b02a4SEd Tanous #endif 52501b8b02a4SEd Tanous } 52511b8b02a4SEd Tanous command = nullptr; 52521b8b02a4SEd Tanous modified = CharT{}; 52531b8b02a4SEd Tanous } 52541b8b02a4SEd Tanous else 52551b8b02a4SEd Tanous os << *fmt; 52561b8b02a4SEd Tanous break; 52571b8b02a4SEd Tanous case 'd': 52581b8b02a4SEd Tanous case 'e': 52591b8b02a4SEd Tanous if (command) 52601b8b02a4SEd Tanous { 52611b8b02a4SEd Tanous if (modified == CharT{'E'}) 52621b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 52631b8b02a4SEd Tanous else 52641b8b02a4SEd Tanous { 52651b8b02a4SEd Tanous if (!fds.ymd.day().ok()) 52661b8b02a4SEd Tanous os.setstate(std::ios::failbit); 52671b8b02a4SEd Tanous auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day())); 52681b8b02a4SEd Tanous #if !ONLY_C_LOCALE 52691b8b02a4SEd Tanous if (modified == CharT{}) 52701b8b02a4SEd Tanous #endif 52711b8b02a4SEd Tanous { 52721b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 52731b8b02a4SEd Tanous if (*fmt == CharT{'d'}) 52741b8b02a4SEd Tanous os.fill('0'); 52751b8b02a4SEd Tanous else 52761b8b02a4SEd Tanous os.fill(' '); 52771b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 52781b8b02a4SEd Tanous os.width(2); 52791b8b02a4SEd Tanous os << d; 52801b8b02a4SEd Tanous } 52811b8b02a4SEd Tanous #if !ONLY_C_LOCALE 52821b8b02a4SEd Tanous else if (modified == CharT{'O'}) 52831b8b02a4SEd Tanous { 52841b8b02a4SEd Tanous tm.tm_mday = d; 52851b8b02a4SEd Tanous CharT f[3] = {'%', 'O', *fmt}; 52861b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 52871b8b02a4SEd Tanous } 52881b8b02a4SEd Tanous #endif 52891b8b02a4SEd Tanous } 52901b8b02a4SEd Tanous command = nullptr; 52911b8b02a4SEd Tanous modified = CharT{}; 52921b8b02a4SEd Tanous } 52931b8b02a4SEd Tanous else 52941b8b02a4SEd Tanous os << *fmt; 52951b8b02a4SEd Tanous break; 52961b8b02a4SEd Tanous case 'D': 52971b8b02a4SEd Tanous if (command) 52981b8b02a4SEd Tanous { 52991b8b02a4SEd Tanous if (modified == CharT{}) 53001b8b02a4SEd Tanous { 53011b8b02a4SEd Tanous if (!fds.ymd.ok()) 53021b8b02a4SEd Tanous os.setstate(std::ios::failbit); 53031b8b02a4SEd Tanous auto const& ymd = fds.ymd; 53041b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 53051b8b02a4SEd Tanous os.fill('0'); 53061b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 53071b8b02a4SEd Tanous os.width(2); 53081b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'/'}; 53091b8b02a4SEd Tanous os.width(2); 53101b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()) << CharT{'/'}; 53111b8b02a4SEd Tanous os.width(2); 53121b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) % 100; 53131b8b02a4SEd Tanous } 53141b8b02a4SEd Tanous else 53151b8b02a4SEd Tanous { 53161b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 53171b8b02a4SEd Tanous modified = CharT{}; 53181b8b02a4SEd Tanous } 53191b8b02a4SEd Tanous command = nullptr; 53201b8b02a4SEd Tanous } 53211b8b02a4SEd Tanous else 53221b8b02a4SEd Tanous os << *fmt; 53231b8b02a4SEd Tanous break; 53241b8b02a4SEd Tanous case 'F': 53251b8b02a4SEd Tanous if (command) 53261b8b02a4SEd Tanous { 53271b8b02a4SEd Tanous if (modified == CharT{}) 53281b8b02a4SEd Tanous { 53291b8b02a4SEd Tanous if (!fds.ymd.ok()) 53301b8b02a4SEd Tanous os.setstate(std::ios::failbit); 53311b8b02a4SEd Tanous auto const& ymd = fds.ymd; 53321b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 53331b8b02a4SEd Tanous os.imbue(std::locale::classic()); 53341b8b02a4SEd Tanous os.fill('0'); 53351b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 53361b8b02a4SEd Tanous os.width(4); 53371b8b02a4SEd Tanous os << static_cast<int>(ymd.year()) << CharT{'-'}; 53381b8b02a4SEd Tanous os.width(2); 53391b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.month()) << CharT{'-'}; 53401b8b02a4SEd Tanous os.width(2); 53411b8b02a4SEd Tanous os << static_cast<unsigned>(ymd.day()); 53421b8b02a4SEd Tanous } 53431b8b02a4SEd Tanous else 53441b8b02a4SEd Tanous { 53451b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 53461b8b02a4SEd Tanous modified = CharT{}; 53471b8b02a4SEd Tanous } 53481b8b02a4SEd Tanous command = nullptr; 53491b8b02a4SEd Tanous } 53501b8b02a4SEd Tanous else 53511b8b02a4SEd Tanous os << *fmt; 53521b8b02a4SEd Tanous break; 53531b8b02a4SEd Tanous case 'g': 53541b8b02a4SEd Tanous case 'G': 53551b8b02a4SEd Tanous if (command) 53561b8b02a4SEd Tanous { 53571b8b02a4SEd Tanous if (modified == CharT{}) 53581b8b02a4SEd Tanous { 53591b8b02a4SEd Tanous if (!fds.ymd.ok()) 53601b8b02a4SEd Tanous os.setstate(std::ios::failbit); 53611b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 53621b8b02a4SEd Tanous auto y = year_month_day{ld + days{3}}.year(); 53631b8b02a4SEd Tanous auto start = local_days((y-years{1})/December/Thursday[last]) + 53641b8b02a4SEd Tanous (Monday-Thursday); 53651b8b02a4SEd Tanous if (ld < start) 53661b8b02a4SEd Tanous --y; 53671b8b02a4SEd Tanous if (*fmt == CharT{'G'}) 53681b8b02a4SEd Tanous os << y; 53691b8b02a4SEd Tanous else 53701b8b02a4SEd Tanous { 53711b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 53721b8b02a4SEd Tanous os.fill('0'); 53731b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 53741b8b02a4SEd Tanous os.width(2); 53751b8b02a4SEd Tanous os << std::abs(static_cast<int>(y)) % 100; 53761b8b02a4SEd Tanous } 53771b8b02a4SEd Tanous } 53781b8b02a4SEd Tanous else 53791b8b02a4SEd Tanous { 53801b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 53811b8b02a4SEd Tanous modified = CharT{}; 53821b8b02a4SEd Tanous } 53831b8b02a4SEd Tanous command = nullptr; 53841b8b02a4SEd Tanous } 53851b8b02a4SEd Tanous else 53861b8b02a4SEd Tanous os << *fmt; 53871b8b02a4SEd Tanous break; 53881b8b02a4SEd Tanous case 'H': 53891b8b02a4SEd Tanous case 'I': 53901b8b02a4SEd Tanous if (command) 53911b8b02a4SEd Tanous { 53921b8b02a4SEd Tanous if (modified == CharT{'E'}) 53931b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 53941b8b02a4SEd Tanous else 53951b8b02a4SEd Tanous { 53961b8b02a4SEd Tanous if (!fds.has_tod) 53971b8b02a4SEd Tanous os.setstate(std::ios::failbit); 53981b8b02a4SEd Tanous if (insert_negative) 53991b8b02a4SEd Tanous { 54001b8b02a4SEd Tanous os << '-'; 54011b8b02a4SEd Tanous insert_negative = false; 54021b8b02a4SEd Tanous } 54031b8b02a4SEd Tanous auto hms = fds.tod; 54041b8b02a4SEd Tanous #if !ONLY_C_LOCALE 54051b8b02a4SEd Tanous if (modified == CharT{}) 54061b8b02a4SEd Tanous #endif 54071b8b02a4SEd Tanous { 54081b8b02a4SEd Tanous auto h = *fmt == CharT{'I'} ? date::make12(hms.hours()) : hms.hours(); 54091b8b02a4SEd Tanous if (h < hours{10}) 54101b8b02a4SEd Tanous os << CharT{'0'}; 54111b8b02a4SEd Tanous os << h.count(); 54121b8b02a4SEd Tanous } 54131b8b02a4SEd Tanous #if !ONLY_C_LOCALE 54141b8b02a4SEd Tanous else if (modified == CharT{'O'}) 54151b8b02a4SEd Tanous { 54161b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 54171b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(hms.hours().count()); 54181b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 54191b8b02a4SEd Tanous } 54201b8b02a4SEd Tanous #endif 54211b8b02a4SEd Tanous } 54221b8b02a4SEd Tanous modified = CharT{}; 54231b8b02a4SEd Tanous command = nullptr; 54241b8b02a4SEd Tanous } 54251b8b02a4SEd Tanous else 54261b8b02a4SEd Tanous os << *fmt; 54271b8b02a4SEd Tanous break; 54281b8b02a4SEd Tanous case 'j': 54291b8b02a4SEd Tanous if (command) 54301b8b02a4SEd Tanous { 54311b8b02a4SEd Tanous if (modified == CharT{}) 54321b8b02a4SEd Tanous { 54331b8b02a4SEd Tanous if (fds.ymd.ok() || fds.has_tod) 54341b8b02a4SEd Tanous { 54351b8b02a4SEd Tanous days doy; 54361b8b02a4SEd Tanous if (fds.ymd.ok()) 54371b8b02a4SEd Tanous { 54381b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 54391b8b02a4SEd Tanous auto y = fds.ymd.year(); 54401b8b02a4SEd Tanous doy = ld - local_days(y/January/1) + days{1}; 54411b8b02a4SEd Tanous } 54421b8b02a4SEd Tanous else 54431b8b02a4SEd Tanous { 54441b8b02a4SEd Tanous doy = duration_cast<days>(fds.tod.to_duration()); 54451b8b02a4SEd Tanous } 54461b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 54471b8b02a4SEd Tanous os.fill('0'); 54481b8b02a4SEd Tanous os.flags(std::ios::dec | std::ios::right); 54491b8b02a4SEd Tanous os.width(3); 54501b8b02a4SEd Tanous os << doy.count(); 54511b8b02a4SEd Tanous } 54521b8b02a4SEd Tanous else 54531b8b02a4SEd Tanous { 54541b8b02a4SEd Tanous os.setstate(std::ios::failbit); 54551b8b02a4SEd Tanous } 54561b8b02a4SEd Tanous } 54571b8b02a4SEd Tanous else 54581b8b02a4SEd Tanous { 54591b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 54601b8b02a4SEd Tanous modified = CharT{}; 54611b8b02a4SEd Tanous } 54621b8b02a4SEd Tanous command = nullptr; 54631b8b02a4SEd Tanous } 54641b8b02a4SEd Tanous else 54651b8b02a4SEd Tanous os << *fmt; 54661b8b02a4SEd Tanous break; 54671b8b02a4SEd Tanous case 'm': 54681b8b02a4SEd Tanous if (command) 54691b8b02a4SEd Tanous { 54701b8b02a4SEd Tanous if (modified == CharT{'E'}) 54711b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 54721b8b02a4SEd Tanous else 54731b8b02a4SEd Tanous { 54741b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 54751b8b02a4SEd Tanous os.setstate(std::ios::failbit); 54761b8b02a4SEd Tanous auto m = static_cast<unsigned>(fds.ymd.month()); 54771b8b02a4SEd Tanous #if !ONLY_C_LOCALE 54781b8b02a4SEd Tanous if (modified == CharT{}) 54791b8b02a4SEd Tanous #endif 54801b8b02a4SEd Tanous { 54811b8b02a4SEd Tanous if (m < 10) 54821b8b02a4SEd Tanous os << CharT{'0'}; 54831b8b02a4SEd Tanous os << m; 54841b8b02a4SEd Tanous } 54851b8b02a4SEd Tanous #if !ONLY_C_LOCALE 54861b8b02a4SEd Tanous else if (modified == CharT{'O'}) 54871b8b02a4SEd Tanous { 54881b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 54891b8b02a4SEd Tanous tm.tm_mon = static_cast<int>(m-1); 54901b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 54911b8b02a4SEd Tanous } 54921b8b02a4SEd Tanous #endif 54931b8b02a4SEd Tanous } 54941b8b02a4SEd Tanous modified = CharT{}; 54951b8b02a4SEd Tanous command = nullptr; 54961b8b02a4SEd Tanous } 54971b8b02a4SEd Tanous else 54981b8b02a4SEd Tanous os << *fmt; 54991b8b02a4SEd Tanous break; 55001b8b02a4SEd Tanous case 'M': 55011b8b02a4SEd Tanous if (command) 55021b8b02a4SEd Tanous { 55031b8b02a4SEd Tanous if (modified == CharT{'E'}) 55041b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 55051b8b02a4SEd Tanous else 55061b8b02a4SEd Tanous { 55071b8b02a4SEd Tanous if (!fds.has_tod) 55081b8b02a4SEd Tanous os.setstate(std::ios::failbit); 55091b8b02a4SEd Tanous if (insert_negative) 55101b8b02a4SEd Tanous { 55111b8b02a4SEd Tanous os << '-'; 55121b8b02a4SEd Tanous insert_negative = false; 55131b8b02a4SEd Tanous } 55141b8b02a4SEd Tanous #if !ONLY_C_LOCALE 55151b8b02a4SEd Tanous if (modified == CharT{}) 55161b8b02a4SEd Tanous #endif 55171b8b02a4SEd Tanous { 55181b8b02a4SEd Tanous if (fds.tod.minutes() < minutes{10}) 55191b8b02a4SEd Tanous os << CharT{'0'}; 55201b8b02a4SEd Tanous os << fds.tod.minutes().count(); 55211b8b02a4SEd Tanous } 55221b8b02a4SEd Tanous #if !ONLY_C_LOCALE 55231b8b02a4SEd Tanous else if (modified == CharT{'O'}) 55241b8b02a4SEd Tanous { 55251b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 55261b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 55271b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 55281b8b02a4SEd Tanous } 55291b8b02a4SEd Tanous #endif 55301b8b02a4SEd Tanous } 55311b8b02a4SEd Tanous modified = CharT{}; 55321b8b02a4SEd Tanous command = nullptr; 55331b8b02a4SEd Tanous } 55341b8b02a4SEd Tanous else 55351b8b02a4SEd Tanous os << *fmt; 55361b8b02a4SEd Tanous break; 55371b8b02a4SEd Tanous case 'n': 55381b8b02a4SEd Tanous if (command) 55391b8b02a4SEd Tanous { 55401b8b02a4SEd Tanous if (modified == CharT{}) 55411b8b02a4SEd Tanous os << CharT{'\n'}; 55421b8b02a4SEd Tanous else 55431b8b02a4SEd Tanous { 55441b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 55451b8b02a4SEd Tanous modified = CharT{}; 55461b8b02a4SEd Tanous } 55471b8b02a4SEd Tanous command = nullptr; 55481b8b02a4SEd Tanous } 55491b8b02a4SEd Tanous else 55501b8b02a4SEd Tanous os << *fmt; 55511b8b02a4SEd Tanous break; 55521b8b02a4SEd Tanous case 'p': 55531b8b02a4SEd Tanous if (command) 55541b8b02a4SEd Tanous { 55551b8b02a4SEd Tanous if (modified == CharT{}) 55561b8b02a4SEd Tanous { 55571b8b02a4SEd Tanous if (!fds.has_tod) 55581b8b02a4SEd Tanous os.setstate(std::ios::failbit); 55591b8b02a4SEd Tanous #if !ONLY_C_LOCALE 55601b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 55611b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 55621b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 55631b8b02a4SEd Tanous #else 55641b8b02a4SEd Tanous if (date::is_am(fds.tod.hours())) 55651b8b02a4SEd Tanous os << ampm_names().first[0]; 55661b8b02a4SEd Tanous else 55671b8b02a4SEd Tanous os << ampm_names().first[1]; 55681b8b02a4SEd Tanous #endif 55691b8b02a4SEd Tanous } 55701b8b02a4SEd Tanous else 55711b8b02a4SEd Tanous { 55721b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 55731b8b02a4SEd Tanous } 55741b8b02a4SEd Tanous modified = CharT{}; 55751b8b02a4SEd Tanous command = nullptr; 55761b8b02a4SEd Tanous } 55771b8b02a4SEd Tanous else 55781b8b02a4SEd Tanous os << *fmt; 55791b8b02a4SEd Tanous break; 55801b8b02a4SEd Tanous case 'Q': 55811b8b02a4SEd Tanous case 'q': 55821b8b02a4SEd Tanous if (command) 55831b8b02a4SEd Tanous { 55841b8b02a4SEd Tanous if (modified == CharT{}) 55851b8b02a4SEd Tanous { 55861b8b02a4SEd Tanous if (!fds.has_tod) 55871b8b02a4SEd Tanous os.setstate(std::ios::failbit); 55881b8b02a4SEd Tanous auto d = fds.tod.to_duration(); 55891b8b02a4SEd Tanous if (*fmt == 'q') 55901b8b02a4SEd Tanous os << get_units<CharT>(typename decltype(d)::period::type{}); 55911b8b02a4SEd Tanous else 55921b8b02a4SEd Tanous os << d.count(); 55931b8b02a4SEd Tanous } 55941b8b02a4SEd Tanous else 55951b8b02a4SEd Tanous { 55961b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 55971b8b02a4SEd Tanous } 55981b8b02a4SEd Tanous modified = CharT{}; 55991b8b02a4SEd Tanous command = nullptr; 56001b8b02a4SEd Tanous } 56011b8b02a4SEd Tanous else 56021b8b02a4SEd Tanous os << *fmt; 56031b8b02a4SEd Tanous break; 56041b8b02a4SEd Tanous case 'r': 56051b8b02a4SEd Tanous if (command) 56061b8b02a4SEd Tanous { 56071b8b02a4SEd Tanous if (modified == CharT{}) 56081b8b02a4SEd Tanous { 56091b8b02a4SEd Tanous if (!fds.has_tod) 56101b8b02a4SEd Tanous os.setstate(std::ios::failbit); 56111b8b02a4SEd Tanous #if !ONLY_C_LOCALE 56121b8b02a4SEd Tanous const CharT f[] = {'%', *fmt}; 56131b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 56141b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 56151b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 56161b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 56171b8b02a4SEd Tanous #else 56181b8b02a4SEd Tanous hh_mm_ss<seconds> tod(duration_cast<seconds>(fds.tod.to_duration())); 56191b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 56201b8b02a4SEd Tanous os.fill('0'); 56211b8b02a4SEd Tanous os.width(2); 56221b8b02a4SEd Tanous os << date::make12(tod.hours()).count() << CharT{':'}; 56231b8b02a4SEd Tanous os.width(2); 56241b8b02a4SEd Tanous os << tod.minutes().count() << CharT{':'}; 56251b8b02a4SEd Tanous os.width(2); 56261b8b02a4SEd Tanous os << tod.seconds().count() << CharT{' '}; 56271b8b02a4SEd Tanous if (date::is_am(tod.hours())) 56281b8b02a4SEd Tanous os << ampm_names().first[0]; 56291b8b02a4SEd Tanous else 56301b8b02a4SEd Tanous os << ampm_names().first[1]; 56311b8b02a4SEd Tanous #endif 56321b8b02a4SEd Tanous } 56331b8b02a4SEd Tanous else 56341b8b02a4SEd Tanous { 56351b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 56361b8b02a4SEd Tanous } 56371b8b02a4SEd Tanous modified = CharT{}; 56381b8b02a4SEd Tanous command = nullptr; 56391b8b02a4SEd Tanous } 56401b8b02a4SEd Tanous else 56411b8b02a4SEd Tanous os << *fmt; 56421b8b02a4SEd Tanous break; 56431b8b02a4SEd Tanous case 'R': 56441b8b02a4SEd Tanous if (command) 56451b8b02a4SEd Tanous { 56461b8b02a4SEd Tanous if (modified == CharT{}) 56471b8b02a4SEd Tanous { 56481b8b02a4SEd Tanous if (!fds.has_tod) 56491b8b02a4SEd Tanous os.setstate(std::ios::failbit); 56501b8b02a4SEd Tanous if (fds.tod.hours() < hours{10}) 56511b8b02a4SEd Tanous os << CharT{'0'}; 56521b8b02a4SEd Tanous os << fds.tod.hours().count() << CharT{':'}; 56531b8b02a4SEd Tanous if (fds.tod.minutes() < minutes{10}) 56541b8b02a4SEd Tanous os << CharT{'0'}; 56551b8b02a4SEd Tanous os << fds.tod.minutes().count(); 56561b8b02a4SEd Tanous } 56571b8b02a4SEd Tanous else 56581b8b02a4SEd Tanous { 56591b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 56601b8b02a4SEd Tanous modified = CharT{}; 56611b8b02a4SEd Tanous } 56621b8b02a4SEd Tanous command = nullptr; 56631b8b02a4SEd Tanous } 56641b8b02a4SEd Tanous else 56651b8b02a4SEd Tanous os << *fmt; 56661b8b02a4SEd Tanous break; 56671b8b02a4SEd Tanous case 'S': 56681b8b02a4SEd Tanous if (command) 56691b8b02a4SEd Tanous { 56701b8b02a4SEd Tanous if (modified == CharT{'E'}) 56711b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 56721b8b02a4SEd Tanous else 56731b8b02a4SEd Tanous { 56741b8b02a4SEd Tanous if (!fds.has_tod) 56751b8b02a4SEd Tanous os.setstate(std::ios::failbit); 56761b8b02a4SEd Tanous if (insert_negative) 56771b8b02a4SEd Tanous { 56781b8b02a4SEd Tanous os << '-'; 56791b8b02a4SEd Tanous insert_negative = false; 56801b8b02a4SEd Tanous } 56811b8b02a4SEd Tanous #if !ONLY_C_LOCALE 56821b8b02a4SEd Tanous if (modified == CharT{}) 56831b8b02a4SEd Tanous #endif 56841b8b02a4SEd Tanous { 56851b8b02a4SEd Tanous os << fds.tod.s_; 56861b8b02a4SEd Tanous } 56871b8b02a4SEd Tanous #if !ONLY_C_LOCALE 56881b8b02a4SEd Tanous else if (modified == CharT{'O'}) 56891b8b02a4SEd Tanous { 56901b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 56911b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.s_.seconds().count()); 56921b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 56931b8b02a4SEd Tanous } 56941b8b02a4SEd Tanous #endif 56951b8b02a4SEd Tanous } 56961b8b02a4SEd Tanous modified = CharT{}; 56971b8b02a4SEd Tanous command = nullptr; 56981b8b02a4SEd Tanous } 56991b8b02a4SEd Tanous else 57001b8b02a4SEd Tanous os << *fmt; 57011b8b02a4SEd Tanous break; 57021b8b02a4SEd Tanous case 't': 57031b8b02a4SEd Tanous if (command) 57041b8b02a4SEd Tanous { 57051b8b02a4SEd Tanous if (modified == CharT{}) 57061b8b02a4SEd Tanous os << CharT{'\t'}; 57071b8b02a4SEd Tanous else 57081b8b02a4SEd Tanous { 57091b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 57101b8b02a4SEd Tanous modified = CharT{}; 57111b8b02a4SEd Tanous } 57121b8b02a4SEd Tanous command = nullptr; 57131b8b02a4SEd Tanous } 57141b8b02a4SEd Tanous else 57151b8b02a4SEd Tanous os << *fmt; 57161b8b02a4SEd Tanous break; 57171b8b02a4SEd Tanous case 'T': 57181b8b02a4SEd Tanous if (command) 57191b8b02a4SEd Tanous { 57201b8b02a4SEd Tanous if (modified == CharT{}) 57211b8b02a4SEd Tanous { 57221b8b02a4SEd Tanous if (!fds.has_tod) 57231b8b02a4SEd Tanous os.setstate(std::ios::failbit); 57241b8b02a4SEd Tanous os << fds.tod; 57251b8b02a4SEd Tanous } 57261b8b02a4SEd Tanous else 57271b8b02a4SEd Tanous { 57281b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 57291b8b02a4SEd Tanous modified = CharT{}; 57301b8b02a4SEd Tanous } 57311b8b02a4SEd Tanous command = nullptr; 57321b8b02a4SEd Tanous } 57331b8b02a4SEd Tanous else 57341b8b02a4SEd Tanous os << *fmt; 57351b8b02a4SEd Tanous break; 57361b8b02a4SEd Tanous case 'u': 57371b8b02a4SEd Tanous if (command) 57381b8b02a4SEd Tanous { 57391b8b02a4SEd Tanous if (modified == CharT{'E'}) 57401b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 57411b8b02a4SEd Tanous else 57421b8b02a4SEd Tanous { 57431b8b02a4SEd Tanous auto wd = extract_weekday(os, fds); 57441b8b02a4SEd Tanous #if !ONLY_C_LOCALE 57451b8b02a4SEd Tanous if (modified == CharT{}) 57461b8b02a4SEd Tanous #endif 57471b8b02a4SEd Tanous { 57481b8b02a4SEd Tanous os << (wd != 0 ? wd : 7u); 57491b8b02a4SEd Tanous } 57501b8b02a4SEd Tanous #if !ONLY_C_LOCALE 57511b8b02a4SEd Tanous else if (modified == CharT{'O'}) 57521b8b02a4SEd Tanous { 57531b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 57541b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(wd); 57551b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 57561b8b02a4SEd Tanous } 57571b8b02a4SEd Tanous #endif 57581b8b02a4SEd Tanous } 57591b8b02a4SEd Tanous modified = CharT{}; 57601b8b02a4SEd Tanous command = nullptr; 57611b8b02a4SEd Tanous } 57621b8b02a4SEd Tanous else 57631b8b02a4SEd Tanous os << *fmt; 57641b8b02a4SEd Tanous break; 57651b8b02a4SEd Tanous case 'U': 57661b8b02a4SEd Tanous if (command) 57671b8b02a4SEd Tanous { 57681b8b02a4SEd Tanous if (modified == CharT{'E'}) 57691b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 57701b8b02a4SEd Tanous else 57711b8b02a4SEd Tanous { 57721b8b02a4SEd Tanous auto const& ymd = fds.ymd; 57731b8b02a4SEd Tanous if (!ymd.ok()) 57741b8b02a4SEd Tanous os.setstate(std::ios::failbit); 57751b8b02a4SEd Tanous auto ld = local_days(ymd); 57761b8b02a4SEd Tanous #if !ONLY_C_LOCALE 57771b8b02a4SEd Tanous if (modified == CharT{}) 57781b8b02a4SEd Tanous #endif 57791b8b02a4SEd Tanous { 57801b8b02a4SEd Tanous auto st = local_days(Sunday[1]/January/ymd.year()); 57811b8b02a4SEd Tanous if (ld < st) 57821b8b02a4SEd Tanous os << CharT{'0'} << CharT{'0'}; 57831b8b02a4SEd Tanous else 57841b8b02a4SEd Tanous { 57851b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 57861b8b02a4SEd Tanous if (wn < 10) 57871b8b02a4SEd Tanous os << CharT{'0'}; 57881b8b02a4SEd Tanous os << wn; 57891b8b02a4SEd Tanous } 57901b8b02a4SEd Tanous } 57911b8b02a4SEd Tanous #if !ONLY_C_LOCALE 57921b8b02a4SEd Tanous else if (modified == CharT{'O'}) 57931b8b02a4SEd Tanous { 57941b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 57951b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 57961b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 57971b8b02a4SEd Tanous if (os.fail()) 57981b8b02a4SEd Tanous return os; 57991b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 58001b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 58011b8b02a4SEd Tanous } 58021b8b02a4SEd Tanous #endif 58031b8b02a4SEd Tanous } 58041b8b02a4SEd Tanous modified = CharT{}; 58051b8b02a4SEd Tanous command = nullptr; 58061b8b02a4SEd Tanous } 58071b8b02a4SEd Tanous else 58081b8b02a4SEd Tanous os << *fmt; 58091b8b02a4SEd Tanous break; 58101b8b02a4SEd Tanous case 'V': 58111b8b02a4SEd Tanous if (command) 58121b8b02a4SEd Tanous { 58131b8b02a4SEd Tanous if (modified == CharT{'E'}) 58141b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 58151b8b02a4SEd Tanous else 58161b8b02a4SEd Tanous { 58171b8b02a4SEd Tanous if (!fds.ymd.ok()) 58181b8b02a4SEd Tanous os.setstate(std::ios::failbit); 58191b8b02a4SEd Tanous auto ld = local_days(fds.ymd); 58201b8b02a4SEd Tanous #if !ONLY_C_LOCALE 58211b8b02a4SEd Tanous if (modified == CharT{}) 58221b8b02a4SEd Tanous #endif 58231b8b02a4SEd Tanous { 58241b8b02a4SEd Tanous auto y = year_month_day{ld + days{3}}.year(); 58251b8b02a4SEd Tanous auto st = local_days((y-years{1})/12/Thursday[last]) + 58261b8b02a4SEd Tanous (Monday-Thursday); 58271b8b02a4SEd Tanous if (ld < st) 58281b8b02a4SEd Tanous { 58291b8b02a4SEd Tanous --y; 58301b8b02a4SEd Tanous st = local_days((y - years{1})/12/Thursday[last]) + 58311b8b02a4SEd Tanous (Monday-Thursday); 58321b8b02a4SEd Tanous } 58331b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 58341b8b02a4SEd Tanous if (wn < 10) 58351b8b02a4SEd Tanous os << CharT{'0'}; 58361b8b02a4SEd Tanous os << wn; 58371b8b02a4SEd Tanous } 58381b8b02a4SEd Tanous #if !ONLY_C_LOCALE 58391b8b02a4SEd Tanous else if (modified == CharT{'O'}) 58401b8b02a4SEd Tanous { 58411b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 58421b8b02a4SEd Tanous auto const& ymd = fds.ymd; 58431b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 58441b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 58451b8b02a4SEd Tanous if (os.fail()) 58461b8b02a4SEd Tanous return os; 58471b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 58481b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 58491b8b02a4SEd Tanous } 58501b8b02a4SEd Tanous #endif 58511b8b02a4SEd Tanous } 58521b8b02a4SEd Tanous modified = CharT{}; 58531b8b02a4SEd Tanous command = nullptr; 58541b8b02a4SEd Tanous } 58551b8b02a4SEd Tanous else 58561b8b02a4SEd Tanous os << *fmt; 58571b8b02a4SEd Tanous break; 58581b8b02a4SEd Tanous case 'w': 58591b8b02a4SEd Tanous if (command) 58601b8b02a4SEd Tanous { 58611b8b02a4SEd Tanous auto wd = extract_weekday(os, fds); 58621b8b02a4SEd Tanous if (os.fail()) 58631b8b02a4SEd Tanous return os; 58641b8b02a4SEd Tanous #if !ONLY_C_LOCALE 58651b8b02a4SEd Tanous if (modified == CharT{}) 58661b8b02a4SEd Tanous #else 58671b8b02a4SEd Tanous if (modified != CharT{'E'}) 58681b8b02a4SEd Tanous #endif 58691b8b02a4SEd Tanous { 58701b8b02a4SEd Tanous os << wd; 58711b8b02a4SEd Tanous } 58721b8b02a4SEd Tanous #if !ONLY_C_LOCALE 58731b8b02a4SEd Tanous else if (modified == CharT{'O'}) 58741b8b02a4SEd Tanous { 58751b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 58761b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(wd); 58771b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 58781b8b02a4SEd Tanous } 58791b8b02a4SEd Tanous #endif 58801b8b02a4SEd Tanous else 58811b8b02a4SEd Tanous { 58821b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 58831b8b02a4SEd Tanous } 58841b8b02a4SEd Tanous modified = CharT{}; 58851b8b02a4SEd Tanous command = nullptr; 58861b8b02a4SEd Tanous } 58871b8b02a4SEd Tanous else 58881b8b02a4SEd Tanous os << *fmt; 58891b8b02a4SEd Tanous break; 58901b8b02a4SEd Tanous case 'W': 58911b8b02a4SEd Tanous if (command) 58921b8b02a4SEd Tanous { 58931b8b02a4SEd Tanous if (modified == CharT{'E'}) 58941b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 58951b8b02a4SEd Tanous else 58961b8b02a4SEd Tanous { 58971b8b02a4SEd Tanous auto const& ymd = fds.ymd; 58981b8b02a4SEd Tanous if (!ymd.ok()) 58991b8b02a4SEd Tanous os.setstate(std::ios::failbit); 59001b8b02a4SEd Tanous auto ld = local_days(ymd); 59011b8b02a4SEd Tanous #if !ONLY_C_LOCALE 59021b8b02a4SEd Tanous if (modified == CharT{}) 59031b8b02a4SEd Tanous #endif 59041b8b02a4SEd Tanous { 59051b8b02a4SEd Tanous auto st = local_days(Monday[1]/January/ymd.year()); 59061b8b02a4SEd Tanous if (ld < st) 59071b8b02a4SEd Tanous os << CharT{'0'} << CharT{'0'}; 59081b8b02a4SEd Tanous else 59091b8b02a4SEd Tanous { 59101b8b02a4SEd Tanous auto wn = duration_cast<weeks>(ld - st).count() + 1; 59111b8b02a4SEd Tanous if (wn < 10) 59121b8b02a4SEd Tanous os << CharT{'0'}; 59131b8b02a4SEd Tanous os << wn; 59141b8b02a4SEd Tanous } 59151b8b02a4SEd Tanous } 59161b8b02a4SEd Tanous #if !ONLY_C_LOCALE 59171b8b02a4SEd Tanous else if (modified == CharT{'O'}) 59181b8b02a4SEd Tanous { 59191b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 59201b8b02a4SEd Tanous tm.tm_year = static_cast<int>(ymd.year()) - 1900; 59211b8b02a4SEd Tanous tm.tm_wday = static_cast<int>(extract_weekday(os, fds)); 59221b8b02a4SEd Tanous if (os.fail()) 59231b8b02a4SEd Tanous return os; 59241b8b02a4SEd Tanous tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count()); 59251b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 59261b8b02a4SEd Tanous } 59271b8b02a4SEd Tanous #endif 59281b8b02a4SEd Tanous } 59291b8b02a4SEd Tanous modified = CharT{}; 59301b8b02a4SEd Tanous command = nullptr; 59311b8b02a4SEd Tanous } 59321b8b02a4SEd Tanous else 59331b8b02a4SEd Tanous os << *fmt; 59341b8b02a4SEd Tanous break; 59351b8b02a4SEd Tanous case 'X': 59361b8b02a4SEd Tanous if (command) 59371b8b02a4SEd Tanous { 59381b8b02a4SEd Tanous if (modified == CharT{'O'}) 59391b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 59401b8b02a4SEd Tanous else 59411b8b02a4SEd Tanous { 59421b8b02a4SEd Tanous if (!fds.has_tod) 59431b8b02a4SEd Tanous os.setstate(std::ios::failbit); 59441b8b02a4SEd Tanous #if !ONLY_C_LOCALE 59451b8b02a4SEd Tanous tm = std::tm{}; 59461b8b02a4SEd Tanous tm.tm_sec = static_cast<int>(fds.tod.seconds().count()); 59471b8b02a4SEd Tanous tm.tm_min = static_cast<int>(fds.tod.minutes().count()); 59481b8b02a4SEd Tanous tm.tm_hour = static_cast<int>(fds.tod.hours().count()); 59491b8b02a4SEd Tanous CharT f[3] = {'%'}; 59501b8b02a4SEd Tanous auto fe = std::begin(f) + 1; 59511b8b02a4SEd Tanous if (modified == CharT{'E'}) 59521b8b02a4SEd Tanous *fe++ = modified; 59531b8b02a4SEd Tanous *fe++ = *fmt; 59541b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), fe); 59551b8b02a4SEd Tanous #else 59561b8b02a4SEd Tanous os << fds.tod; 59571b8b02a4SEd Tanous #endif 59581b8b02a4SEd Tanous } 59591b8b02a4SEd Tanous command = nullptr; 59601b8b02a4SEd Tanous modified = CharT{}; 59611b8b02a4SEd Tanous } 59621b8b02a4SEd Tanous else 59631b8b02a4SEd Tanous os << *fmt; 59641b8b02a4SEd Tanous break; 59651b8b02a4SEd Tanous case 'y': 59661b8b02a4SEd Tanous if (command) 59671b8b02a4SEd Tanous { 59681b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 59691b8b02a4SEd Tanous os.setstate(std::ios::failbit); 59701b8b02a4SEd Tanous auto y = static_cast<int>(fds.ymd.year()); 59711b8b02a4SEd Tanous #if !ONLY_C_LOCALE 59721b8b02a4SEd Tanous if (modified == CharT{}) 59731b8b02a4SEd Tanous { 59741b8b02a4SEd Tanous #endif 59751b8b02a4SEd Tanous y = std::abs(y) % 100; 59761b8b02a4SEd Tanous if (y < 10) 59771b8b02a4SEd Tanous os << CharT{'0'}; 59781b8b02a4SEd Tanous os << y; 59791b8b02a4SEd Tanous #if !ONLY_C_LOCALE 59801b8b02a4SEd Tanous } 59811b8b02a4SEd Tanous else 59821b8b02a4SEd Tanous { 59831b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 59841b8b02a4SEd Tanous tm.tm_year = y - 1900; 59851b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 59861b8b02a4SEd Tanous } 59871b8b02a4SEd Tanous #endif 59881b8b02a4SEd Tanous modified = CharT{}; 59891b8b02a4SEd Tanous command = nullptr; 59901b8b02a4SEd Tanous } 59911b8b02a4SEd Tanous else 59921b8b02a4SEd Tanous os << *fmt; 59931b8b02a4SEd Tanous break; 59941b8b02a4SEd Tanous case 'Y': 59951b8b02a4SEd Tanous if (command) 59961b8b02a4SEd Tanous { 59971b8b02a4SEd Tanous if (modified == CharT{'O'}) 59981b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 59991b8b02a4SEd Tanous else 60001b8b02a4SEd Tanous { 60011b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 60021b8b02a4SEd Tanous os.setstate(std::ios::failbit); 60031b8b02a4SEd Tanous auto y = fds.ymd.year(); 60041b8b02a4SEd Tanous #if !ONLY_C_LOCALE 60051b8b02a4SEd Tanous if (modified == CharT{}) 60061b8b02a4SEd Tanous #endif 60071b8b02a4SEd Tanous { 60081b8b02a4SEd Tanous save_ostream<CharT, Traits> _(os); 60091b8b02a4SEd Tanous os.imbue(std::locale::classic()); 60101b8b02a4SEd Tanous os << y; 60111b8b02a4SEd Tanous } 60121b8b02a4SEd Tanous #if !ONLY_C_LOCALE 60131b8b02a4SEd Tanous else if (modified == CharT{'E'}) 60141b8b02a4SEd Tanous { 60151b8b02a4SEd Tanous const CharT f[] = {'%', modified, *fmt}; 60161b8b02a4SEd Tanous tm.tm_year = static_cast<int>(y) - 1900; 60171b8b02a4SEd Tanous facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); 60181b8b02a4SEd Tanous } 60191b8b02a4SEd Tanous #endif 60201b8b02a4SEd Tanous } 60211b8b02a4SEd Tanous modified = CharT{}; 60221b8b02a4SEd Tanous command = nullptr; 60231b8b02a4SEd Tanous } 60241b8b02a4SEd Tanous else 60251b8b02a4SEd Tanous os << *fmt; 60261b8b02a4SEd Tanous break; 60271b8b02a4SEd Tanous case 'z': 60281b8b02a4SEd Tanous if (command) 60291b8b02a4SEd Tanous { 60301b8b02a4SEd Tanous if (offset_sec == nullptr) 60311b8b02a4SEd Tanous { 60321b8b02a4SEd Tanous // Can not format %z with unknown offset 60331b8b02a4SEd Tanous os.setstate(ios::failbit); 60341b8b02a4SEd Tanous return os; 60351b8b02a4SEd Tanous } 60361b8b02a4SEd Tanous auto m = duration_cast<minutes>(*offset_sec); 60371b8b02a4SEd Tanous auto neg = m < minutes{0}; 60381b8b02a4SEd Tanous m = date::abs(m); 60391b8b02a4SEd Tanous auto h = duration_cast<hours>(m); 60401b8b02a4SEd Tanous m -= h; 60411b8b02a4SEd Tanous if (neg) 60421b8b02a4SEd Tanous os << CharT{'-'}; 60431b8b02a4SEd Tanous else 60441b8b02a4SEd Tanous os << CharT{'+'}; 60451b8b02a4SEd Tanous if (h < hours{10}) 60461b8b02a4SEd Tanous os << CharT{'0'}; 60471b8b02a4SEd Tanous os << h.count(); 60481b8b02a4SEd Tanous if (modified != CharT{}) 60491b8b02a4SEd Tanous os << CharT{':'}; 60501b8b02a4SEd Tanous if (m < minutes{10}) 60511b8b02a4SEd Tanous os << CharT{'0'}; 60521b8b02a4SEd Tanous os << m.count(); 60531b8b02a4SEd Tanous command = nullptr; 60541b8b02a4SEd Tanous modified = CharT{}; 60551b8b02a4SEd Tanous } 60561b8b02a4SEd Tanous else 60571b8b02a4SEd Tanous os << *fmt; 60581b8b02a4SEd Tanous break; 60591b8b02a4SEd Tanous case 'Z': 60601b8b02a4SEd Tanous if (command) 60611b8b02a4SEd Tanous { 60621b8b02a4SEd Tanous if (modified == CharT{}) 60631b8b02a4SEd Tanous { 60641b8b02a4SEd Tanous if (abbrev == nullptr) 60651b8b02a4SEd Tanous { 60661b8b02a4SEd Tanous // Can not format %Z with unknown time_zone 60671b8b02a4SEd Tanous os.setstate(ios::failbit); 60681b8b02a4SEd Tanous return os; 60691b8b02a4SEd Tanous } 60701b8b02a4SEd Tanous for (auto c : *abbrev) 60711b8b02a4SEd Tanous os << CharT(c); 60721b8b02a4SEd Tanous } 60731b8b02a4SEd Tanous else 60741b8b02a4SEd Tanous { 60751b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 60761b8b02a4SEd Tanous modified = CharT{}; 60771b8b02a4SEd Tanous } 60781b8b02a4SEd Tanous command = nullptr; 60791b8b02a4SEd Tanous } 60801b8b02a4SEd Tanous else 60811b8b02a4SEd Tanous os << *fmt; 60821b8b02a4SEd Tanous break; 60831b8b02a4SEd Tanous case 'E': 60841b8b02a4SEd Tanous case 'O': 60851b8b02a4SEd Tanous if (command) 60861b8b02a4SEd Tanous { 60871b8b02a4SEd Tanous if (modified == CharT{}) 60881b8b02a4SEd Tanous { 60891b8b02a4SEd Tanous modified = *fmt; 60901b8b02a4SEd Tanous } 60911b8b02a4SEd Tanous else 60921b8b02a4SEd Tanous { 60931b8b02a4SEd Tanous os << CharT{'%'} << modified << *fmt; 60941b8b02a4SEd Tanous command = nullptr; 60951b8b02a4SEd Tanous modified = CharT{}; 60961b8b02a4SEd Tanous } 60971b8b02a4SEd Tanous } 60981b8b02a4SEd Tanous else 60991b8b02a4SEd Tanous os << *fmt; 61001b8b02a4SEd Tanous break; 61011b8b02a4SEd Tanous case '%': 61021b8b02a4SEd Tanous if (command) 61031b8b02a4SEd Tanous { 61041b8b02a4SEd Tanous if (modified == CharT{}) 61051b8b02a4SEd Tanous { 61061b8b02a4SEd Tanous os << CharT{'%'}; 61071b8b02a4SEd Tanous command = nullptr; 61081b8b02a4SEd Tanous } 61091b8b02a4SEd Tanous else 61101b8b02a4SEd Tanous { 61111b8b02a4SEd Tanous os << CharT{'%'} << modified << CharT{'%'}; 61121b8b02a4SEd Tanous command = nullptr; 61131b8b02a4SEd Tanous modified = CharT{}; 61141b8b02a4SEd Tanous } 61151b8b02a4SEd Tanous } 61161b8b02a4SEd Tanous else 61171b8b02a4SEd Tanous command = fmt; 61181b8b02a4SEd Tanous break; 61191b8b02a4SEd Tanous default: 61201b8b02a4SEd Tanous if (command) 61211b8b02a4SEd Tanous { 61221b8b02a4SEd Tanous os << CharT{'%'}; 61231b8b02a4SEd Tanous command = nullptr; 61241b8b02a4SEd Tanous } 61251b8b02a4SEd Tanous if (modified != CharT{}) 61261b8b02a4SEd Tanous { 61271b8b02a4SEd Tanous os << modified; 61281b8b02a4SEd Tanous modified = CharT{}; 61291b8b02a4SEd Tanous } 61301b8b02a4SEd Tanous os << *fmt; 61311b8b02a4SEd Tanous break; 61321b8b02a4SEd Tanous } 61331b8b02a4SEd Tanous } 61341b8b02a4SEd Tanous if (command) 61351b8b02a4SEd Tanous os << CharT{'%'}; 61361b8b02a4SEd Tanous if (modified != CharT{}) 61371b8b02a4SEd Tanous os << modified; 61381b8b02a4SEd Tanous return os; 61391b8b02a4SEd Tanous } 61401b8b02a4SEd Tanous 61411b8b02a4SEd Tanous template <class CharT, class Traits> 61421b8b02a4SEd Tanous inline 61431b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61441b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year& y) 61451b8b02a4SEd Tanous { 61461b8b02a4SEd Tanous using CT = std::chrono::seconds; 61471b8b02a4SEd Tanous fields<CT> fds{y/0/0}; 61481b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61491b8b02a4SEd Tanous } 61501b8b02a4SEd Tanous 61511b8b02a4SEd Tanous template <class CharT, class Traits> 61521b8b02a4SEd Tanous inline 61531b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61541b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month& m) 61551b8b02a4SEd Tanous { 61561b8b02a4SEd Tanous using CT = std::chrono::seconds; 61571b8b02a4SEd Tanous fields<CT> fds{m/0/nanyear}; 61581b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61591b8b02a4SEd Tanous } 61601b8b02a4SEd Tanous 61611b8b02a4SEd Tanous template <class CharT, class Traits> 61621b8b02a4SEd Tanous inline 61631b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61641b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const day& d) 61651b8b02a4SEd Tanous { 61661b8b02a4SEd Tanous using CT = std::chrono::seconds; 61671b8b02a4SEd Tanous fields<CT> fds{d/0/nanyear}; 61681b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61691b8b02a4SEd Tanous } 61701b8b02a4SEd Tanous 61711b8b02a4SEd Tanous template <class CharT, class Traits> 61721b8b02a4SEd Tanous inline 61731b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61741b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const weekday& wd) 61751b8b02a4SEd Tanous { 61761b8b02a4SEd Tanous using CT = std::chrono::seconds; 61771b8b02a4SEd Tanous fields<CT> fds{wd}; 61781b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61791b8b02a4SEd Tanous } 61801b8b02a4SEd Tanous 61811b8b02a4SEd Tanous template <class CharT, class Traits> 61821b8b02a4SEd Tanous inline 61831b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61841b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year_month& ym) 61851b8b02a4SEd Tanous { 61861b8b02a4SEd Tanous using CT = std::chrono::seconds; 61871b8b02a4SEd Tanous fields<CT> fds{ym/0}; 61881b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61891b8b02a4SEd Tanous } 61901b8b02a4SEd Tanous 61911b8b02a4SEd Tanous template <class CharT, class Traits> 61921b8b02a4SEd Tanous inline 61931b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 61941b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month_day& md) 61951b8b02a4SEd Tanous { 61961b8b02a4SEd Tanous using CT = std::chrono::seconds; 61971b8b02a4SEd Tanous fields<CT> fds{md/nanyear}; 61981b8b02a4SEd Tanous return to_stream(os, fmt, fds); 61991b8b02a4SEd Tanous } 62001b8b02a4SEd Tanous 62011b8b02a4SEd Tanous template <class CharT, class Traits> 62021b8b02a4SEd Tanous inline 62031b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 62041b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 62051b8b02a4SEd Tanous const year_month_day& ymd) 62061b8b02a4SEd Tanous { 62071b8b02a4SEd Tanous using CT = std::chrono::seconds; 62081b8b02a4SEd Tanous fields<CT> fds{ymd}; 62091b8b02a4SEd Tanous return to_stream(os, fmt, fds); 62101b8b02a4SEd Tanous } 62111b8b02a4SEd Tanous 62121b8b02a4SEd Tanous template <class CharT, class Traits, class Rep, class Period> 62131b8b02a4SEd Tanous inline 62141b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 62151b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 62161b8b02a4SEd Tanous const std::chrono::duration<Rep, Period>& d) 62171b8b02a4SEd Tanous { 62181b8b02a4SEd Tanous using Duration = std::chrono::duration<Rep, Period>; 62191b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 62201b8b02a4SEd Tanous fields<CT> fds{hh_mm_ss<CT>{d}}; 62211b8b02a4SEd Tanous return to_stream(os, fmt, fds); 62221b8b02a4SEd Tanous } 62231b8b02a4SEd Tanous 62241b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 62251b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 62261b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 62271b8b02a4SEd Tanous const local_time<Duration>& tp, const std::string* abbrev = nullptr, 62281b8b02a4SEd Tanous const std::chrono::seconds* offset_sec = nullptr) 62291b8b02a4SEd Tanous { 62301b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 62311b8b02a4SEd Tanous auto ld = std::chrono::time_point_cast<days>(tp); 62321b8b02a4SEd Tanous fields<CT> fds; 62331b8b02a4SEd Tanous if (ld <= tp) 62341b8b02a4SEd Tanous fds = fields<CT>{year_month_day{ld}, hh_mm_ss<CT>{tp-local_seconds{ld}}}; 62351b8b02a4SEd Tanous else 62361b8b02a4SEd Tanous fds = fields<CT>{year_month_day{ld - days{1}}, 62371b8b02a4SEd Tanous hh_mm_ss<CT>{days{1} - (local_seconds{ld} - tp)}}; 62381b8b02a4SEd Tanous return to_stream(os, fmt, fds, abbrev, offset_sec); 62391b8b02a4SEd Tanous } 62401b8b02a4SEd Tanous 62411b8b02a4SEd Tanous template <class CharT, class Traits, class Duration> 62421b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 62431b8b02a4SEd Tanous to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, 62441b8b02a4SEd Tanous const sys_time<Duration>& tp) 62451b8b02a4SEd Tanous { 62461b8b02a4SEd Tanous using std::chrono::seconds; 62471b8b02a4SEd Tanous using CT = typename std::common_type<Duration, seconds>::type; 62481b8b02a4SEd Tanous const std::string abbrev("UTC"); 62491b8b02a4SEd Tanous CONSTDATA seconds offset{0}; 62501b8b02a4SEd Tanous auto sd = std::chrono::time_point_cast<days>(tp); 62511b8b02a4SEd Tanous fields<CT> fds; 62521b8b02a4SEd Tanous if (sd <= tp) 62531b8b02a4SEd Tanous fds = fields<CT>{year_month_day{sd}, hh_mm_ss<CT>{tp-sys_seconds{sd}}}; 62541b8b02a4SEd Tanous else 62551b8b02a4SEd Tanous fds = fields<CT>{year_month_day{sd - days{1}}, 62561b8b02a4SEd Tanous hh_mm_ss<CT>{days{1} - (sys_seconds{sd} - tp)}}; 62571b8b02a4SEd Tanous return to_stream(os, fmt, fds, &abbrev, &offset); 62581b8b02a4SEd Tanous } 62591b8b02a4SEd Tanous 62601b8b02a4SEd Tanous // format 62611b8b02a4SEd Tanous 62621b8b02a4SEd Tanous template <class CharT, class Streamable> 62631b8b02a4SEd Tanous auto 62641b8b02a4SEd Tanous format(const std::locale& loc, const CharT* fmt, const Streamable& tp) 62651b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp), 62661b8b02a4SEd Tanous std::basic_string<CharT>{}) 62671b8b02a4SEd Tanous { 62681b8b02a4SEd Tanous std::basic_ostringstream<CharT> os; 62691b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 62701b8b02a4SEd Tanous os.imbue(loc); 62711b8b02a4SEd Tanous to_stream(os, fmt, tp); 62721b8b02a4SEd Tanous return os.str(); 62731b8b02a4SEd Tanous } 62741b8b02a4SEd Tanous 62751b8b02a4SEd Tanous template <class CharT, class Streamable> 62761b8b02a4SEd Tanous auto 62771b8b02a4SEd Tanous format(const CharT* fmt, const Streamable& tp) 62781b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp), 62791b8b02a4SEd Tanous std::basic_string<CharT>{}) 62801b8b02a4SEd Tanous { 62811b8b02a4SEd Tanous std::basic_ostringstream<CharT> os; 62821b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 62831b8b02a4SEd Tanous to_stream(os, fmt, tp); 62841b8b02a4SEd Tanous return os.str(); 62851b8b02a4SEd Tanous } 62861b8b02a4SEd Tanous 62871b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, class Streamable> 62881b8b02a4SEd Tanous auto 62891b8b02a4SEd Tanous format(const std::locale& loc, const std::basic_string<CharT, Traits, Alloc>& fmt, 62901b8b02a4SEd Tanous const Streamable& tp) 62911b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp), 62921b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>{}) 62931b8b02a4SEd Tanous { 62941b8b02a4SEd Tanous std::basic_ostringstream<CharT, Traits, Alloc> os; 62951b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 62961b8b02a4SEd Tanous os.imbue(loc); 62971b8b02a4SEd Tanous to_stream(os, fmt.c_str(), tp); 62981b8b02a4SEd Tanous return os.str(); 62991b8b02a4SEd Tanous } 63001b8b02a4SEd Tanous 63011b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc, class Streamable> 63021b8b02a4SEd Tanous auto 63031b8b02a4SEd Tanous format(const std::basic_string<CharT, Traits, Alloc>& fmt, const Streamable& tp) 63041b8b02a4SEd Tanous -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp), 63051b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>{}) 63061b8b02a4SEd Tanous { 63071b8b02a4SEd Tanous std::basic_ostringstream<CharT, Traits, Alloc> os; 63081b8b02a4SEd Tanous os.exceptions(std::ios::failbit | std::ios::badbit); 63091b8b02a4SEd Tanous to_stream(os, fmt.c_str(), tp); 63101b8b02a4SEd Tanous return os.str(); 63111b8b02a4SEd Tanous } 63121b8b02a4SEd Tanous 63131b8b02a4SEd Tanous // parse 63141b8b02a4SEd Tanous 63151b8b02a4SEd Tanous namespace detail 63161b8b02a4SEd Tanous { 63171b8b02a4SEd Tanous 63181b8b02a4SEd Tanous template <class CharT, class Traits> 63191b8b02a4SEd Tanous bool 63201b8b02a4SEd Tanous read_char(std::basic_istream<CharT, Traits>& is, CharT fmt, std::ios::iostate& err) 63211b8b02a4SEd Tanous { 63221b8b02a4SEd Tanous auto ic = is.get(); 63231b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof()) || 63241b8b02a4SEd Tanous !Traits::eq(Traits::to_char_type(ic), fmt)) 63251b8b02a4SEd Tanous { 63261b8b02a4SEd Tanous err |= std::ios::failbit; 63271b8b02a4SEd Tanous is.setstate(std::ios::failbit); 63281b8b02a4SEd Tanous return false; 63291b8b02a4SEd Tanous } 63301b8b02a4SEd Tanous return true; 63311b8b02a4SEd Tanous } 63321b8b02a4SEd Tanous 63331b8b02a4SEd Tanous template <class CharT, class Traits> 63341b8b02a4SEd Tanous unsigned 63351b8b02a4SEd Tanous read_unsigned(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 63361b8b02a4SEd Tanous { 63371b8b02a4SEd Tanous unsigned x = 0; 63381b8b02a4SEd Tanous unsigned count = 0; 63391b8b02a4SEd Tanous while (true) 63401b8b02a4SEd Tanous { 63411b8b02a4SEd Tanous auto ic = is.peek(); 63421b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 63431b8b02a4SEd Tanous break; 63441b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 63451b8b02a4SEd Tanous if (!('0' <= c && c <= '9')) 63461b8b02a4SEd Tanous break; 63471b8b02a4SEd Tanous (void)is.get(); 63481b8b02a4SEd Tanous ++count; 63491b8b02a4SEd Tanous x = 10*x + static_cast<unsigned>(c - '0'); 63501b8b02a4SEd Tanous if (count == M) 63511b8b02a4SEd Tanous break; 63521b8b02a4SEd Tanous } 63531b8b02a4SEd Tanous if (count < m) 63541b8b02a4SEd Tanous is.setstate(std::ios::failbit); 63551b8b02a4SEd Tanous return x; 63561b8b02a4SEd Tanous } 63571b8b02a4SEd Tanous 63581b8b02a4SEd Tanous template <class CharT, class Traits> 63591b8b02a4SEd Tanous int 63601b8b02a4SEd Tanous read_signed(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 63611b8b02a4SEd Tanous { 63621b8b02a4SEd Tanous auto ic = is.peek(); 63631b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 63641b8b02a4SEd Tanous { 63651b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 63661b8b02a4SEd Tanous if (('0' <= c && c <= '9') || c == '-' || c == '+') 63671b8b02a4SEd Tanous { 63681b8b02a4SEd Tanous if (c == '-' || c == '+') 63691b8b02a4SEd Tanous (void)is.get(); 63701b8b02a4SEd Tanous auto x = static_cast<int>(read_unsigned(is, std::max(m, 1u), M)); 63711b8b02a4SEd Tanous if (!is.fail()) 63721b8b02a4SEd Tanous { 63731b8b02a4SEd Tanous if (c == '-') 63741b8b02a4SEd Tanous x = -x; 63751b8b02a4SEd Tanous return x; 63761b8b02a4SEd Tanous } 63771b8b02a4SEd Tanous } 63781b8b02a4SEd Tanous } 63791b8b02a4SEd Tanous if (m > 0) 63801b8b02a4SEd Tanous is.setstate(std::ios::failbit); 63811b8b02a4SEd Tanous return 0; 63821b8b02a4SEd Tanous } 63831b8b02a4SEd Tanous 63841b8b02a4SEd Tanous template <class CharT, class Traits> 63851b8b02a4SEd Tanous long double 63861b8b02a4SEd Tanous read_long_double(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10) 63871b8b02a4SEd Tanous { 63881b8b02a4SEd Tanous unsigned count = 0; 63891b8b02a4SEd Tanous unsigned fcount = 0; 63901b8b02a4SEd Tanous unsigned long long i = 0; 63911b8b02a4SEd Tanous unsigned long long f = 0; 63921b8b02a4SEd Tanous bool parsing_fraction = false; 63931b8b02a4SEd Tanous #if ONLY_C_LOCALE 63941b8b02a4SEd Tanous typename Traits::int_type decimal_point = '.'; 63951b8b02a4SEd Tanous #else 63961b8b02a4SEd Tanous auto decimal_point = Traits::to_int_type( 63971b8b02a4SEd Tanous std::use_facet<std::numpunct<CharT>>(is.getloc()).decimal_point()); 63981b8b02a4SEd Tanous #endif 63991b8b02a4SEd Tanous while (true) 64001b8b02a4SEd Tanous { 64011b8b02a4SEd Tanous auto ic = is.peek(); 64021b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 64031b8b02a4SEd Tanous break; 64041b8b02a4SEd Tanous if (Traits::eq_int_type(ic, decimal_point)) 64051b8b02a4SEd Tanous { 64061b8b02a4SEd Tanous decimal_point = Traits::eof(); 64071b8b02a4SEd Tanous parsing_fraction = true; 64081b8b02a4SEd Tanous } 64091b8b02a4SEd Tanous else 64101b8b02a4SEd Tanous { 64111b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 64121b8b02a4SEd Tanous if (!('0' <= c && c <= '9')) 64131b8b02a4SEd Tanous break; 64141b8b02a4SEd Tanous if (!parsing_fraction) 64151b8b02a4SEd Tanous { 64161b8b02a4SEd Tanous i = 10*i + static_cast<unsigned>(c - '0'); 64171b8b02a4SEd Tanous } 64181b8b02a4SEd Tanous else 64191b8b02a4SEd Tanous { 64201b8b02a4SEd Tanous f = 10*f + static_cast<unsigned>(c - '0'); 64211b8b02a4SEd Tanous ++fcount; 64221b8b02a4SEd Tanous } 64231b8b02a4SEd Tanous } 64241b8b02a4SEd Tanous (void)is.get(); 64251b8b02a4SEd Tanous if (++count == M) 64261b8b02a4SEd Tanous break; 64271b8b02a4SEd Tanous } 64281b8b02a4SEd Tanous if (count < m) 64291b8b02a4SEd Tanous { 64301b8b02a4SEd Tanous is.setstate(std::ios::failbit); 64311b8b02a4SEd Tanous return 0; 64321b8b02a4SEd Tanous } 64331b8b02a4SEd Tanous return static_cast<long double>(i) + static_cast<long double>(f)/std::pow(10.L, fcount); 64341b8b02a4SEd Tanous } 64351b8b02a4SEd Tanous 64361b8b02a4SEd Tanous struct rs 64371b8b02a4SEd Tanous { 64381b8b02a4SEd Tanous int& i; 64391b8b02a4SEd Tanous unsigned m; 64401b8b02a4SEd Tanous unsigned M; 64411b8b02a4SEd Tanous }; 64421b8b02a4SEd Tanous 64431b8b02a4SEd Tanous struct ru 64441b8b02a4SEd Tanous { 64451b8b02a4SEd Tanous int& i; 64461b8b02a4SEd Tanous unsigned m; 64471b8b02a4SEd Tanous unsigned M; 64481b8b02a4SEd Tanous }; 64491b8b02a4SEd Tanous 64501b8b02a4SEd Tanous struct rld 64511b8b02a4SEd Tanous { 64521b8b02a4SEd Tanous long double& i; 64531b8b02a4SEd Tanous unsigned m; 64541b8b02a4SEd Tanous unsigned M; 64551b8b02a4SEd Tanous }; 64561b8b02a4SEd Tanous 64571b8b02a4SEd Tanous template <class CharT, class Traits> 64581b8b02a4SEd Tanous void 64591b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>&) 64601b8b02a4SEd Tanous { 64611b8b02a4SEd Tanous } 64621b8b02a4SEd Tanous 64631b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64641b8b02a4SEd Tanous void 64651b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args); 64661b8b02a4SEd Tanous 64671b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64681b8b02a4SEd Tanous void 64691b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args); 64701b8b02a4SEd Tanous 64711b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64721b8b02a4SEd Tanous void 64731b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args); 64741b8b02a4SEd Tanous 64751b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64761b8b02a4SEd Tanous void 64771b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args); 64781b8b02a4SEd Tanous 64791b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64801b8b02a4SEd Tanous void 64811b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args); 64821b8b02a4SEd Tanous 64831b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 64841b8b02a4SEd Tanous void 64851b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args) 64861b8b02a4SEd Tanous { 64871b8b02a4SEd Tanous // No-op if a0 == CharT{} 64881b8b02a4SEd Tanous if (a0 != CharT{}) 64891b8b02a4SEd Tanous { 64901b8b02a4SEd Tanous auto ic = is.peek(); 64911b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 64921b8b02a4SEd Tanous { 64931b8b02a4SEd Tanous is.setstate(std::ios::failbit | std::ios::eofbit); 64941b8b02a4SEd Tanous return; 64951b8b02a4SEd Tanous } 64961b8b02a4SEd Tanous if (!Traits::eq(Traits::to_char_type(ic), a0)) 64971b8b02a4SEd Tanous { 64981b8b02a4SEd Tanous is.setstate(std::ios::failbit); 64991b8b02a4SEd Tanous return; 65001b8b02a4SEd Tanous } 65011b8b02a4SEd Tanous (void)is.get(); 65021b8b02a4SEd Tanous } 65031b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 65041b8b02a4SEd Tanous } 65051b8b02a4SEd Tanous 65061b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 65071b8b02a4SEd Tanous void 65081b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args) 65091b8b02a4SEd Tanous { 65101b8b02a4SEd Tanous auto x = read_signed(is, a0.m, a0.M); 65111b8b02a4SEd Tanous if (is.fail()) 65121b8b02a4SEd Tanous return; 65131b8b02a4SEd Tanous a0.i = x; 65141b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 65151b8b02a4SEd Tanous } 65161b8b02a4SEd Tanous 65171b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 65181b8b02a4SEd Tanous void 65191b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args) 65201b8b02a4SEd Tanous { 65211b8b02a4SEd Tanous auto x = read_unsigned(is, a0.m, a0.M); 65221b8b02a4SEd Tanous if (is.fail()) 65231b8b02a4SEd Tanous return; 65241b8b02a4SEd Tanous a0.i = static_cast<int>(x); 65251b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 65261b8b02a4SEd Tanous } 65271b8b02a4SEd Tanous 65281b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 65291b8b02a4SEd Tanous void 65301b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args) 65311b8b02a4SEd Tanous { 65321b8b02a4SEd Tanous if (a0 != -1) 65331b8b02a4SEd Tanous { 65341b8b02a4SEd Tanous auto u = static_cast<unsigned>(a0); 65351b8b02a4SEd Tanous CharT buf[std::numeric_limits<unsigned>::digits10+2u] = {}; 65361b8b02a4SEd Tanous auto e = buf; 65371b8b02a4SEd Tanous do 65381b8b02a4SEd Tanous { 65391b8b02a4SEd Tanous *e++ = static_cast<CharT>(CharT(u % 10) + CharT{'0'}); 65401b8b02a4SEd Tanous u /= 10; 65411b8b02a4SEd Tanous } while (u > 0); 65421b8b02a4SEd Tanous std::reverse(buf, e); 65431b8b02a4SEd Tanous for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) 65441b8b02a4SEd Tanous read(is, *p); 65451b8b02a4SEd Tanous } 65461b8b02a4SEd Tanous if (is.rdstate() == std::ios::goodbit) 65471b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 65481b8b02a4SEd Tanous } 65491b8b02a4SEd Tanous 65501b8b02a4SEd Tanous template <class CharT, class Traits, class ...Args> 65511b8b02a4SEd Tanous void 65521b8b02a4SEd Tanous read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args) 65531b8b02a4SEd Tanous { 65541b8b02a4SEd Tanous auto x = read_long_double(is, a0.m, a0.M); 65551b8b02a4SEd Tanous if (is.fail()) 65561b8b02a4SEd Tanous return; 65571b8b02a4SEd Tanous a0.i = x; 65581b8b02a4SEd Tanous read(is, std::forward<Args>(args)...); 65591b8b02a4SEd Tanous } 65601b8b02a4SEd Tanous 65611b8b02a4SEd Tanous template <class T, class CharT, class Traits> 65621b8b02a4SEd Tanous inline 65631b8b02a4SEd Tanous void 65641b8b02a4SEd Tanous checked_set(T& value, T from, T not_a_value, std::basic_ios<CharT, Traits>& is) 65651b8b02a4SEd Tanous { 65661b8b02a4SEd Tanous if (!is.fail()) 65671b8b02a4SEd Tanous { 65681b8b02a4SEd Tanous if (value == not_a_value) 65691b8b02a4SEd Tanous value = std::move(from); 65701b8b02a4SEd Tanous else if (value != from) 65711b8b02a4SEd Tanous is.setstate(std::ios::failbit); 65721b8b02a4SEd Tanous } 65731b8b02a4SEd Tanous } 65741b8b02a4SEd Tanous 65751b8b02a4SEd Tanous } // namespace detail; 65761b8b02a4SEd Tanous 65771b8b02a4SEd Tanous template <class CharT, class Traits, class Duration, class Alloc = std::allocator<CharT>> 65781b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 65791b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 65801b8b02a4SEd Tanous fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev, 65811b8b02a4SEd Tanous std::chrono::minutes* offset) 65821b8b02a4SEd Tanous { 65831b8b02a4SEd Tanous using std::numeric_limits; 65841b8b02a4SEd Tanous using std::ios; 65851b8b02a4SEd Tanous using std::chrono::duration; 65861b8b02a4SEd Tanous using std::chrono::duration_cast; 65871b8b02a4SEd Tanous using std::chrono::seconds; 65881b8b02a4SEd Tanous using std::chrono::minutes; 65891b8b02a4SEd Tanous using std::chrono::hours; 65901b8b02a4SEd Tanous using detail::round_i; 65911b8b02a4SEd Tanous typename std::basic_istream<CharT, Traits>::sentry ok{is, true}; 65921b8b02a4SEd Tanous if (ok) 65931b8b02a4SEd Tanous { 65941b8b02a4SEd Tanous date::detail::save_istream<CharT, Traits> ss(is); 65951b8b02a4SEd Tanous is.fill(' '); 65961b8b02a4SEd Tanous is.flags(std::ios::skipws | std::ios::dec); 65971b8b02a4SEd Tanous is.width(0); 65981b8b02a4SEd Tanous #if !ONLY_C_LOCALE 65991b8b02a4SEd Tanous auto& f = std::use_facet<std::time_get<CharT>>(is.getloc()); 66001b8b02a4SEd Tanous std::tm tm{}; 66011b8b02a4SEd Tanous #endif 66021b8b02a4SEd Tanous const CharT* command = nullptr; 66031b8b02a4SEd Tanous auto modified = CharT{}; 66041b8b02a4SEd Tanous auto width = -1; 66051b8b02a4SEd Tanous 66061b8b02a4SEd Tanous CONSTDATA int not_a_year = numeric_limits<short>::min(); 66071b8b02a4SEd Tanous CONSTDATA int not_a_2digit_year = 100; 66081b8b02a4SEd Tanous CONSTDATA int not_a_century = not_a_year / 100; 66091b8b02a4SEd Tanous CONSTDATA int not_a_month = 0; 66101b8b02a4SEd Tanous CONSTDATA int not_a_day = 0; 66111b8b02a4SEd Tanous CONSTDATA int not_a_hour = numeric_limits<int>::min(); 66121b8b02a4SEd Tanous CONSTDATA int not_a_hour_12_value = 0; 66131b8b02a4SEd Tanous CONSTDATA int not_a_minute = not_a_hour; 66141b8b02a4SEd Tanous CONSTDATA Duration not_a_second = Duration::min(); 66151b8b02a4SEd Tanous CONSTDATA int not_a_doy = -1; 66161b8b02a4SEd Tanous CONSTDATA int not_a_weekday = 8; 66171b8b02a4SEd Tanous CONSTDATA int not_a_week_num = 100; 66181b8b02a4SEd Tanous CONSTDATA int not_a_ampm = -1; 66191b8b02a4SEd Tanous CONSTDATA minutes not_a_offset = minutes::min(); 66201b8b02a4SEd Tanous 66211b8b02a4SEd Tanous int Y = not_a_year; // c, F, Y * 66221b8b02a4SEd Tanous int y = not_a_2digit_year; // D, x, y * 66231b8b02a4SEd Tanous int g = not_a_2digit_year; // g * 66241b8b02a4SEd Tanous int G = not_a_year; // G * 66251b8b02a4SEd Tanous int C = not_a_century; // C * 66261b8b02a4SEd Tanous int m = not_a_month; // b, B, h, m, c, D, F, x * 66271b8b02a4SEd Tanous int d = not_a_day; // c, d, D, e, F, x * 66281b8b02a4SEd Tanous int j = not_a_doy; // j * 66291b8b02a4SEd Tanous int wd = not_a_weekday; // a, A, u, w * 66301b8b02a4SEd Tanous int H = not_a_hour; // c, H, R, T, X * 66311b8b02a4SEd Tanous int I = not_a_hour_12_value; // I, r * 66321b8b02a4SEd Tanous int p = not_a_ampm; // p, r * 66331b8b02a4SEd Tanous int M = not_a_minute; // c, M, r, R, T, X * 66341b8b02a4SEd Tanous Duration s = not_a_second; // c, r, S, T, X * 66351b8b02a4SEd Tanous int U = not_a_week_num; // U * 66361b8b02a4SEd Tanous int V = not_a_week_num; // V * 66371b8b02a4SEd Tanous int W = not_a_week_num; // W * 66381b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> temp_abbrev; // Z * 66391b8b02a4SEd Tanous minutes temp_offset = not_a_offset; // z * 66401b8b02a4SEd Tanous 66411b8b02a4SEd Tanous using detail::read; 66421b8b02a4SEd Tanous using detail::rs; 66431b8b02a4SEd Tanous using detail::ru; 66441b8b02a4SEd Tanous using detail::rld; 66451b8b02a4SEd Tanous using detail::checked_set; 66461b8b02a4SEd Tanous for (; *fmt != CharT{} && !is.fail(); ++fmt) 66471b8b02a4SEd Tanous { 66481b8b02a4SEd Tanous switch (*fmt) 66491b8b02a4SEd Tanous { 66501b8b02a4SEd Tanous case 'a': 66511b8b02a4SEd Tanous case 'A': 66521b8b02a4SEd Tanous case 'u': 66531b8b02a4SEd Tanous case 'w': // wd: a, A, u, w 66541b8b02a4SEd Tanous if (command) 66551b8b02a4SEd Tanous { 66561b8b02a4SEd Tanous int trial_wd = not_a_weekday; 66571b8b02a4SEd Tanous if (*fmt == 'a' || *fmt == 'A') 66581b8b02a4SEd Tanous { 66591b8b02a4SEd Tanous if (modified == CharT{}) 66601b8b02a4SEd Tanous { 66611b8b02a4SEd Tanous #if !ONLY_C_LOCALE 66621b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 66631b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 66641b8b02a4SEd Tanous is.setstate(err); 66651b8b02a4SEd Tanous if (!is.fail()) 66661b8b02a4SEd Tanous trial_wd = tm.tm_wday; 66671b8b02a4SEd Tanous #else 66681b8b02a4SEd Tanous auto nm = detail::weekday_names(); 66691b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 66701b8b02a4SEd Tanous if (!is.fail()) 66711b8b02a4SEd Tanous trial_wd = i % 7; 66721b8b02a4SEd Tanous #endif 66731b8b02a4SEd Tanous } 66741b8b02a4SEd Tanous else 66751b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 66761b8b02a4SEd Tanous } 66771b8b02a4SEd Tanous else // *fmt == 'u' || *fmt == 'w' 66781b8b02a4SEd Tanous { 66791b8b02a4SEd Tanous #if !ONLY_C_LOCALE 66801b8b02a4SEd Tanous if (modified == CharT{}) 66811b8b02a4SEd Tanous #else 66821b8b02a4SEd Tanous if (modified != CharT{'E'}) 66831b8b02a4SEd Tanous #endif 66841b8b02a4SEd Tanous { 66851b8b02a4SEd Tanous read(is, ru{trial_wd, 1, width == -1 ? 66861b8b02a4SEd Tanous 1u : static_cast<unsigned>(width)}); 66871b8b02a4SEd Tanous if (!is.fail()) 66881b8b02a4SEd Tanous { 66891b8b02a4SEd Tanous if (*fmt == 'u') 66901b8b02a4SEd Tanous { 66911b8b02a4SEd Tanous if (!(1 <= trial_wd && trial_wd <= 7)) 66921b8b02a4SEd Tanous { 66931b8b02a4SEd Tanous trial_wd = not_a_weekday; 66941b8b02a4SEd Tanous is.setstate(ios::failbit); 66951b8b02a4SEd Tanous } 66961b8b02a4SEd Tanous else if (trial_wd == 7) 66971b8b02a4SEd Tanous trial_wd = 0; 66981b8b02a4SEd Tanous } 66991b8b02a4SEd Tanous else // *fmt == 'w' 67001b8b02a4SEd Tanous { 67011b8b02a4SEd Tanous if (!(0 <= trial_wd && trial_wd <= 6)) 67021b8b02a4SEd Tanous { 67031b8b02a4SEd Tanous trial_wd = not_a_weekday; 67041b8b02a4SEd Tanous is.setstate(ios::failbit); 67051b8b02a4SEd Tanous } 67061b8b02a4SEd Tanous } 67071b8b02a4SEd Tanous } 67081b8b02a4SEd Tanous } 67091b8b02a4SEd Tanous #if !ONLY_C_LOCALE 67101b8b02a4SEd Tanous else if (modified == CharT{'O'}) 67111b8b02a4SEd Tanous { 67121b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 67131b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 67141b8b02a4SEd Tanous is.setstate(err); 67151b8b02a4SEd Tanous if (!is.fail()) 67161b8b02a4SEd Tanous trial_wd = tm.tm_wday; 67171b8b02a4SEd Tanous } 67181b8b02a4SEd Tanous #endif 67191b8b02a4SEd Tanous else 67201b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 67211b8b02a4SEd Tanous } 67221b8b02a4SEd Tanous if (trial_wd != not_a_weekday) 67231b8b02a4SEd Tanous checked_set(wd, trial_wd, not_a_weekday, is); 67241b8b02a4SEd Tanous } 67251b8b02a4SEd Tanous else // !command 67261b8b02a4SEd Tanous read(is, *fmt); 67271b8b02a4SEd Tanous command = nullptr; 67281b8b02a4SEd Tanous width = -1; 67291b8b02a4SEd Tanous modified = CharT{}; 67301b8b02a4SEd Tanous break; 67311b8b02a4SEd Tanous case 'b': 67321b8b02a4SEd Tanous case 'B': 67331b8b02a4SEd Tanous case 'h': 67341b8b02a4SEd Tanous if (command) 67351b8b02a4SEd Tanous { 67361b8b02a4SEd Tanous if (modified == CharT{}) 67371b8b02a4SEd Tanous { 67381b8b02a4SEd Tanous int ttm = not_a_month; 67391b8b02a4SEd Tanous #if !ONLY_C_LOCALE 67401b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 67411b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 67421b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 67431b8b02a4SEd Tanous ttm = tm.tm_mon + 1; 67441b8b02a4SEd Tanous is.setstate(err); 67451b8b02a4SEd Tanous #else 67461b8b02a4SEd Tanous auto nm = detail::month_names(); 67471b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 67481b8b02a4SEd Tanous if (!is.fail()) 67491b8b02a4SEd Tanous ttm = i % 12 + 1; 67501b8b02a4SEd Tanous #endif 67511b8b02a4SEd Tanous checked_set(m, ttm, not_a_month, is); 67521b8b02a4SEd Tanous } 67531b8b02a4SEd Tanous else 67541b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 67551b8b02a4SEd Tanous command = nullptr; 67561b8b02a4SEd Tanous width = -1; 67571b8b02a4SEd Tanous modified = CharT{}; 67581b8b02a4SEd Tanous } 67591b8b02a4SEd Tanous else 67601b8b02a4SEd Tanous read(is, *fmt); 67611b8b02a4SEd Tanous break; 67621b8b02a4SEd Tanous case 'c': 67631b8b02a4SEd Tanous if (command) 67641b8b02a4SEd Tanous { 67651b8b02a4SEd Tanous if (modified != CharT{'O'}) 67661b8b02a4SEd Tanous { 67671b8b02a4SEd Tanous #if !ONLY_C_LOCALE 67681b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 67691b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 67701b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 67711b8b02a4SEd Tanous { 67721b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 67731b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 67741b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 67751b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 67761b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 67771b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 67781b8b02a4SEd Tanous not_a_second, is); 67791b8b02a4SEd Tanous } 67801b8b02a4SEd Tanous is.setstate(err); 67811b8b02a4SEd Tanous #else 67821b8b02a4SEd Tanous // "%a %b %e %T %Y" 67831b8b02a4SEd Tanous auto nm = detail::weekday_names(); 67841b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 67851b8b02a4SEd Tanous checked_set(wd, static_cast<int>(i % 7), not_a_weekday, is); 67861b8b02a4SEd Tanous ws(is); 67871b8b02a4SEd Tanous nm = detail::month_names(); 67881b8b02a4SEd Tanous i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 67891b8b02a4SEd Tanous checked_set(m, static_cast<int>(i % 12 + 1), not_a_month, is); 67901b8b02a4SEd Tanous ws(is); 67911b8b02a4SEd Tanous int td = not_a_day; 67921b8b02a4SEd Tanous read(is, rs{td, 1, 2}); 67931b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 67941b8b02a4SEd Tanous ws(is); 67951b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 67961b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 67971b8b02a4SEd Tanous int tH; 67981b8b02a4SEd Tanous int tM; 67991b8b02a4SEd Tanous long double S{}; 68001b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 68011b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 68021b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 68031b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 68041b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 68051b8b02a4SEd Tanous not_a_second, is); 68061b8b02a4SEd Tanous ws(is); 68071b8b02a4SEd Tanous int tY = not_a_year; 68081b8b02a4SEd Tanous read(is, rs{tY, 1, 4u}); 68091b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 68101b8b02a4SEd Tanous #endif 68111b8b02a4SEd Tanous } 68121b8b02a4SEd Tanous else 68131b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 68141b8b02a4SEd Tanous command = nullptr; 68151b8b02a4SEd Tanous width = -1; 68161b8b02a4SEd Tanous modified = CharT{}; 68171b8b02a4SEd Tanous } 68181b8b02a4SEd Tanous else 68191b8b02a4SEd Tanous read(is, *fmt); 68201b8b02a4SEd Tanous break; 68211b8b02a4SEd Tanous case 'x': 68221b8b02a4SEd Tanous if (command) 68231b8b02a4SEd Tanous { 68241b8b02a4SEd Tanous if (modified != CharT{'O'}) 68251b8b02a4SEd Tanous { 68261b8b02a4SEd Tanous #if !ONLY_C_LOCALE 68271b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 68281b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 68291b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 68301b8b02a4SEd Tanous { 68311b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 68321b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 68331b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 68341b8b02a4SEd Tanous } 68351b8b02a4SEd Tanous is.setstate(err); 68361b8b02a4SEd Tanous #else 68371b8b02a4SEd Tanous // "%m/%d/%y" 68381b8b02a4SEd Tanous int ty = not_a_2digit_year; 68391b8b02a4SEd Tanous int tm = not_a_month; 68401b8b02a4SEd Tanous int td = not_a_day; 68411b8b02a4SEd Tanous read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'}, 68421b8b02a4SEd Tanous rs{ty, 1, 2}); 68431b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 68441b8b02a4SEd Tanous checked_set(m, tm, not_a_month, is); 68451b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 68461b8b02a4SEd Tanous #endif 68471b8b02a4SEd Tanous } 68481b8b02a4SEd Tanous else 68491b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 68501b8b02a4SEd Tanous command = nullptr; 68511b8b02a4SEd Tanous width = -1; 68521b8b02a4SEd Tanous modified = CharT{}; 68531b8b02a4SEd Tanous } 68541b8b02a4SEd Tanous else 68551b8b02a4SEd Tanous read(is, *fmt); 68561b8b02a4SEd Tanous break; 68571b8b02a4SEd Tanous case 'X': 68581b8b02a4SEd Tanous if (command) 68591b8b02a4SEd Tanous { 68601b8b02a4SEd Tanous if (modified != CharT{'O'}) 68611b8b02a4SEd Tanous { 68621b8b02a4SEd Tanous #if !ONLY_C_LOCALE 68631b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 68641b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 68651b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 68661b8b02a4SEd Tanous { 68671b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 68681b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 68691b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 68701b8b02a4SEd Tanous not_a_second, is); 68711b8b02a4SEd Tanous } 68721b8b02a4SEd Tanous is.setstate(err); 68731b8b02a4SEd Tanous #else 68741b8b02a4SEd Tanous // "%T" 68751b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 68761b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 68771b8b02a4SEd Tanous int tH = not_a_hour; 68781b8b02a4SEd Tanous int tM = not_a_minute; 68791b8b02a4SEd Tanous long double S{}; 68801b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 68811b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 68821b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 68831b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 68841b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 68851b8b02a4SEd Tanous not_a_second, is); 68861b8b02a4SEd Tanous #endif 68871b8b02a4SEd Tanous } 68881b8b02a4SEd Tanous else 68891b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 68901b8b02a4SEd Tanous command = nullptr; 68911b8b02a4SEd Tanous width = -1; 68921b8b02a4SEd Tanous modified = CharT{}; 68931b8b02a4SEd Tanous } 68941b8b02a4SEd Tanous else 68951b8b02a4SEd Tanous read(is, *fmt); 68961b8b02a4SEd Tanous break; 68971b8b02a4SEd Tanous case 'C': 68981b8b02a4SEd Tanous if (command) 68991b8b02a4SEd Tanous { 69001b8b02a4SEd Tanous int tC = not_a_century; 69011b8b02a4SEd Tanous #if !ONLY_C_LOCALE 69021b8b02a4SEd Tanous if (modified == CharT{}) 69031b8b02a4SEd Tanous { 69041b8b02a4SEd Tanous #endif 69051b8b02a4SEd Tanous read(is, rs{tC, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 69061b8b02a4SEd Tanous #if !ONLY_C_LOCALE 69071b8b02a4SEd Tanous } 69081b8b02a4SEd Tanous else 69091b8b02a4SEd Tanous { 69101b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 69111b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 69121b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 69131b8b02a4SEd Tanous { 69141b8b02a4SEd Tanous auto tY = tm.tm_year + 1900; 69151b8b02a4SEd Tanous tC = (tY >= 0 ? tY : tY-99) / 100; 69161b8b02a4SEd Tanous } 69171b8b02a4SEd Tanous is.setstate(err); 69181b8b02a4SEd Tanous } 69191b8b02a4SEd Tanous #endif 69201b8b02a4SEd Tanous checked_set(C, tC, not_a_century, is); 69211b8b02a4SEd Tanous command = nullptr; 69221b8b02a4SEd Tanous width = -1; 69231b8b02a4SEd Tanous modified = CharT{}; 69241b8b02a4SEd Tanous } 69251b8b02a4SEd Tanous else 69261b8b02a4SEd Tanous read(is, *fmt); 69271b8b02a4SEd Tanous break; 69281b8b02a4SEd Tanous case 'D': 69291b8b02a4SEd Tanous if (command) 69301b8b02a4SEd Tanous { 69311b8b02a4SEd Tanous if (modified == CharT{}) 69321b8b02a4SEd Tanous { 69331b8b02a4SEd Tanous int tn = not_a_month; 69341b8b02a4SEd Tanous int td = not_a_day; 69351b8b02a4SEd Tanous int ty = not_a_2digit_year; 69361b8b02a4SEd Tanous read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, 69371b8b02a4SEd Tanous ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, 69381b8b02a4SEd Tanous rs{ty, 1, 2}); 69391b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 69401b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 69411b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 69421b8b02a4SEd Tanous } 69431b8b02a4SEd Tanous else 69441b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 69451b8b02a4SEd Tanous command = nullptr; 69461b8b02a4SEd Tanous width = -1; 69471b8b02a4SEd Tanous modified = CharT{}; 69481b8b02a4SEd Tanous } 69491b8b02a4SEd Tanous else 69501b8b02a4SEd Tanous read(is, *fmt); 69511b8b02a4SEd Tanous break; 69521b8b02a4SEd Tanous case 'F': 69531b8b02a4SEd Tanous if (command) 69541b8b02a4SEd Tanous { 69551b8b02a4SEd Tanous if (modified == CharT{}) 69561b8b02a4SEd Tanous { 69571b8b02a4SEd Tanous int tY = not_a_year; 69581b8b02a4SEd Tanous int tn = not_a_month; 69591b8b02a4SEd Tanous int td = not_a_day; 69601b8b02a4SEd Tanous read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)}, 69611b8b02a4SEd Tanous CharT{'-'}, ru{tn, 1, 2}, CharT{'-'}, ru{td, 1, 2}); 69621b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 69631b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 69641b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 69651b8b02a4SEd Tanous } 69661b8b02a4SEd Tanous else 69671b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 69681b8b02a4SEd Tanous command = nullptr; 69691b8b02a4SEd Tanous width = -1; 69701b8b02a4SEd Tanous modified = CharT{}; 69711b8b02a4SEd Tanous } 69721b8b02a4SEd Tanous else 69731b8b02a4SEd Tanous read(is, *fmt); 69741b8b02a4SEd Tanous break; 69751b8b02a4SEd Tanous case 'd': 69761b8b02a4SEd Tanous case 'e': 69771b8b02a4SEd Tanous if (command) 69781b8b02a4SEd Tanous { 69791b8b02a4SEd Tanous #if !ONLY_C_LOCALE 69801b8b02a4SEd Tanous if (modified == CharT{}) 69811b8b02a4SEd Tanous #else 69821b8b02a4SEd Tanous if (modified != CharT{'E'}) 69831b8b02a4SEd Tanous #endif 69841b8b02a4SEd Tanous { 69851b8b02a4SEd Tanous int td = not_a_day; 69861b8b02a4SEd Tanous read(is, rs{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 69871b8b02a4SEd Tanous checked_set(d, td, not_a_day, is); 69881b8b02a4SEd Tanous } 69891b8b02a4SEd Tanous #if !ONLY_C_LOCALE 69901b8b02a4SEd Tanous else if (modified == CharT{'O'}) 69911b8b02a4SEd Tanous { 69921b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 69931b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 69941b8b02a4SEd Tanous command = nullptr; 69951b8b02a4SEd Tanous width = -1; 69961b8b02a4SEd Tanous modified = CharT{}; 69971b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 69981b8b02a4SEd Tanous checked_set(d, tm.tm_mday, not_a_day, is); 69991b8b02a4SEd Tanous is.setstate(err); 70001b8b02a4SEd Tanous } 70011b8b02a4SEd Tanous #endif 70021b8b02a4SEd Tanous else 70031b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 70041b8b02a4SEd Tanous command = nullptr; 70051b8b02a4SEd Tanous width = -1; 70061b8b02a4SEd Tanous modified = CharT{}; 70071b8b02a4SEd Tanous } 70081b8b02a4SEd Tanous else 70091b8b02a4SEd Tanous read(is, *fmt); 70101b8b02a4SEd Tanous break; 70111b8b02a4SEd Tanous case 'H': 70121b8b02a4SEd Tanous if (command) 70131b8b02a4SEd Tanous { 70141b8b02a4SEd Tanous #if !ONLY_C_LOCALE 70151b8b02a4SEd Tanous if (modified == CharT{}) 70161b8b02a4SEd Tanous #else 70171b8b02a4SEd Tanous if (modified != CharT{'E'}) 70181b8b02a4SEd Tanous #endif 70191b8b02a4SEd Tanous { 70201b8b02a4SEd Tanous int tH = not_a_hour; 70211b8b02a4SEd Tanous read(is, ru{tH, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 70221b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 70231b8b02a4SEd Tanous } 70241b8b02a4SEd Tanous #if !ONLY_C_LOCALE 70251b8b02a4SEd Tanous else if (modified == CharT{'O'}) 70261b8b02a4SEd Tanous { 70271b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 70281b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 70291b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 70301b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 70311b8b02a4SEd Tanous is.setstate(err); 70321b8b02a4SEd Tanous } 70331b8b02a4SEd Tanous #endif 70341b8b02a4SEd Tanous else 70351b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 70361b8b02a4SEd Tanous command = nullptr; 70371b8b02a4SEd Tanous width = -1; 70381b8b02a4SEd Tanous modified = CharT{}; 70391b8b02a4SEd Tanous } 70401b8b02a4SEd Tanous else 70411b8b02a4SEd Tanous read(is, *fmt); 70421b8b02a4SEd Tanous break; 70431b8b02a4SEd Tanous case 'I': 70441b8b02a4SEd Tanous if (command) 70451b8b02a4SEd Tanous { 70461b8b02a4SEd Tanous if (modified == CharT{}) 70471b8b02a4SEd Tanous { 70481b8b02a4SEd Tanous int tI = not_a_hour_12_value; 70491b8b02a4SEd Tanous // reads in an hour into I, but most be in [1, 12] 70501b8b02a4SEd Tanous read(is, rs{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 70511b8b02a4SEd Tanous if (!(1 <= tI && tI <= 12)) 70521b8b02a4SEd Tanous is.setstate(ios::failbit); 70531b8b02a4SEd Tanous checked_set(I, tI, not_a_hour_12_value, is); 70541b8b02a4SEd Tanous } 70551b8b02a4SEd Tanous else 70561b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 70571b8b02a4SEd Tanous command = nullptr; 70581b8b02a4SEd Tanous width = -1; 70591b8b02a4SEd Tanous modified = CharT{}; 70601b8b02a4SEd Tanous } 70611b8b02a4SEd Tanous else 70621b8b02a4SEd Tanous read(is, *fmt); 70631b8b02a4SEd Tanous break; 70641b8b02a4SEd Tanous case 'j': 70651b8b02a4SEd Tanous if (command) 70661b8b02a4SEd Tanous { 70671b8b02a4SEd Tanous if (modified == CharT{}) 70681b8b02a4SEd Tanous { 70691b8b02a4SEd Tanous int tj = not_a_doy; 70701b8b02a4SEd Tanous read(is, ru{tj, 1, width == -1 ? 3u : static_cast<unsigned>(width)}); 70711b8b02a4SEd Tanous checked_set(j, tj, not_a_doy, is); 70721b8b02a4SEd Tanous } 70731b8b02a4SEd Tanous else 70741b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 70751b8b02a4SEd Tanous command = nullptr; 70761b8b02a4SEd Tanous width = -1; 70771b8b02a4SEd Tanous modified = CharT{}; 70781b8b02a4SEd Tanous } 70791b8b02a4SEd Tanous else 70801b8b02a4SEd Tanous read(is, *fmt); 70811b8b02a4SEd Tanous break; 70821b8b02a4SEd Tanous case 'M': 70831b8b02a4SEd Tanous if (command) 70841b8b02a4SEd Tanous { 70851b8b02a4SEd Tanous #if !ONLY_C_LOCALE 70861b8b02a4SEd Tanous if (modified == CharT{}) 70871b8b02a4SEd Tanous #else 70881b8b02a4SEd Tanous if (modified != CharT{'E'}) 70891b8b02a4SEd Tanous #endif 70901b8b02a4SEd Tanous { 70911b8b02a4SEd Tanous int tM = not_a_minute; 70921b8b02a4SEd Tanous read(is, ru{tM, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 70931b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 70941b8b02a4SEd Tanous } 70951b8b02a4SEd Tanous #if !ONLY_C_LOCALE 70961b8b02a4SEd Tanous else if (modified == CharT{'O'}) 70971b8b02a4SEd Tanous { 70981b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 70991b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 71001b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 71011b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_minute, is); 71021b8b02a4SEd Tanous is.setstate(err); 71031b8b02a4SEd Tanous } 71041b8b02a4SEd Tanous #endif 71051b8b02a4SEd Tanous else 71061b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 71071b8b02a4SEd Tanous command = nullptr; 71081b8b02a4SEd Tanous width = -1; 71091b8b02a4SEd Tanous modified = CharT{}; 71101b8b02a4SEd Tanous } 71111b8b02a4SEd Tanous else 71121b8b02a4SEd Tanous read(is, *fmt); 71131b8b02a4SEd Tanous break; 71141b8b02a4SEd Tanous case 'm': 71151b8b02a4SEd Tanous if (command) 71161b8b02a4SEd Tanous { 71171b8b02a4SEd Tanous #if !ONLY_C_LOCALE 71181b8b02a4SEd Tanous if (modified == CharT{}) 71191b8b02a4SEd Tanous #else 71201b8b02a4SEd Tanous if (modified != CharT{'E'}) 71211b8b02a4SEd Tanous #endif 71221b8b02a4SEd Tanous { 71231b8b02a4SEd Tanous int tn = not_a_month; 71241b8b02a4SEd Tanous read(is, rs{tn, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 71251b8b02a4SEd Tanous checked_set(m, tn, not_a_month, is); 71261b8b02a4SEd Tanous } 71271b8b02a4SEd Tanous #if !ONLY_C_LOCALE 71281b8b02a4SEd Tanous else if (modified == CharT{'O'}) 71291b8b02a4SEd Tanous { 71301b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 71311b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 71321b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 71331b8b02a4SEd Tanous checked_set(m, tm.tm_mon + 1, not_a_month, is); 71341b8b02a4SEd Tanous is.setstate(err); 71351b8b02a4SEd Tanous } 71361b8b02a4SEd Tanous #endif 71371b8b02a4SEd Tanous else 71381b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 71391b8b02a4SEd Tanous command = nullptr; 71401b8b02a4SEd Tanous width = -1; 71411b8b02a4SEd Tanous modified = CharT{}; 71421b8b02a4SEd Tanous } 71431b8b02a4SEd Tanous else 71441b8b02a4SEd Tanous read(is, *fmt); 71451b8b02a4SEd Tanous break; 71461b8b02a4SEd Tanous case 'n': 71471b8b02a4SEd Tanous case 't': 71481b8b02a4SEd Tanous if (command) 71491b8b02a4SEd Tanous { 71501b8b02a4SEd Tanous if (modified == CharT{}) 71511b8b02a4SEd Tanous { 71521b8b02a4SEd Tanous // %n matches a single white space character 71531b8b02a4SEd Tanous // %t matches 0 or 1 white space characters 71541b8b02a4SEd Tanous auto ic = is.peek(); 71551b8b02a4SEd Tanous if (Traits::eq_int_type(ic, Traits::eof())) 71561b8b02a4SEd Tanous { 71571b8b02a4SEd Tanous ios::iostate err = ios::eofbit; 71581b8b02a4SEd Tanous if (*fmt == 'n') 71591b8b02a4SEd Tanous err |= ios::failbit; 71601b8b02a4SEd Tanous is.setstate(err); 71611b8b02a4SEd Tanous break; 71621b8b02a4SEd Tanous } 71631b8b02a4SEd Tanous if (isspace(ic)) 71641b8b02a4SEd Tanous { 71651b8b02a4SEd Tanous (void)is.get(); 71661b8b02a4SEd Tanous } 71671b8b02a4SEd Tanous else if (*fmt == 'n') 71681b8b02a4SEd Tanous is.setstate(ios::failbit); 71691b8b02a4SEd Tanous } 71701b8b02a4SEd Tanous else 71711b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 71721b8b02a4SEd Tanous command = nullptr; 71731b8b02a4SEd Tanous width = -1; 71741b8b02a4SEd Tanous modified = CharT{}; 71751b8b02a4SEd Tanous } 71761b8b02a4SEd Tanous else 71771b8b02a4SEd Tanous read(is, *fmt); 71781b8b02a4SEd Tanous break; 71791b8b02a4SEd Tanous case 'p': 71801b8b02a4SEd Tanous if (command) 71811b8b02a4SEd Tanous { 71821b8b02a4SEd Tanous if (modified == CharT{}) 71831b8b02a4SEd Tanous { 71841b8b02a4SEd Tanous int tp = not_a_ampm; 71851b8b02a4SEd Tanous #if !ONLY_C_LOCALE 71861b8b02a4SEd Tanous tm = std::tm{}; 71871b8b02a4SEd Tanous tm.tm_hour = 1; 71881b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 71891b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 71901b8b02a4SEd Tanous is.setstate(err); 71911b8b02a4SEd Tanous if (tm.tm_hour == 1) 71921b8b02a4SEd Tanous tp = 0; 71931b8b02a4SEd Tanous else if (tm.tm_hour == 13) 71941b8b02a4SEd Tanous tp = 1; 71951b8b02a4SEd Tanous else 71961b8b02a4SEd Tanous is.setstate(err); 71971b8b02a4SEd Tanous #else 71981b8b02a4SEd Tanous auto nm = detail::ampm_names(); 71991b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 72001b8b02a4SEd Tanous tp = static_cast<decltype(tp)>(i); 72011b8b02a4SEd Tanous #endif 72021b8b02a4SEd Tanous checked_set(p, tp, not_a_ampm, is); 72031b8b02a4SEd Tanous } 72041b8b02a4SEd Tanous else 72051b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 72061b8b02a4SEd Tanous command = nullptr; 72071b8b02a4SEd Tanous width = -1; 72081b8b02a4SEd Tanous modified = CharT{}; 72091b8b02a4SEd Tanous } 72101b8b02a4SEd Tanous else 72111b8b02a4SEd Tanous read(is, *fmt); 72121b8b02a4SEd Tanous 72131b8b02a4SEd Tanous break; 72141b8b02a4SEd Tanous case 'r': 72151b8b02a4SEd Tanous if (command) 72161b8b02a4SEd Tanous { 72171b8b02a4SEd Tanous if (modified == CharT{}) 72181b8b02a4SEd Tanous { 72191b8b02a4SEd Tanous #if !ONLY_C_LOCALE 72201b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 72211b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 72221b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 72231b8b02a4SEd Tanous { 72241b8b02a4SEd Tanous checked_set(H, tm.tm_hour, not_a_hour, is); 72251b8b02a4SEd Tanous checked_set(M, tm.tm_min, not_a_hour, is); 72261b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 72271b8b02a4SEd Tanous not_a_second, is); 72281b8b02a4SEd Tanous } 72291b8b02a4SEd Tanous is.setstate(err); 72301b8b02a4SEd Tanous #else 72311b8b02a4SEd Tanous // "%I:%M:%S %p" 72321b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 72331b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 72341b8b02a4SEd Tanous long double S{}; 72351b8b02a4SEd Tanous int tI = not_a_hour_12_value; 72361b8b02a4SEd Tanous int tM = not_a_minute; 72371b8b02a4SEd Tanous read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 72381b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 72391b8b02a4SEd Tanous checked_set(I, tI, not_a_hour_12_value, is); 72401b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 72411b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 72421b8b02a4SEd Tanous not_a_second, is); 72431b8b02a4SEd Tanous ws(is); 72441b8b02a4SEd Tanous auto nm = detail::ampm_names(); 72451b8b02a4SEd Tanous auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; 72461b8b02a4SEd Tanous checked_set(p, static_cast<int>(i), not_a_ampm, is); 72471b8b02a4SEd Tanous #endif 72481b8b02a4SEd Tanous } 72491b8b02a4SEd Tanous else 72501b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 72511b8b02a4SEd Tanous command = nullptr; 72521b8b02a4SEd Tanous width = -1; 72531b8b02a4SEd Tanous modified = CharT{}; 72541b8b02a4SEd Tanous } 72551b8b02a4SEd Tanous else 72561b8b02a4SEd Tanous read(is, *fmt); 72571b8b02a4SEd Tanous break; 72581b8b02a4SEd Tanous case 'R': 72591b8b02a4SEd Tanous if (command) 72601b8b02a4SEd Tanous { 72611b8b02a4SEd Tanous if (modified == CharT{}) 72621b8b02a4SEd Tanous { 72631b8b02a4SEd Tanous int tH = not_a_hour; 72641b8b02a4SEd Tanous int tM = not_a_minute; 72651b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'}, 72661b8b02a4SEd Tanous ru{tM, 1, 2}, CharT{'\0'}); 72671b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 72681b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 72691b8b02a4SEd Tanous } 72701b8b02a4SEd Tanous else 72711b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 72721b8b02a4SEd Tanous command = nullptr; 72731b8b02a4SEd Tanous width = -1; 72741b8b02a4SEd Tanous modified = CharT{}; 72751b8b02a4SEd Tanous } 72761b8b02a4SEd Tanous else 72771b8b02a4SEd Tanous read(is, *fmt); 72781b8b02a4SEd Tanous break; 72791b8b02a4SEd Tanous case 'S': 72801b8b02a4SEd Tanous if (command) 72811b8b02a4SEd Tanous { 72821b8b02a4SEd Tanous #if !ONLY_C_LOCALE 72831b8b02a4SEd Tanous if (modified == CharT{}) 72841b8b02a4SEd Tanous #else 72851b8b02a4SEd Tanous if (modified != CharT{'E'}) 72861b8b02a4SEd Tanous #endif 72871b8b02a4SEd Tanous { 72881b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 72891b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 72901b8b02a4SEd Tanous long double S{}; 72911b8b02a4SEd Tanous read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)}); 72921b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 72931b8b02a4SEd Tanous not_a_second, is); 72941b8b02a4SEd Tanous } 72951b8b02a4SEd Tanous #if !ONLY_C_LOCALE 72961b8b02a4SEd Tanous else if (modified == CharT{'O'}) 72971b8b02a4SEd Tanous { 72981b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 72991b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 73001b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 73011b8b02a4SEd Tanous checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}), 73021b8b02a4SEd Tanous not_a_second, is); 73031b8b02a4SEd Tanous is.setstate(err); 73041b8b02a4SEd Tanous } 73051b8b02a4SEd Tanous #endif 73061b8b02a4SEd Tanous else 73071b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 73081b8b02a4SEd Tanous command = nullptr; 73091b8b02a4SEd Tanous width = -1; 73101b8b02a4SEd Tanous modified = CharT{}; 73111b8b02a4SEd Tanous } 73121b8b02a4SEd Tanous else 73131b8b02a4SEd Tanous read(is, *fmt); 73141b8b02a4SEd Tanous break; 73151b8b02a4SEd Tanous case 'T': 73161b8b02a4SEd Tanous if (command) 73171b8b02a4SEd Tanous { 73181b8b02a4SEd Tanous if (modified == CharT{}) 73191b8b02a4SEd Tanous { 73201b8b02a4SEd Tanous using dfs = detail::decimal_format_seconds<Duration>; 73211b8b02a4SEd Tanous CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; 73221b8b02a4SEd Tanous int tH = not_a_hour; 73231b8b02a4SEd Tanous int tM = not_a_minute; 73241b8b02a4SEd Tanous long double S{}; 73251b8b02a4SEd Tanous read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, 73261b8b02a4SEd Tanous CharT{':'}, rld{S, 1, w}); 73271b8b02a4SEd Tanous checked_set(H, tH, not_a_hour, is); 73281b8b02a4SEd Tanous checked_set(M, tM, not_a_minute, is); 73291b8b02a4SEd Tanous checked_set(s, round_i<Duration>(duration<long double>{S}), 73301b8b02a4SEd Tanous not_a_second, is); 73311b8b02a4SEd Tanous } 73321b8b02a4SEd Tanous else 73331b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 73341b8b02a4SEd Tanous command = nullptr; 73351b8b02a4SEd Tanous width = -1; 73361b8b02a4SEd Tanous modified = CharT{}; 73371b8b02a4SEd Tanous } 73381b8b02a4SEd Tanous else 73391b8b02a4SEd Tanous read(is, *fmt); 73401b8b02a4SEd Tanous break; 73411b8b02a4SEd Tanous case 'Y': 73421b8b02a4SEd Tanous if (command) 73431b8b02a4SEd Tanous { 73441b8b02a4SEd Tanous #if !ONLY_C_LOCALE 73451b8b02a4SEd Tanous if (modified == CharT{}) 73461b8b02a4SEd Tanous #else 73471b8b02a4SEd Tanous if (modified != CharT{'O'}) 73481b8b02a4SEd Tanous #endif 73491b8b02a4SEd Tanous { 73501b8b02a4SEd Tanous int tY = not_a_year; 73511b8b02a4SEd Tanous read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)}); 73521b8b02a4SEd Tanous checked_set(Y, tY, not_a_year, is); 73531b8b02a4SEd Tanous } 73541b8b02a4SEd Tanous #if !ONLY_C_LOCALE 73551b8b02a4SEd Tanous else if (modified == CharT{'E'}) 73561b8b02a4SEd Tanous { 73571b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 73581b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 73591b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 73601b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 73611b8b02a4SEd Tanous is.setstate(err); 73621b8b02a4SEd Tanous } 73631b8b02a4SEd Tanous #endif 73641b8b02a4SEd Tanous else 73651b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 73661b8b02a4SEd Tanous command = nullptr; 73671b8b02a4SEd Tanous width = -1; 73681b8b02a4SEd Tanous modified = CharT{}; 73691b8b02a4SEd Tanous } 73701b8b02a4SEd Tanous else 73711b8b02a4SEd Tanous read(is, *fmt); 73721b8b02a4SEd Tanous break; 73731b8b02a4SEd Tanous case 'y': 73741b8b02a4SEd Tanous if (command) 73751b8b02a4SEd Tanous { 73761b8b02a4SEd Tanous #if !ONLY_C_LOCALE 73771b8b02a4SEd Tanous if (modified == CharT{}) 73781b8b02a4SEd Tanous #endif 73791b8b02a4SEd Tanous { 73801b8b02a4SEd Tanous int ty = not_a_2digit_year; 73811b8b02a4SEd Tanous read(is, ru{ty, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 73821b8b02a4SEd Tanous checked_set(y, ty, not_a_2digit_year, is); 73831b8b02a4SEd Tanous } 73841b8b02a4SEd Tanous #if !ONLY_C_LOCALE 73851b8b02a4SEd Tanous else 73861b8b02a4SEd Tanous { 73871b8b02a4SEd Tanous ios::iostate err = ios::goodbit; 73881b8b02a4SEd Tanous f.get(is, nullptr, is, err, &tm, command, fmt+1); 73891b8b02a4SEd Tanous if ((err & ios::failbit) == 0) 73901b8b02a4SEd Tanous checked_set(Y, tm.tm_year + 1900, not_a_year, is); 73911b8b02a4SEd Tanous is.setstate(err); 73921b8b02a4SEd Tanous } 73931b8b02a4SEd Tanous #endif 73941b8b02a4SEd Tanous command = nullptr; 73951b8b02a4SEd Tanous width = -1; 73961b8b02a4SEd Tanous modified = CharT{}; 73971b8b02a4SEd Tanous } 73981b8b02a4SEd Tanous else 73991b8b02a4SEd Tanous read(is, *fmt); 74001b8b02a4SEd Tanous break; 74011b8b02a4SEd Tanous case 'g': 74021b8b02a4SEd Tanous if (command) 74031b8b02a4SEd Tanous { 74041b8b02a4SEd Tanous if (modified == CharT{}) 74051b8b02a4SEd Tanous { 74061b8b02a4SEd Tanous int tg = not_a_2digit_year; 74071b8b02a4SEd Tanous read(is, ru{tg, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 74081b8b02a4SEd Tanous checked_set(g, tg, not_a_2digit_year, is); 74091b8b02a4SEd Tanous } 74101b8b02a4SEd Tanous else 74111b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 74121b8b02a4SEd Tanous command = nullptr; 74131b8b02a4SEd Tanous width = -1; 74141b8b02a4SEd Tanous modified = CharT{}; 74151b8b02a4SEd Tanous } 74161b8b02a4SEd Tanous else 74171b8b02a4SEd Tanous read(is, *fmt); 74181b8b02a4SEd Tanous break; 74191b8b02a4SEd Tanous case 'G': 74201b8b02a4SEd Tanous if (command) 74211b8b02a4SEd Tanous { 74221b8b02a4SEd Tanous if (modified == CharT{}) 74231b8b02a4SEd Tanous { 74241b8b02a4SEd Tanous int tG = not_a_year; 74251b8b02a4SEd Tanous read(is, rs{tG, 1, width == -1 ? 4u : static_cast<unsigned>(width)}); 74261b8b02a4SEd Tanous checked_set(G, tG, not_a_year, is); 74271b8b02a4SEd Tanous } 74281b8b02a4SEd Tanous else 74291b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 74301b8b02a4SEd Tanous command = nullptr; 74311b8b02a4SEd Tanous width = -1; 74321b8b02a4SEd Tanous modified = CharT{}; 74331b8b02a4SEd Tanous } 74341b8b02a4SEd Tanous else 74351b8b02a4SEd Tanous read(is, *fmt); 74361b8b02a4SEd Tanous break; 74371b8b02a4SEd Tanous case 'U': 74381b8b02a4SEd Tanous if (command) 74391b8b02a4SEd Tanous { 74401b8b02a4SEd Tanous if (modified == CharT{}) 74411b8b02a4SEd Tanous { 74421b8b02a4SEd Tanous int tU = not_a_week_num; 74431b8b02a4SEd Tanous read(is, ru{tU, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 74441b8b02a4SEd Tanous checked_set(U, tU, not_a_week_num, is); 74451b8b02a4SEd Tanous } 74461b8b02a4SEd Tanous else 74471b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 74481b8b02a4SEd Tanous command = nullptr; 74491b8b02a4SEd Tanous width = -1; 74501b8b02a4SEd Tanous modified = CharT{}; 74511b8b02a4SEd Tanous } 74521b8b02a4SEd Tanous else 74531b8b02a4SEd Tanous read(is, *fmt); 74541b8b02a4SEd Tanous break; 74551b8b02a4SEd Tanous case 'V': 74561b8b02a4SEd Tanous if (command) 74571b8b02a4SEd Tanous { 74581b8b02a4SEd Tanous if (modified == CharT{}) 74591b8b02a4SEd Tanous { 74601b8b02a4SEd Tanous int tV = not_a_week_num; 74611b8b02a4SEd Tanous read(is, ru{tV, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 74621b8b02a4SEd Tanous checked_set(V, tV, not_a_week_num, is); 74631b8b02a4SEd Tanous } 74641b8b02a4SEd Tanous else 74651b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 74661b8b02a4SEd Tanous command = nullptr; 74671b8b02a4SEd Tanous width = -1; 74681b8b02a4SEd Tanous modified = CharT{}; 74691b8b02a4SEd Tanous } 74701b8b02a4SEd Tanous else 74711b8b02a4SEd Tanous read(is, *fmt); 74721b8b02a4SEd Tanous break; 74731b8b02a4SEd Tanous case 'W': 74741b8b02a4SEd Tanous if (command) 74751b8b02a4SEd Tanous { 74761b8b02a4SEd Tanous if (modified == CharT{}) 74771b8b02a4SEd Tanous { 74781b8b02a4SEd Tanous int tW = not_a_week_num; 74791b8b02a4SEd Tanous read(is, ru{tW, 1, width == -1 ? 2u : static_cast<unsigned>(width)}); 74801b8b02a4SEd Tanous checked_set(W, tW, not_a_week_num, is); 74811b8b02a4SEd Tanous } 74821b8b02a4SEd Tanous else 74831b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 74841b8b02a4SEd Tanous command = nullptr; 74851b8b02a4SEd Tanous width = -1; 74861b8b02a4SEd Tanous modified = CharT{}; 74871b8b02a4SEd Tanous } 74881b8b02a4SEd Tanous else 74891b8b02a4SEd Tanous read(is, *fmt); 74901b8b02a4SEd Tanous break; 74911b8b02a4SEd Tanous case 'E': 74921b8b02a4SEd Tanous case 'O': 74931b8b02a4SEd Tanous if (command) 74941b8b02a4SEd Tanous { 74951b8b02a4SEd Tanous if (modified == CharT{}) 74961b8b02a4SEd Tanous { 74971b8b02a4SEd Tanous modified = *fmt; 74981b8b02a4SEd Tanous } 74991b8b02a4SEd Tanous else 75001b8b02a4SEd Tanous { 75011b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 75021b8b02a4SEd Tanous command = nullptr; 75031b8b02a4SEd Tanous width = -1; 75041b8b02a4SEd Tanous modified = CharT{}; 75051b8b02a4SEd Tanous } 75061b8b02a4SEd Tanous } 75071b8b02a4SEd Tanous else 75081b8b02a4SEd Tanous read(is, *fmt); 75091b8b02a4SEd Tanous break; 75101b8b02a4SEd Tanous case '%': 75111b8b02a4SEd Tanous if (command) 75121b8b02a4SEd Tanous { 75131b8b02a4SEd Tanous if (modified == CharT{}) 75141b8b02a4SEd Tanous read(is, *fmt); 75151b8b02a4SEd Tanous else 75161b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 75171b8b02a4SEd Tanous command = nullptr; 75181b8b02a4SEd Tanous width = -1; 75191b8b02a4SEd Tanous modified = CharT{}; 75201b8b02a4SEd Tanous } 75211b8b02a4SEd Tanous else 75221b8b02a4SEd Tanous command = fmt; 75231b8b02a4SEd Tanous break; 75241b8b02a4SEd Tanous case 'z': 75251b8b02a4SEd Tanous if (command) 75261b8b02a4SEd Tanous { 75271b8b02a4SEd Tanous int tH, tM; 75281b8b02a4SEd Tanous minutes toff = not_a_offset; 75291b8b02a4SEd Tanous bool neg = false; 75301b8b02a4SEd Tanous auto ic = is.peek(); 75311b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 75321b8b02a4SEd Tanous { 75331b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 75341b8b02a4SEd Tanous if (c == '-') 75351b8b02a4SEd Tanous neg = true; 75361b8b02a4SEd Tanous } 75371b8b02a4SEd Tanous if (modified == CharT{}) 75381b8b02a4SEd Tanous { 75391b8b02a4SEd Tanous read(is, rs{tH, 2, 2}); 75401b8b02a4SEd Tanous if (!is.fail()) 75411b8b02a4SEd Tanous toff = hours{std::abs(tH)}; 75421b8b02a4SEd Tanous if (is.good()) 75431b8b02a4SEd Tanous { 75441b8b02a4SEd Tanous ic = is.peek(); 75451b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 75461b8b02a4SEd Tanous { 75471b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 75481b8b02a4SEd Tanous if ('0' <= c && c <= '9') 75491b8b02a4SEd Tanous { 75501b8b02a4SEd Tanous read(is, ru{tM, 2, 2}); 75511b8b02a4SEd Tanous if (!is.fail()) 75521b8b02a4SEd Tanous toff += minutes{tM}; 75531b8b02a4SEd Tanous } 75541b8b02a4SEd Tanous } 75551b8b02a4SEd Tanous } 75561b8b02a4SEd Tanous } 75571b8b02a4SEd Tanous else 75581b8b02a4SEd Tanous { 75591b8b02a4SEd Tanous read(is, rs{tH, 1, 2}); 75601b8b02a4SEd Tanous if (!is.fail()) 75611b8b02a4SEd Tanous toff = hours{std::abs(tH)}; 75621b8b02a4SEd Tanous if (is.good()) 75631b8b02a4SEd Tanous { 75641b8b02a4SEd Tanous ic = is.peek(); 75651b8b02a4SEd Tanous if (!Traits::eq_int_type(ic, Traits::eof())) 75661b8b02a4SEd Tanous { 75671b8b02a4SEd Tanous auto c = static_cast<char>(Traits::to_char_type(ic)); 75681b8b02a4SEd Tanous if (c == ':') 75691b8b02a4SEd Tanous { 75701b8b02a4SEd Tanous (void)is.get(); 75711b8b02a4SEd Tanous read(is, ru{tM, 2, 2}); 75721b8b02a4SEd Tanous if (!is.fail()) 75731b8b02a4SEd Tanous toff += minutes{tM}; 75741b8b02a4SEd Tanous } 75751b8b02a4SEd Tanous } 75761b8b02a4SEd Tanous } 75771b8b02a4SEd Tanous } 75781b8b02a4SEd Tanous if (neg) 75791b8b02a4SEd Tanous toff = -toff; 75801b8b02a4SEd Tanous checked_set(temp_offset, toff, not_a_offset, is); 75811b8b02a4SEd Tanous command = nullptr; 75821b8b02a4SEd Tanous width = -1; 75831b8b02a4SEd Tanous modified = CharT{}; 75841b8b02a4SEd Tanous } 75851b8b02a4SEd Tanous else 75861b8b02a4SEd Tanous read(is, *fmt); 75871b8b02a4SEd Tanous break; 75881b8b02a4SEd Tanous case 'Z': 75891b8b02a4SEd Tanous if (command) 75901b8b02a4SEd Tanous { 75911b8b02a4SEd Tanous if (modified == CharT{}) 75921b8b02a4SEd Tanous { 75931b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc> buf; 75941b8b02a4SEd Tanous while (is.rdstate() == std::ios::goodbit) 75951b8b02a4SEd Tanous { 75961b8b02a4SEd Tanous auto i = is.rdbuf()->sgetc(); 75971b8b02a4SEd Tanous if (Traits::eq_int_type(i, Traits::eof())) 75981b8b02a4SEd Tanous { 75991b8b02a4SEd Tanous is.setstate(ios::eofbit); 76001b8b02a4SEd Tanous break; 76011b8b02a4SEd Tanous } 76021b8b02a4SEd Tanous auto wc = Traits::to_char_type(i); 76031b8b02a4SEd Tanous auto c = static_cast<char>(wc); 76041b8b02a4SEd Tanous // is c a valid time zone name or abbreviation character? 76051b8b02a4SEd Tanous if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) || 76061b8b02a4SEd Tanous c == '_' || c == '/' || c == '-' || c == '+')) 76071b8b02a4SEd Tanous break; 76081b8b02a4SEd Tanous buf.push_back(c); 76091b8b02a4SEd Tanous is.rdbuf()->sbumpc(); 76101b8b02a4SEd Tanous } 76111b8b02a4SEd Tanous if (buf.empty()) 76121b8b02a4SEd Tanous is.setstate(ios::failbit); 76131b8b02a4SEd Tanous checked_set(temp_abbrev, buf, {}, is); 76141b8b02a4SEd Tanous } 76151b8b02a4SEd Tanous else 76161b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 76171b8b02a4SEd Tanous command = nullptr; 76181b8b02a4SEd Tanous width = -1; 76191b8b02a4SEd Tanous modified = CharT{}; 76201b8b02a4SEd Tanous } 76211b8b02a4SEd Tanous else 76221b8b02a4SEd Tanous read(is, *fmt); 76231b8b02a4SEd Tanous break; 76241b8b02a4SEd Tanous default: 76251b8b02a4SEd Tanous if (command) 76261b8b02a4SEd Tanous { 76271b8b02a4SEd Tanous if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') 76281b8b02a4SEd Tanous { 76291b8b02a4SEd Tanous width = static_cast<char>(*fmt) - '0'; 76301b8b02a4SEd Tanous while ('0' <= fmt[1] && fmt[1] <= '9') 76311b8b02a4SEd Tanous width = 10*width + static_cast<char>(*++fmt) - '0'; 76321b8b02a4SEd Tanous } 76331b8b02a4SEd Tanous else 76341b8b02a4SEd Tanous { 76351b8b02a4SEd Tanous if (modified == CharT{}) 76361b8b02a4SEd Tanous read(is, CharT{'%'}, width, *fmt); 76371b8b02a4SEd Tanous else 76381b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified, *fmt); 76391b8b02a4SEd Tanous command = nullptr; 76401b8b02a4SEd Tanous width = -1; 76411b8b02a4SEd Tanous modified = CharT{}; 76421b8b02a4SEd Tanous } 76431b8b02a4SEd Tanous } 76441b8b02a4SEd Tanous else // !command 76451b8b02a4SEd Tanous { 76461b8b02a4SEd Tanous if (isspace(static_cast<unsigned char>(*fmt))) 76471b8b02a4SEd Tanous { 76481b8b02a4SEd Tanous // space matches 0 or more white space characters 76491b8b02a4SEd Tanous if (is.good()) 76501b8b02a4SEd Tanous ws(is); 76511b8b02a4SEd Tanous } 76521b8b02a4SEd Tanous else 76531b8b02a4SEd Tanous read(is, *fmt); 76541b8b02a4SEd Tanous } 76551b8b02a4SEd Tanous break; 76561b8b02a4SEd Tanous } 76571b8b02a4SEd Tanous } 76581b8b02a4SEd Tanous // is.fail() || *fmt == CharT{} 76591b8b02a4SEd Tanous if (is.rdstate() == ios::goodbit && command) 76601b8b02a4SEd Tanous { 76611b8b02a4SEd Tanous if (modified == CharT{}) 76621b8b02a4SEd Tanous read(is, CharT{'%'}, width); 76631b8b02a4SEd Tanous else 76641b8b02a4SEd Tanous read(is, CharT{'%'}, width, modified); 76651b8b02a4SEd Tanous } 76661b8b02a4SEd Tanous if (!is.fail()) 76671b8b02a4SEd Tanous { 76681b8b02a4SEd Tanous if (y != not_a_2digit_year) 76691b8b02a4SEd Tanous { 76701b8b02a4SEd Tanous // Convert y and an optional C to Y 76711b8b02a4SEd Tanous if (!(0 <= y && y <= 99)) 76721b8b02a4SEd Tanous goto broken; 76731b8b02a4SEd Tanous if (C == not_a_century) 76741b8b02a4SEd Tanous { 76751b8b02a4SEd Tanous if (Y == not_a_year) 76761b8b02a4SEd Tanous { 76771b8b02a4SEd Tanous if (y >= 69) 76781b8b02a4SEd Tanous C = 19; 76791b8b02a4SEd Tanous else 76801b8b02a4SEd Tanous C = 20; 76811b8b02a4SEd Tanous } 76821b8b02a4SEd Tanous else 76831b8b02a4SEd Tanous { 76841b8b02a4SEd Tanous C = (Y >= 0 ? Y : Y-100) / 100; 76851b8b02a4SEd Tanous } 76861b8b02a4SEd Tanous } 76871b8b02a4SEd Tanous int tY; 76881b8b02a4SEd Tanous if (C >= 0) 76891b8b02a4SEd Tanous tY = 100*C + y; 76901b8b02a4SEd Tanous else 76911b8b02a4SEd Tanous tY = 100*(C+1) - (y == 0 ? 100 : y); 76921b8b02a4SEd Tanous if (Y != not_a_year && Y != tY) 76931b8b02a4SEd Tanous goto broken; 76941b8b02a4SEd Tanous Y = tY; 76951b8b02a4SEd Tanous } 76961b8b02a4SEd Tanous if (g != not_a_2digit_year) 76971b8b02a4SEd Tanous { 76981b8b02a4SEd Tanous // Convert g and an optional C to G 76991b8b02a4SEd Tanous if (!(0 <= g && g <= 99)) 77001b8b02a4SEd Tanous goto broken; 77011b8b02a4SEd Tanous if (C == not_a_century) 77021b8b02a4SEd Tanous { 77031b8b02a4SEd Tanous if (G == not_a_year) 77041b8b02a4SEd Tanous { 77051b8b02a4SEd Tanous if (g >= 69) 77061b8b02a4SEd Tanous C = 19; 77071b8b02a4SEd Tanous else 77081b8b02a4SEd Tanous C = 20; 77091b8b02a4SEd Tanous } 77101b8b02a4SEd Tanous else 77111b8b02a4SEd Tanous { 77121b8b02a4SEd Tanous C = (G >= 0 ? G : G-100) / 100; 77131b8b02a4SEd Tanous } 77141b8b02a4SEd Tanous } 77151b8b02a4SEd Tanous int tG; 77161b8b02a4SEd Tanous if (C >= 0) 77171b8b02a4SEd Tanous tG = 100*C + g; 77181b8b02a4SEd Tanous else 77191b8b02a4SEd Tanous tG = 100*(C+1) - (g == 0 ? 100 : g); 77201b8b02a4SEd Tanous if (G != not_a_year && G != tG) 77211b8b02a4SEd Tanous goto broken; 77221b8b02a4SEd Tanous G = tG; 77231b8b02a4SEd Tanous } 77241b8b02a4SEd Tanous if (Y < static_cast<int>(year::min()) || Y > static_cast<int>(year::max())) 77251b8b02a4SEd Tanous Y = not_a_year; 77261b8b02a4SEd Tanous bool computed = false; 77271b8b02a4SEd Tanous if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) 77281b8b02a4SEd Tanous { 77291b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{G-1}/December/Thursday[last]) + 77301b8b02a4SEd Tanous (Monday-Thursday) + weeks{V-1} + 77311b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)}-Monday); 77321b8b02a4SEd Tanous if (Y == not_a_year) 77331b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 77341b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 77351b8b02a4SEd Tanous goto broken; 77361b8b02a4SEd Tanous if (m == not_a_month) 77371b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 77381b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 77391b8b02a4SEd Tanous goto broken; 77401b8b02a4SEd Tanous if (d == not_a_day) 77411b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 77421b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 77431b8b02a4SEd Tanous goto broken; 77441b8b02a4SEd Tanous computed = true; 77451b8b02a4SEd Tanous } 77461b8b02a4SEd Tanous if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday) 77471b8b02a4SEd Tanous { 77481b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) + 77491b8b02a4SEd Tanous weeks{U-1} + 77501b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)} - Sunday); 77511b8b02a4SEd Tanous if (Y == not_a_year) 77521b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 77531b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 77541b8b02a4SEd Tanous goto broken; 77551b8b02a4SEd Tanous if (m == not_a_month) 77561b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 77571b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 77581b8b02a4SEd Tanous goto broken; 77591b8b02a4SEd Tanous if (d == not_a_day) 77601b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 77611b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 77621b8b02a4SEd Tanous goto broken; 77631b8b02a4SEd Tanous computed = true; 77641b8b02a4SEd Tanous } 77651b8b02a4SEd Tanous if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday) 77661b8b02a4SEd Tanous { 77671b8b02a4SEd Tanous year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) + 77681b8b02a4SEd Tanous weeks{W-1} + 77691b8b02a4SEd Tanous (weekday{static_cast<unsigned>(wd)} - Monday); 77701b8b02a4SEd Tanous if (Y == not_a_year) 77711b8b02a4SEd Tanous Y = static_cast<int>(ymd_trial.year()); 77721b8b02a4SEd Tanous else if (year{Y} != ymd_trial.year()) 77731b8b02a4SEd Tanous goto broken; 77741b8b02a4SEd Tanous if (m == not_a_month) 77751b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 77761b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 77771b8b02a4SEd Tanous goto broken; 77781b8b02a4SEd Tanous if (d == not_a_day) 77791b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 77801b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 77811b8b02a4SEd Tanous goto broken; 77821b8b02a4SEd Tanous computed = true; 77831b8b02a4SEd Tanous } 77841b8b02a4SEd Tanous if (j != not_a_doy && Y != not_a_year) 77851b8b02a4SEd Tanous { 77861b8b02a4SEd Tanous auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; 77871b8b02a4SEd Tanous if (m == not_a_month) 77881b8b02a4SEd Tanous m = static_cast<int>(static_cast<unsigned>(ymd_trial.month())); 77891b8b02a4SEd Tanous else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) 77901b8b02a4SEd Tanous goto broken; 77911b8b02a4SEd Tanous if (d == not_a_day) 77921b8b02a4SEd Tanous d = static_cast<int>(static_cast<unsigned>(ymd_trial.day())); 77931b8b02a4SEd Tanous else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) 77941b8b02a4SEd Tanous goto broken; 77951b8b02a4SEd Tanous j = not_a_doy; 77961b8b02a4SEd Tanous } 77971b8b02a4SEd Tanous auto ymd = year{Y}/m/d; 77981b8b02a4SEd Tanous if (ymd.ok()) 77991b8b02a4SEd Tanous { 78001b8b02a4SEd Tanous if (wd == not_a_weekday) 78011b8b02a4SEd Tanous wd = static_cast<int>((weekday(sys_days(ymd)) - Sunday).count()); 78021b8b02a4SEd Tanous else if (wd != static_cast<int>((weekday(sys_days(ymd)) - Sunday).count())) 78031b8b02a4SEd Tanous goto broken; 78041b8b02a4SEd Tanous if (!computed) 78051b8b02a4SEd Tanous { 78061b8b02a4SEd Tanous if (G != not_a_year || V != not_a_week_num) 78071b8b02a4SEd Tanous { 78081b8b02a4SEd Tanous sys_days sd = ymd; 78091b8b02a4SEd Tanous auto G_trial = year_month_day{sd + days{3}}.year(); 78101b8b02a4SEd Tanous auto start = sys_days((G_trial - years{1})/December/Thursday[last]) + 78111b8b02a4SEd Tanous (Monday - Thursday); 78121b8b02a4SEd Tanous if (sd < start) 78131b8b02a4SEd Tanous { 78141b8b02a4SEd Tanous --G_trial; 78151b8b02a4SEd Tanous if (V != not_a_week_num) 78161b8b02a4SEd Tanous start = sys_days((G_trial - years{1})/December/Thursday[last]) 78171b8b02a4SEd Tanous + (Monday - Thursday); 78181b8b02a4SEd Tanous } 78191b8b02a4SEd Tanous if (G != not_a_year && G != static_cast<int>(G_trial)) 78201b8b02a4SEd Tanous goto broken; 78211b8b02a4SEd Tanous if (V != not_a_week_num) 78221b8b02a4SEd Tanous { 78231b8b02a4SEd Tanous auto V_trial = duration_cast<weeks>(sd - start).count() + 1; 78241b8b02a4SEd Tanous if (V != V_trial) 78251b8b02a4SEd Tanous goto broken; 78261b8b02a4SEd Tanous } 78271b8b02a4SEd Tanous } 78281b8b02a4SEd Tanous if (U != not_a_week_num) 78291b8b02a4SEd Tanous { 78301b8b02a4SEd Tanous auto start = sys_days(Sunday[1]/January/ymd.year()); 78311b8b02a4SEd Tanous auto U_trial = floor<weeks>(sys_days(ymd) - start).count() + 1; 78321b8b02a4SEd Tanous if (U != U_trial) 78331b8b02a4SEd Tanous goto broken; 78341b8b02a4SEd Tanous } 78351b8b02a4SEd Tanous if (W != not_a_week_num) 78361b8b02a4SEd Tanous { 78371b8b02a4SEd Tanous auto start = sys_days(Monday[1]/January/ymd.year()); 78381b8b02a4SEd Tanous auto W_trial = floor<weeks>(sys_days(ymd) - start).count() + 1; 78391b8b02a4SEd Tanous if (W != W_trial) 78401b8b02a4SEd Tanous goto broken; 78411b8b02a4SEd Tanous } 78421b8b02a4SEd Tanous } 78431b8b02a4SEd Tanous } 78441b8b02a4SEd Tanous fds.ymd = ymd; 78451b8b02a4SEd Tanous if (I != not_a_hour_12_value) 78461b8b02a4SEd Tanous { 78471b8b02a4SEd Tanous if (!(1 <= I && I <= 12)) 78481b8b02a4SEd Tanous goto broken; 78491b8b02a4SEd Tanous if (p != not_a_ampm) 78501b8b02a4SEd Tanous { 78511b8b02a4SEd Tanous // p is in [0, 1] == [AM, PM] 78521b8b02a4SEd Tanous // Store trial H in I 78531b8b02a4SEd Tanous if (I == 12) 78541b8b02a4SEd Tanous --p; 78551b8b02a4SEd Tanous I += p*12; 78561b8b02a4SEd Tanous // Either set H from I or make sure H and I are consistent 78571b8b02a4SEd Tanous if (H == not_a_hour) 78581b8b02a4SEd Tanous H = I; 78591b8b02a4SEd Tanous else if (I != H) 78601b8b02a4SEd Tanous goto broken; 78611b8b02a4SEd Tanous } 78621b8b02a4SEd Tanous else // p == not_a_ampm 78631b8b02a4SEd Tanous { 78641b8b02a4SEd Tanous // if H, make sure H and I could be consistent 78651b8b02a4SEd Tanous if (H != not_a_hour) 78661b8b02a4SEd Tanous { 78671b8b02a4SEd Tanous if (I == 12) 78681b8b02a4SEd Tanous { 78691b8b02a4SEd Tanous if (H != 0 && H != 12) 78701b8b02a4SEd Tanous goto broken; 78711b8b02a4SEd Tanous } 78721b8b02a4SEd Tanous else if (!(I == H || I == H+12)) 78731b8b02a4SEd Tanous { 78741b8b02a4SEd Tanous goto broken; 78751b8b02a4SEd Tanous } 78761b8b02a4SEd Tanous } 78771b8b02a4SEd Tanous else // I is ambiguous, AM or PM? 78781b8b02a4SEd Tanous goto broken; 78791b8b02a4SEd Tanous } 78801b8b02a4SEd Tanous } 78811b8b02a4SEd Tanous if (H != not_a_hour) 78821b8b02a4SEd Tanous { 78831b8b02a4SEd Tanous fds.has_tod = true; 78841b8b02a4SEd Tanous fds.tod = hh_mm_ss<Duration>{hours{H}}; 78851b8b02a4SEd Tanous } 78861b8b02a4SEd Tanous if (M != not_a_minute) 78871b8b02a4SEd Tanous { 78881b8b02a4SEd Tanous fds.has_tod = true; 78891b8b02a4SEd Tanous fds.tod.m_ = minutes{M}; 78901b8b02a4SEd Tanous } 78911b8b02a4SEd Tanous if (s != not_a_second) 78921b8b02a4SEd Tanous { 78931b8b02a4SEd Tanous fds.has_tod = true; 78941b8b02a4SEd Tanous fds.tod.s_ = detail::decimal_format_seconds<Duration>{s}; 78951b8b02a4SEd Tanous } 78961b8b02a4SEd Tanous if (j != not_a_doy) 78971b8b02a4SEd Tanous { 78981b8b02a4SEd Tanous fds.has_tod = true; 78991b8b02a4SEd Tanous fds.tod.h_ += hours{days{j}}; 79001b8b02a4SEd Tanous } 79011b8b02a4SEd Tanous if (wd != not_a_weekday) 79021b8b02a4SEd Tanous fds.wd = weekday{static_cast<unsigned>(wd)}; 79031b8b02a4SEd Tanous if (abbrev != nullptr) 79041b8b02a4SEd Tanous *abbrev = std::move(temp_abbrev); 79051b8b02a4SEd Tanous if (offset != nullptr && temp_offset != not_a_offset) 79061b8b02a4SEd Tanous *offset = temp_offset; 79071b8b02a4SEd Tanous } 79081b8b02a4SEd Tanous return is; 79091b8b02a4SEd Tanous } 79101b8b02a4SEd Tanous broken: 79111b8b02a4SEd Tanous is.setstate(ios::failbit); 79121b8b02a4SEd Tanous return is; 79131b8b02a4SEd Tanous } 79141b8b02a4SEd Tanous 79151b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79161b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79171b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year& y, 79181b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79191b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 79201b8b02a4SEd Tanous { 79211b8b02a4SEd Tanous using CT = std::chrono::seconds; 79221b8b02a4SEd Tanous fields<CT> fds{}; 79231b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 79241b8b02a4SEd Tanous if (!fds.ymd.year().ok()) 79251b8b02a4SEd Tanous is.setstate(std::ios::failbit); 79261b8b02a4SEd Tanous if (!is.fail()) 79271b8b02a4SEd Tanous y = fds.ymd.year(); 79281b8b02a4SEd Tanous return is; 79291b8b02a4SEd Tanous } 79301b8b02a4SEd Tanous 79311b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79321b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79331b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month& m, 79341b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79351b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 79361b8b02a4SEd Tanous { 79371b8b02a4SEd Tanous using CT = std::chrono::seconds; 79381b8b02a4SEd Tanous fields<CT> fds{}; 79391b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 79401b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 79411b8b02a4SEd Tanous is.setstate(std::ios::failbit); 79421b8b02a4SEd Tanous if (!is.fail()) 79431b8b02a4SEd Tanous m = fds.ymd.month(); 79441b8b02a4SEd Tanous return is; 79451b8b02a4SEd Tanous } 79461b8b02a4SEd Tanous 79471b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79481b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79491b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, day& d, 79501b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79511b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 79521b8b02a4SEd Tanous { 79531b8b02a4SEd Tanous using CT = std::chrono::seconds; 79541b8b02a4SEd Tanous fields<CT> fds{}; 79551b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 79561b8b02a4SEd Tanous if (!fds.ymd.day().ok()) 79571b8b02a4SEd Tanous is.setstate(std::ios::failbit); 79581b8b02a4SEd Tanous if (!is.fail()) 79591b8b02a4SEd Tanous d = fds.ymd.day(); 79601b8b02a4SEd Tanous return is; 79611b8b02a4SEd Tanous } 79621b8b02a4SEd Tanous 79631b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79641b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79651b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, weekday& wd, 79661b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79671b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 79681b8b02a4SEd Tanous { 79691b8b02a4SEd Tanous using CT = std::chrono::seconds; 79701b8b02a4SEd Tanous fields<CT> fds{}; 79711b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 79721b8b02a4SEd Tanous if (!fds.wd.ok()) 79731b8b02a4SEd Tanous is.setstate(std::ios::failbit); 79741b8b02a4SEd Tanous if (!is.fail()) 79751b8b02a4SEd Tanous wd = fds.wd; 79761b8b02a4SEd Tanous return is; 79771b8b02a4SEd Tanous } 79781b8b02a4SEd Tanous 79791b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79801b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79811b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month& ym, 79821b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79831b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 79841b8b02a4SEd Tanous { 79851b8b02a4SEd Tanous using CT = std::chrono::seconds; 79861b8b02a4SEd Tanous fields<CT> fds{}; 79871b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 79881b8b02a4SEd Tanous if (!fds.ymd.month().ok()) 79891b8b02a4SEd Tanous is.setstate(std::ios::failbit); 79901b8b02a4SEd Tanous if (!is.fail()) 79911b8b02a4SEd Tanous ym = fds.ymd.year()/fds.ymd.month(); 79921b8b02a4SEd Tanous return is; 79931b8b02a4SEd Tanous } 79941b8b02a4SEd Tanous 79951b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 79961b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 79971b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month_day& md, 79981b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 79991b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80001b8b02a4SEd Tanous { 80011b8b02a4SEd Tanous using CT = std::chrono::seconds; 80021b8b02a4SEd Tanous fields<CT> fds{}; 80031b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 80041b8b02a4SEd Tanous if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) 80051b8b02a4SEd Tanous is.setstate(std::ios::failbit); 80061b8b02a4SEd Tanous if (!is.fail()) 80071b8b02a4SEd Tanous md = fds.ymd.month()/fds.ymd.day(); 80081b8b02a4SEd Tanous return is; 80091b8b02a4SEd Tanous } 80101b8b02a4SEd Tanous 80111b8b02a4SEd Tanous template <class CharT, class Traits, class Alloc = std::allocator<CharT>> 80121b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 80131b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 80141b8b02a4SEd Tanous year_month_day& ymd, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 80151b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80161b8b02a4SEd Tanous { 80171b8b02a4SEd Tanous using CT = std::chrono::seconds; 80181b8b02a4SEd Tanous fields<CT> fds{}; 80191b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 80201b8b02a4SEd Tanous if (!fds.ymd.ok()) 80211b8b02a4SEd Tanous is.setstate(std::ios::failbit); 80221b8b02a4SEd Tanous if (!is.fail()) 80231b8b02a4SEd Tanous ymd = fds.ymd; 80241b8b02a4SEd Tanous return is; 80251b8b02a4SEd Tanous } 80261b8b02a4SEd Tanous 80271b8b02a4SEd Tanous template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>> 80281b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 80291b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 80301b8b02a4SEd Tanous sys_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 80311b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80321b8b02a4SEd Tanous { 80331b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 80341b8b02a4SEd Tanous using detail::round_i; 80351b8b02a4SEd Tanous std::chrono::minutes offset_local{}; 80361b8b02a4SEd Tanous auto offptr = offset ? offset : &offset_local; 80371b8b02a4SEd Tanous fields<CT> fds{}; 80381b8b02a4SEd Tanous fds.has_tod = true; 80391b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offptr); 80401b8b02a4SEd Tanous if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) 80411b8b02a4SEd Tanous is.setstate(std::ios::failbit); 80421b8b02a4SEd Tanous if (!is.fail()) 80431b8b02a4SEd Tanous tp = round_i<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); 80441b8b02a4SEd Tanous return is; 80451b8b02a4SEd Tanous } 80461b8b02a4SEd Tanous 80471b8b02a4SEd Tanous template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>> 80481b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 80491b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 80501b8b02a4SEd Tanous local_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 80511b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80521b8b02a4SEd Tanous { 80531b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 80541b8b02a4SEd Tanous using detail::round_i; 80551b8b02a4SEd Tanous fields<CT> fds{}; 80561b8b02a4SEd Tanous fds.has_tod = true; 80571b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 80581b8b02a4SEd Tanous if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) 80591b8b02a4SEd Tanous is.setstate(std::ios::failbit); 80601b8b02a4SEd Tanous if (!is.fail()) 80611b8b02a4SEd Tanous tp = round_i<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); 80621b8b02a4SEd Tanous return is; 80631b8b02a4SEd Tanous } 80641b8b02a4SEd Tanous 80651b8b02a4SEd Tanous template <class Rep, class Period, class CharT, class Traits, class Alloc = std::allocator<CharT>> 80661b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 80671b8b02a4SEd Tanous from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, 80681b8b02a4SEd Tanous std::chrono::duration<Rep, Period>& d, 80691b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 80701b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80711b8b02a4SEd Tanous { 80721b8b02a4SEd Tanous using Duration = std::chrono::duration<Rep, Period>; 80731b8b02a4SEd Tanous using CT = typename std::common_type<Duration, std::chrono::seconds>::type; 80741b8b02a4SEd Tanous using detail::round_i; 80751b8b02a4SEd Tanous fields<CT> fds{}; 80761b8b02a4SEd Tanous date::from_stream(is, fmt, fds, abbrev, offset); 80771b8b02a4SEd Tanous if (!fds.has_tod) 80781b8b02a4SEd Tanous is.setstate(std::ios::failbit); 80791b8b02a4SEd Tanous if (!is.fail()) 80801b8b02a4SEd Tanous d = round_i<Duration>(fds.tod.to_duration()); 80811b8b02a4SEd Tanous return is; 80821b8b02a4SEd Tanous } 80831b8b02a4SEd Tanous 80841b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits = std::char_traits<CharT>, 80851b8b02a4SEd Tanous class Alloc = std::allocator<CharT>> 80861b8b02a4SEd Tanous struct parse_manip 80871b8b02a4SEd Tanous { 80881b8b02a4SEd Tanous const std::basic_string<CharT, Traits, Alloc> format_; 80891b8b02a4SEd Tanous Parsable& tp_; 80901b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev_; 80911b8b02a4SEd Tanous std::chrono::minutes* offset_; 80921b8b02a4SEd Tanous 80931b8b02a4SEd Tanous public: 80941b8b02a4SEd Tanous parse_manip(std::basic_string<CharT, Traits, Alloc> format, Parsable& tp, 80951b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 80961b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 80971b8b02a4SEd Tanous : format_(std::move(format)) 80981b8b02a4SEd Tanous , tp_(tp) 80991b8b02a4SEd Tanous , abbrev_(abbrev) 81001b8b02a4SEd Tanous , offset_(offset) 81011b8b02a4SEd Tanous {} 81021b8b02a4SEd Tanous 81031b8b02a4SEd Tanous #if HAS_STRING_VIEW 81041b8b02a4SEd Tanous parse_manip(const CharT* format, Parsable& tp, 81051b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 81061b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 81071b8b02a4SEd Tanous : format_(format) 81081b8b02a4SEd Tanous , tp_(tp) 81091b8b02a4SEd Tanous , abbrev_(abbrev) 81101b8b02a4SEd Tanous , offset_(offset) 81111b8b02a4SEd Tanous {} 81121b8b02a4SEd Tanous 81131b8b02a4SEd Tanous parse_manip(std::basic_string_view<CharT, Traits> format, Parsable& tp, 81141b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr, 81151b8b02a4SEd Tanous std::chrono::minutes* offset = nullptr) 81161b8b02a4SEd Tanous : format_(format) 81171b8b02a4SEd Tanous , tp_(tp) 81181b8b02a4SEd Tanous , abbrev_(abbrev) 81191b8b02a4SEd Tanous , offset_(offset) 81201b8b02a4SEd Tanous {} 81211b8b02a4SEd Tanous #endif // HAS_STRING_VIEW 81221b8b02a4SEd Tanous }; 81231b8b02a4SEd Tanous 81241b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81251b8b02a4SEd Tanous std::basic_istream<CharT, Traits>& 81261b8b02a4SEd Tanous operator>>(std::basic_istream<CharT, Traits>& is, 81271b8b02a4SEd Tanous const parse_manip<Parsable, CharT, Traits, Alloc>& x) 81281b8b02a4SEd Tanous { 81291b8b02a4SEd Tanous return date::from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); 81301b8b02a4SEd Tanous } 81311b8b02a4SEd Tanous 81321b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81331b8b02a4SEd Tanous inline 81341b8b02a4SEd Tanous auto 81351b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp) 81361b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 81371b8b02a4SEd Tanous format.c_str(), tp), 81381b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp}) 81391b8b02a4SEd Tanous { 81401b8b02a4SEd Tanous return {format, tp}; 81411b8b02a4SEd Tanous } 81421b8b02a4SEd Tanous 81431b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81441b8b02a4SEd Tanous inline 81451b8b02a4SEd Tanous auto 81461b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 81471b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev) 81481b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 81491b8b02a4SEd Tanous format.c_str(), tp, &abbrev), 81501b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev}) 81511b8b02a4SEd Tanous { 81521b8b02a4SEd Tanous return {format, tp, &abbrev}; 81531b8b02a4SEd Tanous } 81541b8b02a4SEd Tanous 81551b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81561b8b02a4SEd Tanous inline 81571b8b02a4SEd Tanous auto 81581b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 81591b8b02a4SEd Tanous std::chrono::minutes& offset) 81601b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 81611b8b02a4SEd Tanous format.c_str(), tp, 81621b8b02a4SEd Tanous std::declval<std::basic_string<CharT, Traits, Alloc>*>(), 81631b8b02a4SEd Tanous &offset), 81641b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, nullptr, &offset}) 81651b8b02a4SEd Tanous { 81661b8b02a4SEd Tanous return {format, tp, nullptr, &offset}; 81671b8b02a4SEd Tanous } 81681b8b02a4SEd Tanous 81691b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81701b8b02a4SEd Tanous inline 81711b8b02a4SEd Tanous auto 81721b8b02a4SEd Tanous parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, 81731b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset) 81741b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), 81751b8b02a4SEd Tanous format.c_str(), tp, &abbrev, &offset), 81761b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset}) 81771b8b02a4SEd Tanous { 81781b8b02a4SEd Tanous return {format, tp, &abbrev, &offset}; 81791b8b02a4SEd Tanous } 81801b8b02a4SEd Tanous 81811b8b02a4SEd Tanous // const CharT* formats 81821b8b02a4SEd Tanous 81831b8b02a4SEd Tanous template <class Parsable, class CharT> 81841b8b02a4SEd Tanous inline 81851b8b02a4SEd Tanous auto 81861b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp) 81871b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp), 81881b8b02a4SEd Tanous parse_manip<Parsable, CharT>{format, tp}) 81891b8b02a4SEd Tanous { 81901b8b02a4SEd Tanous return {format, tp}; 81911b8b02a4SEd Tanous } 81921b8b02a4SEd Tanous 81931b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 81941b8b02a4SEd Tanous inline 81951b8b02a4SEd Tanous auto 81961b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits, Alloc>& abbrev) 81971b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, 81981b8b02a4SEd Tanous tp, &abbrev), 81991b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev}) 82001b8b02a4SEd Tanous { 82011b8b02a4SEd Tanous return {format, tp, &abbrev}; 82021b8b02a4SEd Tanous } 82031b8b02a4SEd Tanous 82041b8b02a4SEd Tanous template <class Parsable, class CharT> 82051b8b02a4SEd Tanous inline 82061b8b02a4SEd Tanous auto 82071b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) 82081b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT>&>(), format, 82091b8b02a4SEd Tanous tp, std::declval<std::basic_string<CharT>*>(), &offset), 82101b8b02a4SEd Tanous parse_manip<Parsable, CharT>{format, tp, nullptr, &offset}) 82111b8b02a4SEd Tanous { 82121b8b02a4SEd Tanous return {format, tp, nullptr, &offset}; 82131b8b02a4SEd Tanous } 82141b8b02a4SEd Tanous 82151b8b02a4SEd Tanous template <class Parsable, class CharT, class Traits, class Alloc> 82161b8b02a4SEd Tanous inline 82171b8b02a4SEd Tanous auto 82181b8b02a4SEd Tanous parse(const CharT* format, Parsable& tp, 82191b8b02a4SEd Tanous std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset) 82201b8b02a4SEd Tanous -> decltype(date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, 82211b8b02a4SEd Tanous tp, &abbrev, &offset), 82221b8b02a4SEd Tanous parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset}) 82231b8b02a4SEd Tanous { 82241b8b02a4SEd Tanous return {format, tp, &abbrev, &offset}; 82251b8b02a4SEd Tanous } 82261b8b02a4SEd Tanous 82271b8b02a4SEd Tanous // duration streaming 82281b8b02a4SEd Tanous 82291b8b02a4SEd Tanous template <class CharT, class Traits, class Rep, class Period> 82301b8b02a4SEd Tanous inline 82311b8b02a4SEd Tanous std::basic_ostream<CharT, Traits>& 82321b8b02a4SEd Tanous operator<<(std::basic_ostream<CharT, Traits>& os, 82331b8b02a4SEd Tanous const std::chrono::duration<Rep, Period>& d) 82341b8b02a4SEd Tanous { 82351b8b02a4SEd Tanous return os << detail::make_string<CharT, Traits>::from(d.count()) + 82361b8b02a4SEd Tanous detail::get_units<CharT>(typename Period::type{}); 82371b8b02a4SEd Tanous } 82381b8b02a4SEd Tanous 82391b8b02a4SEd Tanous } // namespace date 82401b8b02a4SEd Tanous 82411b8b02a4SEd Tanous #ifdef _MSC_VER 82421b8b02a4SEd Tanous # pragma warning(pop) 82431b8b02a4SEd Tanous #endif 82441b8b02a4SEd Tanous 82451b8b02a4SEd Tanous #ifdef __GNUC__ 82461b8b02a4SEd Tanous # pragma GCC diagnostic pop 82471b8b02a4SEd Tanous #endif 82481b8b02a4SEd Tanous 82491b8b02a4SEd Tanous // NOLINTEND 82501b8b02a4SEd Tanous // clang-format off 8251