Port to gcc-5.2.0 on OS X.

*  This also fixes an overflow bug in Zone::get_info.
This commit is contained in:
Howard Hinnant
2015-07-25 18:01:31 -04:00
parent 0c44d8c70d
commit 5c370dbfd9

30
tz.cpp
View File

@@ -26,7 +26,7 @@ namespace date
static std::string install{"/Users/howardhinnant/Downloads/tzdata2015e"}; static std::string install{"/Users/howardhinnant/Downloads/tzdata2015e"};
static const std::vector<const std::string> files = static const std::vector<std::string> files =
{ {
"africa", "antarctica", "asia", "australasia", "backward", "etcetera", "europe", "africa", "antarctica", "asia", "australasia", "backward", "etcetera", "europe",
"pacificnew", "northamerica", "southamerica", "systemv", "leapseconds" "pacificnew", "northamerica", "southamerica", "systemv", "leapseconds"
@@ -803,10 +803,12 @@ Rule::split_overlaps(std::vector<Rule>& rules)
Zone::zonelet::~zonelet() Zone::zonelet::~zonelet()
{ {
using minutes = std::chrono::minutes;
using string = std::string;
if (tag_ == has_save) if (tag_ == has_save)
u.save_.~decltype(u.save_)(); u.save_.~minutes();
else else
u.rule_.~decltype(u.rule_)(); u.rule_.~string();
} }
Zone::zonelet::zonelet() Zone::zonelet::zonelet()
@@ -1166,10 +1168,11 @@ Zone::adjust_infos(const std::vector<Rule>& rules)
try try
{ {
using namespace std::chrono; using namespace std::chrono;
using string = std::string;
std::istringstream in(z.u.rule_); std::istringstream in(z.u.rule_);
in.exceptions(std::ios::failbit | std::ios::badbit); in.exceptions(std::ios::failbit | std::ios::badbit);
auto tmp = duration_cast<minutes>(parse_signed_time(in)); auto tmp = duration_cast<minutes>(parse_signed_time(in));
z.u.rule_.~decltype(z.u.rule_)(); z.u.rule_.~string();
z.tag_ = zonelet::has_save; z.tag_ = zonelet::has_save;
::new(&z.u.save_) minutes(tmp); ::new(&z.u.save_) minutes(tmp);
} }
@@ -1267,8 +1270,9 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const
throw std::runtime_error("The year " + std::to_string(static_cast<int>(y)) + throw std::runtime_error("The year " + std::to_string(static_cast<int>(y)) +
" is out of range:[" + std::to_string(static_cast<int>(min_year)) + ", " " is out of range:[" + std::to_string(static_cast<int>(min_year)) + ", "
+ std::to_string(static_cast<int>(max_year)) + "]"); + std::to_string(static_cast<int>(max_year)) + "]");
auto i = std::upper_bound(zonelets_.begin(), zonelets_.end(), tp, auto tps = floor<seconds>(tp);
[timezone](std::chrono::system_clock::time_point t, const zonelet& zl) auto i = std::upper_bound(zonelets_.begin(), zonelets_.end(), tps,
[timezone](seconds_point t, const zonelet& zl)
{ {
return timezone == tz::utc ? t < zl.until_utc_ : t < zl.until_loc_; return timezone == tz::utc ? t < zl.until_utc_ : t < zl.until_loc_;
}); });
@@ -1278,8 +1282,10 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const
{ {
if (i->tag_ == zonelet::has_save) if (i->tag_ == zonelet::has_save)
{ {
r.begin = i != zonelets_.begin() ? i[-1].until_utc_ if (i != zonelets_.begin())
: day_point(year::min()/boring_day); r.begin = i[-1].until_utc_;
else
r.begin = day_point(year::min()/boring_day);
r.end = i->until_utc_; r.end = i->until_utc_;
r.offset = i->gmtoff_ + i->u.save_; r.offset = i->gmtoff_ + i->u.save_;
r.save = i->u.save_; r.save = i->u.save_;
@@ -1287,8 +1293,10 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const
} }
else if (i->u.rule_.empty()) else if (i->u.rule_.empty())
{ {
r.begin = i != zonelets_.begin() ? i[-1].until_utc_ if (i != zonelets_.begin())
: day_point(year::min()/boring_day); r.begin = i[-1].until_utc_;
else
r.begin = day_point(year::min()/boring_day);
r.end = i->until_utc_; r.end = i->until_utc_;
r.offset = i->gmtoff_; r.offset = i->gmtoff_;
r.abbrev = i->format_; r.abbrev = i->format_;
@@ -1296,7 +1304,7 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const
else else
{ {
r = find_rule(i->first_rule_, i->last_rule_, y, i->gmtoff_, r = find_rule(i->first_rule_, i->last_rule_, y, i->gmtoff_,
MonthDayTime(floor<seconds>(tp), timezone), i->initial_save_, MonthDayTime(tps, timezone), i->initial_save_,
i->initial_abbrev_); i->initial_abbrev_);
auto k = i->format_.find("%s"); auto k = i->format_.find("%s");
if (k != std::string::npos) if (k != std::string::npos)