From 582d0c4369b90ffca22b22200237d0d9a989f943 Mon Sep 17 00:00:00 2001 From: Per Malmberg Date: Sun, 11 Mar 2018 20:24:55 +0100 Subject: [PATCH] date.h as git submodule. --- .gitmodules | 3 + libcron/CMakeLists.txt | 6 +- libcron/CronData.cpp | 2 +- libcron/CronSchedule.h | 2 +- libcron/externals/date | 1 + libcron/externals/date/date.h | 8046 --------------------------------- test/CMakeLists.txt | 6 +- test/CronDataTest.cpp | 4 +- test/CronScheduleTest.cpp | 2 +- 9 files changed, 14 insertions(+), 8058 deletions(-) create mode 100644 .gitmodules create mode 160000 libcron/externals/date delete mode 100644 libcron/externals/date/date.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..268af22 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libcron/externals/date"] + path = libcron/externals/date + url = https://github.com/HowardHinnant/date.git diff --git a/libcron/CMakeLists.txt b/libcron/CMakeLists.txt index de6412a..84fd93f 100644 --- a/libcron/CMakeLists.txt +++ b/libcron/CMakeLists.txt @@ -4,7 +4,7 @@ project(libcron) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") -include_directories(externals/date) +include_directories(${CMAKE_CURRENT_LIST_DIR}/externals/date/include) add_library(${PROJECT_NAME} Cron.h @@ -15,6 +15,6 @@ add_library(${PROJECT_NAME} CronData.cpp CronSchedule.cpp CronSchedule.h - externals/date/date.h DateTime.h - Task.cpp CronClock.h) + Task.cpp + CronClock.h) diff --git a/libcron/CronData.cpp b/libcron/CronData.cpp index bbd6d67..7658fe7 100644 --- a/libcron/CronData.cpp +++ b/libcron/CronData.cpp @@ -1,4 +1,4 @@ -#include +#include #include "CronData.h" using namespace date; diff --git a/libcron/CronSchedule.h b/libcron/CronSchedule.h index 15e9d88..f93479c 100644 --- a/libcron/CronSchedule.h +++ b/libcron/CronSchedule.h @@ -2,7 +2,7 @@ #include "CronData.h" #include -#include "externals/date/date.h" +#include #include "DateTime.h" namespace libcron diff --git a/libcron/externals/date b/libcron/externals/date new file mode 160000 index 0000000..38c5ca3 --- /dev/null +++ b/libcron/externals/date @@ -0,0 +1 @@ +Subproject commit 38c5ca38bb73b292b72e088c31595add564d31f6 diff --git a/libcron/externals/date/date.h b/libcron/externals/date/date.h deleted file mode 100644 index 28328df..0000000 --- a/libcron/externals/date/date.h +++ /dev/null @@ -1,8046 +0,0 @@ -#ifndef DATE_H -#define DATE_H - -// The MIT License (MIT) -// -// Copyright (c) 2015, 2016, 2017 Howard Hinnant -// Copyright (c) 2016 Adrian Colomitchi -// Copyright (c) 2017 Florian Dang -// Copyright (c) 2017 Paul Thompson -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// Our apologies. When the previous paragraph was written, lowercase had not yet -// been invented (that would involve another several millennia of evolution). -// We did not mean to shout. - -#ifndef HAS_STRING_VIEW -# if __cplusplus >= 201703 -# define HAS_STRING_VIEW 1 -# else -# define HAS_STRING_VIEW 0 -# endif -#endif // HAS_STRING_VIEW - -#include -#include -#include -#include -#include -#if !(__cplusplus >= 201402) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if HAS_STRING_VIEW -# include -#endif -#include -#include - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpedantic" -# if __GNUC__ < 5 - // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -# endif -#endif - -namespace date -{ - -//---------------+ -// Configuration | -//---------------+ - -#ifndef ONLY_C_LOCALE -# define ONLY_C_LOCALE 0 -#endif - -#if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910)) -// MSVC -# if _MSC_VER < 1910 -// before VS2017 -# define CONSTDATA const -# define CONSTCD11 -# define CONSTCD14 -# define NOEXCEPT _NOEXCEPT -# else -// VS2017 and later -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 constexpr -# define NOEXCEPT noexcept -# endif - -#elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 -// Oracle Developer Studio 12.6 and earlier -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 -# define NOEXCEPT noexcept - -#elif __cplusplus >= 201402 -// C++14 -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 constexpr -# define NOEXCEPT noexcept -#else -// C++11 -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 -# define NOEXCEPT noexcept -#endif - -#ifndef HAS_VOID_T -# if __cplusplus >= 201703 -# define HAS_VOID_T 1 -# else -# define HAS_VOID_T 0 -# endif -#endif // HAS_VOID_T - -// Protect from Oracle sun macro -#ifdef sun -# undef sun -#endif - -//-----------+ -// Interface | -//-----------+ - -// durations - -using days = std::chrono::duration - , std::chrono::hours::period>>; - -using weeks = std::chrono::duration - , days::period>>; - -using years = std::chrono::duration - , days::period>>; - -using months = std::chrono::duration - >>; - -// time_point - -template - using sys_time = std::chrono::time_point; - -using sys_days = sys_time; -using sys_seconds = sys_time; - -struct local_t {}; - -template - using local_time = std::chrono::time_point; - -using local_seconds = local_time; -using local_days = local_time; - -// types - -struct last_spec -{ - explicit last_spec() = default; -}; - -class day; -class month; -class year; - -class weekday; -class weekday_indexed; -class weekday_last; - -class month_day; -class month_day_last; -class month_weekday; -class month_weekday_last; - -class year_month; - -class year_month_day; -class year_month_day_last; -class year_month_weekday; -class year_month_weekday_last; - -// date composition operators - -CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; -CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; - -CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; -CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; -CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; -CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; -CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; - -CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; -CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; -CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; -CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; - -CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; -CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; -CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; -CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; - -CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; - -CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; -CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; -CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; -CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; -CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; -CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; - -CONSTCD11 - year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const year& y, const month_weekday& mwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(int y, const month_weekday& mwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const month_weekday& mwd, const year& y) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const month_weekday& mwd, int y) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; - -// Detailed interface - -// day - -class day -{ - unsigned char d_; - -public: - day() = default; - explicit CONSTCD11 day(unsigned d) NOEXCEPT; - - CONSTCD14 day& operator++() NOEXCEPT; - CONSTCD14 day operator++(int) NOEXCEPT; - CONSTCD14 day& operator--() NOEXCEPT; - CONSTCD14 day operator--(int) NOEXCEPT; - - CONSTCD14 day& operator+=(const days& d) NOEXCEPT; - CONSTCD14 day& operator-=(const days& d) NOEXCEPT; - - CONSTCD11 explicit operator unsigned() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; - -CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; -CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; -CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; -CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const day& d); - -// month - -class month -{ - unsigned char m_; - -public: - month() = default; - explicit CONSTCD11 month(unsigned m) NOEXCEPT; - - CONSTCD14 month& operator++() NOEXCEPT; - CONSTCD14 month operator++(int) NOEXCEPT; - CONSTCD14 month& operator--() NOEXCEPT; - CONSTCD14 month operator--(int) NOEXCEPT; - - CONSTCD14 month& operator+=(const months& m) NOEXCEPT; - CONSTCD14 month& operator-=(const months& m) NOEXCEPT; - - CONSTCD11 explicit operator unsigned() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; - -CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; -CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; -CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; -CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month& m); - -// year - -class year -{ - short y_; - -public: - year() = default; - explicit CONSTCD11 year(int y) NOEXCEPT; - - CONSTCD14 year& operator++() NOEXCEPT; - CONSTCD14 year operator++(int) NOEXCEPT; - CONSTCD14 year& operator--() NOEXCEPT; - CONSTCD14 year operator--(int) NOEXCEPT; - - CONSTCD14 year& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 year operator-() const NOEXCEPT; - CONSTCD11 year operator+() const NOEXCEPT; - - CONSTCD11 bool is_leap() const NOEXCEPT; - - CONSTCD11 explicit operator int() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; - - static CONSTCD11 year min() NOEXCEPT; - static CONSTCD11 year max() NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; - -CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; -CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; -CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; -CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year& y); - -// weekday - -class weekday -{ - unsigned char wd_; -public: - weekday() = default; - explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; - CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; - CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; - - CONSTCD14 weekday& operator++() NOEXCEPT; - CONSTCD14 weekday operator++(int) NOEXCEPT; - CONSTCD14 weekday& operator--() NOEXCEPT; - CONSTCD14 weekday operator--(int) NOEXCEPT; - - CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; - CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; - - CONSTCD11 explicit operator unsigned() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; - - CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; - CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; - -private: - static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; -}; - -CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; - -CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; -CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; -CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; -CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday& wd); - -// weekday_indexed - -class weekday_indexed -{ - unsigned char wd_ : 4; - unsigned char index_ : 4; - -public: - weekday_indexed() = default; - CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT; - - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 unsigned index() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_indexed& wdi); - -// weekday_last - -class weekday_last -{ - date::weekday wd_; - -public: - explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT; - - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_last& wdl); - -// year_month - -class year_month -{ - date::year y_; - date::month m_; - -public: - year_month() = default; - CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - - CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; - CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; - CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; - CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; - -CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; -CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; -CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; - -CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; -CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; -CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month& ym); - -// month_day - -class month_day -{ - date::month m_; - date::day d_; - -public: - month_day() = default; - CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::day day() const NOEXCEPT; - - CONSTCD14 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day& md); - -// month_day_last - -class month_day_last -{ - date::month m_; - -public: - CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day_last& mdl); - -// month_weekday - -class month_weekday -{ - date::month m_; - date::weekday_indexed wdi_; -public: - CONSTCD11 month_weekday(const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday& mwd); - -// month_weekday_last - -class month_weekday_last -{ - date::month m_; - date::weekday_last wdl_; - -public: - CONSTCD11 month_weekday_last(const date::month& m, - const date::weekday_last& wd) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); - -// class year_month_day - -class year_month_day -{ - date::year y_; - date::month m_; - date::day d_; - -public: - year_month_day() = default; - CONSTCD11 year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT; - CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; - - CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; - CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; - - CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::day day() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD14 bool ok() const NOEXCEPT; - -private: - static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; - -CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; -CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; -CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; -CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; -CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; -CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day& ymd); - -// year_month_day_last - -class year_month_day_last -{ - date::year y_; - date::month_day_last mdl_; - -public: - CONSTCD11 year_month_day_last(const date::year& y, - const date::month_day_last& mdl) NOEXCEPT; - - CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; - CONSTCD14 date::day day() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; - -CONSTCD14 -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; - -CONSTCD14 -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; - -CONSTCD14 -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); - -// year_month_weekday - -class year_month_weekday -{ - date::year y_; - date::month m_; - date::weekday_indexed wdi_; - -public: - year_month_weekday() = default; - CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT; - CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; - CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; - - CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 unsigned index() const NOEXCEPT; - CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD14 bool ok() const NOEXCEPT; - -private: - static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; - -CONSTCD14 -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; - -CONSTCD14 -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; - -CONSTCD14 -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); - -// year_month_weekday_last - -class year_month_weekday_last -{ - date::year y_; - date::month m_; - date::weekday_last wdl_; - -public: - CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, - const date::weekday_last& wdl) NOEXCEPT; - - CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; - -private: - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 -bool -operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; - -CONSTCD11 -bool -operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; - -CONSTCD14 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; - -CONSTCD14 -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; - -CONSTCD14 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -inline namespace literals -{ - -CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT; -CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT; - -// CONSTDATA date::month jan{1}; -// CONSTDATA date::month feb{2}; -// CONSTDATA date::month mar{3}; -// CONSTDATA date::month apr{4}; -// CONSTDATA date::month may{5}; -// CONSTDATA date::month jun{6}; -// CONSTDATA date::month jul{7}; -// CONSTDATA date::month aug{8}; -// CONSTDATA date::month sep{9}; -// CONSTDATA date::month oct{10}; -// CONSTDATA date::month nov{11}; -// CONSTDATA date::month dec{12}; -// -// CONSTDATA date::weekday sun{0u}; -// CONSTDATA date::weekday mon{1u}; -// CONSTDATA date::weekday tue{2u}; -// CONSTDATA date::weekday wed{3u}; -// CONSTDATA date::weekday thu{4u}; -// CONSTDATA date::weekday fri{5u}; -// CONSTDATA date::weekday sat{6u}; - -} // inline namespace literals -#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) - -#if HAS_VOID_T - -template > -struct is_clock - : std::false_type -{}; - -template -struct is_clock> - : std::true_type -{}; - -#endif // HAS_VOID_T - -//----------------+ -// Implementation | -//----------------+ - -// utilities -namespace detail { - -template> -class save_stream -{ - std::basic_ostream& os_; - CharT fill_; - std::ios::fmtflags flags_; - std::locale loc_; - -public: - ~save_stream() - { - os_.fill(fill_); - os_.flags(flags_); - os_.imbue(loc_); - } - - save_stream(const save_stream&) = delete; - save_stream& operator=(const save_stream&) = delete; - - explicit save_stream(std::basic_ostream& os) - : os_(os) - , fill_(os.fill()) - , flags_(os.flags()) - , loc_(os.getloc()) - {} -}; - -template -struct choose_trunc_type -{ - static const int digits = std::numeric_limits::digits; - using type = typename std::conditional - < - digits < 32, - std::int32_t, - typename std::conditional - < - digits < 64, - std::int64_t, -#ifdef __SIZEOF_INT128__ - __int128 -#else - std::int64_t -#endif - >::type - >::type; -}; - -template -CONSTCD11 -inline -typename std::enable_if -< - !std::chrono::treat_as_floating_point::value, - T ->::type -trunc(T t) NOEXCEPT -{ - return t; -} - -template -CONSTCD14 -inline -typename std::enable_if -< - std::chrono::treat_as_floating_point::value, - T ->::type -trunc(T t) NOEXCEPT -{ - using namespace std; - using I = typename choose_trunc_type::type; - CONSTDATA auto digits = numeric_limits::digits; - static_assert(digits < numeric_limits::digits, ""); - CONSTDATA auto max = I{1} << (digits-1); - CONSTDATA auto min = -max; - const auto negative = t < T{0}; - if (min <= t && t <= max && t != 0 && t == t) - { - t = static_cast(static_cast(t)); - if (t == 0 && negative) - t = -t; - } - return t; -} - -template -struct static_gcd -{ - static const std::intmax_t value = static_gcd::value; -}; - -template -struct static_gcd -{ - static const std::intmax_t value = Xp; -}; - -template <> -struct static_gcd<0, 0> -{ - static const std::intmax_t value = 1; -}; - -template -struct no_overflow -{ -private: - static const std::intmax_t gcd_n1_n2 = static_gcd::value; - static const std::intmax_t gcd_d1_d2 = static_gcd::value; - static const std::intmax_t n1 = R1::num / gcd_n1_n2; - static const std::intmax_t d1 = R1::den / gcd_d1_d2; - static const std::intmax_t n2 = R2::num / gcd_n1_n2; - static const std::intmax_t d2 = R2::den / gcd_d1_d2; - static const std::intmax_t max = -((std::intmax_t(1) << - (sizeof(std::intmax_t) * CHAR_BIT - 1)) + 1); - - template - struct mul // overflow == false - { - static const std::intmax_t value = Xp * Yp; - }; - - template - struct mul - { - static const std::intmax_t value = 1; - }; - -public: - static const bool value = (n1 <= max / d2) && (n2 <= max / d1); - typedef std::ratio::value, - mul::value> type; -}; - -} // detail - -// trunc towards zero -template -CONSTCD11 -inline -typename std::enable_if -< - detail::no_overflow::value, - To ->::type -trunc(const std::chrono::duration& d) -{ - return To{detail::trunc(std::chrono::duration_cast(d).count())}; -} - -template -CONSTCD11 -inline -typename std::enable_if -< - !detail::no_overflow::value, - To ->::type -trunc(const std::chrono::duration& d) -{ - using namespace std::chrono; - using rep = typename std::common_type::type; - return To{detail::trunc(duration_cast(duration_cast>(d)).count())}; -} - -#ifndef HAS_CHRONO_ROUNDING -# if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__))) -# define HAS_CHRONO_ROUNDING 1 -# elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510 -# define HAS_CHRONO_ROUNDING 1 -# elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800 -# define HAS_CHRONO_ROUNDING 1 -# else -# define HAS_CHRONO_ROUNDING 0 -# endif -#endif // HAS_CHRONO_ROUNDING - -#if HAS_CHRONO_ROUNDING == 0 - -// round down -template -CONSTCD14 -inline -typename std::enable_if -< - detail::no_overflow::value, - To ->::type -floor(const std::chrono::duration& d) -{ - auto t = trunc(d); - if (t > d) - return t - To{1}; - return t; -} - -template -CONSTCD14 -inline -typename std::enable_if -< - !detail::no_overflow::value, - To ->::type -floor(const std::chrono::duration& d) -{ - using namespace std::chrono; - using rep = typename std::common_type::type; - return floor(floor>(d)); -} - -// round to nearest, to even on tie -template -CONSTCD14 -inline -To -round(const std::chrono::duration& d) -{ - auto t0 = floor(d); - auto t1 = t0 + To{1}; - if (t1 == To{0} && t0 < To{0}) - t1 = -t1; - auto diff0 = d - t0; - auto diff1 = t1 - d; - if (diff0 == diff1) - { - if (t0 - trunc(t0/2)*2 == To{0}) - return t0; - return t1; - } - if (diff0 < diff1) - return t0; - return t1; -} - -// round up -template -CONSTCD14 -inline -To -ceil(const std::chrono::duration& d) -{ - auto t = trunc(d); - if (t < d) - return t + To{1}; - return t; -} - -template ::is_signed - >::type> -CONSTCD11 -std::chrono::duration -abs(std::chrono::duration d) -{ - return d >= d.zero() ? d : -d; -} - -// round down -template -CONSTCD11 -inline -std::chrono::time_point -floor(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{date::floor(tp.time_since_epoch())}; -} - -// round to nearest, to even on tie -template -CONSTCD11 -inline -std::chrono::time_point -round(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{round(tp.time_since_epoch())}; -} - -// round up -template -CONSTCD11 -inline -std::chrono::time_point -ceil(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{ceil(tp.time_since_epoch())}; -} - -#else // HAS_CHRONO_ROUNDING == 1 - -using std::chrono::floor; -using std::chrono::ceil; -using std::chrono::round; -using std::chrono::abs; - -#endif // HAS_CHRONO_ROUNDING - -// trunc towards zero -template -CONSTCD11 -inline -std::chrono::time_point -trunc(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{trunc(tp.time_since_epoch())}; -} - -// day - -CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} -CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} -CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} -CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} -CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} -CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} -CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} -CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} - -CONSTCD11 -inline -bool -operator==(const day& x, const day& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const day& x, const day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const day& x, const day& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const day& x, const day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const day& x, const day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const day& x, const day& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD11 -inline -days -operator-(const day& x, const day& y) NOEXCEPT -{ - return days{static_cast(static_cast(x) - - static_cast(y))}; -} - -CONSTCD11 -inline -day -operator+(const day& x, const days& y) NOEXCEPT -{ - return day{static_cast(x) + static_cast(y.count())}; -} - -CONSTCD11 -inline -day -operator+(const days& x, const day& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD11 -inline -day -operator-(const day& x, const days& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const day& d) -{ - detail::save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(d); - return os; -} - -// month - -CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} -CONSTCD14 inline month& month::operator++() NOEXCEPT {if (++m_ == 13) m_ = 1; return *this;} -CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline month& month::operator--() NOEXCEPT {if (--m_ == 0) m_ = 12; return *this;} -CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} - -CONSTCD14 -inline -month& -month::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -month& -month::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} -CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} - -CONSTCD11 -inline -bool -operator==(const month& x, const month& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const month& x, const month& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month& x, const month& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const month& x, const month& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month& x, const month& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month& x, const month& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD14 -inline -months -operator-(const month& x, const month& y) NOEXCEPT -{ - auto const d = static_cast(x) - static_cast(y); - return months(d <= 11 ? d : d + 12); -} - -CONSTCD14 -inline -month -operator+(const month& x, const months& y) NOEXCEPT -{ - auto const mu = static_cast(static_cast(x)) - 1 + y.count(); - auto const yr = (mu >= 0 ? mu : mu-11) / 12; - return month{static_cast(mu - yr * 12 + 1)}; -} - -CONSTCD14 -inline -month -operator+(const months& x, const month& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD14 -inline -month -operator-(const month& x, const months& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month& m) -{ - switch (static_cast(m)) - { - case 1: - os << "Jan"; - break; - case 2: - os << "Feb"; - break; - case 3: - os << "Mar"; - break; - case 4: - os << "Apr"; - break; - case 5: - os << "May"; - break; - case 6: - os << "Jun"; - break; - case 7: - os << "Jul"; - break; - case 8: - os << "Aug"; - break; - case 9: - os << "Sep"; - break; - case 10: - os << "Oct"; - break; - case 11: - os << "Nov"; - break; - case 12: - os << "Dec"; - break; - default: - os << static_cast(m) << " is not a valid month"; - break; - } - return os; -} - -// year - -CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} -CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} -CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} -CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} -CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} -CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} -CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};} -CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;} - -CONSTCD11 -inline -bool -year::is_leap() const NOEXCEPT -{ - return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0); -} - -CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} - -CONSTCD11 -inline -bool -year::ok() const NOEXCEPT -{ - return y_ != std::numeric_limits::min(); -} - -CONSTCD11 -inline -year -year::min() NOEXCEPT -{ - return year{-32767}; -} - -CONSTCD11 -inline -year -year::max() NOEXCEPT -{ - return year{32767}; -} - -CONSTCD11 -inline -bool -operator==(const year& x, const year& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const year& x, const year& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year& x, const year& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const year& x, const year& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year& x, const year& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year& x, const year& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD11 -inline -years -operator-(const year& x, const year& y) NOEXCEPT -{ - return years{static_cast(x) - static_cast(y)}; -} - -CONSTCD11 -inline -year -operator+(const year& x, const years& y) NOEXCEPT -{ - return year{static_cast(x) + y.count()}; -} - -CONSTCD11 -inline -year -operator+(const years& x, const year& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD11 -inline -year -operator-(const year& x, const years& y) NOEXCEPT -{ - return year{static_cast(x) - y.count()}; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year& y) -{ - detail::save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::internal); - os.width(4 + (y < year{0})); - os << static_cast(y); - return os; -} - -// weekday - -CONSTCD11 -inline -unsigned char -weekday::weekday_from_days(int z) NOEXCEPT -{ - return static_cast(static_cast( - z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6)); -} - -CONSTCD11 -inline -weekday::weekday(unsigned wd) NOEXCEPT - : wd_(static_cast(wd)) - {} - -CONSTCD11 -inline -weekday::weekday(const sys_days& dp) NOEXCEPT - : wd_(weekday_from_days(dp.time_since_epoch().count())) - {} - -CONSTCD11 -inline -weekday::weekday(const local_days& dp) NOEXCEPT - : wd_(weekday_from_days(dp.time_since_epoch().count())) - {} - -CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 7) wd_ = 0; return *this;} -CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 0) wd_ = 6; return *this;} -CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} - -CONSTCD14 -inline -weekday& -weekday::operator+=(const days& d) NOEXCEPT -{ - *this = *this + d; - return *this; -} - -CONSTCD14 -inline -weekday& -weekday::operator-=(const days& d) NOEXCEPT -{ - *this = *this - d; - return *this; -} - -CONSTCD11 -inline -weekday::operator unsigned() const NOEXCEPT -{ - return static_cast(wd_); -} - -CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} - -CONSTCD11 -inline -bool -operator==(const weekday& x, const weekday& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const weekday& x, const weekday& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD14 -inline -days -operator-(const weekday& x, const weekday& y) NOEXCEPT -{ - auto const diff = static_cast(x) - static_cast(y); - return days{diff <= 6 ? diff : diff + 7}; -} - -CONSTCD14 -inline -weekday -operator+(const weekday& x, const days& y) NOEXCEPT -{ - auto const wdu = static_cast(static_cast(x)) + y.count(); - auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; - return weekday{static_cast(wdu - wk * 7)}; -} - -CONSTCD14 -inline -weekday -operator+(const days& x, const weekday& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD14 -inline -weekday -operator-(const weekday& x, const days& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday& wd) -{ - switch (static_cast(wd)) - { - case 0: - os << "Sun"; - break; - case 1: - os << "Mon"; - break; - case 2: - os << "Tue"; - break; - case 3: - os << "Wed"; - break; - case 4: - os << "Thu"; - break; - case 5: - os << "Fri"; - break; - case 6: - os << "Sat"; - break; - default: - os << static_cast(wd) << " is not a valid weekday"; - break; - } - return os; -} - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -inline namespace literals -{ - -CONSTCD11 -inline -date::day -operator "" _d(unsigned long long d) NOEXCEPT -{ - return date::day{static_cast(d)}; -} - -CONSTCD11 -inline -date::year -operator "" _y(unsigned long long y) NOEXCEPT -{ - return date::year(static_cast(y)); -} -#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) - -CONSTDATA date::last_spec last{}; - -CONSTDATA date::month jan{1}; -CONSTDATA date::month feb{2}; -CONSTDATA date::month mar{3}; -CONSTDATA date::month apr{4}; -CONSTDATA date::month may{5}; -CONSTDATA date::month jun{6}; -CONSTDATA date::month jul{7}; -CONSTDATA date::month aug{8}; -CONSTDATA date::month sep{9}; -CONSTDATA date::month oct{10}; -CONSTDATA date::month nov{11}; -CONSTDATA date::month dec{12}; - -CONSTDATA date::weekday sun{0u}; -CONSTDATA date::weekday mon{1u}; -CONSTDATA date::weekday tue{2u}; -CONSTDATA date::weekday wed{3u}; -CONSTDATA date::weekday thu{4u}; -CONSTDATA date::weekday fri{5u}; -CONSTDATA date::weekday sat{6u}; - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -} // inline namespace literals -#endif - -// weekday_indexed - -CONSTCD11 -inline -weekday -weekday_indexed::weekday() const NOEXCEPT -{ - return date::weekday{static_cast(wd_)}; -} - -CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} - -CONSTCD11 -inline -bool -weekday_indexed::ok() const NOEXCEPT -{ - return weekday().ok() && 1 <= index_ && index_ <= 5; -} - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" -#endif // __GNUC__ - -CONSTCD11 -inline -weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT - : wd_(static_cast(static_cast(wd))) - , index_(static_cast(index)) - {} - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif // __GNUC__ - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_indexed& wdi) -{ - return os << wdi.weekday() << '[' << wdi.index() << ']'; -} - -CONSTCD11 -inline -weekday_indexed -weekday::operator[](unsigned index) const NOEXCEPT -{ - return {*this, index}; -} - -CONSTCD11 -inline -bool -operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT -{ - return x.weekday() == y.weekday() && x.index() == y.index(); -} - -CONSTCD11 -inline -bool -operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT -{ - return !(x == y); -} - -// weekday_last - -CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} -CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} -CONSTCD11 inline weekday_last::weekday_last(const date::weekday& wd) NOEXCEPT : wd_(wd) {} - -CONSTCD11 -inline -bool -operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT -{ - return x.weekday() == y.weekday(); -} - -CONSTCD11 -inline -bool -operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_last& wdl) -{ - return os << wdl.weekday() << "[last]"; -} - -CONSTCD11 -inline -weekday_last -weekday::operator[](last_spec) const NOEXCEPT -{ - return weekday_last{*this}; -} - -// year_month - -CONSTCD11 -inline -year_month::year_month(const date::year& y, const date::month& m) NOEXCEPT - : y_(y) - , m_(m) - {} - -CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} -CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} - -CONSTCD14 -inline -year_month& -year_month::operator+=(const months& dm) NOEXCEPT -{ - *this = *this + dm; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator-=(const months& dm) NOEXCEPT -{ - *this = *this - dm; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator+=(const years& dy) NOEXCEPT -{ - *this = *this + dy; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator-=(const years& dy) NOEXCEPT -{ - *this = *this - dy; - return *this; -} - -CONSTCD11 -inline -bool -operator==(const year_month& x, const year_month& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month& x, const year_month& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month() < y.month())); -} - -CONSTCD11 -inline -bool -operator>(const year_month& x, const year_month& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD14 -inline -year_month -operator+(const year_month& ym, const months& dm) NOEXCEPT -{ - auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); - auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; - dmi = dmi - dy * 12 + 1; - return (ym.year() + years(dy)) / month(static_cast(dmi)); -} - -CONSTCD14 -inline -year_month -operator+(const months& dm, const year_month& ym) NOEXCEPT -{ - return ym + dm; -} - -CONSTCD14 -inline -year_month -operator-(const year_month& ym, const months& dm) NOEXCEPT -{ - return ym + -dm; -} - -CONSTCD11 -inline -months -operator-(const year_month& x, const year_month& y) NOEXCEPT -{ - return (x.year() - y.year()) + - months(static_cast(x.month()) - static_cast(y.month())); -} - -CONSTCD11 -inline -year_month -operator+(const year_month& ym, const years& dy) NOEXCEPT -{ - return (ym.year() + dy) / ym.month(); -} - -CONSTCD11 -inline -year_month -operator+(const years& dy, const year_month& ym) NOEXCEPT -{ - return ym + dy; -} - -CONSTCD11 -inline -year_month -operator-(const year_month& ym, const years& dy) NOEXCEPT -{ - return ym + -dy; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month& ym) -{ - return os << ym.year() << '/' << ym.month(); -} - -// month_day - -CONSTCD11 -inline -month_day::month_day(const date::month& m, const date::day& d) NOEXCEPT - : m_(m) - , d_(d) - {} - -CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;} -CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;} - -CONSTCD14 -inline -bool -month_day::ok() const NOEXCEPT -{ - CONSTDATA date::day d[] = - { - date::day(31), date::day(29), date::day(31), - date::day(30), date::day(31), date::day(30), - date::day(31), date::day(31), date::day(30), - date::day(31), date::day(30), date::day(31) - }; - return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast(m_)-1]; -} - -CONSTCD11 -inline -bool -operator==(const month_day& x, const month_day& y) NOEXCEPT -{ - return x.month() == y.month() && x.day() == y.day(); -} - -CONSTCD11 -inline -bool -operator!=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month_day& x, const month_day& y) NOEXCEPT -{ - return x.month() < y.month() ? true - : (x.month() > y.month() ? false - : (x.day() < y.day())); -} - -CONSTCD11 -inline -bool -operator>(const month_day& x, const month_day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day& md) -{ - return os << md.month() << '/' << md.day(); -} - -// month_day_last - -CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} -CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} -CONSTCD11 inline month_day_last::month_day_last(const date::month& m) NOEXCEPT : m_(m) {} - -CONSTCD11 -inline -bool -operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return x.month() == y.month(); -} - -CONSTCD11 -inline -bool -operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return x.month() < y.month(); -} - -CONSTCD11 -inline -bool -operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day_last& mdl) -{ - return os << mdl.month() << "/last"; -} - -// month_weekday - -CONSTCD11 -inline -month_weekday::month_weekday(const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT - : m_(m) - , wdi_(wdi) - {} - -CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday_indexed -month_weekday::weekday_indexed() const NOEXCEPT -{ - return wdi_; -} - -CONSTCD11 -inline -bool -month_weekday::ok() const NOEXCEPT -{ - return m_.ok() && wdi_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT -{ - return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); -} - -CONSTCD11 -inline -bool -operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday& mwd) -{ - return os << mwd.month() << '/' << mwd.weekday_indexed(); -} - -// month_weekday_last - -CONSTCD11 -inline -month_weekday_last::month_weekday_last(const date::month& m, - const date::weekday_last& wdl) NOEXCEPT - : m_(m) - , wdl_(wdl) - {} - -CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday_last -month_weekday_last::weekday_last() const NOEXCEPT -{ - return wdl_; -} - -CONSTCD11 -inline -bool -month_weekday_last::ok() const NOEXCEPT -{ - return m_.ok() && wdl_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT -{ - return x.month() == y.month() && x.weekday_last() == y.weekday_last(); -} - -CONSTCD11 -inline -bool -operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) -{ - return os << mwdl.month() << '/' << mwdl.weekday_last(); -} - -// year_month_day_last - -CONSTCD11 -inline -year_month_day_last::year_month_day_last(const date::year& y, - const date::month_day_last& mdl) NOEXCEPT - : y_(y) - , mdl_(mdl) - {} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} - -CONSTCD11 -inline -month_day_last -year_month_day_last::month_day_last() const NOEXCEPT -{ - return mdl_; -} - -CONSTCD14 -inline -day -year_month_day_last::day() const NOEXCEPT -{ - CONSTDATA date::day d[] = - { - date::day(31), date::day(28), date::day(31), - date::day(30), date::day(31), date::day(30), - date::day(31), date::day(31), date::day(30), - date::day(31), date::day(30), date::day(31) - }; - return month() != feb || !y_.is_leap() ? - d[static_cast(month()) - 1] : date::day{29}; -} - -CONSTCD14 -inline -year_month_day_last::operator sys_days() const NOEXCEPT -{ - return sys_days(year()/month()/day()); -} - -CONSTCD14 -inline -year_month_day_last::operator local_days() const NOEXCEPT -{ - return local_days(year()/month()/day()); -} - -CONSTCD11 -inline -bool -year_month_day_last::ok() const NOEXCEPT -{ - return y_.ok() && mdl_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return x.year() == y.year() && x.month_day_last() == y.month_day_last(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month_day_last() < y.month_day_last())); -} - -CONSTCD11 -inline -bool -operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) -{ - return os << ymdl.year() << '/' << ymdl.month_day_last(); -} - -CONSTCD14 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return (ymdl.year() / ymdl.month() + dm) / last; -} - -CONSTCD14 -inline -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dm; -} - -CONSTCD14 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return ymdl + (-dm); -} - -CONSTCD11 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return {ymdl.year()+dy, ymdl.month_day_last()}; -} - -CONSTCD11 -inline -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dy; -} - -CONSTCD11 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return ymdl + (-dy); -} - -// year_month_day - -CONSTCD11 -inline -year_month_day::year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT - : y_(y) - , m_(m) - , d_(d) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT - : y_(ymdl.year()) - , m_(ymdl.month()) - , d_(ymdl.day()) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(sys_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(local_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} - -CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} -CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD14 -inline -days -year_month_day::to_days() const NOEXCEPT -{ - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const y = static_cast(y_) - (m_ <= feb); - auto const m = static_cast(m_); - auto const d = static_cast(d_); - auto const era = (y >= 0 ? y : y-399) / 400; - auto const yoe = static_cast(y - era * 400); // [0, 399] - auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] - auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] - return days{era * 146097 + static_cast(doe) - 719468}; -} - -CONSTCD14 -inline -year_month_day::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_day::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD14 -inline -bool -year_month_day::ok() const NOEXCEPT -{ - if (!(y_.ok() && m_.ok())) - return false; - return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month() < y.month() ? true - : (x.month() > y.month() ? false - : (x.day() < y.day())))); -} - -CONSTCD11 -inline -bool -operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day& ymd) -{ - detail::save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os << ymd.year() << '-'; - os.width(2); - os << static_cast(ymd.month()) << '-'; - os << ymd.day(); - return os; -} - -CONSTCD14 -inline -year_month_day -year_month_day::from_days(days dp) NOEXCEPT -{ - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const z = dp.count() + 719468; - auto const era = (z >= 0 ? z : z - 146096) / 146097; - auto const doe = static_cast(z - era * 146097); // [0, 146096] - auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] - auto const y = static_cast(yoe) + era * 400; - auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] - auto const mp = (5*doy + 2)/153; // [0, 11] - auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] - auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] - return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; -} - -CONSTCD14 -inline -year_month_day -operator+(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return (ymd.year() / ymd.month() + dm) / ymd.day(); -} - -CONSTCD14 -inline -year_month_day -operator+(const months& dm, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dm; -} - -CONSTCD14 -inline -year_month_day -operator-(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return ymd + (-dm); -} - -CONSTCD11 -inline -year_month_day -operator+(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return (ymd.year() + dy) / ymd.month() / ymd.day(); -} - -CONSTCD11 -inline -year_month_day -operator+(const years& dy, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dy; -} - -CONSTCD11 -inline -year_month_day -operator-(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return ymd + (-dy); -} - -// year_month_weekday - -CONSTCD11 -inline -year_month_weekday::year_month_weekday(const date::year& y, const date::month& m, - const date::weekday_indexed& wdi) - NOEXCEPT - : y_(y) - , m_(m) - , wdi_(wdi) - {} - -CONSTCD14 -inline -year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT - : year_month_weekday(from_days(dp.time_since_epoch())) - {} - -CONSTCD14 -inline -year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT - : year_month_weekday(from_days(dp.time_since_epoch())) - {} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday -year_month_weekday::weekday() const NOEXCEPT -{ - return wdi_.weekday(); -} - -CONSTCD11 -inline -unsigned -year_month_weekday::index() const NOEXCEPT -{ - return wdi_.index(); -} - -CONSTCD11 -inline -weekday_indexed -year_month_weekday::weekday_indexed() const NOEXCEPT -{ - return wdi_; -} - -CONSTCD14 -inline -year_month_weekday::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_weekday::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD14 -inline -bool -year_month_weekday::ok() const NOEXCEPT -{ - if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) - return false; - if (wdi_.index() <= 4) - return true; - auto d2 = wdi_.weekday() - date::weekday(static_cast(y_/m_/1)) + days((wdi_.index()-1)*7 + 1); - return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); -} - -CONSTCD14 -inline -year_month_weekday -year_month_weekday::from_days(days d) NOEXCEPT -{ - sys_days dp{d}; - auto const wd = date::weekday(dp); - auto const ymd = year_month_day(dp); - return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; -} - -CONSTCD14 -inline -days -year_month_weekday::to_days() const NOEXCEPT -{ - auto d = sys_days(y_/m_/1); - return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) - ).time_since_epoch(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && - x.weekday_indexed() == y.weekday_indexed(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) -{ - return os << ymwdi.year() << '/' << ymwdi.month() - << '/' << ymwdi.weekday_indexed(); -} - -CONSTCD14 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); -} - -CONSTCD14 -inline -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dm; -} - -CONSTCD14 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return ymwd + (-dm); -} - -CONSTCD11 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; -} - -CONSTCD11 -inline -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dy; -} - -CONSTCD11 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return ymwd + (-dy); -} - -// year_month_weekday_last - -CONSTCD11 -inline -year_month_weekday_last::year_month_weekday_last(const date::year& y, - const date::month& m, - const date::weekday_last& wdl) NOEXCEPT - : y_(y) - , m_(m) - , wdl_(wdl) - {} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday -year_month_weekday_last::weekday() const NOEXCEPT -{ - return wdl_.weekday(); -} - -CONSTCD11 -inline -weekday_last -year_month_weekday_last::weekday_last() const NOEXCEPT -{ - return wdl_; -} - -CONSTCD14 -inline -year_month_weekday_last::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_weekday_last::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD11 -inline -bool -year_month_weekday_last::ok() const NOEXCEPT -{ - return y_.ok() && m_.ok() && wdl_.ok(); -} - -CONSTCD14 -inline -days -year_month_weekday_last::to_days() const NOEXCEPT -{ - auto const d = sys_days(y_/m_/last); - return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && - x.weekday_last() == y.weekday_last(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) -{ - return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); -} - -CONSTCD14 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); -} - -CONSTCD14 -inline -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dm; -} - -CONSTCD14 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return ymwdl + (-dm); -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dy; -} - -CONSTCD11 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return ymwdl + (-dy); -} - -// year_month from operator/() - -CONSTCD11 -inline -year_month -operator/(const year& y, const month& m) NOEXCEPT -{ - return {y, m}; -} - -CONSTCD11 -inline -year_month -operator/(const year& y, int m) NOEXCEPT -{ - return y / month(static_cast(m)); -} - -// month_day from operator/() - -CONSTCD11 -inline -month_day -operator/(const month& m, const day& d) NOEXCEPT -{ - return {m, d}; -} - -CONSTCD11 -inline -month_day -operator/(const day& d, const month& m) NOEXCEPT -{ - return m / d; -} - -CONSTCD11 -inline -month_day -operator/(const month& m, int d) NOEXCEPT -{ - return m / day(static_cast(d)); -} - -CONSTCD11 -inline -month_day -operator/(int m, const day& d) NOEXCEPT -{ - return month(static_cast(m)) / d; -} - -CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} - -// month_day_last from operator/() - -CONSTCD11 -inline -month_day_last -operator/(const month& m, last_spec) NOEXCEPT -{ - return month_day_last{m}; -} - -CONSTCD11 -inline -month_day_last -operator/(last_spec, const month& m) NOEXCEPT -{ - return m/last; -} - -CONSTCD11 -inline -month_day_last -operator/(int m, last_spec) NOEXCEPT -{ - return month(static_cast(m))/last; -} - -CONSTCD11 -inline -month_day_last -operator/(last_spec, int m) NOEXCEPT -{ - return m/last; -} - -// month_weekday from operator/() - -CONSTCD11 -inline -month_weekday -operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT -{ - return {m, wdi}; -} - -CONSTCD11 -inline -month_weekday -operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT -{ - return m / wdi; -} - -CONSTCD11 -inline -month_weekday -operator/(int m, const weekday_indexed& wdi) NOEXCEPT -{ - return month(static_cast(m)) / wdi; -} - -CONSTCD11 -inline -month_weekday -operator/(const weekday_indexed& wdi, int m) NOEXCEPT -{ - return m / wdi; -} - -// month_weekday_last from operator/() - -CONSTCD11 -inline -month_weekday_last -operator/(const month& m, const weekday_last& wdl) NOEXCEPT -{ - return {m, wdl}; -} - -CONSTCD11 -inline -month_weekday_last -operator/(const weekday_last& wdl, const month& m) NOEXCEPT -{ - return m / wdl; -} - -CONSTCD11 -inline -month_weekday_last -operator/(int m, const weekday_last& wdl) NOEXCEPT -{ - return month(static_cast(m)) / wdl; -} - -CONSTCD11 -inline -month_weekday_last -operator/(const weekday_last& wdl, int m) NOEXCEPT -{ - return m / wdl; -} - -// year_month_day from operator/() - -CONSTCD11 -inline -year_month_day -operator/(const year_month& ym, const day& d) NOEXCEPT -{ - return {ym.year(), ym.month(), d}; -} - -CONSTCD11 -inline -year_month_day -operator/(const year_month& ym, int d) NOEXCEPT -{ - return ym / day(static_cast(d)); -} - -CONSTCD11 -inline -year_month_day -operator/(const year& y, const month_day& md) NOEXCEPT -{ - return y / md.month() / md.day(); -} - -CONSTCD11 -inline -year_month_day -operator/(int y, const month_day& md) NOEXCEPT -{ - return year(y) / md; -} - -CONSTCD11 -inline -year_month_day -operator/(const month_day& md, const year& y) NOEXCEPT -{ - return y / md; -} - -CONSTCD11 -inline -year_month_day -operator/(const month_day& md, int y) NOEXCEPT -{ - return year(y) / md; -} - -// year_month_day_last from operator/() - -CONSTCD11 -inline -year_month_day_last -operator/(const year_month& ym, last_spec) NOEXCEPT -{ - return {ym.year(), month_day_last{ym.month()}}; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const year& y, const month_day_last& mdl) NOEXCEPT -{ - return {y, mdl}; -} - -CONSTCD11 -inline -year_month_day_last -operator/(int y, const month_day_last& mdl) NOEXCEPT -{ - return year(y) / mdl; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const month_day_last& mdl, const year& y) NOEXCEPT -{ - return y / mdl; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const month_day_last& mdl, int y) NOEXCEPT -{ - return year(y) / mdl; -} - -// year_month_weekday from operator/() - -CONSTCD11 -inline -year_month_weekday -operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT -{ - return {ym.year(), ym.month(), wdi}; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const year& y, const month_weekday& mwd) NOEXCEPT -{ - return {y, mwd.month(), mwd.weekday_indexed()}; -} - -CONSTCD11 -inline -year_month_weekday -operator/(int y, const month_weekday& mwd) NOEXCEPT -{ - return year(y) / mwd; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const month_weekday& mwd, const year& y) NOEXCEPT -{ - return y / mwd; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const month_weekday& mwd, int y) NOEXCEPT -{ - return year(y) / mwd; -} - -// year_month_weekday_last from operator/() - -CONSTCD11 -inline -year_month_weekday_last -operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT -{ - return {ym.year(), ym.month(), wdl}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT -{ - return {y, mwdl.month(), mwdl.weekday_last()}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(int y, const month_weekday_last& mwdl) NOEXCEPT -{ - return year(y) / mwdl; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT -{ - return y / mwdl; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const month_weekday_last& mwdl, int y) NOEXCEPT -{ - return year(y) / mwdl; -} - -template -struct fields; - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev = nullptr, - const std::chrono::seconds* offset_sec = nullptr); - -template -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr); - -// time_of_day - -enum {am = 1, pm}; - -namespace detail -{ - -// width::value is the number of fractional decimal digits in 1/n -// width<0>::value and width<1>::value are defined to be 0 -// If 1/n takes more than 18 fractional decimal digits, -// the result is truncated to 19. -// Example: width<2>::value == 1 -// Example: width<3>::value == 19 -// Example: width<4>::value == 2 -// Example: width<10>::value == 1 -// Example: width<1000>::value == 3 -template -struct width -{ - static CONSTDATA unsigned value = 1 + width::value; -}; - -template -struct width -{ - static CONSTDATA unsigned value = 0; -}; - -template -struct static_pow10 -{ -private: - static CONSTDATA std::uint64_t h = static_pow10::value; -public: - static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1); -}; - -template <> -struct static_pow10<0> -{ - static CONSTDATA std::uint64_t value = 1; -}; - -template -struct make_precision -{ - using type = std::chrono::duration::value>>; - static CONSTDATA unsigned width = w; -}; - -template -struct make_precision -{ - using type = std::chrono::duration; - static CONSTDATA unsigned width = 6; -}; - -template ::type::period::den>::value> -class decimal_format_seconds -{ -public: - using rep = typename std::common_type::type::rep; - using precision = typename make_precision::type; - static auto CONSTDATA width = make_precision::width; - -private: - std::chrono::seconds s_; - precision sub_s_; - -public: - CONSTCD11 decimal_format_seconds() - : s_() - , sub_s_() - {} - - CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT - : s_(std::chrono::duration_cast(d)) - , sub_s_(std::chrono::duration_cast(d - s_)) - {} - - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} - CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return s_ + sub_s_; - } - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - using namespace std::chrono; - return sub_s_ < std::chrono::seconds{1} && s_ < minutes{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const decimal_format_seconds& x) - { - date::detail::save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << x.s_.count() << - std::use_facet>(os.getloc()).decimal_point(); - os.width(width); - os << static_cast(x.sub_s_.count()); - return os; - } -}; - -template -class decimal_format_seconds -{ - static CONSTDATA unsigned w = 0; -public: - using rep = typename std::common_type::type::rep; - using precision = std::chrono::duration; - static auto CONSTDATA width = make_precision::width; -private: - - std::chrono::seconds s_; - -public: - CONSTCD11 decimal_format_seconds() : s_() {} - CONSTCD11 explicit decimal_format_seconds(const precision& s) NOEXCEPT - : s_(s) - {} - - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} - CONSTCD14 precision to_duration() const NOEXCEPT {return s_;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - using namespace std::chrono; - return s_ < minutes{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const decimal_format_seconds& x) - { - date::detail::save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << x.s_.count(); - return os; - } -}; - -enum class classify -{ - not_valid, - hour, - minute, - second, - subsecond -}; - -template -struct classify_duration -{ - static CONSTDATA classify value = - std::is_convertible::value - ? classify::hour : - std::is_convertible::value - ? classify::minute : - std::is_convertible::value - ? classify::second : - std::chrono::treat_as_floating_point::value - ? classify::not_valid : - classify::subsecond; -}; - -template -inline -CONSTCD11 -typename std::enable_if - < - std::numeric_limits::is_signed, - std::chrono::duration - >::type -abs(std::chrono::duration d) -{ - return d >= d.zero() ? d : -d; -} - -template -inline -CONSTCD11 -typename std::enable_if - < - !std::numeric_limits::is_signed, - std::chrono::duration - >::type -abs(std::chrono::duration d) -{ - return d; -} - -class time_of_day_base -{ -protected: - std::chrono::hours h_; - unsigned char mode_; - bool neg_; - - enum {is24hr}; - - CONSTCD11 time_of_day_base() NOEXCEPT - : h_(0) - , mode_(static_cast(is24hr)) - , neg_(false) - {} - - - CONSTCD11 time_of_day_base(std::chrono::hours h, bool neg, unsigned m) NOEXCEPT - : h_(detail::abs(h)) - , mode_(static_cast(m)) - , neg_(neg) - {} - - CONSTCD14 void make24() NOEXCEPT; - CONSTCD14 void make12() NOEXCEPT; - - CONSTCD14 std::chrono::hours to24hr() const; - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return !neg_ && h_ < days{1}; - } -}; - -CONSTCD14 -inline -std::chrono::hours -time_of_day_base::to24hr() const -{ - auto h = h_; - if (mode_ == am || mode_ == pm) - { - CONSTDATA auto h12 = std::chrono::hours(12); - if (mode_ == pm) - { - if (h != h12) - h = h + h12; - } - else if (h == h12) - h = std::chrono::hours(0); - } - return h; -} - -CONSTCD14 -inline -void -time_of_day_base::make24() NOEXCEPT -{ - h_ = to24hr(); - mode_ = is24hr; -} - -CONSTCD14 -inline -void -time_of_day_base::make12() NOEXCEPT -{ - if (mode_ == is24hr) - { - CONSTDATA auto h12 = std::chrono::hours(12); - if (h_ >= h12) - { - if (h_ > h12) - h_ = h_ - h12; - mode_ = pm; - } - else - { - if (h_ == std::chrono::hours(0)) - h_ = h12; - mode_ = am; - } - } -} - -template ::value> -class time_of_day_storage; - -template -class time_of_day_storage, detail::classify::hour> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - -public: - using precision = std::chrono::hours; - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - CONSTCD11 time_of_day_storage() NOEXCEPT = default; -#else - CONSTCD11 time_of_day_storage() = default; -#endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */ - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours since_midnight) NOEXCEPT - : base(since_midnight, since_midnight < std::chrono::hours{0}, is24hr) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, unsigned md) NOEXCEPT - : base(h, h < std::chrono::hours{0}, md) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr(); - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_stream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count(); - switch (t.mode_) - { - case time_of_day_storage::is24hr: - os << "00"; - break; - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } -}; - -template -class time_of_day_storage, detail::classify::minute> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - - std::chrono::minutes m_; - -public: - using precision = std::chrono::minutes; - - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::minutes since_midnight) NOEXCEPT - : base(std::chrono::duration_cast(since_midnight), - since_midnight < std::chrono::minutes{0}, is24hr) - , m_(detail::abs(since_midnight) - h_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_stream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count(); - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } -}; - -template -class time_of_day_storage, detail::classify::second> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - using dfs = decimal_format_seconds; - - std::chrono::minutes m_; - dfs s_; - -public: - using precision = std::chrono::seconds; - - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - , s_() - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::seconds since_midnight) NOEXCEPT - : base(std::chrono::duration_cast(since_midnight), - since_midnight < std::chrono::seconds{0}, is24hr) - , m_(std::chrono::duration_cast(detail::abs(since_midnight) - h_)) - , s_(detail::abs(since_midnight) - h_ - m_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - std::chrono::seconds s, unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - , s_(s) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + s_.to_duration() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1} && - s_.in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_stream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count() << ':' << t.s_; - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } - - template - friend - std::basic_ostream& - date::to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec); - - template - friend - std::basic_istream& - date::from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, - std::basic_string* abbrev, std::chrono::minutes* offset); -}; - -template -class time_of_day_storage, detail::classify::subsecond> - : private detail::time_of_day_base -{ -public: - using Duration = std::chrono::duration; - using dfs = decimal_format_seconds::type>; - using precision = typename dfs::precision; - -private: - using base = detail::time_of_day_base; - - std::chrono::minutes m_; - dfs s_; - -public: - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - , s_() - {} - - CONSTCD11 explicit time_of_day_storage(Duration since_midnight) NOEXCEPT - : base(date::trunc(since_midnight), - since_midnight < Duration{0}, is24hr) - , m_(date::trunc(detail::abs(since_midnight) - h_)) - , s_(detail::abs(since_midnight) - h_ - m_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - std::chrono::seconds s, precision sub_s, - unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - , s_(s + sub_s) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} - CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + s_.to_duration() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1} && - s_.in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_stream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count() << ':' << t.s_; - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } - - template - friend - std::basic_ostream& - date::to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec); - - template - friend - std::basic_istream& - date::from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, - std::basic_string* abbrev, std::chrono::minutes* offset); -}; - -} // namespace detail - -template -class time_of_day - : public detail::time_of_day_storage -{ - using base = detail::time_of_day_storage; -public: -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - CONSTCD11 time_of_day() NOEXCEPT = default; -#else - CONSTCD11 time_of_day() = default; -#endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */ - - CONSTCD11 explicit time_of_day(Duration since_midnight) NOEXCEPT - : base(since_midnight) - {} - - template - CONSTCD11 - explicit time_of_day(Arg0&& arg0, Arg1&& arg1, Args&& ...args) NOEXCEPT - : base(std::forward(arg0), std::forward(arg1), std::forward(args)...) - {} -}; - -template ::value>::type> -CONSTCD11 -inline -time_of_day> -make_time(const std::chrono::duration& d) -{ - return time_of_day>(d); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, unsigned md) -{ - return time_of_day(h, md); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - unsigned md) -{ - return time_of_day(h, m, md); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - const std::chrono::seconds& s, unsigned md) -{ - return time_of_day(h, m, s, md); -} - -template >::value>::type> -CONSTCD11 -inline -time_of_day> -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - const std::chrono::seconds& s, const std::chrono::duration& sub_s, - unsigned md) -{ - return time_of_day>(h, m, s, sub_s, md); -} - -template -inline -typename std::enable_if -< - !std::chrono::treat_as_floating_point::value && - std::ratio_less::value - , std::basic_ostream& ->::type -operator<<(std::basic_ostream& os, const sys_time& tp) -{ - auto const dp = date::floor(tp); - return os << year_month_day(dp) << ' ' << make_time(tp-dp); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const sys_days& dp) -{ - return os << year_month_day(dp); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const local_time& ut) -{ - return (os << sys_time{ut.time_since_epoch()}); -} - -// to_stream - -template -struct fields -{ - year_month_day ymd{year{0}/0/0}; - weekday wd{7u}; - time_of_day tod{}; - - fields() = default; - - fields(year_month_day ymd_) : ymd(ymd_) {} - fields(weekday wd_) : wd(wd_) {} - fields(time_of_day tod_) : tod(tod_) {} - - fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {} - fields(year_month_day ymd_, time_of_day tod_) : ymd(ymd_), tod(tod_) {} - - fields(weekday wd_, time_of_day tod_) : wd(wd_), tod(tod_) {} - - fields(year_month_day ymd_, weekday wd_, time_of_day tod_) - : ymd(ymd_) - , wd(wd_) - , tod(tod_) - {} -}; - -namespace detail -{ - -template -unsigned -extract_weekday(std::basic_ostream& os, const fields& fds) -{ - if (!fds.ymd.ok() && !fds.wd.ok()) - { - // fds does not contain a valid weekday - os.setstate(std::ios::failbit); - return 7; - } - unsigned wd; - if (fds.ymd.ok()) - { - wd = static_cast(weekday{fds.ymd}); - if (fds.wd.ok() && wd != static_cast(fds.wd)) - { - // fds.ymd and fds.wd are inconsistent - os.setstate(std::ios::failbit); - return 7; - } - } - else - wd = static_cast(fds.wd); - return wd; -} - -template -unsigned -extract_month(std::basic_ostream& os, const fields& fds) -{ - if (!fds.ymd.month().ok()) - { - // fds does not contain a valid month - os.setstate(std::ios::failbit); - return 0; - } - return static_cast(fds.ymd.month()); -} - -} // namespace detail - -#if ONLY_C_LOCALE - -namespace detail -{ - -inline -std::pair -weekday_names() -{ - using namespace std; - static const string nm[] = - { - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat" - }; - return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -inline -std::pair -month_names() -{ - using namespace std; - static const string nm[] = - { - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - }; - return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -inline -std::pair -ampm_names() -{ - using namespace std; - static const string nm[] = - { - "AM", - "PM" - }; - return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -template -FwdIter -scan_keyword(std::basic_istream& is, FwdIter kb, FwdIter ke) -{ - using namespace std; - size_t nkw = static_cast(std::distance(kb, ke)); - const unsigned char doesnt_match = '\0'; - const unsigned char might_match = '\1'; - const unsigned char does_match = '\2'; - unsigned char statbuf[100]; - unsigned char* status = statbuf; - unique_ptr stat_hold(0, free); - if (nkw > sizeof(statbuf)) - { - status = (unsigned char*)malloc(nkw); - if (status == nullptr) - throw bad_alloc(); - stat_hold.reset(status); - } - size_t n_might_match = nkw; // At this point, any keyword might match - size_t n_does_match = 0; // but none of them definitely do - // Initialize all statuses to might_match, except for "" keywords are does_match - unsigned char* st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (!ky->empty()) - *st = might_match; - else - { - *st = does_match; - --n_might_match; - ++n_does_match; - } - } - // While there might be a match, test keywords against the next CharT - for (size_t indx = 0; is && n_might_match > 0; ++indx) - { - // Peek at the next CharT but don't consume it - auto ic = is.peek(); - if (ic == EOF) - { - is.setstate(ios::eofbit); - break; - } - auto c = static_cast(toupper(ic)); - bool consume = false; - // For each keyword which might match, see if the indx character is c - // If a match if found, consume c - // If a match is found, and that is the last character in the keyword, - // then that keyword matches. - // If the keyword doesn't match this character, then change the keyword - // to doesn't match - st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (*st == might_match) - { - if (c == static_cast(toupper((*ky)[indx]))) - { - consume = true; - if (ky->size() == indx+1) - { - *st = does_match; - --n_might_match; - ++n_does_match; - } - } - else - { - *st = doesnt_match; - --n_might_match; - } - } - } - // consume if we matched a character - if (consume) - { - (void)is.get(); - // If we consumed a character and there might be a matched keyword that - // was marked matched on a previous iteration, then such keywords - // are now marked as not matching. - if (n_might_match + n_does_match > 1) - { - st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (*st == does_match && ky->size() != indx+1) - { - *st = doesnt_match; - --n_does_match; - } - } - } - } - } - // We've exited the loop because we hit eof and/or we have no more "might matches". - // Return the first matching result - for (st = status; kb != ke; ++kb, ++st) - if (*st == does_match) - break; - if (kb == ke) - is.setstate(ios_base::failbit); - return kb; -} - -} // namespace detail - -#endif // ONLY_C_LOCALE - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec) -{ - using namespace std; - using namespace std::chrono; - using namespace detail; - tm tm{}; -#if !ONLY_C_LOCALE - auto& facet = use_facet>(os.getloc()); -#endif - const CharT* command = nullptr; - CharT modified = CharT{}; - for (; *fmt; ++fmt) - { - switch (*fmt) - { - case 'a': - case 'A': - if (command) - { - if (modified == CharT{}) - { - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else // ONLY_C_LOCALE - os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')]; -#endif // ONLY_C_LOCALE - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'b': - case 'B': - case 'h': - if (command) - { - if (modified == CharT{}) - { - tm.tm_mon = static_cast(extract_month(os, fds)) - 1; -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else // ONLY_C_LOCALE - os << month_names().first[tm.tm_mon+12*(*fmt == 'b')]; -#endif // ONLY_C_LOCALE - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'c': - case 'x': - if (command) - { - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { -#if !ONLY_C_LOCALE - tm = std::tm{}; - auto const& ymd = fds.ymd; - auto ld = local_days(ymd); - tm.tm_sec = static_cast(fds.tod.seconds().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_hour = static_cast(fds.tod.hours().count()); - tm.tm_mday = static_cast(static_cast(ymd.day())); - tm.tm_mon = static_cast(extract_month(os, fds) - 1); - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - CharT f[3] = {'%'}; - auto fe = begin(f) + 1; - if (modified == CharT{'E'}) - *fe++ = modified; - *fe++ = *fmt; - facet.put(os, os, os.fill(), &tm, begin(f), fe); -#else // ONLY_C_LOCALE - if (*fmt == 'c') - { - auto wd = static_cast(extract_weekday(os, fds)); - os << weekday_names().first[static_cast(wd)+7] - << ' '; - os << month_names().first[extract_month(os, fds)-1+12] << ' '; - auto d = static_cast(static_cast(fds.ymd.day())); - if (d < 10) - os << ' '; - os << d << ' ' - << make_time(duration_cast(fds.tod.to_duration())) - << ' ' << fds.ymd.year(); - - } - else // *fmt == 'x' - { - auto const& ymd = fds.ymd; - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(ymd.month()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.day()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.year()) % 100; - } -#endif // ONLY_C_LOCALE - } - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'C': - if (command) - { - auto y = static_cast(fds.ymd.year()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (y >= 0) - { - os.width(2); - os << y/100; - } - else - { - os << CharT{'-'}; - os.width(2); - os << -(y-99)/100; - } -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'E'}) - { - tm.tm_year = y - 1900; - CharT f[3] = {'%', 'E', 'C'}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'd': - case 'e': - if (command) - { - auto d = static_cast(static_cast(fds.ymd.day())); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - save_stream _(os); - if (*fmt == CharT{'d'}) - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << d; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - tm.tm_mday = d; - CharT f[3] = {'%', 'O', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'D': - if (command) - { - if (modified == CharT{}) - { - auto const& ymd = fds.ymd; - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(ymd.month()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.day()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.year()) % 100; - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'F': - if (command) - { - if (modified == CharT{}) - { - auto const& ymd = fds.ymd; - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(4); - os << static_cast(ymd.year()) << CharT{'-'}; - os.width(2); - os << static_cast(ymd.month()) << CharT{'-'}; - os.width(2); - os << static_cast(ymd.day()); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'g': - case 'G': - if (command) - { - if (modified == CharT{}) - { - auto ld = local_days(fds.ymd); - auto y = year_month_day{ld + days{3}}.year(); - auto start = local_days((y - years{1})/date::dec/thu[last]) + (mon-thu); - if (ld < start) - --y; - if (*fmt == CharT{'G'}) - os << y; - else - { - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << std::abs(static_cast(y)) % 100; - } - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'H': - case 'I': - if (command) - { - auto hms = fds.tod; -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - if (*fmt == CharT{'I'}) - hms.make12(); - if (hms.hours() < hours{10}) - os << CharT{'0'}; - os << hms.hours().count(); -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_hour = static_cast(hms.hours().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'j': - if (command) - { - if (modified == CharT{}) - { - auto ld = local_days(fds.ymd); - auto y = fds.ymd.year(); - auto doy = ld - local_days(y/jan/1) + days{1}; - save_stream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(3); - os << doy.count(); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'm': - if (command) - { - auto m = static_cast(fds.ymd.month()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - if (m < 10) - os << CharT{'0'}; - os << m; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_mon = static_cast(m-1); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'M': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - if (fds.tod.minutes() < minutes{10}) - os << CharT{'0'}; - os << fds.tod.minutes().count(); -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_min = static_cast(fds.tod.minutes().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'n': - if (command) - { - if (modified == CharT{}) - os << CharT{'\n'}; - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'p': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { - const CharT f[] = {'%', *fmt}; - tm.tm_hour = static_cast(fds.tod.hours().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#else - if (fds.tod.hours() < hours{12}) - os << ampm_names().first[0]; - else - os << ampm_names().first[1]; -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'r': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { - const CharT f[] = {'%', *fmt}; - tm.tm_hour = static_cast(fds.tod.hours().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_sec = static_cast(fds.tod.seconds().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#else - time_of_day tod(duration_cast(fds.tod.to_duration())); - tod.make12(); - save_stream _(os); - os.fill('0'); - os.width(2); - os << tod.hours().count() << CharT{':'}; - os.width(2); - os << tod.minutes().count() << CharT{':'}; - os.width(2); - os << tod.seconds().count() << CharT{' '}; - tod.make24(); - if (tod.hours() < hours{12}) - os << ampm_names().first[0]; - else - os << ampm_names().first[1]; -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'R': - if (command) - { - if (modified == CharT{}) - { - if (fds.tod.hours() < hours{10}) - os << CharT{'0'}; - os << fds.tod.hours().count() << CharT{':'}; - if (fds.tod.minutes() < minutes{10}) - os << CharT{'0'}; - os << fds.tod.minutes().count(); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'S': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - os << fds.tod.s_; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_sec = static_cast(fds.tod.s_.seconds().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 't': - if (command) - { - if (modified == CharT{}) - os << CharT{'\t'}; - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'T': - if (command) - { - if (modified == CharT{}) - { - os << fds.tod; - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'u': - if (command) - { - auto wd = extract_weekday(os, fds); - if (os.fail()) - return os; -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - os << (wd != 0 ? wd : 7u); -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_wday = static_cast(wd); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'U': - if (command) - { - auto const& ymd = fds.ymd; - auto ld = local_days(ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - auto st = local_days(sun[1]/jan/ymd.year()); - if (ld < st) - os << CharT{'0'} << CharT{'0'}; - else - { - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; - } - #if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'V': - if (command) - { - auto ld = local_days(fds.ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - auto y = year_month_day{ld + days{3}}.year(); - auto st = local_days((y - years{1})/12/thu[last]) + (mon-thu); - if (ld < st) - { - --y; - st = local_days((y - years{1})/12/thu[last]) + (mon-thu); - } - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - auto const& ymd = fds.ymd; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'w': - if (command) - { - auto wd = extract_weekday(os, fds); - if (os.fail()) - return os; -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - os << wd; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_wday = static_cast(wd); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'W': - if (command) - { - auto const& ymd = fds.ymd; - auto ld = local_days(ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - auto st = local_days(mon[1]/jan/ymd.year()); - if (ld < st) - os << CharT{'0'} << CharT{'0'}; - else - { - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; - } -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'X': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { - tm = std::tm{}; - tm.tm_sec = static_cast(fds.tod.seconds().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_hour = static_cast(fds.tod.hours().count()); - CharT f[3] = {'%'}; - auto fe = begin(f) + 1; - if (modified == CharT{'E'}) - *fe++ = modified; - *fe++ = *fmt; - facet.put(os, os, os.fill(), &tm, begin(f), fe); - } -#else - os << fds.tod; -#endif - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'y': - if (command) - { - auto y = static_cast(fds.ymd.year()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - y = std::abs(y) % 100; - if (y < 10) - os << CharT{'0'}; - os << y; -#if !ONLY_C_LOCALE - } - else - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = y - 1900; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'Y': - if (command) - { - auto y = fds.ymd.year(); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - os << y; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'E'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(y) - 1900; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } - else - { - os << CharT{'%'} << modified << *fmt; - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'z': - if (command) - { - if (offset_sec == nullptr) - { - // Can not format %z with unknown offset - os.setstate(ios::failbit); - return os; - } - auto m = duration_cast(*offset_sec); - auto neg = m < minutes{0}; - m = date::abs(m); - auto h = duration_cast(m); - m -= h; - if (neg) - os << CharT{'-'}; - else - os << CharT{'+'}; - if (h < hours{10}) - os << CharT{'0'}; - os << h.count(); - if (modified != CharT{}) - os << CharT{':'}; - if (m < minutes{10}) - os << CharT{'0'}; - os << m.count(); - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'Z': - if (command) - { - if (modified == CharT{}) - { - if (abbrev == nullptr) - { - // Can not format %Z with unknown time_zone - os.setstate(ios::failbit); - return os; - } - for (auto c : *abbrev) - os << CharT(c); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'E': - case 'O': - if (command) - { - if (modified == CharT{}) - { - modified = *fmt; - } - else - { - os << CharT{'%'} << modified << *fmt; - command = nullptr; - modified = CharT{}; - } - } - else - os << *fmt; - break; - case '%': - if (command) - { - if (modified == CharT{}) - { - os << CharT{'%'}; - command = nullptr; - } - else - { - os << CharT{'%'} << modified << CharT{'%'}; - command = nullptr; - modified = CharT{}; - } - } - else - command = fmt; - break; - default: - if (command) - { - os << CharT{'%'}; - command = nullptr; - } - if (modified != CharT{}) - { - os << modified; - modified = CharT{}; - } - os << *fmt; - break; - } - } - if (command) - os << CharT{'%'}; - if (modified != CharT{}) - os << modified; - return os; -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const year& y) -{ - using CT = std::chrono::seconds; - fields fds{y/0/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const month& m) -{ - using CT = std::chrono::seconds; - fields fds{m/0/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const day& d) -{ - using CT = std::chrono::seconds; - fields fds{d/0/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const weekday& wd) -{ - using CT = std::chrono::seconds; - fields fds{wd}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const year_month& ym) -{ - using CT = std::chrono::seconds; - fields fds{ym/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const month_day& md) -{ - using CT = std::chrono::seconds; - fields fds{md/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const year_month_day& ymd) -{ - using CT = std::chrono::seconds; - fields fds{ymd}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const std::chrono::duration& d) -{ - using Duration = std::chrono::duration; - using CT = typename std::common_type::type; - fields fds{time_of_day{d}}; - return to_stream(os, fmt, fds); -} - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const local_time& tp, const std::string* abbrev = nullptr, - const std::chrono::seconds* offset_sec = nullptr) -{ - using CT = typename std::common_type::type; - auto ld = floor(tp); - fields fds{year_month_day{ld}, time_of_day{tp-local_seconds{ld}}}; - return to_stream(os, fmt, fds, abbrev, offset_sec); -} - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const sys_time& tp) -{ - using namespace std::chrono; - using CT = typename std::common_type::type; - const std::string abbrev("UTC"); - CONSTDATA seconds offset{0}; - auto sd = floor(tp); - fields fds{year_month_day{sd}, time_of_day{tp-sys_seconds{sd}}}; - return to_stream(os, fmt, fds, &abbrev, &offset); -} - -// format - -template -auto -format(const std::locale& loc, const CharT* fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt, tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - os.imbue(loc); - to_stream(os, fmt, tp); - return os.str(); -} - -template -auto -format(const CharT* fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt, tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - to_stream(os, fmt, tp); - return os.str(); -} - -template -auto -format(const std::locale& loc, const std::basic_string& fmt, - const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - os.imbue(loc); - to_stream(os, fmt.c_str(), tp); - return os.str(); -} - -template -auto -format(const std::basic_string& fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - to_stream(os, fmt.c_str(), tp); - return os.str(); -} - -// parse - -namespace detail -{ - -template -bool -read_char(std::basic_istream& is, CharT fmt, std::ios::iostate& err) -{ - auto ic = is.get(); - if (Traits::eq_int_type(ic, Traits::eof()) || - !Traits::eq(Traits::to_char_type(ic), fmt)) - { - err |= std::ios::failbit; - is.setstate(std::ios::failbit); - return false; - } - return true; -} - -template -unsigned -read_unsigned(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - unsigned x = 0; - unsigned count = 0; - while (true) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - break; - auto c = static_cast(Traits::to_char_type(ic)); - if (!('0' <= c && c <= '9')) - break; - (void)is.get(); - ++count; - x = 10*x + static_cast(c - '0'); - if (count == M) - break; - } - if (count < m) - is.setstate(std::ios::failbit); - return x; -} - -template -int -read_signed(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - auto ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if (('0' <= c && c <= '9') || c == '-' || c == '+') - { - if (c == '-' || c == '+') - (void)is.get(); - auto x = static_cast(read_unsigned(is, std::max(m, 1u), M)); - if (!is.fail()) - { - if (c == '-') - x = -x; - return x; - } - } - } - if (m > 0) - is.setstate(std::ios::failbit); - return 0; -} - -template -long double -read_long_double(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - using namespace std; - unsigned count = 0; - auto decimal_point = Traits::to_int_type( - use_facet>(is.getloc()).decimal_point()); - std::string buf; - while (true) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - break; - if (Traits::eq_int_type(ic, decimal_point)) - { - buf += '.'; - decimal_point = Traits::eof(); - is.get(); - } - else - { - auto c = static_cast(Traits::to_char_type(ic)); - if (!('0' <= c && c <= '9')) - break; - buf += c; - (void)is.get(); - } - if (++count == M) - break; - } - if (count < m) - { - is.setstate(std::ios::failbit); - return 0; - } - return std::stold(buf); -} - -struct rs -{ - int& i; - unsigned m; - unsigned M; -}; - -struct ru -{ - int& i; - unsigned m; - unsigned M; -}; - -struct rld -{ - long double& i; - unsigned m; - unsigned M; -}; - -template -void -read(std::basic_istream&) -{ -} - -template -void -read(std::basic_istream& is, CharT a0, Args&& ...args); - -template -void -read(std::basic_istream& is, rs a0, Args&& ...args); - -template -void -read(std::basic_istream& is, ru a0, Args&& ...args); - -template -void -read(std::basic_istream& is, int a0, Args&& ...args); - -template -void -read(std::basic_istream& is, rld a0, Args&& ...args); - -template -void -read(std::basic_istream& is, CharT a0, Args&& ...args) -{ - // No-op if a0 == CharT{} - if (a0 != CharT{}) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - { - is.setstate(std::ios::failbit | std::ios::eofbit); - return; - } - if (!Traits::eq(Traits::to_char_type(ic), a0)) - { - is.setstate(std::ios::failbit); - return; - } - (void)is.get(); - } - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, rs a0, Args&& ...args) -{ - auto x = read_signed(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = x; - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, ru a0, Args&& ...args) -{ - auto x = read_unsigned(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = static_cast(x); - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, int a0, Args&& ...args) -{ - if (a0 != -1) - { - auto u = static_cast(a0); - CharT buf[std::numeric_limits::digits10+2] = {}; - auto e = buf; - do - { - *e++ = CharT(u % 10) + CharT{'0'}; - u /= 10; - } while (u > 0); - std::reverse(buf, e); - for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) - read(is, *p); - } - if (is.rdstate() == std::ios::goodbit) - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, rld a0, Args&& ...args) -{ - auto x = read_long_double(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = x; - read(is, std::forward(args)...); -} - -} // namespace detail; - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, std::basic_string* abbrev, - std::chrono::minutes* offset) -{ - using namespace std; - using namespace std::chrono; - typename basic_istream::sentry ok{is, true}; - if (ok) - { -#if !ONLY_C_LOCALE - auto& f = use_facet>(is.getloc()); - std::tm tm{}; -#endif - std::basic_string temp_abbrev; - minutes temp_offset{}; - const CharT* command = nullptr; - auto modified = CharT{}; - auto width = -1; - CONSTDATA int not_a_year = numeric_limits::min(); - int Y = not_a_year; - CONSTDATA int not_a_century = not_a_year / 100; - int C = not_a_century; - CONSTDATA int not_a_2digit_year = 100; - int y = not_a_2digit_year; - int m{}; - int d{}; - int j{}; - CONSTDATA int not_a_weekday = 7; - int wd = not_a_weekday; - CONSTDATA int not_a_hour_12_value = 0; - int I = not_a_hour_12_value; - hours h{}; - minutes min{}; - Duration s{}; - int g = not_a_2digit_year; - int G = not_a_year; - CONSTDATA int not_a_week_num = 100; - int V = not_a_week_num; - int U = not_a_week_num; - int W = not_a_week_num; - using detail::read; - using detail::rs; - using detail::ru; - using detail::rld; - for (; *fmt && is.rdstate() == std::ios::goodbit; ++fmt) - { - switch (*fmt) - { - case 'a': - case 'A': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - wd = tm.tm_wday; - is.setstate(err); -#else - auto nm = detail::weekday_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (!is.fail()) - wd = i % 7; -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'b': - case 'B': - case 'h': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - m = tm.tm_mon + 1; - is.setstate(err); -#else - auto nm = detail::month_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (!is.fail()) - m = i % 12 + 1; -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'c': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - Y = tm.tm_year + 1900; - m = tm.tm_mon + 1; - d = tm.tm_mday; - h = hours{tm.tm_hour}; - min = minutes{tm.tm_min}; - s = duration_cast(seconds{tm.tm_sec}); - } - is.setstate(err); -#else - auto nm = detail::weekday_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (is.fail()) - goto broken; - wd = i % 7; - ws(is); - nm = detail::month_names(); - i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (is.fail()) - goto broken; - m = i % 12 + 1; - ws(is); - read(is, rs{d, 1, 2}); - if (is.fail()) - goto broken; - ws(is); - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int H; - int M; - long double S; - read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2}, - CharT{':'}, rld{S, 1, w}); - if (is.fail()) - goto broken; - h = hours{H}; - min = minutes{M}; - s = round(duration{S}); - ws(is); - read(is, rs{Y, 1, 4u}); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'x': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - Y = tm.tm_year + 1900; - m = tm.tm_mon + 1; - d = tm.tm_mday; - } - is.setstate(err); -#else - read(is, ru{m, 1, 2}, CharT{'/'}, ru{d, 1, 2}, CharT{'/'}, - rs{y, 1, 2}); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'X': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - h = hours{tm.tm_hour}; - min = minutes{tm.tm_min}; - s = duration_cast(seconds{tm.tm_sec}); - } - is.setstate(err); -#else - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int H; - int M; - long double S; - read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2}, - CharT{':'}, rld{S, 1, w}); - if (!is.fail()) - { - h = hours{H}; - min = minutes{M}; - s = round(duration{S}); - } -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'C': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - read(is, rs{C, 1, width == -1 ? 2u : static_cast(width)}); -#if !ONLY_C_LOCALE - } - else - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - auto tY = tm.tm_year + 1900; - C = (tY >= 0 ? tY : tY-99) / 100; - } - is.setstate(err); - } -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'D': - if (command) - { - if (modified == CharT{}) - read(is, ru{m, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, - ru{d, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, - rs{y, 1, 2}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'F': - if (command) - { - if (modified == CharT{}) - read(is, rs{Y, 1, width == -1 ? 4u : static_cast(width)}, - CharT{'-'}, ru{m, 1, 2}, CharT{'-'}, ru{d, 1, 2}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'd': - case 'e': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - read(is, rs{d, 1, width == -1 ? 2u : static_cast(width)}); -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - command = nullptr; - width = -1; - modified = CharT{}; - if ((err & ios::failbit) == 0) - d = tm.tm_mday; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'H': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - int H; - read(is, ru{H, 1, width == -1 ? 2u : static_cast(width)}); - if (!is.fail()) - h = hours{H}; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - h = hours{tm.tm_hour}; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'I': - if (command) - { - if (modified == CharT{}) - { - // reads in an hour into I, but most be in [1, 12] - read(is, rs{I, 1, width == -1 ? 2u : static_cast(width)}); - if (I != not_a_hour_12_value) - { - if (!(1 <= I && I <= 12)) - { - I = not_a_hour_12_value; - goto broken; - } - } - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'j': - if (command) - { - if (modified == CharT{}) - read(is, ru{j, 1, width == -1 ? 3u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'M': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - int M; - read(is, ru{M, 1, width == -1 ? 2u : static_cast(width)}); - if (!is.fail()) - min = minutes{M}; -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - min = minutes{tm.tm_min}; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'm': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - read(is, rs{m, 1, width == -1 ? 2u : static_cast(width)}); -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - m = tm.tm_mon + 1; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'n': - case 't': - if (command) - { - // %n matches a single white space character - // %t matches 0 or 1 white space characters - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - { - ios_base::iostate err = ios_base::eofbit; - if (*fmt == 'n') - err |= ios_base::failbit; - is.setstate(err); - break; - } - if (isspace(ic)) - { - (void)is.get(); - } - else if (*fmt == 'n') - is.setstate(ios_base::failbit); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'p': - // Error if haven't yet seen %I - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { - if (I == not_a_hour_12_value) - goto broken; - tm = std::tm{}; - tm.tm_hour = I; - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if (err & ios::failbit) - goto broken; - h = hours{tm.tm_hour}; - I = not_a_hour_12_value; - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#else - if (I == not_a_hour_12_value) - goto broken; - auto nm = detail::ampm_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (is.fail()) - goto broken; - h = hours{I}; - if (i == 1) - { - if (h != hours{12}) - h += hours{12}; - } - else if (h == hours{12}) - h = hours{0}; - I = not_a_hour_12_value; -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - - break; - case 'r': - if (command) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - h = hours{tm.tm_hour}; - min = minutes{tm.tm_min}; - s = duration_cast(seconds{tm.tm_sec}); - } - is.setstate(err); -#else - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int H; - int M; - long double S; - read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2}, - CharT{':'}, rld{S, 1, w}); - if (is.fail() || !(1 <= H && H <= 12)) - goto broken; - ws(is); - auto nm = detail::ampm_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (is.fail()) - goto broken; - h = hours{H}; - if (i == 1) - { - if (h != hours{12}) - h += hours{12}; - } - else if (h == hours{12}) - h = hours{0}; - min = minutes{M}; - s = round(duration{S}); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'R': - if (command) - { - if (modified == CharT{}) - { - int H, M; - read(is, ru{H, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'}, - ru{M, 1, 2}, CharT{'\0'}); - if (!is.fail()) - { - h = hours{H}; - min = minutes{M}; - } - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'S': - if (command) - { - #if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - long double S; - read(is, rld{S, 1, width == -1 ? w : static_cast(width)}); - if (!is.fail()) - s = round(duration{S}); -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - s = duration_cast(seconds{tm.tm_sec}); - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'T': - if (command) - { - if (modified == CharT{}) - { - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int H; - int M; - long double S; - read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2}, - CharT{':'}, rld{S, 1, w}); - if (!is.fail()) - { - h = hours{H}; - min = minutes{M}; - s = round(duration{S}); - } - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'Y': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - read(is, rs{Y, 1, width == -1 ? 4u : static_cast(width)}); -#if !ONLY_C_LOCALE - else if (modified == CharT{'E'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - Y = tm.tm_year + 1900; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'y': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - read(is, ru{y, 1, width == -1 ? 2u : static_cast(width)}); -#if !ONLY_C_LOCALE - else - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - Y = tm.tm_year + 1900; - is.setstate(err); - } -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'g': - if (command) - { - if (modified == CharT{}) - read(is, ru{g, 1, width == -1 ? 2u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'G': - if (command) - { - if (modified == CharT{}) - read(is, rs{G, 1, width == -1 ? 4u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'U': - if (command) - { - if (modified == CharT{}) - read(is, ru{U, 1, width == -1 ? 2u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'V': - if (command) - { - if (modified == CharT{}) - read(is, ru{V, 1, width == -1 ? 2u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'W': - if (command) - { - if (modified == CharT{}) - read(is, ru{W, 1, width == -1 ? 2u : static_cast(width)}); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'u': - case 'w': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - read(is, ru{wd, 1, width == -1 ? 1u : static_cast(width)}); - if (!is.fail() && *fmt == 'u') - { - if (wd == 7) - wd = 0; - else if (wd == 0) - wd = 7; - } -#if !ONLY_C_LOCALE - } - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - wd = tm.tm_wday; - is.setstate(err); - } - else - read(is, CharT{'%'}, width, modified, *fmt); -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'E': - case 'O': - if (command) - { - if (modified == CharT{}) - { - modified = *fmt; - } - else - { - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - } - else - read(is, *fmt); - break; - case '%': - if (command) - { - if (modified == CharT{}) - read(is, *fmt); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - command = fmt; - break; - case 'z': - if (command) - { - int H, M; - if (modified == CharT{}) - { - read(is, rs{H, 2, 2}); - if (!is.fail()) - temp_offset = hours{H}; - if (is.good()) - { - auto ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if ('0' <= c && c <= '9') - { - read(is, ru{M, 2, 2}); - if (!is.fail()) - temp_offset += minutes{ H < 0 ? -M : M }; - } - } - } - } - else - { - read(is, rs{H, 1, 2}); - if (!is.fail()) - temp_offset = hours{H}; - if (is.good()) - { - auto ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if (c == ':') - { - (void)is.get(); - read(is, ru{M, 2, 2}); - if (!is.fail()) - temp_offset += minutes{ H < 0 ? -M : M }; - } - } - } - } - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'Z': - if (command) - { - if (modified == CharT{}) - { - if (!temp_abbrev.empty()) - is.setstate(ios::failbit); - else - { - while (is.rdstate() == std::ios::goodbit) - { - auto i = is.rdbuf()->sgetc(); - if (Traits::eq_int_type(i, Traits::eof())) - { - is.setstate(ios::eofbit); - break; - } - auto wc = Traits::to_char_type(i); - auto c = static_cast(wc); - // is c a valid time zone name or abbreviation character? - if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) || - c == '_' || c == '/' || c == '-' || c == '+')) - break; - temp_abbrev.push_back(c); - is.rdbuf()->sbumpc(); - } - if (temp_abbrev.empty()) - is.setstate(ios::failbit); - } - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - default: - if (command) - { - if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') - { - width = static_cast(*fmt) - '0'; - while ('0' <= fmt[1] && fmt[1] <= '9') - width = 10*width + static_cast(*++fmt) - '0'; - } - else - { - if (modified == CharT{}) - read(is, CharT{'%'}, width, *fmt); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - } - else // !command - { - if (isspace(*fmt)) - ws(is); // space matches 0 or more white space characters - else - read(is, *fmt); - } - break; - } - } - // is.rdstate() != ios::goodbit || *fmt == CharT{} - if (is.rdstate() == ios::goodbit && command) - { - if (modified == CharT{}) - read(is, CharT{'%'}, width); - else - read(is, CharT{'%'}, width, modified); - } - if (is.rdstate() != ios::goodbit && *fmt != CharT{} && !is.fail()) - is.setstate(ios::failbit); - if (!is.fail()) - { - if (y != not_a_2digit_year) - { - // Convert y and an optional C to Y - if (!(0 <= y && y <= 99)) - goto broken; - if (C == not_a_century) - { - if (Y == not_a_year) - { - if (y >= 69) - C = 19; - else - C = 20; - } - else - { - C = (Y >= 0 ? Y : Y-100) / 100; - } - } - int tY; - if (C >= 0) - tY = 100*C + y; - else - tY = 100*(C+1) - (y == 0 ? 100 : y); - if (Y != not_a_year && Y != tY) - goto broken; - Y = tY; - } - if (g != not_a_2digit_year) - { - // Convert g and an optional C to G - if (!(0 <= g && g <= 99)) - goto broken; - if (C == not_a_century) - { - if (G == not_a_year) - { - if (g >= 69) - C = 19; - else - C = 20; - } - else - { - C = (G >= 0 ? G : G-100) / 100; - } - } - int tG; - if (C >= 0) - tG = 100*C + g; - else - tG = 100*(C+1) - (g == 0 ? 100 : g); - if (G != not_a_year && G != tG) - goto broken; - G = tG; - } - if (G != not_a_year) - { - // Convert G, V and wd to Y, m and d - if (V == not_a_week_num || wd == not_a_weekday) - goto broken; - auto ymd = year_month_day{local_days(year{G-1}/dec/thu[last]) + - (mon-thu) + weeks{V-1} + - (weekday{static_cast(wd)}-mon)}; - if (Y == not_a_year) - Y = static_cast(ymd.year()); - else if (year{Y} != ymd.year()) - goto broken; - if (m == 0) - m = static_cast(static_cast(ymd.month())); - else if (month(static_cast(m)) != ymd.month()) - goto broken; - if (d == 0) - d = static_cast(static_cast(ymd.day())); - else if (day(static_cast(d)) != ymd.day()) - goto broken; - } - if (j != 0 && Y != not_a_year) - { - auto ymd = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; - if (m == 0) - m = static_cast(static_cast(ymd.month())); - else if (month(static_cast(m)) != ymd.month()) - goto broken; - if (d == 0) - d = static_cast(static_cast(ymd.day())); - else if (day(static_cast(d)) != ymd.day()) - goto broken; - } - if (U != not_a_week_num && Y != not_a_year) - { - if (wd == not_a_weekday) - goto broken; - sys_days sd; - if (U == 0) - sd = year{Y-1}/dec/weekday{static_cast(wd)}[last]; - else - sd = sys_days(year{Y}/jan/sun[1]) + weeks{U-1} + - (weekday{static_cast(wd)} - sun); - year_month_day ymd = sd; - if (year{Y} != ymd.year()) - goto broken; - if (m == 0) - m = static_cast(static_cast(ymd.month())); - else if (month(static_cast(m)) != ymd.month()) - goto broken; - if (d == 0) - d = static_cast(static_cast(ymd.day())); - else if (day(static_cast(d)) != ymd.day()) - goto broken; - } - if (W != not_a_week_num && Y != not_a_year) - { - if (wd == not_a_weekday) - goto broken; - sys_days sd; - if (W == 0) - sd = year{Y-1}/dec/weekday{static_cast(wd)}[last]; - else - sd = sys_days(year{Y}/jan/mon[1]) + weeks{W-1} + - (weekday{static_cast(wd)} - mon); - year_month_day ymd = sd; - if (year{Y} != ymd.year()) - goto broken; - if (m == 0) - m = static_cast(static_cast(ymd.month())); - else if (month(static_cast(m)) != ymd.month()) - goto broken; - if (d == 0) - d = static_cast(static_cast(ymd.day())); - else if (day(static_cast(d)) != ymd.day()) - goto broken; - } - if (Y < static_cast(year::min()) || Y > static_cast(year::max())) - Y = not_a_year; - auto ymd = year{Y}/m/d; - if (wd != not_a_weekday && ymd.ok()) - { - if (weekday{static_cast(wd)} != weekday(ymd)) - goto broken; - } - fds.ymd = ymd; - fds.tod = time_of_day{h}; - fds.tod.m_ = min; - fds.tod.s_ = detail::decimal_format_seconds{s}; - if (wd != not_a_weekday) - fds.wd = weekday{static_cast(wd)}; - if (abbrev != nullptr) - *abbrev = std::move(temp_abbrev); - if (offset != nullptr) - *offset = temp_offset; - } - return is; - } -broken: - is.setstate(ios_base::failbit); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, year& y, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.year().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - y = fds.ymd.year(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, month& m, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - m = fds.ymd.month(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, day& d, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.day().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - d = fds.ymd.day(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, weekday& wd, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.wd.ok()) - is.setstate(ios::failbit); - if (!is.fail()) - wd = fds.wd; - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, year_month& ym, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - ym = fds.ymd.year()/fds.ymd.month(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, month_day& md, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - md = fds.ymd.month()/fds.ymd.day(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - year_month_day& ymd, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.ok()) - is.setstate(ios::failbit); - if (!is.fail()) - ymd = fds.ymd; - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - sys_time& tp, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - minutes offset_local{}; - auto offptr = offset ? offset : &offset_local; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offptr); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); - if (!is.fail()) - tp = round(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - local_time& tp, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); - if (!is.fail()) - tp = round(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - std::chrono::duration& d, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using Duration = std::chrono::duration; - using CT = typename common_type::type; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!is.fail()) - d = duration_cast(fds.tod.to_duration()); - return is; -} - -template , - class Alloc = std::allocator> -struct parse_manip -{ - const std::basic_string format_; - Parsable& tp_; - std::basic_string* abbrev_; - std::chrono::minutes* offset_; - -public: - parse_manip(std::basic_string format, Parsable& tp, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) - : format_(std::move(format)) - , tp_(tp) - , abbrev_(abbrev) - , offset_(offset) - {} - -}; - -template -std::basic_istream& -operator>>(std::basic_istream& is, - const parse_manip& x) -{ - return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp), - parse_manip{format, tp}) -{ - return {format, tp}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, &abbrev), - parse_manip{format, tp, &abbrev}) -{ - return {format, tp, &abbrev}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, nullptr, &offset), - parse_manip{format, tp, nullptr, &offset}) -{ - return {format, tp, nullptr, &offset}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, &abbrev, &offset), - parse_manip{format, tp, &abbrev, &offset}) -{ - return {format, tp, &abbrev, &offset}; -} - -// const CharT* formats - -template -inline -auto -parse(const CharT* format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), format, tp), - parse_manip{format, tp}) -{ - return {format, tp}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), format, - tp, &abbrev), - parse_manip{format, tp, &abbrev}) -{ - return {format, tp, &abbrev}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, - tp, nullptr, &offset), - parse_manip{format, tp, nullptr, &offset}) -{ - return {format, tp, nullptr, &offset}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, - tp, &abbrev, &offset), - parse_manip{format, tp, &abbrev, &offset}) -{ - return {format, tp, &abbrev, &offset}; -} - -// duration streaming - -namespace detail -{ - -#if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \ - && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150) - -template -class string_literal -{ - CharT p_[N]; - -public: - using const_iterator = const CharT*; - - string_literal(string_literal const&) = default; - string_literal& operator=(string_literal const&) = delete; - - template > - CONSTCD14 string_literal(CharT c) NOEXCEPT - : p_{c} - { - } - - CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - template > - CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - template {}>> - CONSTCD14 string_literal(string_literal const& a) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - template > - CONSTCD14 string_literal(const string_literal& x, - const string_literal& y) NOEXCEPT - : p_{} - { - std::size_t i = 0; - for (; i < N1-1; ++i) - p_[i] = x[i]; - for (std::size_t j = 0; j < N2; ++j, ++i) - p_[i] = y[j]; - } - - CONSTCD14 const CharT* data() const NOEXCEPT {return p_;} - CONSTCD14 std::size_t size() const NOEXCEPT {return N-1;} - - CONSTCD14 const_iterator begin() const NOEXCEPT {return p_;} - CONSTCD14 const_iterator end() const NOEXCEPT {return p_ + N-1;} - - CONSTCD14 CharT const& operator[](std::size_t n) const NOEXCEPT - { - return p_[n]; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const string_literal& s) - { - return os << s.p_; - } -}; - -template -CONSTCD14 -inline -string_literal, - N1 + N2 - 1> -operator+(const string_literal& x, const string_literal& y) NOEXCEPT -{ - using CharT = std::conditional_t; - return string_literal{string_literal{x}, - string_literal{y}}; -} - -template -inline -std::basic_string -operator+(std::basic_string x, - const string_literal& y) NOEXCEPT -{ - x.append(y.data(), y.size()); - return x; -} - -template -CONSTCD14 -inline -string_literal -msl(const CharT(&a)[N]) NOEXCEPT -{ - return string_literal{a}; -} - -template {} || - std::is_same{} || - std::is_same{} || - std::is_same{}>> -CONSTCD14 -inline -string_literal -msl(CharT c) NOEXCEPT -{ - return string_literal{c}; -} - -CONSTCD14 -inline -std::size_t -to_string_len(std::intmax_t i) -{ - std::size_t r = 0; - do - { - i /= 10; - ++r; - } while (i > 0); - return r; -} - -template -CONSTCD14 -inline -std::enable_if_t -< - N < 10, - string_literal -> -msl() NOEXCEPT -{ - return msl(char(N % 10 + '0')); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - 10 <= N, - string_literal -> -msl() NOEXCEPT -{ - return msl() + msl(char(N % 10 + '0')); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - std::ratio::type::den != 1, - string_literal::type::num) + - to_string_len(std::ratio::type::den) + 4> -> -msl(std::ratio) NOEXCEPT -{ - using R = typename std::ratio::type; - return msl(CharT{'['}) + msl() + msl(CharT{'/'}) + - msl() + msl(CharT{']'}); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - std::ratio::type::den == 1, - string_literal::type::num) + 3> -> -msl(std::ratio) NOEXCEPT -{ - using R = typename std::ratio::type; - return msl(CharT{'['}) + msl() + msl(CharT{']'}); -} - -template -CONSTCD14 -inline -auto -msl(std::atto) NOEXCEPT -{ - return msl(CharT{'a'}); -} - -template -CONSTCD14 -inline -auto -msl(std::femto) NOEXCEPT -{ - return msl(CharT{'f'}); -} - -template -CONSTCD14 -inline -auto -msl(std::pico) NOEXCEPT -{ - return msl(CharT{'p'}); -} - -template -CONSTCD14 -inline -auto -msl(std::nano) NOEXCEPT -{ - return msl(CharT{'n'}); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - std::is_same{}, - string_literal -> -msl(std::micro) NOEXCEPT -{ - return string_literal{"\xC2\xB5"}; -} - -template -CONSTCD14 -inline -std::enable_if_t -< - !std::is_same{}, - string_literal -> -msl(std::micro) NOEXCEPT -{ - return string_literal{CharT{static_cast('\xB5')}}; -} - -template -CONSTCD14 -inline -auto -msl(std::milli) NOEXCEPT -{ - return msl(CharT{'m'}); -} - -template -CONSTCD14 -inline -auto -msl(std::centi) NOEXCEPT -{ - return msl(CharT{'c'}); -} - -template -CONSTCD14 -inline -auto -msl(std::deci) NOEXCEPT -{ - return msl(CharT{'d'}); -} - -template -CONSTCD14 -inline -auto -msl(std::deca) NOEXCEPT -{ - return string_literal{"da"}; -} - -template -CONSTCD14 -inline -auto -msl(std::hecto) NOEXCEPT -{ - return msl(CharT{'h'}); -} - -template -CONSTCD14 -inline -auto -msl(std::kilo) NOEXCEPT -{ - return msl(CharT{'k'}); -} - -template -CONSTCD14 -inline -auto -msl(std::mega) NOEXCEPT -{ - return msl(CharT{'M'}); -} - -template -CONSTCD14 -inline -auto -msl(std::giga) NOEXCEPT -{ - return msl(CharT{'G'}); -} - -template -CONSTCD14 -inline -auto -msl(std::tera) NOEXCEPT -{ - return msl(CharT{'T'}); -} - -template -CONSTCD14 -inline -auto -msl(std::peta) NOEXCEPT -{ - return msl(CharT{'P'}); -} - -template -CONSTCD14 -inline -auto -msl(std::exa) NOEXCEPT -{ - return msl(CharT{'E'}); -} - -template -CONSTCD14 -auto -get_units(Period p) -{ - return msl(p) + string_literal{"s"}; -} - -template -CONSTCD14 -auto -get_units(std::ratio<1>) -{ - return string_literal{"s"}; -} - -template -CONSTCD14 -auto -get_units(std::ratio<60>) -{ - return string_literal{"min"}; -} - -template -CONSTCD14 -auto -get_units(std::ratio<3600>) -{ - return string_literal{"h"}; -} - -#else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) - -inline -std::string -to_string(std::uint64_t x) -{ - return std::to_string(x); -} - -template -std::basic_string -to_string(std::uint64_t x) -{ - auto y = std::to_string(x); - return std::basic_string(y.begin(), y.end()); -} - -template -inline -typename std::enable_if -< - std::ratio::type::den != 1, - std::basic_string ->::type -msl(std::ratio) -{ - using R = typename std::ratio::type; - return std::basic_string(1, '[') + to_string(R::num) + CharT{'/'} + - to_string(R::den) + CharT{']'}; -} - -template -inline -typename std::enable_if -< - std::ratio::type::den == 1, - std::basic_string ->::type -msl(std::ratio) -{ - using R = typename std::ratio::type; - return std::basic_string(1, '[') + to_string(R::num) + CharT{']'}; -} - -template -inline -std::basic_string -msl(std::atto) -{ - return {'a'}; -} - -template -inline -std::basic_string -msl(std::femto) -{ - return {'f'}; -} - -template -inline -std::basic_string -msl(std::pico) -{ - return {'p'}; -} - -template -inline -std::basic_string -msl(std::nano) -{ - return {'n'}; -} - -template -inline -typename std::enable_if -< - std::is_same::value, - std::string ->::type -msl(std::micro) -{ - return "\xC2\xB5"; -} - -template -inline -typename std::enable_if -< - !std::is_same::value, - std::basic_string ->::type -msl(std::micro) -{ - return {CharT(static_cast('\xB5'))}; -} - -template -inline -std::basic_string -msl(std::milli) -{ - return {'m'}; -} - -template -inline -std::basic_string -msl(std::centi) -{ - return {'c'}; -} - -template -inline -std::basic_string -msl(std::deci) -{ - return {'d'}; -} - -template -inline -std::basic_string -msl(std::deca) -{ - return {'d', 'a'}; -} - -template -inline -std::basic_string -msl(std::hecto) -{ - return {'h'}; -} - -template -inline -std::basic_string -msl(std::kilo) -{ - return {'k'}; -} - -template -inline -std::basic_string -msl(std::mega) -{ - return {'M'}; -} - -template -inline -std::basic_string -msl(std::giga) -{ - return {'G'}; -} - -template -inline -std::basic_string -msl(std::tera) -{ - return {'T'}; -} - -template -inline -std::basic_string -msl(std::peta) -{ - return {'P'}; -} - -template -inline -std::basic_string -msl(std::exa) -{ - return {'E'}; -} - -template -std::basic_string -get_units(Period p) -{ - return msl(p) + CharT{'s'}; -} - -template -std::basic_string -get_units(std::ratio<1>) -{ - return {'s'}; -} - -template -std::basic_string -get_units(std::ratio<60>) -{ - return {'m', 'i', 'n'}; -} - -template -std::basic_string -get_units(std::ratio<3600>) -{ - return {'h'}; -} - -#endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) - -template > -struct make_string; - -template <> -struct make_string -{ - template - static - std::string - from(Rep n) - { - return std::to_string(n); - } -}; - -template -struct make_string -{ - template - static - std::basic_string - from(Rep n) - { - auto s = std::to_string(n); - return std::basic_string(s.begin(), s.end()); - } -}; - -template <> -struct make_string -{ - template - static - std::wstring - from(Rep n) - { - return std::to_wstring(n); - } -}; - -template -struct make_string -{ - template - static - std::basic_string - from(Rep n) - { - auto s = std::to_wstring(n); - return std::basic_string(s.begin(), s.end()); - } -}; - -} // namespace detail - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::chrono::duration& d) -{ - using namespace detail; - return os << make_string::from(d.count()) + - get_units(typename Period::type{}); -} - -} // namespace date - - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - - -#endif // DATE_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 393c946..442251d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,9 +5,9 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Wextra") include_directories( - externals/Catch2/single_include/ - .. - ../libcron/externals/date + ${CMAKE_CURRENT_LIST_DIR}/externals/Catch2/single_include/ + ${CMAKE_CURRENT_LIST_DIR}/../libcron/externals/date/include + ${CMAKE_CURRENT_LIST_DIR}/.. ) add_executable( diff --git a/test/CronDataTest.cpp b/test/CronDataTest.cpp index bd75483..92a93c1 100644 --- a/test/CronDataTest.cpp +++ b/test/CronDataTest.cpp @@ -1,7 +1,7 @@ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file #include -#include +#include #include #include @@ -21,8 +21,6 @@ bool has_value_range(const std::set& set, uint8_t low, uint8_t high) return found; } - - SCENARIO("Numerical inputs") { GIVEN("Valid numerical inputs") diff --git a/test/CronScheduleTest.cpp b/test/CronScheduleTest.cpp index 8115cf6..44ff14a 100644 --- a/test/CronScheduleTest.cpp +++ b/test/CronScheduleTest.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include