annotate common/date/date.h @ 0:a4671277546c tip

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