Add from_stream

This commit is contained in:
Howard Hinnant
2017-03-02 13:16:22 -10:00
parent 1e7e7a214d
commit 3df43424ac
2 changed files with 142 additions and 795 deletions

662
date.h
View File

@@ -3397,10 +3397,9 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
template <class CharT, class Traits, class Duration> template <class CharT, class Traits, class Duration>
void void
parse(std::basic_istream<CharT, Traits>& is, from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
const CharT* fmt, fields<Duration>& fds, fields<Duration>& fds, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::basic_string<CharT, Traits>* abbrev = nullptr, std::chrono::minutes* offset = nullptr);
std::chrono::minutes* offset = nullptr);
// time_of_day // time_of_day
@@ -3918,7 +3917,7 @@ public:
template <class CharT, class Traits, class Duration> template <class CharT, class Traits, class Duration>
friend friend
void void
date::parse(std::basic_istream<CharT, Traits>& is, const CharT* fmt, date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
fields<Duration>& fds, fields<Duration>& fds,
std::basic_string<CharT, Traits>* abbrev, std::chrono::minutes* offset); std::basic_string<CharT, Traits>* abbrev, std::chrono::minutes* offset);
}; };
@@ -4022,7 +4021,7 @@ public:
template <class CharT, class Traits, class Duration> template <class CharT, class Traits, class Duration>
friend friend
void void
date::parse(std::basic_istream<CharT, Traits>& is, const CharT* fmt, date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
fields<Duration>& fds, fields<Duration>& fds,
std::basic_string<CharT, Traits>* abbrev, std::chrono::minutes* offset); std::basic_string<CharT, Traits>* abbrev, std::chrono::minutes* offset);
}; };
@@ -5016,8 +5015,6 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
// format // format
#ifndef NO_EXPRESSION_SFINAE
template <class CharT, class Streamable> template <class CharT, class Streamable>
auto auto
format(const std::locale& loc, const CharT* fmt, const Streamable& tp) format(const std::locale& loc, const CharT* fmt, const Streamable& tp)
@@ -5065,172 +5062,6 @@ format(const std::basic_string<CharT, Traits>& fmt, const Streamable& tp)
return os.str(); return os.str();
} }
#else // NO_EXPRESSION_SFINAE
// const CharT* formats
template <class CharT>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const year_month_day& ymd)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, ymd);
return os.str();
}
template <class CharT>
std::basic_string<CharT>
format(const CharT* fmt, const year_month_day& ymd)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, ymd);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const local_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const local_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const sys_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const sys_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Rep, class Period>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt,
const std::chrono::duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, d);
return os.str();
}
template <class CharT, class Rep, class Period>
std::basic_string<CharT>
format(const CharT* fmt, const std::chrono::duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, d);
return os.str();
}
// basic_string formats
template <class CharT, class Traits>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const year_month_day& ymd)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), ymd);
return os.str();
}
template <class CharT, class Traits>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const year_month_day& ymd)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), ymd);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const local_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const local_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const sys_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const sys_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Rep, class Period>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const std::chrono::duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), d);
return os.str();
}
template <class CharT, class Traits, class Rep, class Period>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt,
const std::chrono::duration<Rep, Period>& d)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt.c_str(), d);
return os.str();
}
#endif // NO_EXPRESSION_SFINAE
// parse // parse
namespace detail namespace detail
@@ -5468,8 +5299,9 @@ read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args)
template <class CharT, class Traits, class Duration> template <class CharT, class Traits, class Duration>
void void
parse(std::basic_istream<CharT, Traits>& is, const CharT* fmt, fields<Duration>& fds, from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
std::basic_string<CharT, Traits>* abbrev, std::chrono::minutes* offset) fields<Duration>& fds, std::basic_string<CharT, Traits>* abbrev,
std::chrono::minutes* offset)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
@@ -6367,167 +6199,87 @@ broken:
is.setstate(ios_base::failbit); is.setstate(ios_base::failbit);
} }
template <class Parsable, class CharT, class Traits = std::char_traits<CharT>>
struct parse_manip;
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT, Traits>::type
parse(const std::basic_string<CharT, Traits>& format, Parsable& tp)
{
return {format, tp};
}
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT, Traits>::type
parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
std::basic_string<CharT, Traits>& abbrev)
{
return {format, tp, &abbrev};
}
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT, Traits>::type
parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
std::chrono::minutes& offset)
{
return {format, tp, nullptr, &offset};
}
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT, Traits>::type
parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
{
return {format, tp, &abbrev, &offset};
}
// const CharT* formats
template <class Parsable, class CharT>
inline
typename parse_manip<Parsable, CharT>::type
parse(const CharT* format, Parsable& tp)
{
return {format, tp};
}
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT>::type
parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits>& abbrev)
{
return {format, tp, &abbrev};
}
template <class Parsable, class CharT>
inline
typename parse_manip<Parsable, CharT>::type
parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset)
{
return {format, tp, nullptr, &offset};
}
template <class Parsable, class CharT, class Traits>
inline
typename parse_manip<Parsable, CharT>::type
parse(const CharT* format, Parsable& tp,
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
{
return {format, tp, &abbrev, &offset};
}
template <class CharT, class Traits> template <class CharT, class Traits>
struct parse_manip<year_month_day, CharT, Traits> void
{ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
using type = parse_manip; year_month_day& ymd, std::basic_string<CharT, Traits>* abbrev = nullptr,
const std::basic_string<CharT, Traits> format_; std::chrono::minutes* offset = nullptr)
year_month_day& ymd_;
std::basic_string<CharT, Traits>* abbrev_;
std::chrono::minutes* offset_;
parse_manip(std::basic_string<CharT, Traits> format,
year_month_day& ymd, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
: format_(std::move(format))
, ymd_(ymd)
, abbrev_(abbrev)
, offset_(offset)
{}
};
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
const parse_manip<year_month_day, CharT, Traits>& x)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using CT = seconds; using CT = seconds;
fields<CT> fds{}; fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, x.offset_); from_stream(is, fmt, fds, abbrev, offset);
if (!fds.ymd.ok()) if (!fds.ymd.ok())
is.setstate(ios::failbit); is.setstate(ios::failbit);
if (!is.fail()) if (!is.fail())
x.ymd_ = fds.ymd; ymd = fds.ymd;
return is;
} }
template <class Duration, class CharT, class Traits> template <class Duration, class CharT, class Traits>
struct parse_manip<local_time<Duration>, CharT, Traits> void
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
sys_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
{ {
using type = parse_manip; using namespace std;
const std::basic_string<CharT, Traits> format_; using namespace std::chrono;
local_time<Duration>& tp_; using CT = typename common_type<Duration, seconds>::type;
std::basic_string<CharT, Traits>* abbrev_; minutes offset_local{};
std::chrono::minutes* offset_; auto offptr = offset ? offset : &offset_local;
fields<CT> fds{};
public: from_stream(is, fmt, fds, abbrev, offptr);
parse_manip(std::basic_string<CharT, Traits> format, if (!fds.ymd.ok())
local_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr, is.setstate(ios::failbit);
std::chrono::minutes* offset = nullptr) if (!is.fail())
: format_(std::move(format)) tp = sys_days(fds.ymd) + duration_cast<Duration>(fds.tod.to_duration() - *offptr);
, tp_(tp) }
, abbrev_(abbrev)
, offset_(offset)
{}
};
template <class Duration, class CharT, class Traits> template <class Duration, class CharT, class Traits>
inline void
std::basic_istream<CharT, Traits>& from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
operator>>(std::basic_istream<CharT, Traits>& is, local_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
const parse_manip<local_time<Duration>, CharT, Traits>& x) std::chrono::minutes* offset = nullptr)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using CT = typename common_type<Duration, seconds>::type; using CT = typename common_type<Duration, seconds>::type;
fields<CT> fds{}; fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, x.offset_); from_stream(is, fmt, fds, abbrev, offset);
if (!fds.ymd.ok()) if (!fds.ymd.ok())
is.setstate(ios::failbit); is.setstate(ios::failbit);
if (!is.fail()) if (!is.fail())
x.tp_ = local_days(fds.ymd) + duration_cast<Duration>(fds.tod.to_duration()); tp = local_days(fds.ymd) + duration_cast<Duration>(fds.tod.to_duration());
return is;
} }
template <class Duration, class CharT, class Traits> template <class Rep, class Period, class CharT, class Traits>
struct parse_manip<sys_time<Duration>, CharT, Traits> void
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
std::chrono::duration<Rep, Period>& d,
std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
{
using namespace std;
using namespace std::chrono;
using Duration = std::chrono::duration<Rep, Period>;
using CT = typename common_type<Duration, seconds>::type;
fields<CT> fds{};
from_stream(is, fmt, fds, abbrev, offset);
if (!is.fail())
d = duration_cast<Duration>(fds.tod.to_duration());
}
template <class Parsable, class CharT, class Traits = std::char_traits<CharT>>
struct parse_manip
{ {
using type = parse_manip;
const std::basic_string<CharT, Traits> format_; const std::basic_string<CharT, Traits> format_;
sys_time<Duration>& tp_; Parsable& tp_;
std::basic_string<CharT, Traits>* abbrev_; std::basic_string<CharT, Traits>* abbrev_;
std::chrono::minutes* offset_; std::chrono::minutes* offset_;
public: public:
parse_manip(std::basic_string<CharT, Traits> format, parse_manip(std::basic_string<CharT, Traits> format,
sys_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr, Parsable& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr) std::chrono::minutes* offset = nullptr)
: format_(std::move(format)) : format_(std::move(format))
, tp_(tp) , tp_(tp)
@@ -6537,288 +6289,108 @@ public:
}; };
template <class Duration, class CharT, class Traits> template <class Parsable, class CharT, class Traits>
std::basic_istream<CharT, Traits>& std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, operator>>(std::basic_istream<CharT, Traits>& is,
const parse_manip<sys_time<Duration>, CharT, Traits>& x) const parse_manip<Parsable, CharT, Traits>& x)
{ {
using namespace std; from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_);
using namespace std::chrono;
using CT = typename common_type<Duration, seconds>::type;
minutes offset{};
auto offptr = x.offset_ ? x.offset_ : &offset;
fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, offptr);
if (!fds.ymd.ok())
is.setstate(ios::failbit);
if (!is.fail())
x.tp_ = sys_days(fds.ymd) +
duration_cast<Duration>(fds.tod.to_duration() - *offptr);
return is; return is;
} }
template <class Rep, class Period, class CharT, class Traits> template <class Parsable, class CharT, class Traits>
struct parse_manip<std::chrono::duration<Rep, Period>, CharT, Traits>
{
using type = parse_manip;
using Duration = std::chrono::duration<Rep, Period>;
const std::basic_string<CharT, Traits> format_;
Duration& d_;
public:
parse_manip(std::basic_string<CharT, Traits> format, Duration& d)
: format_(std::move(format))
, d_(d)
{}
};
template <class Rep, class Period, class CharT, class Traits>
inline inline
std::basic_istream<CharT, Traits>& auto
operator>>(std::basic_istream<CharT, Traits>& is, parse(const std::basic_string<CharT, Traits>& format, Parsable& tp)
const parse_manip<std::chrono::duration<Rep, Period>, CharT, Traits>& x) -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
format.c_str(), tp),
parse_manip<Parsable, CharT, Traits>{format, tp})
{ {
using namespace std; return {format, tp};
using namespace std::chrono;
using Duration = std::chrono::duration<Rep, Period>;
using CT = typename common_type<Duration, seconds>::type;
fields<CT> fds{};
parse(is, x.format_.c_str(), fds);
if (fds.ymd.ok())
is.setstate(ios::failbit);
if (!is.fail())
x.d_ = duration_cast<Duration>(fds.tod.to_duration());
return is;
} }
#if 0 // use in >> parse(format, x); instead template <class Parsable, class CharT, class Traits>
template <class CharT, class Traits, class Duration>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp)
{
std::chrono::minutes offset{};
local_time<Duration> lt;
detail::parse(is, format.c_str(), lt, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is,
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
std::basic_string<CharT, Traits>& abbrev) std::basic_string<CharT, Traits>& abbrev)
-> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
format.c_str(), tp, &abbrev),
parse_manip<Parsable, CharT, Traits>{format, tp, &abbrev})
{ {
std::chrono::minutes offset{}; return {format, tp, &abbrev};
local_time<Duration> lt;
detail::parse(is, format.c_str(), lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
} }
template <class CharT, class Traits, class Duration> template <class Parsable, class CharT, class Traits>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
std::chrono::minutes& offset) std::chrono::minutes& offset)
-> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
format.c_str(), tp, nullptr, &offset),
parse_manip<Parsable, CharT, Traits>{format, tp, nullptr, &offset})
{ {
local_time<Duration> lt; return {format, tp, nullptr, &offset};
detail::parse(is, format.c_str(), lt, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
} }
template <class CharT, class Traits, class Duration> template <class Parsable, class CharT, class Traits>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset) std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
-> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
format.c_str(), tp, &abbrev, &offset),
parse_manip<Parsable, CharT, Traits>{format, tp, &abbrev, &offset})
{ {
local_time<Duration> lt; return {format, tp, &abbrev, &offset};
detail::parse(is, format.c_str(), lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
} }
template <class CharT, class Traits, class Duration> // const CharT* formats
template <class Parsable, class CharT>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const CharT* format, Parsable& tp)
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp, -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp),
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev) parse_manip<Parsable, CharT>{format, tp})
{ {
local_time<Duration> lt; return {format, tp};
detail::parse(is, format.c_str(), lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
} }
template <class CharT, class Traits, class Duration> template <class Parsable, class CharT, class Traits>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits>& abbrev)
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp) -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
tp, &abbrev),
parse_manip<Parsable, CharT, Traits>{format, tp, &abbrev})
{ {
detail::parse(is, format.c_str(), tp); return {format, tp, &abbrev};
} }
template <class CharT, class Traits, class Duration> template <class Parsable, class CharT>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset)
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp, -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format,
std::basic_string<CharT, Traits>& abbrev) tp, nullptr, &offset),
parse_manip<Parsable, CharT>{format, tp, nullptr, &offset})
{ {
detail::parse(is, format.c_str(), tp, &abbrev); return {format, tp, nullptr, &offset};
} }
template <class CharT, class Traits, class Duration> template <class Parsable, class CharT, class Traits>
inline inline
void auto
parse(std::basic_istream<CharT, Traits>& is, parse(const CharT* format, Parsable& tp,
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
std::chrono::minutes& offset)
{
detail::parse(is, format.c_str(), tp, &offset);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is,
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset) std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
-> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
tp, &abbrev, &offset),
parse_manip<Parsable, CharT, Traits>{format, tp, &abbrev, &offset})
{ {
detail::parse(is, format.c_str(), tp, &abbrev, &offset); return {format, tp, &abbrev, &offset};
} }
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is,
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
{
detail::parse(is, format.c_str(), tp, &abbrev, &offset);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp)
{
std::chrono::minutes offset{};
local_time<Duration> lt;
detail::parse(is, format, lt, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
std::basic_string<CharT, Traits>& abbrev)
{
std::chrono::minutes offset{};
local_time<Duration> lt;
detail::parse(is, format, lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
std::chrono::minutes& offset)
{
local_time<Duration> lt;
detail::parse(is, format, lt, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
{
local_time<Duration> lt;
detail::parse(is, format, lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
{
local_time<Duration> lt;
detail::parse(is, format, lt, &abbrev, &offset);
if (!is.fail())
tp = sys_time<Duration>{floor<Duration>(lt - offset).time_since_epoch()};
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
local_time<Duration>& tp)
{
detail::parse(is, format, tp);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev)
{
detail::parse(is, format, tp, &abbrev);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
local_time<Duration>& tp, std::chrono::minutes& offset)
{
detail::parse(is, format, tp, &offset);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev,
std::chrono::minutes& offset)
{
detail::parse(is, format, tp, &abbrev, &offset);
}
template <class CharT, class Traits, class Duration>
inline
void
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
local_time<Duration>& tp, std::chrono::minutes& offset,
std::basic_string<CharT, Traits>& abbrev)
{
detail::parse(is, format, tp, &abbrev, &offset);
}
#endif // use in >> parse(format, x); instead
} // namespace date } // namespace date
#endif // DATE_H #endif // DATE_H

275
tz.h
View File

@@ -1159,38 +1159,18 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
} }
template <class Duration, class CharT, class Traits> template <class Duration, class CharT, class Traits>
struct parse_manip<utc_time<Duration>, CharT, Traits> void
{ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
using type = parse_manip; utc_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
const std::basic_string<CharT, Traits> format_; std::chrono::minutes* offset = nullptr)
utc_time<Duration>& tp_;
std::basic_string<CharT, Traits>* abbrev_;
std::chrono::minutes* offset_;
public:
parse_manip(std::basic_string<CharT, Traits> format,
utc_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
: format_(std::move(format))
, tp_(tp)
, abbrev_(abbrev)
, offset_(offset)
{}
};
template <class Duration, class CharT, class Traits>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
const parse_manip<utc_time<Duration>, CharT, Traits>& x)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using CT = typename common_type<Duration, seconds>::type; using CT = typename common_type<Duration, seconds>::type;
minutes offset{}; minutes offset_local{};
auto offptr = x.offset_ ? x.offset_ : &offset; auto offptr = offset ? offset : &offset_local;
fields<CT> fds{}; fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, offptr); from_stream(is, fmt, fds, abbrev, offptr);
if (!fds.ymd.ok()) if (!fds.ymd.ok())
is.setstate(ios::failbit); is.setstate(ios::failbit);
if (!is.fail()) if (!is.fail())
@@ -1198,12 +1178,11 @@ operator>>(std::basic_istream<CharT, Traits>& is,
bool is_leap_second = fds.tod.seconds() == seconds{60}; bool is_leap_second = fds.tod.seconds() == seconds{60};
if (is_leap_second) if (is_leap_second)
fds.tod.seconds() -= seconds{1}; fds.tod.seconds() -= seconds{1};
x.tp_ = to_utc_time(sys_days(fds.ymd) + tp = to_utc_time(sys_days(fds.ymd) +
duration_cast<Duration>(fds.tod.to_duration() - *offptr)); duration_cast<Duration>(fds.tod.to_duration() - *offptr));
if (is_leap_second) if (is_leap_second)
x.tp_ += seconds{1}; tp += seconds{1};
} }
return is;
} }
// tai_clock // tai_clock
@@ -1291,45 +1270,24 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const tai_time<Duration>& t)
} }
template <class Duration, class CharT, class Traits> template <class Duration, class CharT, class Traits>
struct parse_manip<tai_time<Duration>, CharT, Traits> void
{ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
using type = parse_manip; tai_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
const std::basic_string<CharT, Traits> format_; std::chrono::minutes* offset = nullptr)
tai_time<Duration>& tp_;
std::basic_string<CharT, Traits>* abbrev_;
std::chrono::minutes* offset_;
public:
parse_manip(std::basic_string<CharT, Traits> format,
tai_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
: format_(std::move(format))
, tp_(tp)
, abbrev_(abbrev)
, offset_(offset)
{}
};
template <class Duration, class CharT, class Traits>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
const parse_manip<tai_time<Duration>, CharT, Traits>& x)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using CT = typename common_type<Duration, seconds>::type; using CT = typename common_type<Duration, seconds>::type;
minutes offset{}; minutes offset_local{};
auto offptr = x.offset_ ? x.offset_ : &offset; auto offptr = offset ? offset : &offset_local;
fields<CT> fds{}; fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, offptr); from_stream(is, fmt, fds, abbrev, offptr);
if (!fds.ymd.ok()) if (!fds.ymd.ok())
is.setstate(ios::failbit); is.setstate(ios::failbit);
if (!is.fail()) if (!is.fail())
x.tp_ = tai_time<Duration>{duration_cast<Duration>( tp = tai_time<Duration>{duration_cast<Duration>(
(sys_days(fds.ymd) + fds.tod.to_duration() + (sys_days(year{1970}/jan/1) - (sys_days(fds.ymd) + fds.tod.to_duration() + (sys_days(year{1970}/jan/1) -
sys_days(year{1958}/jan/1)) - *offptr).time_since_epoch())}; sys_days(year{1958}/jan/1)) - *offptr).time_since_epoch())};
return is;
} }
// gps_clock // gps_clock
@@ -1417,46 +1375,25 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const gps_time<Duration>& t)
} }
template <class Duration, class CharT, class Traits> template <class Duration, class CharT, class Traits>
struct parse_manip<gps_time<Duration>, CharT, Traits> void
{ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
using type = parse_manip; gps_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
const std::basic_string<CharT, Traits> format_; std::chrono::minutes* offset = nullptr)
gps_time<Duration>& tp_;
std::basic_string<CharT, Traits>* abbrev_;
std::chrono::minutes* offset_;
public:
parse_manip(std::basic_string<CharT, Traits> format,
gps_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
: format_(std::move(format))
, tp_(tp)
, abbrev_(abbrev)
, offset_(offset)
{}
};
template <class Duration, class CharT, class Traits>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
const parse_manip<gps_time<Duration>, CharT, Traits>& x)
{ {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using CT = typename common_type<Duration, seconds>::type; using CT = typename common_type<Duration, seconds>::type;
minutes offset{}; minutes offset_local{};
auto offptr = x.offset_ ? x.offset_ : &offset; auto offptr = offset ? offset : &offset_local;
fields<CT> fds{}; fields<CT> fds{};
parse(is, x.format_.c_str(), fds, x.abbrev_, offptr); from_stream(is, fmt, fds, abbrev, offptr);
if (!fds.ymd.ok()) if (!fds.ymd.ok())
is.setstate(ios::failbit); is.setstate(ios::failbit);
if (!is.fail()) if (!is.fail())
x.tp_ = gps_time<Duration>{duration_cast<Duration>( tp = gps_time<Duration>{duration_cast<Duration>(
(sys_days(fds.ymd) + fds.tod.to_duration() - (sys_days(fds.ymd) + fds.tod.to_duration() -
(sys_days(year{1980}/jan/sun[1]) - (sys_days(year{1980}/jan/sun[1]) -
sys_days(year{1970}/jan/1)) - *offptr).time_since_epoch())}; sys_days(year{1970}/jan/1)) - *offptr).time_since_epoch())};
return is;
} }
template <class Duration> template <class Duration>
@@ -1497,168 +1434,6 @@ to_gps_time(const tai_time<Duration>& t) NOEXCEPT
(sys_days(year{1980}/jan/sun[1]) - sys_days(year{1958}/jan/1) + seconds{19}); (sys_days(year{1980}/jan/sun[1]) - sys_days(year{1958}/jan/1) + seconds{19});
} }
#ifdef NO_EXPRESSION_SFINAE
// format
// basic_string formats
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const zoned_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const zoned_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const zoned_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const zoned_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const utc_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const utc_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const utc_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const utc_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const tai_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const tai_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const tai_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const tai_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const std::locale& loc, const CharT* fmt, const gps_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
os.imbue(loc);
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Duration>
std::basic_string<CharT>
format(const CharT* fmt, const gps_time<Duration>& tp)
{
std::basic_ostringstream<CharT> os;
to_stream(os, fmt, tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
const gps_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
os.imbue(loc);
to_stream(os, fmt.c_str(), tp);
return os.str();
}
template <class CharT, class Traits, class Duration>
std::basic_string<CharT, Traits>
format(const std::basic_string<CharT, Traits>& fmt, const gps_time<Duration>& tp)
{
std::basic_ostringstream<CharT, Traits> os;
to_stream(os, fmt.c_str(), tp);
return os.str();
}
#endif // NO_EXPRESSION_SFINAE
} // namespace date } // namespace date
#endif // TZ_H #endif // TZ_H