aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/abseil-cpp-tstring/y_absl/time
diff options
context:
space:
mode:
authoranastasy888 <anastasy888@yandex-team.ru>2022-02-10 16:45:55 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:55 +0300
commit3a7a498715ef1b66f5054455421b845e45e3a653 (patch)
tree1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/restricted/abseil-cpp-tstring/y_absl/time
parent49f765d71da452ea93138a25559dfa68dd76c7f3 (diff)
downloadydb-3a7a498715ef1b66f5054455421b845e45e3a653.tar.gz
Restoring authorship annotation for <anastasy888@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp-tstring/y_absl/time')
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc286
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.h840
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time/ya.make32
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.cc800
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.h120
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/duration.cc1676
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/format.cc188
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time.h652
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time_detail.h1126
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h684
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/zone_info_source.h162
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/civil_time_detail.cc174
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc224
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.h84
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_format.cc1708
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.cc76
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h118
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.cc182
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.h156
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc1516
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.h230
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.cc560
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.h90
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc350
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.cc300
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.h242
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h196
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc120
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_chrono.inc54
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_posix.inc36
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/test_util.h52
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/zoneinfo.inc1458
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/time.cc858
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h2660
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone/ya.make48
-rw-r--r--contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make42
36 files changed, 9050 insertions, 9050 deletions
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc
index c26166935d..f24bac91e8 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc
@@ -1,173 +1,173 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "y_absl/time/civil_time.h"
-
-#include <cstdlib>
+
+#include <cstdlib>
#include <util/generic/string.h>
-
+
#include "y_absl/strings/str_cat.h"
#include "y_absl/time/time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-namespace {
-
+
+namespace {
+
// Since a civil time has a larger year range than y_absl::Time (64-bit years vs
-// 64-bit seconds, respectively) we normalize years to roughly +/- 400 years
-// around the year 2400, which will produce an equivalent year in a range that
+// 64-bit seconds, respectively) we normalize years to roughly +/- 400 years
+// around the year 2400, which will produce an equivalent year in a range that
// y_absl::Time can handle.
-inline civil_year_t NormalizeYear(civil_year_t year) {
- return 2400 + year % 400;
-}
-
-// Formats the given CivilSecond according to the given format.
+inline civil_year_t NormalizeYear(civil_year_t year) {
+ return 2400 + year % 400;
+}
+
+// Formats the given CivilSecond according to the given format.
TString FormatYearAnd(string_view fmt, CivilSecond cs) {
- const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(),
- cs.hour(), cs.minute(), cs.second());
- const TimeZone utc = UTCTimeZone();
+ const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(),
+ cs.hour(), cs.minute(), cs.second());
+ const TimeZone utc = UTCTimeZone();
return StrCat(cs.year(), FormatTime(fmt, FromCivil(ncs, utc), utc));
-}
-
-template <typename CivilT>
-bool ParseYearAnd(string_view fmt, string_view s, CivilT* c) {
+}
+
+template <typename CivilT>
+bool ParseYearAnd(string_view fmt, string_view s, CivilT* c) {
// Civil times support a larger year range than y_absl::Time, so we need to
// parse the year separately, normalize it, then use y_absl::ParseTime on the
// normalized string.
const TString ss = TString(s); // TODO(y_absl-team): Avoid conversion.
- const char* const np = ss.c_str();
- char* endp;
- errno = 0;
- const civil_year_t y =
- std::strtoll(np, &endp, 10); // NOLINT(runtime/deprecated_fn)
- if (endp == np || errno == ERANGE) return false;
+ const char* const np = ss.c_str();
+ char* endp;
+ errno = 0;
+ const civil_year_t y =
+ std::strtoll(np, &endp, 10); // NOLINT(runtime/deprecated_fn)
+ if (endp == np || errno == ERANGE) return false;
const TString norm = StrCat(NormalizeYear(y), endp);
-
- const TimeZone utc = UTCTimeZone();
- Time t;
- if (ParseTime(StrCat("%Y", fmt), norm, utc, &t, nullptr)) {
- const auto cs = ToCivilSecond(t, utc);
- *c = CivilT(y, cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second());
- return true;
- }
-
- return false;
-}
-
-// Tries to parse the type as a CivilT1, but then assigns the result to the
-// argument of type CivilT2.
-template <typename CivilT1, typename CivilT2>
-bool ParseAs(string_view s, CivilT2* c) {
- CivilT1 t1;
- if (ParseCivilTime(s, &t1)) {
- *c = CivilT2(t1);
- return true;
- }
- return false;
-}
-
-template <typename CivilT>
-bool ParseLenient(string_view s, CivilT* c) {
+
+ const TimeZone utc = UTCTimeZone();
+ Time t;
+ if (ParseTime(StrCat("%Y", fmt), norm, utc, &t, nullptr)) {
+ const auto cs = ToCivilSecond(t, utc);
+ *c = CivilT(y, cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second());
+ return true;
+ }
+
+ return false;
+}
+
+// Tries to parse the type as a CivilT1, but then assigns the result to the
+// argument of type CivilT2.
+template <typename CivilT1, typename CivilT2>
+bool ParseAs(string_view s, CivilT2* c) {
+ CivilT1 t1;
+ if (ParseCivilTime(s, &t1)) {
+ *c = CivilT2(t1);
+ return true;
+ }
+ return false;
+}
+
+template <typename CivilT>
+bool ParseLenient(string_view s, CivilT* c) {
// A fastpath for when the given string data parses exactly into the given
- // type T (e.g., s="YYYY-MM-DD" and CivilT=CivilDay).
- if (ParseCivilTime(s, c)) return true;
- // Try parsing as each of the 6 types, trying the most common types first
- // (based on csearch results).
- if (ParseAs<CivilDay>(s, c)) return true;
- if (ParseAs<CivilSecond>(s, c)) return true;
- if (ParseAs<CivilHour>(s, c)) return true;
- if (ParseAs<CivilMonth>(s, c)) return true;
- if (ParseAs<CivilMinute>(s, c)) return true;
- if (ParseAs<CivilYear>(s, c)) return true;
- return false;
-}
-} // namespace
-
+ // type T (e.g., s="YYYY-MM-DD" and CivilT=CivilDay).
+ if (ParseCivilTime(s, c)) return true;
+ // Try parsing as each of the 6 types, trying the most common types first
+ // (based on csearch results).
+ if (ParseAs<CivilDay>(s, c)) return true;
+ if (ParseAs<CivilSecond>(s, c)) return true;
+ if (ParseAs<CivilHour>(s, c)) return true;
+ if (ParseAs<CivilMonth>(s, c)) return true;
+ if (ParseAs<CivilMinute>(s, c)) return true;
+ if (ParseAs<CivilYear>(s, c)) return true;
+ return false;
+}
+} // namespace
+
TString FormatCivilTime(CivilSecond c) {
return FormatYearAnd("-%m-%d%ET%H:%M:%S", c);
-}
+}
TString FormatCivilTime(CivilMinute c) {
return FormatYearAnd("-%m-%d%ET%H:%M", c);
-}
+}
TString FormatCivilTime(CivilHour c) {
return FormatYearAnd("-%m-%d%ET%H", c);
-}
+}
TString FormatCivilTime(CivilDay c) { return FormatYearAnd("-%m-%d", c); }
TString FormatCivilTime(CivilMonth c) { return FormatYearAnd("-%m", c); }
TString FormatCivilTime(CivilYear c) { return FormatYearAnd("", c); }
-
-bool ParseCivilTime(string_view s, CivilSecond* c) {
+
+bool ParseCivilTime(string_view s, CivilSecond* c) {
return ParseYearAnd("-%m-%d%ET%H:%M:%S", s, c);
-}
-bool ParseCivilTime(string_view s, CivilMinute* c) {
+}
+bool ParseCivilTime(string_view s, CivilMinute* c) {
return ParseYearAnd("-%m-%d%ET%H:%M", s, c);
-}
-bool ParseCivilTime(string_view s, CivilHour* c) {
+}
+bool ParseCivilTime(string_view s, CivilHour* c) {
return ParseYearAnd("-%m-%d%ET%H", s, c);
-}
-bool ParseCivilTime(string_view s, CivilDay* c) {
- return ParseYearAnd("-%m-%d", s, c);
-}
-bool ParseCivilTime(string_view s, CivilMonth* c) {
- return ParseYearAnd("-%m", s, c);
-}
-bool ParseCivilTime(string_view s, CivilYear* c) {
- return ParseYearAnd("", s, c);
-}
-
-bool ParseLenientCivilTime(string_view s, CivilSecond* c) {
- return ParseLenient(s, c);
-}
-bool ParseLenientCivilTime(string_view s, CivilMinute* c) {
- return ParseLenient(s, c);
-}
-bool ParseLenientCivilTime(string_view s, CivilHour* c) {
- return ParseLenient(s, c);
-}
-bool ParseLenientCivilTime(string_view s, CivilDay* c) {
- return ParseLenient(s, c);
-}
-bool ParseLenientCivilTime(string_view s, CivilMonth* c) {
- return ParseLenient(s, c);
-}
-bool ParseLenientCivilTime(string_view s, CivilYear* c) {
- return ParseLenient(s, c);
-}
-
-namespace time_internal {
-
-std::ostream& operator<<(std::ostream& os, CivilYear y) {
- return os << FormatCivilTime(y);
-}
-std::ostream& operator<<(std::ostream& os, CivilMonth m) {
- return os << FormatCivilTime(m);
-}
-std::ostream& operator<<(std::ostream& os, CivilDay d) {
- return os << FormatCivilTime(d);
-}
-std::ostream& operator<<(std::ostream& os, CivilHour h) {
- return os << FormatCivilTime(h);
-}
-std::ostream& operator<<(std::ostream& os, CivilMinute m) {
- return os << FormatCivilTime(m);
-}
-std::ostream& operator<<(std::ostream& os, CivilSecond s) {
- return os << FormatCivilTime(s);
-}
-
-} // namespace time_internal
-
+}
+bool ParseCivilTime(string_view s, CivilDay* c) {
+ return ParseYearAnd("-%m-%d", s, c);
+}
+bool ParseCivilTime(string_view s, CivilMonth* c) {
+ return ParseYearAnd("-%m", s, c);
+}
+bool ParseCivilTime(string_view s, CivilYear* c) {
+ return ParseYearAnd("", s, c);
+}
+
+bool ParseLenientCivilTime(string_view s, CivilSecond* c) {
+ return ParseLenient(s, c);
+}
+bool ParseLenientCivilTime(string_view s, CivilMinute* c) {
+ return ParseLenient(s, c);
+}
+bool ParseLenientCivilTime(string_view s, CivilHour* c) {
+ return ParseLenient(s, c);
+}
+bool ParseLenientCivilTime(string_view s, CivilDay* c) {
+ return ParseLenient(s, c);
+}
+bool ParseLenientCivilTime(string_view s, CivilMonth* c) {
+ return ParseLenient(s, c);
+}
+bool ParseLenientCivilTime(string_view s, CivilYear* c) {
+ return ParseLenient(s, c);
+}
+
+namespace time_internal {
+
+std::ostream& operator<<(std::ostream& os, CivilYear y) {
+ return os << FormatCivilTime(y);
+}
+std::ostream& operator<<(std::ostream& os, CivilMonth m) {
+ return os << FormatCivilTime(m);
+}
+std::ostream& operator<<(std::ostream& os, CivilDay d) {
+ return os << FormatCivilTime(d);
+}
+std::ostream& operator<<(std::ostream& os, CivilHour h) {
+ return os << FormatCivilTime(h);
+}
+std::ostream& operator<<(std::ostream& os, CivilMinute m) {
+ return os << FormatCivilTime(m);
+}
+std::ostream& operator<<(std::ostream& os, CivilSecond s) {
+ return os << FormatCivilTime(s);
+}
+
+} // namespace time_internal
+
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.h
index 8c38deaefb..64fb6da494 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.h
@@ -1,538 +1,538 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: civil_time.h
-// -----------------------------------------------------------------------------
-//
-// This header file defines abstractions for computing with "civil time".
-// The term "civil time" refers to the legally recognized human-scale time
-// that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date"
-// is perhaps the most common example of a civil time (represented here as
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: civil_time.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines abstractions for computing with "civil time".
+// The term "civil time" refers to the legally recognized human-scale time
+// that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date"
+// is perhaps the most common example of a civil time (represented here as
// an `y_absl::CivilDay`).
-//
-// Modern-day civil time follows the Gregorian Calendar and is a
-// time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for
-// example, is not tied to a time zone. Put another way, a civil time does not
-// map to a unique point in time; a civil time must be mapped to an absolute
-// time *through* a time zone.
-//
-// Because a civil time is what most people think of as "time," it is common to
-// map absolute times to civil times to present to users.
-//
-// Time zones define the relationship between absolute and civil times. Given an
-// absolute or civil time and a time zone, you can compute the other time:
-//
-// Civil Time = F(Absolute Time, Time Zone)
-// Absolute Time = G(Civil Time, Time Zone)
-//
-// The Abseil time library allows you to construct such civil times from
-// absolute times; consult time.h for such functionality.
-//
-// This library provides six classes for constructing civil-time objects, and
-// provides several helper functions for rounding, iterating, and performing
-// arithmetic on civil-time objects, while avoiding complications like
-// daylight-saving time (DST):
-//
+//
+// Modern-day civil time follows the Gregorian Calendar and is a
+// time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for
+// example, is not tied to a time zone. Put another way, a civil time does not
+// map to a unique point in time; a civil time must be mapped to an absolute
+// time *through* a time zone.
+//
+// Because a civil time is what most people think of as "time," it is common to
+// map absolute times to civil times to present to users.
+//
+// Time zones define the relationship between absolute and civil times. Given an
+// absolute or civil time and a time zone, you can compute the other time:
+//
+// Civil Time = F(Absolute Time, Time Zone)
+// Absolute Time = G(Civil Time, Time Zone)
+//
+// The Abseil time library allows you to construct such civil times from
+// absolute times; consult time.h for such functionality.
+//
+// This library provides six classes for constructing civil-time objects, and
+// provides several helper functions for rounding, iterating, and performing
+// arithmetic on civil-time objects, while avoiding complications like
+// daylight-saving time (DST):
+//
// * `y_absl::CivilSecond`
// * `y_absl::CivilMinute`
// * `y_absl::CivilHour`
// * `y_absl::CivilDay`
// * `y_absl::CivilMonth`
// * `y_absl::CivilYear`
-//
-// Example:
-//
-// // Construct a civil-time object for a specific day
+//
+// Example:
+//
+// // Construct a civil-time object for a specific day
// const y_absl::CivilDay cd(1969, 07, 20);
-//
-// // Construct a civil-time object for a specific second
+//
+// // Construct a civil-time object for a specific second
// const y_absl::CivilSecond cd(2018, 8, 1, 12, 0, 1);
-//
-// Note: In C++14 and later, this library is usable in a constexpr context.
-//
-// Example:
-//
-// // Valid in C++14
+//
+// Note: In C++14 and later, this library is usable in a constexpr context.
+//
+// Example:
+//
+// // Valid in C++14
// constexpr y_absl::CivilDay cd(1969, 07, 20);
-
-#ifndef ABSL_TIME_CIVIL_TIME_H_
-#define ABSL_TIME_CIVIL_TIME_H_
-
+
+#ifndef ABSL_TIME_CIVIL_TIME_H_
+#define ABSL_TIME_CIVIL_TIME_H_
+
#include <util/generic/string.h>
-
+
#include "y_absl/strings/string_view.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-namespace time_internal {
-struct second_tag : cctz::detail::second_tag {};
-struct minute_tag : second_tag, cctz::detail::minute_tag {};
-struct hour_tag : minute_tag, cctz::detail::hour_tag {};
-struct day_tag : hour_tag, cctz::detail::day_tag {};
-struct month_tag : day_tag, cctz::detail::month_tag {};
-struct year_tag : month_tag, cctz::detail::year_tag {};
-} // namespace time_internal
-
-// -----------------------------------------------------------------------------
-// CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear
-// -----------------------------------------------------------------------------
-//
-// Each of these civil-time types is a simple value type with the same
-// interface for construction and the same six accessors for each of the civil
-// time fields (year, month, day, hour, minute, and second, aka YMDHMS). These
-// classes differ only in their alignment, which is indicated by the type name
-// and specifies the field on which arithmetic operates.
-//
-// CONSTRUCTION
-//
-// Each of the civil-time types can be constructed in two ways: by directly
-// passing to the constructor up to six integers representing the YMDHMS fields,
-// or by copying the YMDHMS fields from a differently aligned civil-time type.
-// Omitted fields are assigned their minimum valid value. Hours, minutes, and
-// seconds will be set to 0, month and day will be set to 1. Since there is no
-// minimum year, the default is 1970.
-//
-// Examples:
-//
+
+namespace time_internal {
+struct second_tag : cctz::detail::second_tag {};
+struct minute_tag : second_tag, cctz::detail::minute_tag {};
+struct hour_tag : minute_tag, cctz::detail::hour_tag {};
+struct day_tag : hour_tag, cctz::detail::day_tag {};
+struct month_tag : day_tag, cctz::detail::month_tag {};
+struct year_tag : month_tag, cctz::detail::year_tag {};
+} // namespace time_internal
+
+// -----------------------------------------------------------------------------
+// CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear
+// -----------------------------------------------------------------------------
+//
+// Each of these civil-time types is a simple value type with the same
+// interface for construction and the same six accessors for each of the civil
+// time fields (year, month, day, hour, minute, and second, aka YMDHMS). These
+// classes differ only in their alignment, which is indicated by the type name
+// and specifies the field on which arithmetic operates.
+//
+// CONSTRUCTION
+//
+// Each of the civil-time types can be constructed in two ways: by directly
+// passing to the constructor up to six integers representing the YMDHMS fields,
+// or by copying the YMDHMS fields from a differently aligned civil-time type.
+// Omitted fields are assigned their minimum valid value. Hours, minutes, and
+// seconds will be set to 0, month and day will be set to 1. Since there is no
+// minimum year, the default is 1970.
+//
+// Examples:
+//
// y_absl::CivilDay default_value; // 1970-01-01 00:00:00
-//
+//
// y_absl::CivilDay a(2015, 2, 3); // 2015-02-03 00:00:00
// y_absl::CivilDay b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00
// y_absl::CivilDay c(2015); // 2015-01-01 00:00:00
-//
+//
// y_absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06
// y_absl::CivilMinute mm(ss); // 2015-02-03 04:05:00
// y_absl::CivilHour hh(mm); // 2015-02-03 04:00:00
// y_absl::CivilDay d(hh); // 2015-02-03 00:00:00
// y_absl::CivilMonth m(d); // 2015-02-01 00:00:00
// y_absl::CivilYear y(m); // 2015-01-01 00:00:00
-//
+//
// m = y_absl::CivilMonth(y); // 2015-01-01 00:00:00
// d = y_absl::CivilDay(m); // 2015-01-01 00:00:00
// hh = y_absl::CivilHour(d); // 2015-01-01 00:00:00
// mm = y_absl::CivilMinute(hh); // 2015-01-01 00:00:00
// ss = y_absl::CivilSecond(mm); // 2015-01-01 00:00:00
-//
-// Each civil-time class is aligned to the civil-time field indicated in the
-// class's name after normalization. Alignment is performed by setting all the
-// inferior fields to their minimum valid value (as described above). The
-// following are examples of how each of the six types would align the fields
-// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
-// string format used here is not important; it's just a shorthand way of
-// showing the six YMDHMS fields.)
-//
+//
+// Each civil-time class is aligned to the civil-time field indicated in the
+// class's name after normalization. Alignment is performed by setting all the
+// inferior fields to their minimum valid value (as described above). The
+// following are examples of how each of the six types would align the fields
+// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
+// string format used here is not important; it's just a shorthand way of
+// showing the six YMDHMS fields.)
+//
// y_absl::CivilSecond : 2015-11-22 12:34:56
// y_absl::CivilMinute : 2015-11-22 12:34:00
// y_absl::CivilHour : 2015-11-22 12:00:00
// y_absl::CivilDay : 2015-11-22 00:00:00
// y_absl::CivilMonth : 2015-11-01 00:00:00
// y_absl::CivilYear : 2015-01-01 00:00:00
-//
-// Each civil-time type performs arithmetic on the field to which it is
+//
+// Each civil-time type performs arithmetic on the field to which it is
// aligned. This means that adding 1 to an y_absl::CivilDay increments the day
// field (normalizing as necessary), and subtracting 7 from an y_absl::CivilMonth
-// operates on the month field (normalizing as necessary). All arithmetic
-// produces a valid civil time. Difference requires two similarly aligned
-// civil-time objects and returns the scalar answer in units of the objects'
+// operates on the month field (normalizing as necessary). All arithmetic
+// produces a valid civil time. Difference requires two similarly aligned
+// civil-time objects and returns the scalar answer in units of the objects'
// alignment. For example, the difference between two y_absl::CivilHour objects
-// will give an answer in units of civil hours.
-//
-// ALIGNMENT CONVERSION
-//
-// The alignment of a civil-time object cannot change, but the object may be
-// used to construct a new object with a different alignment. This is referred
-// to as "realigning". When realigning to a type with the same or more
+// will give an answer in units of civil hours.
+//
+// ALIGNMENT CONVERSION
+//
+// The alignment of a civil-time object cannot change, but the object may be
+// used to construct a new object with a different alignment. This is referred
+// to as "realigning". When realigning to a type with the same or more
// precision (e.g., y_absl::CivilDay -> y_absl::CivilSecond), the conversion may be
-// performed implicitly since no information is lost. However, if information
-// could be discarded (e.g., CivilSecond -> CivilDay), the conversion must
-// be explicit at the call site.
-//
-// Examples:
-//
+// performed implicitly since no information is lost. However, if information
+// could be discarded (e.g., CivilSecond -> CivilDay), the conversion must
+// be explicit at the call site.
+//
+// Examples:
+//
// void UseDay(y_absl::CivilDay day);
-//
+//
// y_absl::CivilSecond cs;
-// UseDay(cs); // Won't compile because data may be discarded
+// UseDay(cs); // Won't compile because data may be discarded
// UseDay(y_absl::CivilDay(cs)); // OK: explicit conversion
-//
+//
// y_absl::CivilDay cd;
-// UseDay(cd); // OK: no conversion needed
-//
+// UseDay(cd); // OK: no conversion needed
+//
// y_absl::CivilMonth cm;
// UseDay(cm); // OK: implicit conversion to y_absl::CivilDay
-//
-// NORMALIZATION
-//
-// Normalization takes invalid values and adjusts them to produce valid values.
-// Within the civil-time library, integer arguments passed to the Civil*
-// constructors may be out-of-range, in which case they are normalized by
-// carrying overflow into a field of courser granularity to produce valid
-// civil-time objects. This normalization enables natural arithmetic on
-// constructor arguments without worrying about the field's range.
-//
-// Examples:
-//
-// // Out-of-range; normalized to 2016-11-01
+//
+// NORMALIZATION
+//
+// Normalization takes invalid values and adjusts them to produce valid values.
+// Within the civil-time library, integer arguments passed to the Civil*
+// constructors may be out-of-range, in which case they are normalized by
+// carrying overflow into a field of courser granularity to produce valid
+// civil-time objects. This normalization enables natural arithmetic on
+// constructor arguments without worrying about the field's range.
+//
+// Examples:
+//
+// // Out-of-range; normalized to 2016-11-01
// y_absl::CivilDay d(2016, 10, 32);
-// // Out-of-range, negative: normalized to 2016-10-30T23
+// // Out-of-range, negative: normalized to 2016-10-30T23
// y_absl::CivilHour h1(2016, 10, 31, -1);
-// // Normalization is cumulative: normalized to 2016-10-30T23
+// // Normalization is cumulative: normalized to 2016-10-30T23
// y_absl::CivilHour h2(2016, 10, 32, -25);
-//
-// Note: If normalization is undesired, you can signal an error by comparing
-// the constructor arguments to the normalized values returned by the YMDHMS
-// properties.
-//
-// COMPARISON
-//
-// Comparison between civil-time objects considers all six YMDHMS fields,
-// regardless of the type's alignment. Comparison between differently aligned
-// civil-time types is allowed.
-//
-// Examples:
-//
+//
+// Note: If normalization is undesired, you can signal an error by comparing
+// the constructor arguments to the normalized values returned by the YMDHMS
+// properties.
+//
+// COMPARISON
+//
+// Comparison between civil-time objects considers all six YMDHMS fields,
+// regardless of the type's alignment. Comparison between differently aligned
+// civil-time types is allowed.
+//
+// Examples:
+//
// y_absl::CivilDay feb_3(2015, 2, 3); // 2015-02-03 00:00:00
// y_absl::CivilDay mar_4(2015, 3, 4); // 2015-03-04 00:00:00
-// // feb_3 < mar_4
+// // feb_3 < mar_4
// // y_absl::CivilYear(feb_3) == y_absl::CivilYear(mar_4)
-//
+//
// y_absl::CivilSecond feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00
-// // feb_3 < feb_3_noon
+// // feb_3 < feb_3_noon
// // feb_3 == y_absl::CivilDay(feb_3_noon)
-//
-// // Iterates all the days of February 2015.
+//
+// // Iterates all the days of February 2015.
// for (y_absl::CivilDay d(2015, 2, 1); d < y_absl::CivilMonth(2015, 3); ++d) {
-// // ...
-// }
-//
-// ARITHMETIC
-//
-// Civil-time types support natural arithmetic operators such as addition,
-// subtraction, and difference. Arithmetic operates on the civil-time field
-// indicated in the type's name. Difference operators require arguments with
-// the same alignment and return the answer in units of the alignment.
-//
-// Example:
-//
+// // ...
+// }
+//
+// ARITHMETIC
+//
+// Civil-time types support natural arithmetic operators such as addition,
+// subtraction, and difference. Arithmetic operates on the civil-time field
+// indicated in the type's name. Difference operators require arguments with
+// the same alignment and return the answer in units of the alignment.
+//
+// Example:
+//
// y_absl::CivilDay a(2015, 2, 3);
-// ++a; // 2015-02-04 00:00:00
-// --a; // 2015-02-03 00:00:00
+// ++a; // 2015-02-04 00:00:00
+// --a; // 2015-02-03 00:00:00
// y_absl::CivilDay b = a + 1; // 2015-02-04 00:00:00
// y_absl::CivilDay c = 1 + b; // 2015-02-05 00:00:00
-// int n = c - a; // n = 2 (civil days)
+// int n = c - a; // n = 2 (civil days)
// int m = c - y_absl::CivilMonth(c); // Won't compile: different types.
-//
-// ACCESSORS
-//
-// Each civil-time type has accessors for all six of the civil-time fields:
-// year, month, day, hour, minute, and second.
-//
-// civil_year_t year()
-// int month()
-// int day()
-// int hour()
-// int minute()
-// int second()
-//
-// Recall that fields inferior to the type's alignment will be set to their
-// minimum valid value.
-//
-// Example:
-//
+//
+// ACCESSORS
+//
+// Each civil-time type has accessors for all six of the civil-time fields:
+// year, month, day, hour, minute, and second.
+//
+// civil_year_t year()
+// int month()
+// int day()
+// int hour()
+// int minute()
+// int second()
+//
+// Recall that fields inferior to the type's alignment will be set to their
+// minimum valid value.
+//
+// Example:
+//
// y_absl::CivilDay d(2015, 6, 28);
-// // d.year() == 2015
-// // d.month() == 6
-// // d.day() == 28
-// // d.hour() == 0
-// // d.minute() == 0
-// // d.second() == 0
-//
-// CASE STUDY: Adding a month to January 31.
-//
-// One of the classic questions that arises when considering a civil time
-// library (or a date library or a date/time library) is this:
-// "What is the result of adding a month to January 31?"
-// This is an interesting question because it is unclear what is meant by a
-// "month", and several different answers are possible, depending on context:
-//
-// 1. March 3 (or 2 if a leap year), if "add a month" means to add a month to
-// the current month, and adjust the date to overflow the extra days into
-// March. In this case the result of "February 31" would be normalized as
-// within the civil-time library.
-// 2. February 28 (or 29 if a leap year), if "add a month" means to add a
-// month, and adjust the date while holding the resulting month constant.
-// In this case, the result of "February 31" would be truncated to the last
-// day in February.
-// 3. An error. The caller may get some error, an exception, an invalid date
-// object, or perhaps return `false`. This may make sense because there is
-// no single unambiguously correct answer to the question.
-//
-// Practically speaking, any answer that is not what the programmer intended
-// is the wrong answer.
-//
-// The Abseil time library avoids this problem by making it impossible to
-// ask ambiguous questions. All civil-time objects are aligned to a particular
-// civil-field boundary (such as aligned to a year, month, day, hour, minute,
-// or second), and arithmetic operates on the field to which the object is
-// aligned. This means that in order to "add a month" the object must first be
-// aligned to a month boundary, which is equivalent to the first day of that
-// month.
-//
-// Of course, there are ways to compute an answer the question at hand using
-// this Abseil time library, but they require the programmer to be explicit
-// about the answer they expect. To illustrate, let's see how to compute all
-// three of the above possible answers to the question of "Jan 31 plus 1
-// month":
-//
-// Example:
-//
+// // d.year() == 2015
+// // d.month() == 6
+// // d.day() == 28
+// // d.hour() == 0
+// // d.minute() == 0
+// // d.second() == 0
+//
+// CASE STUDY: Adding a month to January 31.
+//
+// One of the classic questions that arises when considering a civil time
+// library (or a date library or a date/time library) is this:
+// "What is the result of adding a month to January 31?"
+// This is an interesting question because it is unclear what is meant by a
+// "month", and several different answers are possible, depending on context:
+//
+// 1. March 3 (or 2 if a leap year), if "add a month" means to add a month to
+// the current month, and adjust the date to overflow the extra days into
+// March. In this case the result of "February 31" would be normalized as
+// within the civil-time library.
+// 2. February 28 (or 29 if a leap year), if "add a month" means to add a
+// month, and adjust the date while holding the resulting month constant.
+// In this case, the result of "February 31" would be truncated to the last
+// day in February.
+// 3. An error. The caller may get some error, an exception, an invalid date
+// object, or perhaps return `false`. This may make sense because there is
+// no single unambiguously correct answer to the question.
+//
+// Practically speaking, any answer that is not what the programmer intended
+// is the wrong answer.
+//
+// The Abseil time library avoids this problem by making it impossible to
+// ask ambiguous questions. All civil-time objects are aligned to a particular
+// civil-field boundary (such as aligned to a year, month, day, hour, minute,
+// or second), and arithmetic operates on the field to which the object is
+// aligned. This means that in order to "add a month" the object must first be
+// aligned to a month boundary, which is equivalent to the first day of that
+// month.
+//
+// Of course, there are ways to compute an answer the question at hand using
+// this Abseil time library, but they require the programmer to be explicit
+// about the answer they expect. To illustrate, let's see how to compute all
+// three of the above possible answers to the question of "Jan 31 plus 1
+// month":
+//
+// Example:
+//
// const y_absl::CivilDay d(2015, 1, 31);
-//
-// // Answer 1:
-// // Add 1 to the month field in the constructor, and rely on normalization.
+//
+// // Answer 1:
+// // Add 1 to the month field in the constructor, and rely on normalization.
// const auto normalized = y_absl::CivilDay(d.year(), d.month() + 1, d.day());
-// // normalized == 2015-03-03 (aka Feb 31)
-//
-// // Answer 2:
-// // Add 1 to month field, capping to the end of next month.
+// // normalized == 2015-03-03 (aka Feb 31)
+//
+// // Answer 2:
+// // Add 1 to month field, capping to the end of next month.
// const auto next_month = y_absl::CivilMonth(d) + 1;
// const auto last_day_of_next_month = y_absl::CivilDay(next_month + 1) - 1;
-// const auto capped = std::min(normalized, last_day_of_next_month);
-// // capped == 2015-02-28
-//
-// // Answer 3:
-// // Signal an error if the normalized answer is not in next month.
+// const auto capped = std::min(normalized, last_day_of_next_month);
+// // capped == 2015-02-28
+//
+// // Answer 3:
+// // Signal an error if the normalized answer is not in next month.
// if (y_absl::CivilMonth(normalized) != next_month) {
-// // error, month overflow
-// }
-//
-using CivilSecond =
- time_internal::cctz::detail::civil_time<time_internal::second_tag>;
-using CivilMinute =
- time_internal::cctz::detail::civil_time<time_internal::minute_tag>;
-using CivilHour =
- time_internal::cctz::detail::civil_time<time_internal::hour_tag>;
-using CivilDay =
- time_internal::cctz::detail::civil_time<time_internal::day_tag>;
-using CivilMonth =
- time_internal::cctz::detail::civil_time<time_internal::month_tag>;
-using CivilYear =
- time_internal::cctz::detail::civil_time<time_internal::year_tag>;
-
-// civil_year_t
-//
-// Type alias of a civil-time year value. This type is guaranteed to (at least)
-// support any year value supported by `time_t`.
-//
-// Example:
-//
+// // error, month overflow
+// }
+//
+using CivilSecond =
+ time_internal::cctz::detail::civil_time<time_internal::second_tag>;
+using CivilMinute =
+ time_internal::cctz::detail::civil_time<time_internal::minute_tag>;
+using CivilHour =
+ time_internal::cctz::detail::civil_time<time_internal::hour_tag>;
+using CivilDay =
+ time_internal::cctz::detail::civil_time<time_internal::day_tag>;
+using CivilMonth =
+ time_internal::cctz::detail::civil_time<time_internal::month_tag>;
+using CivilYear =
+ time_internal::cctz::detail::civil_time<time_internal::year_tag>;
+
+// civil_year_t
+//
+// Type alias of a civil-time year value. This type is guaranteed to (at least)
+// support any year value supported by `time_t`.
+//
+// Example:
+//
// y_absl::CivilSecond cs = ...;
// y_absl::civil_year_t y = cs.year();
// cs = y_absl::CivilSecond(y, 1, 1, 0, 0, 0); // CivilSecond(CivilYear(cs))
-//
-using civil_year_t = time_internal::cctz::year_t;
-
-// civil_diff_t
-//
-// Type alias of the difference between two civil-time values.
-// This type is used to indicate arguments that are not
-// normalized (such as parameters to the civil-time constructors), the results
-// of civil-time subtraction, or the operand to civil-time addition.
-//
-// Example:
-//
+//
+using civil_year_t = time_internal::cctz::year_t;
+
+// civil_diff_t
+//
+// Type alias of the difference between two civil-time values.
+// This type is used to indicate arguments that are not
+// normalized (such as parameters to the civil-time constructors), the results
+// of civil-time subtraction, or the operand to civil-time addition.
+//
+// Example:
+//
// y_absl::civil_diff_t n_sec = cs1 - cs2; // cs1 == cs2 + n_sec;
-//
-using civil_diff_t = time_internal::cctz::diff_t;
-
-// Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday,
-// Weekday::friday, Weekday::saturday, Weekday::sunday
-//
-// The Weekday enum class represents the civil-time concept of a "weekday" with
-// members for all days of the week.
-//
+//
+using civil_diff_t = time_internal::cctz::diff_t;
+
+// Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday,
+// Weekday::friday, Weekday::saturday, Weekday::sunday
+//
+// The Weekday enum class represents the civil-time concept of a "weekday" with
+// members for all days of the week.
+//
// y_absl::Weekday wd = y_absl::Weekday::thursday;
-//
-using Weekday = time_internal::cctz::weekday;
-
-// GetWeekday()
-//
+//
+using Weekday = time_internal::cctz::weekday;
+
+// GetWeekday()
+//
// Returns the y_absl::Weekday for the given (realigned) civil-time value.
-//
-// Example:
-//
+//
+// Example:
+//
// y_absl::CivilDay a(2015, 8, 13);
// y_absl::Weekday wd = y_absl::GetWeekday(a); // wd == y_absl::Weekday::thursday
-//
-inline Weekday GetWeekday(CivilSecond cs) {
- return time_internal::cctz::get_weekday(cs);
-}
-
-// NextWeekday()
-// PrevWeekday()
-//
+//
+inline Weekday GetWeekday(CivilSecond cs) {
+ return time_internal::cctz::get_weekday(cs);
+}
+
+// NextWeekday()
+// PrevWeekday()
+//
// Returns the y_absl::CivilDay that strictly follows or precedes a given
// y_absl::CivilDay, and that falls on the given y_absl::Weekday.
-//
-// Example, given the following month:
-//
-// August 2015
-// Su Mo Tu We Th Fr Sa
-// 1
-// 2 3 4 5 6 7 8
-// 9 10 11 12 13 14 15
-// 16 17 18 19 20 21 22
-// 23 24 25 26 27 28 29
-// 30 31
-//
+//
+// Example, given the following month:
+//
+// August 2015
+// Su Mo Tu We Th Fr Sa
+// 1
+// 2 3 4 5 6 7 8
+// 9 10 11 12 13 14 15
+// 16 17 18 19 20 21 22
+// 23 24 25 26 27 28 29
+// 30 31
+//
// y_absl::CivilDay a(2015, 8, 13);
// // y_absl::GetWeekday(a) == y_absl::Weekday::thursday
// y_absl::CivilDay b = y_absl::NextWeekday(a, y_absl::Weekday::thursday);
-// // b = 2015-08-20
+// // b = 2015-08-20
// y_absl::CivilDay c = y_absl::PrevWeekday(a, y_absl::Weekday::thursday);
-// // c = 2015-08-06
-//
+// // c = 2015-08-06
+//
// y_absl::CivilDay d = ...
-// // Gets the following Thursday if d is not already Thursday
+// // Gets the following Thursday if d is not already Thursday
// y_absl::CivilDay thurs1 = y_absl::NextWeekday(d - 1, y_absl::Weekday::thursday);
-// // Gets the previous Thursday if d is not already Thursday
+// // Gets the previous Thursday if d is not already Thursday
// y_absl::CivilDay thurs2 = y_absl::PrevWeekday(d + 1, y_absl::Weekday::thursday);
-//
-inline CivilDay NextWeekday(CivilDay cd, Weekday wd) {
- return CivilDay(time_internal::cctz::next_weekday(cd, wd));
-}
-inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) {
- return CivilDay(time_internal::cctz::prev_weekday(cd, wd));
-}
-
-// GetYearDay()
-//
-// Returns the day-of-year for the given (realigned) civil-time value.
-//
-// Example:
-//
+//
+inline CivilDay NextWeekday(CivilDay cd, Weekday wd) {
+ return CivilDay(time_internal::cctz::next_weekday(cd, wd));
+}
+inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) {
+ return CivilDay(time_internal::cctz::prev_weekday(cd, wd));
+}
+
+// GetYearDay()
+//
+// Returns the day-of-year for the given (realigned) civil-time value.
+//
+// Example:
+//
// y_absl::CivilDay a(2015, 1, 1);
// int yd_jan_1 = y_absl::GetYearDay(a); // yd_jan_1 = 1
// y_absl::CivilDay b(2015, 12, 31);
// int yd_dec_31 = y_absl::GetYearDay(b); // yd_dec_31 = 365
-//
-inline int GetYearDay(CivilSecond cs) {
- return time_internal::cctz::get_yearday(cs);
-}
-
-// FormatCivilTime()
-//
-// Formats the given civil-time value into a string value of the following
-// format:
-//
-// Type | Format
-// ---------------------------------
-// CivilSecond | YYYY-MM-DDTHH:MM:SS
-// CivilMinute | YYYY-MM-DDTHH:MM
-// CivilHour | YYYY-MM-DDTHH
-// CivilDay | YYYY-MM-DD
-// CivilMonth | YYYY-MM
-// CivilYear | YYYY
-//
-// Example:
-//
+//
+inline int GetYearDay(CivilSecond cs) {
+ return time_internal::cctz::get_yearday(cs);
+}
+
+// FormatCivilTime()
+//
+// Formats the given civil-time value into a string value of the following
+// format:
+//
+// Type | Format
+// ---------------------------------
+// CivilSecond | YYYY-MM-DDTHH:MM:SS
+// CivilMinute | YYYY-MM-DDTHH:MM
+// CivilHour | YYYY-MM-DDTHH
+// CivilDay | YYYY-MM-DD
+// CivilMonth | YYYY-MM
+// CivilYear | YYYY
+//
+// Example:
+//
// y_absl::CivilDay d = y_absl::CivilDay(1969, 7, 20);
// TString day_string = y_absl::FormatCivilTime(d); // "1969-07-20"
-//
+//
TString FormatCivilTime(CivilSecond c);
TString FormatCivilTime(CivilMinute c);
TString FormatCivilTime(CivilHour c);
TString FormatCivilTime(CivilDay c);
TString FormatCivilTime(CivilMonth c);
TString FormatCivilTime(CivilYear c);
-
+
// y_absl::ParseCivilTime()
-//
+//
// Parses a civil-time value from the specified `y_absl::string_view` into the
-// passed output parameter. Returns `true` upon successful parsing.
-//
-// The expected form of the input string is as follows:
-//
-// Type | Format
-// ---------------------------------
-// CivilSecond | YYYY-MM-DDTHH:MM:SS
-// CivilMinute | YYYY-MM-DDTHH:MM
-// CivilHour | YYYY-MM-DDTHH
-// CivilDay | YYYY-MM-DD
-// CivilMonth | YYYY-MM
-// CivilYear | YYYY
-//
-// Example:
-//
+// passed output parameter. Returns `true` upon successful parsing.
+//
+// The expected form of the input string is as follows:
+//
+// Type | Format
+// ---------------------------------
+// CivilSecond | YYYY-MM-DDTHH:MM:SS
+// CivilMinute | YYYY-MM-DDTHH:MM
+// CivilHour | YYYY-MM-DDTHH
+// CivilDay | YYYY-MM-DD
+// CivilMonth | YYYY-MM
+// CivilYear | YYYY
+//
+// Example:
+//
// y_absl::CivilDay d;
// bool ok = y_absl::ParseCivilTime("2018-01-02", &d); // OK
-//
-// Note that parsing will fail if the string's format does not match the
-// expected type exactly. `ParseLenientCivilTime()` below is more lenient.
-//
+//
+// Note that parsing will fail if the string's format does not match the
+// expected type exactly. `ParseLenientCivilTime()` below is more lenient.
+//
bool ParseCivilTime(y_absl::string_view s, CivilSecond* c);
bool ParseCivilTime(y_absl::string_view s, CivilMinute* c);
bool ParseCivilTime(y_absl::string_view s, CivilHour* c);
bool ParseCivilTime(y_absl::string_view s, CivilDay* c);
bool ParseCivilTime(y_absl::string_view s, CivilMonth* c);
bool ParseCivilTime(y_absl::string_view s, CivilYear* c);
-
-// ParseLenientCivilTime()
-//
+
+// ParseLenientCivilTime()
+//
// Parses any of the formats accepted by `y_absl::ParseCivilTime()`, but is more
-// lenient if the format of the string does not exactly match the associated
-// type.
-//
-// Example:
-//
+// lenient if the format of the string does not exactly match the associated
+// type.
+//
+// Example:
+//
// y_absl::CivilDay d;
// bool ok = y_absl::ParseLenientCivilTime("1969-07-20", &d); // OK
// ok = y_absl::ParseLenientCivilTime("1969-07-20T10", &d); // OK: T10 floored
// ok = y_absl::ParseLenientCivilTime("1969-07", &d); // OK: day defaults to 1
-//
+//
bool ParseLenientCivilTime(y_absl::string_view s, CivilSecond* c);
bool ParseLenientCivilTime(y_absl::string_view s, CivilMinute* c);
bool ParseLenientCivilTime(y_absl::string_view s, CivilHour* c);
bool ParseLenientCivilTime(y_absl::string_view s, CivilDay* c);
bool ParseLenientCivilTime(y_absl::string_view s, CivilMonth* c);
bool ParseLenientCivilTime(y_absl::string_view s, CivilYear* c);
-
-namespace time_internal { // For functions found via ADL on civil-time tags.
-
-// Streaming Operators
-//
-// Each civil-time type may be sent to an output stream using operator<<().
-// The result matches the string produced by `FormatCivilTime()`.
-//
-// Example:
-//
+
+namespace time_internal { // For functions found via ADL on civil-time tags.
+
+// Streaming Operators
+//
+// Each civil-time type may be sent to an output stream using operator<<().
+// The result matches the string produced by `FormatCivilTime()`.
+//
+// Example:
+//
// y_absl::CivilDay d = y_absl::CivilDay(1969, 7, 20);
-// std::cout << "Date is: " << d << "\n";
-//
-std::ostream& operator<<(std::ostream& os, CivilYear y);
-std::ostream& operator<<(std::ostream& os, CivilMonth m);
-std::ostream& operator<<(std::ostream& os, CivilDay d);
-std::ostream& operator<<(std::ostream& os, CivilHour h);
-std::ostream& operator<<(std::ostream& os, CivilMinute m);
-std::ostream& operator<<(std::ostream& os, CivilSecond s);
-
-} // namespace time_internal
-
+// std::cout << "Date is: " << d << "\n";
+//
+std::ostream& operator<<(std::ostream& os, CivilYear y);
+std::ostream& operator<<(std::ostream& os, CivilMonth m);
+std::ostream& operator<<(std::ostream& os, CivilDay d);
+std::ostream& operator<<(std::ostream& os, CivilHour h);
+std::ostream& operator<<(std::ostream& os, CivilMinute m);
+std::ostream& operator<<(std::ostream& os, CivilSecond s);
+
+} // namespace time_internal
+
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_CIVIL_TIME_H_
+
+#endif // ABSL_TIME_CIVIL_TIME_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time/ya.make
index ac600f852c..919773f619 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time/ya.make
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time/ya.make
@@ -1,26 +1,26 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-
+
OWNER(
somov
g:cpp-contrib
)
-LICENSE(Apache-2.0)
-
+LICENSE(Apache-2.0)
+
ADDINCL(
GLOBAL contrib/restricted/abseil-cpp-tstring
)
-
-NO_COMPILER_WARNINGS()
-
+
+NO_COMPILER_WARNINGS()
+
SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src)
-
-SRCS(
- civil_time_detail.cc
-)
-
-END()
+
+SRCS(
+ civil_time_detail.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.cc
index d29b8e89d0..dcc12b5633 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.cc
@@ -1,178 +1,178 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "y_absl/time/clock.h"
-
+
#include "y_absl/base/attributes.h"
#include "y_absl/base/optimization.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#include <algorithm>
-#include <atomic>
-#include <cerrno>
-#include <cstdint>
-#include <ctime>
-#include <limits>
-
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <algorithm>
+#include <atomic>
+#include <cerrno>
+#include <cstdint>
+#include <ctime>
+#include <limits>
+
#include "y_absl/base/internal/spinlock.h"
#include "y_absl/base/internal/unscaledcycleclock.h"
#include "y_absl/base/macros.h"
#include "y_absl/base/port.h"
#include "y_absl/base/thread_annotations.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-Time Now() {
- // TODO(bww): Get a timespec instead so we don't have to divide.
+Time Now() {
+ // TODO(bww): Get a timespec instead so we don't have to divide.
int64_t n = y_absl::GetCurrentTimeNanos();
- if (n >= 0) {
- return time_internal::FromUnixDuration(
- time_internal::MakeDuration(n / 1000000000, n % 1000000000 * 4));
- }
+ if (n >= 0) {
+ return time_internal::FromUnixDuration(
+ time_internal::MakeDuration(n / 1000000000, n % 1000000000 * 4));
+ }
return time_internal::FromUnixDuration(y_absl::Nanoseconds(n));
-}
+}
ABSL_NAMESPACE_END
} // namespace y_absl
-
-// Decide if we should use the fast GetCurrentTimeNanos() algorithm
-// based on the cyclecounter, otherwise just get the time directly
-// from the OS on every call. This can be chosen at compile-time via
-// -DABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS=[0|1]
-#ifndef ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
-#if ABSL_USE_UNSCALED_CYCLECLOCK
-#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 1
-#else
-#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 0
-#endif
-#endif
-
-#if defined(__APPLE__) || defined(_WIN32)
+
+// Decide if we should use the fast GetCurrentTimeNanos() algorithm
+// based on the cyclecounter, otherwise just get the time directly
+// from the OS on every call. This can be chosen at compile-time via
+// -DABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS=[0|1]
+#ifndef ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
+#if ABSL_USE_UNSCALED_CYCLECLOCK
+#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 1
+#else
+#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 0
+#endif
+#endif
+
+#if defined(__APPLE__) || defined(_WIN32)
#include "y_absl/time/internal/get_current_time_chrono.inc"
-#else
+#else
#include "y_absl/time/internal/get_current_time_posix.inc"
-#endif
-
-// Allows override by test.
-#ifndef GET_CURRENT_TIME_NANOS_FROM_SYSTEM
-#define GET_CURRENT_TIME_NANOS_FROM_SYSTEM() \
+#endif
+
+// Allows override by test.
+#ifndef GET_CURRENT_TIME_NANOS_FROM_SYSTEM
+#define GET_CURRENT_TIME_NANOS_FROM_SYSTEM() \
::y_absl::time_internal::GetCurrentTimeNanosFromSystem()
-#endif
-
-#if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
+#endif
+
+#if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
namespace y_absl {
ABSL_NAMESPACE_BEGIN
int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); }
ABSL_NAMESPACE_END
} // namespace y_absl
-#else // Use the cyclecounter-based implementation below.
-
-// Allows override by test.
-#ifndef GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW
-#define GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW() \
+#else // Use the cyclecounter-based implementation below.
+
+// Allows override by test.
+#ifndef GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW
+#define GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW() \
::y_absl::time_internal::UnscaledCycleClockWrapperForGetCurrentTime::Now()
-#endif
-
+#endif
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-// This is a friend wrapper around UnscaledCycleClock::Now()
-// (needed to access UnscaledCycleClock).
-class UnscaledCycleClockWrapperForGetCurrentTime {
- public:
- static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); }
-};
-} // namespace time_internal
-
-// uint64_t is used in this module to provide an extra bit in multiplications
-
-// ---------------------------------------------------------------------
-// An implementation of reader-write locks that use no atomic ops in the read
-// case. This is a generalization of Lamport's method for reading a multiword
-// clock. Increment a word on each write acquisition, using the low-order bit
-// as a spinlock; the word is the high word of the "clock". Readers read the
-// high word, then all other data, then the high word again, and repeat the
-// read if the reads of the high words yields different answers, or an odd
-// value (either case suggests possible interference from a writer).
-// Here we use a spinlock to ensure only one writer at a time, rather than
-// spinning on the bottom bit of the word to benefit from SpinLock
-// spin-delay tuning.
-
-// Acquire seqlock (*seq) and return the value to be written to unlock.
-static inline uint64_t SeqAcquire(std::atomic<uint64_t> *seq) {
- uint64_t x = seq->fetch_add(1, std::memory_order_relaxed);
-
- // We put a release fence between update to *seq and writes to shared data.
- // Thus all stores to shared data are effectively release operations and
- // update to *seq above cannot be re-ordered past any of them. Note that
- // this barrier is not for the fetch_add above. A release barrier for the
- // fetch_add would be before it, not after.
- std::atomic_thread_fence(std::memory_order_release);
-
- return x + 2; // original word plus 2
-}
-
-// Release seqlock (*seq) by writing x to it---a value previously returned by
-// SeqAcquire.
-static inline void SeqRelease(std::atomic<uint64_t> *seq, uint64_t x) {
- // The unlock store to *seq must have release ordering so that all
- // updates to shared data must finish before this store.
- seq->store(x, std::memory_order_release); // release lock for readers
-}
-
-// ---------------------------------------------------------------------
-
-// "nsscaled" is unit of time equal to a (2**kScale)th of a nanosecond.
-enum { kScale = 30 };
-
-// The minimum interval between samples of the time base.
-// We pick enough time to amortize the cost of the sample,
-// to get a reasonably accurate cycle counter rate reading,
-// and not so much that calculations will overflow 64-bits.
-static const uint64_t kMinNSBetweenSamples = 2000 << 20;
-
-// We require that kMinNSBetweenSamples shifted by kScale
-// have at least a bit left over for 64-bit calculations.
-static_assert(((kMinNSBetweenSamples << (kScale + 1)) >> (kScale + 1)) ==
- kMinNSBetweenSamples,
- "cannot represent kMaxBetweenSamplesNSScaled");
-
-// data from a sample of the kernel's time value
-struct TimeSampleAtomic {
+namespace time_internal {
+// This is a friend wrapper around UnscaledCycleClock::Now()
+// (needed to access UnscaledCycleClock).
+class UnscaledCycleClockWrapperForGetCurrentTime {
+ public:
+ static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); }
+};
+} // namespace time_internal
+
+// uint64_t is used in this module to provide an extra bit in multiplications
+
+// ---------------------------------------------------------------------
+// An implementation of reader-write locks that use no atomic ops in the read
+// case. This is a generalization of Lamport's method for reading a multiword
+// clock. Increment a word on each write acquisition, using the low-order bit
+// as a spinlock; the word is the high word of the "clock". Readers read the
+// high word, then all other data, then the high word again, and repeat the
+// read if the reads of the high words yields different answers, or an odd
+// value (either case suggests possible interference from a writer).
+// Here we use a spinlock to ensure only one writer at a time, rather than
+// spinning on the bottom bit of the word to benefit from SpinLock
+// spin-delay tuning.
+
+// Acquire seqlock (*seq) and return the value to be written to unlock.
+static inline uint64_t SeqAcquire(std::atomic<uint64_t> *seq) {
+ uint64_t x = seq->fetch_add(1, std::memory_order_relaxed);
+
+ // We put a release fence between update to *seq and writes to shared data.
+ // Thus all stores to shared data are effectively release operations and
+ // update to *seq above cannot be re-ordered past any of them. Note that
+ // this barrier is not for the fetch_add above. A release barrier for the
+ // fetch_add would be before it, not after.
+ std::atomic_thread_fence(std::memory_order_release);
+
+ return x + 2; // original word plus 2
+}
+
+// Release seqlock (*seq) by writing x to it---a value previously returned by
+// SeqAcquire.
+static inline void SeqRelease(std::atomic<uint64_t> *seq, uint64_t x) {
+ // The unlock store to *seq must have release ordering so that all
+ // updates to shared data must finish before this store.
+ seq->store(x, std::memory_order_release); // release lock for readers
+}
+
+// ---------------------------------------------------------------------
+
+// "nsscaled" is unit of time equal to a (2**kScale)th of a nanosecond.
+enum { kScale = 30 };
+
+// The minimum interval between samples of the time base.
+// We pick enough time to amortize the cost of the sample,
+// to get a reasonably accurate cycle counter rate reading,
+// and not so much that calculations will overflow 64-bits.
+static const uint64_t kMinNSBetweenSamples = 2000 << 20;
+
+// We require that kMinNSBetweenSamples shifted by kScale
+// have at least a bit left over for 64-bit calculations.
+static_assert(((kMinNSBetweenSamples << (kScale + 1)) >> (kScale + 1)) ==
+ kMinNSBetweenSamples,
+ "cannot represent kMaxBetweenSamplesNSScaled");
+
+// data from a sample of the kernel's time value
+struct TimeSampleAtomic {
std::atomic<uint64_t> raw_ns{0}; // raw kernel time
std::atomic<uint64_t> base_ns{0}; // our estimate of time
std::atomic<uint64_t> base_cycles{0}; // cycle counter reading
std::atomic<uint64_t> nsscaled_per_cycle{0}; // cycle period
- // cycles before we'll sample again (a scaled reciprocal of the period,
- // to avoid a division on the fast path).
+ // cycles before we'll sample again (a scaled reciprocal of the period,
+ // to avoid a division on the fast path).
std::atomic<uint64_t> min_cycles_per_sample{0};
-};
-// Same again, but with non-atomic types
-struct TimeSample {
+};
+// Same again, but with non-atomic types
+struct TimeSample {
uint64_t raw_ns = 0; // raw kernel time
uint64_t base_ns = 0; // our estimate of time
uint64_t base_cycles = 0; // cycle counter reading
uint64_t nsscaled_per_cycle = 0; // cycle period
uint64_t min_cycles_per_sample = 0; // approx cycles before next sample
-};
-
+};
+
struct ABSL_CACHELINE_ALIGNED TimeState {
std::atomic<uint64_t> seq{0};
TimeSampleAtomic last_sample; // the last sample; under seq
-
+
// The following counters are used only by the test code.
int64_t stats_initializations{0};
int64_t stats_reinitializations{0};
@@ -255,205 +255,205 @@ static int64_t GetCurrentTimeNanosFromKernel(uint64_t last_cycleclock,
return current_time_nanos_from_system;
}
-static int64_t GetCurrentTimeNanosSlowPath() ABSL_ATTRIBUTE_COLD;
-
-// Read the contents of *atomic into *sample.
-// Each field is read atomically, but to maintain atomicity between fields,
-// the access must be done under a lock.
-static void ReadTimeSampleAtomic(const struct TimeSampleAtomic *atomic,
- struct TimeSample *sample) {
- sample->base_ns = atomic->base_ns.load(std::memory_order_relaxed);
- sample->base_cycles = atomic->base_cycles.load(std::memory_order_relaxed);
- sample->nsscaled_per_cycle =
- atomic->nsscaled_per_cycle.load(std::memory_order_relaxed);
- sample->min_cycles_per_sample =
- atomic->min_cycles_per_sample.load(std::memory_order_relaxed);
- sample->raw_ns = atomic->raw_ns.load(std::memory_order_relaxed);
-}
-
-// Public routine.
-// Algorithm: We wish to compute real time from a cycle counter. In normal
-// operation, we construct a piecewise linear approximation to the kernel time
-// source, using the cycle counter value. The start of each line segment is at
-// the same point as the end of the last, but may have a different slope (that
-// is, a different idea of the cycle counter frequency). Every couple of
-// seconds, the kernel time source is sampled and compared with the current
-// approximation. A new slope is chosen that, if followed for another couple
-// of seconds, will correct the error at the current position. The information
-// for a sample is in the "last_sample" struct. The linear approximation is
-// estimated_time = last_sample.base_ns +
-// last_sample.ns_per_cycle * (counter_reading - last_sample.base_cycles)
-// (ns_per_cycle is actually stored in different units and scaled, to avoid
-// overflow). The base_ns of the next linear approximation is the
-// estimated_time using the last approximation; the base_cycles is the cycle
-// counter value at that time; the ns_per_cycle is the number of ns per cycle
-// measured since the last sample, but adjusted so that most of the difference
-// between the estimated_time and the kernel time will be corrected by the
-// estimated time to the next sample. In normal operation, this algorithm
-// relies on:
-// - the cycle counter and kernel time rates not changing a lot in a few
-// seconds.
-// - the client calling into the code often compared to a couple of seconds, so
-// the time to the next correction can be estimated.
-// Any time ns_per_cycle is not known, a major error is detected, or the
-// assumption about frequent calls is violated, the implementation returns the
-// kernel time. It records sufficient data that a linear approximation can
-// resume a little later.
-
-int64_t GetCurrentTimeNanos() {
- // read the data from the "last_sample" struct (but don't need raw_ns yet)
- // The reads of "seq" and test of the values emulate a reader lock.
- uint64_t base_ns;
- uint64_t base_cycles;
- uint64_t nsscaled_per_cycle;
- uint64_t min_cycles_per_sample;
- uint64_t seq_read0;
- uint64_t seq_read1;
-
- // If we have enough information to interpolate, the value returned will be
- // derived from this cycleclock-derived time estimate. On some platforms
- // (POWER) the function to retrieve this value has enough complexity to
- // contribute to register pressure - reading it early before initializing
- // the other pieces of the calculation minimizes spill/restore instructions,
- // minimizing icache cost.
- uint64_t now_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW();
-
- // Acquire pairs with the barrier in SeqRelease - if this load sees that
- // store, the shared-data reads necessarily see that SeqRelease's updates
- // to the same shared data.
+static int64_t GetCurrentTimeNanosSlowPath() ABSL_ATTRIBUTE_COLD;
+
+// Read the contents of *atomic into *sample.
+// Each field is read atomically, but to maintain atomicity between fields,
+// the access must be done under a lock.
+static void ReadTimeSampleAtomic(const struct TimeSampleAtomic *atomic,
+ struct TimeSample *sample) {
+ sample->base_ns = atomic->base_ns.load(std::memory_order_relaxed);
+ sample->base_cycles = atomic->base_cycles.load(std::memory_order_relaxed);
+ sample->nsscaled_per_cycle =
+ atomic->nsscaled_per_cycle.load(std::memory_order_relaxed);
+ sample->min_cycles_per_sample =
+ atomic->min_cycles_per_sample.load(std::memory_order_relaxed);
+ sample->raw_ns = atomic->raw_ns.load(std::memory_order_relaxed);
+}
+
+// Public routine.
+// Algorithm: We wish to compute real time from a cycle counter. In normal
+// operation, we construct a piecewise linear approximation to the kernel time
+// source, using the cycle counter value. The start of each line segment is at
+// the same point as the end of the last, but may have a different slope (that
+// is, a different idea of the cycle counter frequency). Every couple of
+// seconds, the kernel time source is sampled and compared with the current
+// approximation. A new slope is chosen that, if followed for another couple
+// of seconds, will correct the error at the current position. The information
+// for a sample is in the "last_sample" struct. The linear approximation is
+// estimated_time = last_sample.base_ns +
+// last_sample.ns_per_cycle * (counter_reading - last_sample.base_cycles)
+// (ns_per_cycle is actually stored in different units and scaled, to avoid
+// overflow). The base_ns of the next linear approximation is the
+// estimated_time using the last approximation; the base_cycles is the cycle
+// counter value at that time; the ns_per_cycle is the number of ns per cycle
+// measured since the last sample, but adjusted so that most of the difference
+// between the estimated_time and the kernel time will be corrected by the
+// estimated time to the next sample. In normal operation, this algorithm
+// relies on:
+// - the cycle counter and kernel time rates not changing a lot in a few
+// seconds.
+// - the client calling into the code often compared to a couple of seconds, so
+// the time to the next correction can be estimated.
+// Any time ns_per_cycle is not known, a major error is detected, or the
+// assumption about frequent calls is violated, the implementation returns the
+// kernel time. It records sufficient data that a linear approximation can
+// resume a little later.
+
+int64_t GetCurrentTimeNanos() {
+ // read the data from the "last_sample" struct (but don't need raw_ns yet)
+ // The reads of "seq" and test of the values emulate a reader lock.
+ uint64_t base_ns;
+ uint64_t base_cycles;
+ uint64_t nsscaled_per_cycle;
+ uint64_t min_cycles_per_sample;
+ uint64_t seq_read0;
+ uint64_t seq_read1;
+
+ // If we have enough information to interpolate, the value returned will be
+ // derived from this cycleclock-derived time estimate. On some platforms
+ // (POWER) the function to retrieve this value has enough complexity to
+ // contribute to register pressure - reading it early before initializing
+ // the other pieces of the calculation minimizes spill/restore instructions,
+ // minimizing icache cost.
+ uint64_t now_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW();
+
+ // Acquire pairs with the barrier in SeqRelease - if this load sees that
+ // store, the shared-data reads necessarily see that SeqRelease's updates
+ // to the same shared data.
seq_read0 = time_state.seq.load(std::memory_order_acquire);
-
+
base_ns = time_state.last_sample.base_ns.load(std::memory_order_relaxed);
base_cycles =
time_state.last_sample.base_cycles.load(std::memory_order_relaxed);
- nsscaled_per_cycle =
+ nsscaled_per_cycle =
time_state.last_sample.nsscaled_per_cycle.load(std::memory_order_relaxed);
min_cycles_per_sample = time_state.last_sample.min_cycles_per_sample.load(
std::memory_order_relaxed);
-
- // This acquire fence pairs with the release fence in SeqAcquire. Since it
- // is sequenced between reads of shared data and seq_read1, the reads of
- // shared data are effectively acquiring.
- std::atomic_thread_fence(std::memory_order_acquire);
-
- // The shared-data reads are effectively acquire ordered, and the
- // shared-data writes are effectively release ordered. Therefore if our
- // shared-data reads see any of a particular update's shared-data writes,
- // seq_read1 is guaranteed to see that update's SeqAcquire.
+
+ // This acquire fence pairs with the release fence in SeqAcquire. Since it
+ // is sequenced between reads of shared data and seq_read1, the reads of
+ // shared data are effectively acquiring.
+ std::atomic_thread_fence(std::memory_order_acquire);
+
+ // The shared-data reads are effectively acquire ordered, and the
+ // shared-data writes are effectively release ordered. Therefore if our
+ // shared-data reads see any of a particular update's shared-data writes,
+ // seq_read1 is guaranteed to see that update's SeqAcquire.
seq_read1 = time_state.seq.load(std::memory_order_relaxed);
-
- // Fast path. Return if min_cycles_per_sample has not yet elapsed since the
- // last sample, and we read a consistent sample. The fast path activates
- // only when min_cycles_per_sample is non-zero, which happens when we get an
- // estimate for the cycle time. The predicate will fail if now_cycles <
- // base_cycles, or if some other thread is in the slow path.
- //
- // Since we now read now_cycles before base_ns, it is possible for now_cycles
- // to be less than base_cycles (if we were interrupted between those loads and
- // last_sample was updated). This is harmless, because delta_cycles will wrap
- // and report a time much much bigger than min_cycles_per_sample. In that case
- // we will take the slow path.
+
+ // Fast path. Return if min_cycles_per_sample has not yet elapsed since the
+ // last sample, and we read a consistent sample. The fast path activates
+ // only when min_cycles_per_sample is non-zero, which happens when we get an
+ // estimate for the cycle time. The predicate will fail if now_cycles <
+ // base_cycles, or if some other thread is in the slow path.
+ //
+ // Since we now read now_cycles before base_ns, it is possible for now_cycles
+ // to be less than base_cycles (if we were interrupted between those loads and
+ // last_sample was updated). This is harmless, because delta_cycles will wrap
+ // and report a time much much bigger than min_cycles_per_sample. In that case
+ // we will take the slow path.
uint64_t delta_cycles;
- if (seq_read0 == seq_read1 && (seq_read0 & 1) == 0 &&
+ if (seq_read0 == seq_read1 && (seq_read0 & 1) == 0 &&
(delta_cycles = now_cycles - base_cycles) < min_cycles_per_sample) {
- return base_ns + ((delta_cycles * nsscaled_per_cycle) >> kScale);
- }
- return GetCurrentTimeNanosSlowPath();
-}
-
-// Return (a << kScale)/b.
-// Zero is returned if b==0. Scaling is performed internally to
-// preserve precision without overflow.
-static uint64_t SafeDivideAndScale(uint64_t a, uint64_t b) {
- // Find maximum safe_shift so that
- // 0 <= safe_shift <= kScale and (a << safe_shift) does not overflow.
- int safe_shift = kScale;
- while (((a << safe_shift) >> safe_shift) != a) {
- safe_shift--;
- }
- uint64_t scaled_b = b >> (kScale - safe_shift);
- uint64_t quotient = 0;
- if (scaled_b != 0) {
- quotient = (a << safe_shift) / scaled_b;
- }
- return quotient;
-}
-
-static uint64_t UpdateLastSample(
- uint64_t now_cycles, uint64_t now_ns, uint64_t delta_cycles,
- const struct TimeSample *sample) ABSL_ATTRIBUTE_COLD;
-
-// The slow path of GetCurrentTimeNanos(). This is taken while gathering
-// initial samples, when enough time has elapsed since the last sample, and if
-// any other thread is writing to last_sample.
-//
-// Manually mark this 'noinline' to minimize stack frame size of the fast
-// path. Without this, sometimes a compiler may inline this big block of code
-// into the fast path. That causes lots of register spills and reloads that
-// are unnecessary unless the slow path is taken.
-//
+ return base_ns + ((delta_cycles * nsscaled_per_cycle) >> kScale);
+ }
+ return GetCurrentTimeNanosSlowPath();
+}
+
+// Return (a << kScale)/b.
+// Zero is returned if b==0. Scaling is performed internally to
+// preserve precision without overflow.
+static uint64_t SafeDivideAndScale(uint64_t a, uint64_t b) {
+ // Find maximum safe_shift so that
+ // 0 <= safe_shift <= kScale and (a << safe_shift) does not overflow.
+ int safe_shift = kScale;
+ while (((a << safe_shift) >> safe_shift) != a) {
+ safe_shift--;
+ }
+ uint64_t scaled_b = b >> (kScale - safe_shift);
+ uint64_t quotient = 0;
+ if (scaled_b != 0) {
+ quotient = (a << safe_shift) / scaled_b;
+ }
+ return quotient;
+}
+
+static uint64_t UpdateLastSample(
+ uint64_t now_cycles, uint64_t now_ns, uint64_t delta_cycles,
+ const struct TimeSample *sample) ABSL_ATTRIBUTE_COLD;
+
+// The slow path of GetCurrentTimeNanos(). This is taken while gathering
+// initial samples, when enough time has elapsed since the last sample, and if
+// any other thread is writing to last_sample.
+//
+// Manually mark this 'noinline' to minimize stack frame size of the fast
+// path. Without this, sometimes a compiler may inline this big block of code
+// into the fast path. That causes lots of register spills and reloads that
+// are unnecessary unless the slow path is taken.
+//
// TODO(y_absl-team): Remove this attribute when our compiler is smart enough
-// to do the right thing.
-ABSL_ATTRIBUTE_NOINLINE
+// to do the right thing.
+ABSL_ATTRIBUTE_NOINLINE
static int64_t GetCurrentTimeNanosSlowPath()
ABSL_LOCKS_EXCLUDED(time_state.lock) {
- // Serialize access to slow-path. Fast-path readers are not blocked yet, and
- // code below must not modify last_sample until the seqlock is acquired.
+ // Serialize access to slow-path. Fast-path readers are not blocked yet, and
+ // code below must not modify last_sample until the seqlock is acquired.
time_state.lock.Lock();
-
- // Sample the kernel time base. This is the definition of
- // "now" if we take the slow path.
- uint64_t now_cycles;
+
+ // Sample the kernel time base. This is the definition of
+ // "now" if we take the slow path.
+ uint64_t now_cycles;
uint64_t now_ns =
GetCurrentTimeNanosFromKernel(time_state.last_now_cycles, &now_cycles);
time_state.last_now_cycles = now_cycles;
-
- uint64_t estimated_base_ns;
-
- // ----------
- // Read the "last_sample" values again; this time holding the write lock.
- struct TimeSample sample;
+
+ uint64_t estimated_base_ns;
+
+ // ----------
+ // Read the "last_sample" values again; this time holding the write lock.
+ struct TimeSample sample;
ReadTimeSampleAtomic(&time_state.last_sample, &sample);
-
- // ----------
- // Try running the fast path again; another thread may have updated the
- // sample between our run of the fast path and the sample we just read.
- uint64_t delta_cycles = now_cycles - sample.base_cycles;
- if (delta_cycles < sample.min_cycles_per_sample) {
- // Another thread updated the sample. This path does not take the seqlock
- // so that blocked readers can make progress without blocking new readers.
- estimated_base_ns = sample.base_ns +
- ((delta_cycles * sample.nsscaled_per_cycle) >> kScale);
+
+ // ----------
+ // Try running the fast path again; another thread may have updated the
+ // sample between our run of the fast path and the sample we just read.
+ uint64_t delta_cycles = now_cycles - sample.base_cycles;
+ if (delta_cycles < sample.min_cycles_per_sample) {
+ // Another thread updated the sample. This path does not take the seqlock
+ // so that blocked readers can make progress without blocking new readers.
+ estimated_base_ns = sample.base_ns +
+ ((delta_cycles * sample.nsscaled_per_cycle) >> kScale);
time_state.stats_fast_slow_paths++;
- } else {
- estimated_base_ns =
- UpdateLastSample(now_cycles, now_ns, delta_cycles, &sample);
- }
-
+ } else {
+ estimated_base_ns =
+ UpdateLastSample(now_cycles, now_ns, delta_cycles, &sample);
+ }
+
time_state.lock.Unlock();
-
- return estimated_base_ns;
-}
-
-// Main part of the algorithm. Locks out readers, updates the approximation
-// using the new sample from the kernel, and stores the result in last_sample
-// for readers. Returns the new estimated time.
-static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns,
- uint64_t delta_cycles,
- const struct TimeSample *sample)
+
+ return estimated_base_ns;
+}
+
+// Main part of the algorithm. Locks out readers, updates the approximation
+// using the new sample from the kernel, and stores the result in last_sample
+// for readers. Returns the new estimated time.
+static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns,
+ uint64_t delta_cycles,
+ const struct TimeSample *sample)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(time_state.lock) {
- uint64_t estimated_base_ns = now_ns;
+ uint64_t estimated_base_ns = now_ns;
uint64_t lock_value =
SeqAcquire(&time_state.seq); // acquire seqlock to block readers
-
- // The 5s in the next if-statement limits the time for which we will trust
- // the cycle counter and our last sample to give a reasonable result.
- // Errors in the rate of the source clock can be multiplied by the ratio
- // between this limit and kMinNSBetweenSamples.
- if (sample->raw_ns == 0 || // no recent sample, or clock went backwards
- sample->raw_ns + static_cast<uint64_t>(5) * 1000 * 1000 * 1000 < now_ns ||
- now_ns < sample->raw_ns || now_cycles < sample->base_cycles) {
- // record this sample, and forget any previously known slope.
+
+ // The 5s in the next if-statement limits the time for which we will trust
+ // the cycle counter and our last sample to give a reasonable result.
+ // Errors in the rate of the source clock can be multiplied by the ratio
+ // between this limit and kMinNSBetweenSamples.
+ if (sample->raw_ns == 0 || // no recent sample, or clock went backwards
+ sample->raw_ns + static_cast<uint64_t>(5) * 1000 * 1000 * 1000 < now_ns ||
+ now_ns < sample->raw_ns || now_cycles < sample->base_cycles) {
+ // record this sample, and forget any previously known slope.
time_state.last_sample.raw_ns.store(now_ns, std::memory_order_relaxed);
time_state.last_sample.base_ns.store(estimated_base_ns,
std::memory_order_relaxed);
@@ -464,122 +464,122 @@ static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns,
time_state.last_sample.min_cycles_per_sample.store(
0, std::memory_order_relaxed);
time_state.stats_initializations++;
- } else if (sample->raw_ns + 500 * 1000 * 1000 < now_ns &&
- sample->base_cycles + 50 < now_cycles) {
- // Enough time has passed to compute the cycle time.
- if (sample->nsscaled_per_cycle != 0) { // Have a cycle time estimate.
- // Compute time from counter reading, but avoiding overflow
- // delta_cycles may be larger than on the fast path.
- uint64_t estimated_scaled_ns;
- int s = -1;
- do {
- s++;
- estimated_scaled_ns = (delta_cycles >> s) * sample->nsscaled_per_cycle;
- } while (estimated_scaled_ns / sample->nsscaled_per_cycle !=
- (delta_cycles >> s));
- estimated_base_ns = sample->base_ns +
- (estimated_scaled_ns >> (kScale - s));
- }
-
- // Compute the assumed cycle time kMinNSBetweenSamples ns into the future
- // assuming the cycle counter rate stays the same as the last interval.
- uint64_t ns = now_ns - sample->raw_ns;
- uint64_t measured_nsscaled_per_cycle = SafeDivideAndScale(ns, delta_cycles);
-
- uint64_t assumed_next_sample_delta_cycles =
- SafeDivideAndScale(kMinNSBetweenSamples, measured_nsscaled_per_cycle);
-
- int64_t diff_ns = now_ns - estimated_base_ns; // estimate low by this much
-
- // We want to set nsscaled_per_cycle so that our estimate of the ns time
- // at the assumed cycle time is the assumed ns time.
- // That is, we want to set nsscaled_per_cycle so:
- // kMinNSBetweenSamples + diff_ns ==
- // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale
- // But we wish to damp oscillations, so instead correct only most
- // of our current error, by solving:
- // kMinNSBetweenSamples + diff_ns - (diff_ns / 16) ==
- // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale
- ns = kMinNSBetweenSamples + diff_ns - (diff_ns / 16);
- uint64_t new_nsscaled_per_cycle =
- SafeDivideAndScale(ns, assumed_next_sample_delta_cycles);
- if (new_nsscaled_per_cycle != 0 &&
- diff_ns < 100 * 1000 * 1000 && -diff_ns < 100 * 1000 * 1000) {
- // record the cycle time measurement
+ } else if (sample->raw_ns + 500 * 1000 * 1000 < now_ns &&
+ sample->base_cycles + 50 < now_cycles) {
+ // Enough time has passed to compute the cycle time.
+ if (sample->nsscaled_per_cycle != 0) { // Have a cycle time estimate.
+ // Compute time from counter reading, but avoiding overflow
+ // delta_cycles may be larger than on the fast path.
+ uint64_t estimated_scaled_ns;
+ int s = -1;
+ do {
+ s++;
+ estimated_scaled_ns = (delta_cycles >> s) * sample->nsscaled_per_cycle;
+ } while (estimated_scaled_ns / sample->nsscaled_per_cycle !=
+ (delta_cycles >> s));
+ estimated_base_ns = sample->base_ns +
+ (estimated_scaled_ns >> (kScale - s));
+ }
+
+ // Compute the assumed cycle time kMinNSBetweenSamples ns into the future
+ // assuming the cycle counter rate stays the same as the last interval.
+ uint64_t ns = now_ns - sample->raw_ns;
+ uint64_t measured_nsscaled_per_cycle = SafeDivideAndScale(ns, delta_cycles);
+
+ uint64_t assumed_next_sample_delta_cycles =
+ SafeDivideAndScale(kMinNSBetweenSamples, measured_nsscaled_per_cycle);
+
+ int64_t diff_ns = now_ns - estimated_base_ns; // estimate low by this much
+
+ // We want to set nsscaled_per_cycle so that our estimate of the ns time
+ // at the assumed cycle time is the assumed ns time.
+ // That is, we want to set nsscaled_per_cycle so:
+ // kMinNSBetweenSamples + diff_ns ==
+ // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale
+ // But we wish to damp oscillations, so instead correct only most
+ // of our current error, by solving:
+ // kMinNSBetweenSamples + diff_ns - (diff_ns / 16) ==
+ // (assumed_next_sample_delta_cycles * nsscaled_per_cycle) >> kScale
+ ns = kMinNSBetweenSamples + diff_ns - (diff_ns / 16);
+ uint64_t new_nsscaled_per_cycle =
+ SafeDivideAndScale(ns, assumed_next_sample_delta_cycles);
+ if (new_nsscaled_per_cycle != 0 &&
+ diff_ns < 100 * 1000 * 1000 && -diff_ns < 100 * 1000 * 1000) {
+ // record the cycle time measurement
time_state.last_sample.nsscaled_per_cycle.store(
- new_nsscaled_per_cycle, std::memory_order_relaxed);
- uint64_t new_min_cycles_per_sample =
- SafeDivideAndScale(kMinNSBetweenSamples, new_nsscaled_per_cycle);
+ new_nsscaled_per_cycle, std::memory_order_relaxed);
+ uint64_t new_min_cycles_per_sample =
+ SafeDivideAndScale(kMinNSBetweenSamples, new_nsscaled_per_cycle);
time_state.last_sample.min_cycles_per_sample.store(
- new_min_cycles_per_sample, std::memory_order_relaxed);
+ new_min_cycles_per_sample, std::memory_order_relaxed);
time_state.stats_calibrations++;
- } else { // something went wrong; forget the slope
+ } else { // something went wrong; forget the slope
time_state.last_sample.nsscaled_per_cycle.store(
0, std::memory_order_relaxed);
time_state.last_sample.min_cycles_per_sample.store(
0, std::memory_order_relaxed);
- estimated_base_ns = now_ns;
+ estimated_base_ns = now_ns;
time_state.stats_reinitializations++;
- }
+ }
time_state.last_sample.raw_ns.store(now_ns, std::memory_order_relaxed);
time_state.last_sample.base_ns.store(estimated_base_ns,
std::memory_order_relaxed);
time_state.last_sample.base_cycles.store(now_cycles,
std::memory_order_relaxed);
- } else {
- // have a sample, but no slope; waiting for enough time for a calibration
+ } else {
+ // have a sample, but no slope; waiting for enough time for a calibration
time_state.stats_slow_paths++;
- }
-
+ }
+
SeqRelease(&time_state.seq, lock_value); // release the readers
-
- return estimated_base_ns;
-}
+
+ return estimated_base_ns;
+}
ABSL_NAMESPACE_END
} // namespace y_absl
-#endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
-
+#endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace {
-
-// Returns the maximum duration that SleepOnce() can sleep for.
+namespace {
+
+// Returns the maximum duration that SleepOnce() can sleep for.
constexpr y_absl::Duration MaxSleep() {
-#ifdef _WIN32
- // Windows Sleep() takes unsigned long argument in milliseconds.
+#ifdef _WIN32
+ // Windows Sleep() takes unsigned long argument in milliseconds.
return y_absl::Milliseconds(
- std::numeric_limits<unsigned long>::max()); // NOLINT(runtime/int)
-#else
+ std::numeric_limits<unsigned long>::max()); // NOLINT(runtime/int)
+#else
return y_absl::Seconds(std::numeric_limits<time_t>::max());
-#endif
-}
-
-// Sleeps for the given duration.
-// REQUIRES: to_sleep <= MaxSleep().
+#endif
+}
+
+// Sleeps for the given duration.
+// REQUIRES: to_sleep <= MaxSleep().
void SleepOnce(y_absl::Duration to_sleep) {
-#ifdef _WIN32
+#ifdef _WIN32
Sleep(to_sleep / y_absl::Milliseconds(1));
-#else
+#else
struct timespec sleep_time = y_absl::ToTimespec(to_sleep);
- while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {
- // Ignore signals and wait for the full interval to elapse.
- }
-#endif
-}
-
-} // namespace
+ while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {
+ // Ignore signals and wait for the full interval to elapse.
+ }
+#endif
+}
+
+} // namespace
ABSL_NAMESPACE_END
} // namespace y_absl
-
-extern "C" {
-
+
+extern "C" {
+
ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(
y_absl::Duration duration) {
while (duration > y_absl::ZeroDuration()) {
y_absl::Duration to_sleep = std::min(duration, y_absl::MaxSleep());
y_absl::SleepOnce(to_sleep);
- duration -= to_sleep;
- }
-}
-
-} // extern "C"
+ duration -= to_sleep;
+ }
+}
+
+} // extern "C"
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.h
index d2d9b721e0..178b96d828 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/clock.h
@@ -1,74 +1,74 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: clock.h
-// -----------------------------------------------------------------------------
-//
-// This header file contains utility functions for working with the system-wide
-// realtime clock. For descriptions of the main time abstractions used within
-// this header file, consult the time.h header file.
-#ifndef ABSL_TIME_CLOCK_H_
-#define ABSL_TIME_CLOCK_H_
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: clock.h
+// -----------------------------------------------------------------------------
+//
+// This header file contains utility functions for working with the system-wide
+// realtime clock. For descriptions of the main time abstractions used within
+// this header file, consult the time.h header file.
+#ifndef ABSL_TIME_CLOCK_H_
+#define ABSL_TIME_CLOCK_H_
+
#include "y_absl/base/macros.h"
#include "y_absl/time/time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-// Now()
-//
+
+// Now()
+//
// Returns the current time, expressed as an `y_absl::Time` absolute time value.
y_absl::Time Now();
-
-// GetCurrentTimeNanos()
-//
-// Returns the current time, expressed as a count of nanoseconds since the Unix
+
+// GetCurrentTimeNanos()
+//
+// Returns the current time, expressed as a count of nanoseconds since the Unix
// Epoch (https://en.wikipedia.org/wiki/Unix_time). Prefer `y_absl::Now()` instead
-// for all but the most performance-sensitive cases (i.e. when you are calling
-// this function hundreds of thousands of times per second).
-int64_t GetCurrentTimeNanos();
-
-// SleepFor()
-//
+// for all but the most performance-sensitive cases (i.e. when you are calling
+// this function hundreds of thousands of times per second).
+int64_t GetCurrentTimeNanos();
+
+// SleepFor()
+//
// Sleeps for the specified duration, expressed as an `y_absl::Duration`.
-//
-// Notes:
-// * Signal interruptions will not reduce the sleep duration.
-// * Returns immediately when passed a nonpositive duration.
+//
+// Notes:
+// * Signal interruptions will not reduce the sleep duration.
+// * Returns immediately when passed a nonpositive duration.
void SleepFor(y_absl::Duration duration);
-
+
ABSL_NAMESPACE_END
} // namespace y_absl
-
-// -----------------------------------------------------------------------------
-// Implementation Details
-// -----------------------------------------------------------------------------
-
-// In some build configurations we pass --detect-odr-violations to the
-// gold linker. This causes it to flag weak symbol overrides as ODR
-// violations. Because ODR only applies to C++ and not C,
-// --detect-odr-violations ignores symbols not mangled with C++ names.
-// By changing our extension points to be extern "C", we dodge this
-// check.
-extern "C" {
+
+// -----------------------------------------------------------------------------
+// Implementation Details
+// -----------------------------------------------------------------------------
+
+// In some build configurations we pass --detect-odr-violations to the
+// gold linker. This causes it to flag weak symbol overrides as ODR
+// violations. Because ODR only applies to C++ and not C,
+// --detect-odr-violations ignores symbols not mangled with C++ names.
+// By changing our extension points to be extern "C", we dodge this
+// check.
+extern "C" {
void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(y_absl::Duration duration);
-} // extern "C"
-
+} // extern "C"
+
inline void y_absl::SleepFor(y_absl::Duration duration) {
ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(duration);
-}
-
-#endif // ABSL_TIME_CLOCK_H_
+}
+
+#endif // ABSL_TIME_CLOCK_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/duration.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/duration.cc
index 308098673f..d4914556e6 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/duration.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/duration.cc
@@ -1,720 +1,720 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// The implementation of the y_absl::Duration class, which is declared in
// //y_absl/time.h. This class behaves like a numeric type; it has no public
-// methods and is used only through the operators defined here.
-//
-// Implementation notes:
-//
+// methods and is used only through the operators defined here.
+//
+// Implementation notes:
+//
// An y_absl::Duration is represented as
-//
-// rep_hi_ : (int64_t) Whole seconds
-// rep_lo_ : (uint32_t) Fractions of a second
-//
-// The seconds value (rep_hi_) may be positive or negative as appropriate.
-// The fractional seconds (rep_lo_) is always a positive offset from rep_hi_.
-// The API for Duration guarantees at least nanosecond resolution, which
-// means rep_lo_ could have a max value of 1B - 1 if it stored nanoseconds.
-// However, to utilize more of the available 32 bits of space in rep_lo_,
-// we instead store quarters of a nanosecond in rep_lo_ resulting in a max
-// value of 4B - 1. This allows us to correctly handle calculations like
-// 0.5 nanos + 0.5 nanos = 1 nano. The following example shows the actual
-// Duration rep using quarters of a nanosecond.
-//
-// 2.5 sec = {rep_hi_=2, rep_lo_=2000000000} // lo = 4 * 500000000
-// -2.5 sec = {rep_hi_=-3, rep_lo_=2000000000}
-//
-// Infinite durations are represented as Durations with the rep_lo_ field set
-// to all 1s.
-//
-// +InfiniteDuration:
-// rep_hi_ : kint64max
-// rep_lo_ : ~0U
-//
-// -InfiniteDuration:
-// rep_hi_ : kint64min
-// rep_lo_ : ~0U
-//
-// Arithmetic overflows/underflows to +/- infinity and saturates.
-
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
-#include <algorithm>
-#include <cassert>
-#include <cctype>
-#include <cerrno>
-#include <cmath>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <functional>
-#include <limits>
+//
+// rep_hi_ : (int64_t) Whole seconds
+// rep_lo_ : (uint32_t) Fractions of a second
+//
+// The seconds value (rep_hi_) may be positive or negative as appropriate.
+// The fractional seconds (rep_lo_) is always a positive offset from rep_hi_.
+// The API for Duration guarantees at least nanosecond resolution, which
+// means rep_lo_ could have a max value of 1B - 1 if it stored nanoseconds.
+// However, to utilize more of the available 32 bits of space in rep_lo_,
+// we instead store quarters of a nanosecond in rep_lo_ resulting in a max
+// value of 4B - 1. This allows us to correctly handle calculations like
+// 0.5 nanos + 0.5 nanos = 1 nano. The following example shows the actual
+// Duration rep using quarters of a nanosecond.
+//
+// 2.5 sec = {rep_hi_=2, rep_lo_=2000000000} // lo = 4 * 500000000
+// -2.5 sec = {rep_hi_=-3, rep_lo_=2000000000}
+//
+// Infinite durations are represented as Durations with the rep_lo_ field set
+// to all 1s.
+//
+// +InfiniteDuration:
+// rep_hi_ : kint64max
+// rep_lo_ : ~0U
+//
+// -InfiniteDuration:
+// rep_hi_ : kint64min
+// rep_lo_ : ~0U
+//
+// Arithmetic overflows/underflows to +/- infinity and saturates.
+
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cmath>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <functional>
+#include <limits>
#include <util/generic/string.h>
-
+
#include "y_absl/base/casts.h"
#include "y_absl/base/macros.h"
#include "y_absl/numeric/int128.h"
#include "y_absl/strings/string_view.h"
#include "y_absl/strings/strip.h"
#include "y_absl/time/time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-namespace {
-
-using time_internal::kTicksPerNanosecond;
-using time_internal::kTicksPerSecond;
-
-constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
-constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
-
-// Can't use std::isinfinite() because it doesn't exist on windows.
-inline bool IsFinite(double d) {
- if (std::isnan(d)) return false;
- return d != std::numeric_limits<double>::infinity() &&
- d != -std::numeric_limits<double>::infinity();
-}
-
-inline bool IsValidDivisor(double d) {
- if (std::isnan(d)) return false;
- return d != 0.0;
-}
-
-// Can't use std::round() because it is only available in C++11.
-// Note that we ignore the possibility of floating-point over/underflow.
-template <typename Double>
-inline double Round(Double d) {
- return d < 0 ? std::ceil(d - 0.5) : std::floor(d + 0.5);
-}
-
-// *sec may be positive or negative. *ticks must be in the range
-// -kTicksPerSecond < *ticks < kTicksPerSecond. If *ticks is negative it
-// will be normalized to a positive value by adjusting *sec accordingly.
-inline void NormalizeTicks(int64_t* sec, int64_t* ticks) {
- if (*ticks < 0) {
- --*sec;
- *ticks += kTicksPerSecond;
- }
-}
-
-// Makes a uint128 from the absolute value of the given scalar.
-inline uint128 MakeU128(int64_t a) {
- uint128 u128 = 0;
- if (a < 0) {
- ++u128;
- ++a; // Makes it safe to negate 'a'
- a = -a;
- }
- u128 += static_cast<uint64_t>(a);
- return u128;
-}
-
-// Makes a uint128 count of ticks out of the absolute value of the Duration.
-inline uint128 MakeU128Ticks(Duration d) {
- int64_t rep_hi = time_internal::GetRepHi(d);
- uint32_t rep_lo = time_internal::GetRepLo(d);
- if (rep_hi < 0) {
- ++rep_hi;
- rep_hi = -rep_hi;
- rep_lo = kTicksPerSecond - rep_lo;
- }
- uint128 u128 = static_cast<uint64_t>(rep_hi);
- u128 *= static_cast<uint64_t>(kTicksPerSecond);
- u128 += rep_lo;
- return u128;
-}
-
-// Breaks a uint128 of ticks into a Duration.
-inline Duration MakeDurationFromU128(uint128 u128, bool is_neg) {
- int64_t rep_hi;
- uint32_t rep_lo;
- const uint64_t h64 = Uint128High64(u128);
- const uint64_t l64 = Uint128Low64(u128);
- if (h64 == 0) { // fastpath
- const uint64_t hi = l64 / kTicksPerSecond;
- rep_hi = static_cast<int64_t>(hi);
- rep_lo = static_cast<uint32_t>(l64 - hi * kTicksPerSecond);
- } else {
- // kMaxRepHi64 is the high 64 bits of (2^63 * kTicksPerSecond).
- // Any positive tick count whose high 64 bits are >= kMaxRepHi64
- // is not representable as a Duration. A negative tick count can
- // have its high 64 bits == kMaxRepHi64 but only when the low 64
- // bits are all zero, otherwise it is not representable either.
- const uint64_t kMaxRepHi64 = 0x77359400UL;
- if (h64 >= kMaxRepHi64) {
- if (is_neg && h64 == kMaxRepHi64 && l64 == 0) {
- // Avoid trying to represent -kint64min below.
- return time_internal::MakeDuration(kint64min);
- }
- return is_neg ? -InfiniteDuration() : InfiniteDuration();
- }
- const uint128 kTicksPerSecond128 = static_cast<uint64_t>(kTicksPerSecond);
- const uint128 hi = u128 / kTicksPerSecond128;
- rep_hi = static_cast<int64_t>(Uint128Low64(hi));
- rep_lo =
- static_cast<uint32_t>(Uint128Low64(u128 - hi * kTicksPerSecond128));
- }
- if (is_neg) {
- rep_hi = -rep_hi;
- if (rep_lo != 0) {
- --rep_hi;
- rep_lo = kTicksPerSecond - rep_lo;
- }
- }
- return time_internal::MakeDuration(rep_hi, rep_lo);
-}
-
-// Convert between int64_t and uint64_t, preserving representation. This
-// allows us to do arithmetic in the unsigned domain, where overflow has
-// well-defined behavior. See operator+=() and operator-=().
-//
-// C99 7.20.1.1.1, as referenced by C++11 18.4.1.2, says, "The typedef
-// name intN_t designates a signed integer type with width N, no padding
-// bits, and a two's complement representation." So, we can convert to
-// and from the corresponding uint64_t value using a bit cast.
-inline uint64_t EncodeTwosComp(int64_t v) {
+
+namespace {
+
+using time_internal::kTicksPerNanosecond;
+using time_internal::kTicksPerSecond;
+
+constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
+constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
+
+// Can't use std::isinfinite() because it doesn't exist on windows.
+inline bool IsFinite(double d) {
+ if (std::isnan(d)) return false;
+ return d != std::numeric_limits<double>::infinity() &&
+ d != -std::numeric_limits<double>::infinity();
+}
+
+inline bool IsValidDivisor(double d) {
+ if (std::isnan(d)) return false;
+ return d != 0.0;
+}
+
+// Can't use std::round() because it is only available in C++11.
+// Note that we ignore the possibility of floating-point over/underflow.
+template <typename Double>
+inline double Round(Double d) {
+ return d < 0 ? std::ceil(d - 0.5) : std::floor(d + 0.5);
+}
+
+// *sec may be positive or negative. *ticks must be in the range
+// -kTicksPerSecond < *ticks < kTicksPerSecond. If *ticks is negative it
+// will be normalized to a positive value by adjusting *sec accordingly.
+inline void NormalizeTicks(int64_t* sec, int64_t* ticks) {
+ if (*ticks < 0) {
+ --*sec;
+ *ticks += kTicksPerSecond;
+ }
+}
+
+// Makes a uint128 from the absolute value of the given scalar.
+inline uint128 MakeU128(int64_t a) {
+ uint128 u128 = 0;
+ if (a < 0) {
+ ++u128;
+ ++a; // Makes it safe to negate 'a'
+ a = -a;
+ }
+ u128 += static_cast<uint64_t>(a);
+ return u128;
+}
+
+// Makes a uint128 count of ticks out of the absolute value of the Duration.
+inline uint128 MakeU128Ticks(Duration d) {
+ int64_t rep_hi = time_internal::GetRepHi(d);
+ uint32_t rep_lo = time_internal::GetRepLo(d);
+ if (rep_hi < 0) {
+ ++rep_hi;
+ rep_hi = -rep_hi;
+ rep_lo = kTicksPerSecond - rep_lo;
+ }
+ uint128 u128 = static_cast<uint64_t>(rep_hi);
+ u128 *= static_cast<uint64_t>(kTicksPerSecond);
+ u128 += rep_lo;
+ return u128;
+}
+
+// Breaks a uint128 of ticks into a Duration.
+inline Duration MakeDurationFromU128(uint128 u128, bool is_neg) {
+ int64_t rep_hi;
+ uint32_t rep_lo;
+ const uint64_t h64 = Uint128High64(u128);
+ const uint64_t l64 = Uint128Low64(u128);
+ if (h64 == 0) { // fastpath
+ const uint64_t hi = l64 / kTicksPerSecond;
+ rep_hi = static_cast<int64_t>(hi);
+ rep_lo = static_cast<uint32_t>(l64 - hi * kTicksPerSecond);
+ } else {
+ // kMaxRepHi64 is the high 64 bits of (2^63 * kTicksPerSecond).
+ // Any positive tick count whose high 64 bits are >= kMaxRepHi64
+ // is not representable as a Duration. A negative tick count can
+ // have its high 64 bits == kMaxRepHi64 but only when the low 64
+ // bits are all zero, otherwise it is not representable either.
+ const uint64_t kMaxRepHi64 = 0x77359400UL;
+ if (h64 >= kMaxRepHi64) {
+ if (is_neg && h64 == kMaxRepHi64 && l64 == 0) {
+ // Avoid trying to represent -kint64min below.
+ return time_internal::MakeDuration(kint64min);
+ }
+ return is_neg ? -InfiniteDuration() : InfiniteDuration();
+ }
+ const uint128 kTicksPerSecond128 = static_cast<uint64_t>(kTicksPerSecond);
+ const uint128 hi = u128 / kTicksPerSecond128;
+ rep_hi = static_cast<int64_t>(Uint128Low64(hi));
+ rep_lo =
+ static_cast<uint32_t>(Uint128Low64(u128 - hi * kTicksPerSecond128));
+ }
+ if (is_neg) {
+ rep_hi = -rep_hi;
+ if (rep_lo != 0) {
+ --rep_hi;
+ rep_lo = kTicksPerSecond - rep_lo;
+ }
+ }
+ return time_internal::MakeDuration(rep_hi, rep_lo);
+}
+
+// Convert between int64_t and uint64_t, preserving representation. This
+// allows us to do arithmetic in the unsigned domain, where overflow has
+// well-defined behavior. See operator+=() and operator-=().
+//
+// C99 7.20.1.1.1, as referenced by C++11 18.4.1.2, says, "The typedef
+// name intN_t designates a signed integer type with width N, no padding
+// bits, and a two's complement representation." So, we can convert to
+// and from the corresponding uint64_t value using a bit cast.
+inline uint64_t EncodeTwosComp(int64_t v) {
return y_absl::bit_cast<uint64_t>(v);
-}
+}
inline int64_t DecodeTwosComp(uint64_t v) { return y_absl::bit_cast<int64_t>(v); }
-
-// Note: The overflow detection in this function is done using greater/less *or
-// equal* because kint64max/min is too large to be represented exactly in a
-// double (which only has 53 bits of precision). In order to avoid assigning to
-// rep->hi a double value that is too large for an int64_t (and therefore is
-// undefined), we must consider computations that equal kint64max/min as a
-// double as overflow cases.
-inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) {
- double c = a_hi + b_hi;
- if (c >= static_cast<double>(kint64max)) {
- *d = InfiniteDuration();
- return false;
- }
- if (c <= static_cast<double>(kint64min)) {
- *d = -InfiniteDuration();
- return false;
- }
- *d = time_internal::MakeDuration(c, time_internal::GetRepLo(*d));
- return true;
-}
-
-// A functor that's similar to std::multiplies<T>, except this returns the max
-// T value instead of overflowing. This is only defined for uint128.
-template <typename Ignored>
-struct SafeMultiply {
- uint128 operator()(uint128 a, uint128 b) const {
- // b hi is always zero because it originated as an int64_t.
- assert(Uint128High64(b) == 0);
- // Fastpath to avoid the expensive overflow check with division.
- if (Uint128High64(a) == 0) {
- return (((Uint128Low64(a) | Uint128Low64(b)) >> 32) == 0)
- ? static_cast<uint128>(Uint128Low64(a) * Uint128Low64(b))
- : a * b;
- }
- return b == 0 ? b : (a > kuint128max / b) ? kuint128max : a * b;
- }
-};
-
-// Scales (i.e., multiplies or divides, depending on the Operation template)
-// the Duration d by the int64_t r.
-template <template <typename> class Operation>
-inline Duration ScaleFixed(Duration d, int64_t r) {
- const uint128 a = MakeU128Ticks(d);
- const uint128 b = MakeU128(r);
- const uint128 q = Operation<uint128>()(a, b);
- const bool is_neg = (time_internal::GetRepHi(d) < 0) != (r < 0);
- return MakeDurationFromU128(q, is_neg);
-}
-
-// Scales (i.e., multiplies or divides, depending on the Operation template)
-// the Duration d by the double r.
-template <template <typename> class Operation>
-inline Duration ScaleDouble(Duration d, double r) {
- Operation<double> op;
- double hi_doub = op(time_internal::GetRepHi(d), r);
- double lo_doub = op(time_internal::GetRepLo(d), r);
-
- double hi_int = 0;
- double hi_frac = std::modf(hi_doub, &hi_int);
-
- // Moves hi's fractional bits to lo.
- lo_doub /= kTicksPerSecond;
- lo_doub += hi_frac;
-
- double lo_int = 0;
- double lo_frac = std::modf(lo_doub, &lo_int);
-
- // Rolls lo into hi if necessary.
- int64_t lo64 = Round(lo_frac * kTicksPerSecond);
-
- Duration ans;
- if (!SafeAddRepHi(hi_int, lo_int, &ans)) return ans;
- int64_t hi64 = time_internal::GetRepHi(ans);
- if (!SafeAddRepHi(hi64, lo64 / kTicksPerSecond, &ans)) return ans;
- hi64 = time_internal::GetRepHi(ans);
- lo64 %= kTicksPerSecond;
- NormalizeTicks(&hi64, &lo64);
- return time_internal::MakeDuration(hi64, lo64);
-}
-
-// Tries to divide num by den as fast as possible by looking for common, easy
-// cases. If the division was done, the quotient is in *q and the remainder is
-// in *rem and true will be returned.
-inline bool IDivFastPath(const Duration num, const Duration den, int64_t* q,
- Duration* rem) {
- // Bail if num or den is an infinity.
- if (time_internal::IsInfiniteDuration(num) ||
- time_internal::IsInfiniteDuration(den))
- return false;
-
- int64_t num_hi = time_internal::GetRepHi(num);
- uint32_t num_lo = time_internal::GetRepLo(num);
- int64_t den_hi = time_internal::GetRepHi(den);
- uint32_t den_lo = time_internal::GetRepLo(den);
-
- if (den_hi == 0 && den_lo == kTicksPerNanosecond) {
- // Dividing by 1ns
- if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000000) {
- *q = num_hi * 1000000000 + num_lo / kTicksPerNanosecond;
- *rem = time_internal::MakeDuration(0, num_lo % den_lo);
- return true;
- }
- } else if (den_hi == 0 && den_lo == 100 * kTicksPerNanosecond) {
- // Dividing by 100ns (common when converting to Universal time)
- if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 10000000) {
- *q = num_hi * 10000000 + num_lo / (100 * kTicksPerNanosecond);
- *rem = time_internal::MakeDuration(0, num_lo % den_lo);
- return true;
- }
- } else if (den_hi == 0 && den_lo == 1000 * kTicksPerNanosecond) {
- // Dividing by 1us
- if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000) {
- *q = num_hi * 1000000 + num_lo / (1000 * kTicksPerNanosecond);
- *rem = time_internal::MakeDuration(0, num_lo % den_lo);
- return true;
- }
- } else if (den_hi == 0 && den_lo == 1000000 * kTicksPerNanosecond) {
- // Dividing by 1ms
- if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000) {
- *q = num_hi * 1000 + num_lo / (1000000 * kTicksPerNanosecond);
- *rem = time_internal::MakeDuration(0, num_lo % den_lo);
- return true;
- }
- } else if (den_hi > 0 && den_lo == 0) {
- // Dividing by positive multiple of 1s
- if (num_hi >= 0) {
- if (den_hi == 1) {
- *q = num_hi;
- *rem = time_internal::MakeDuration(0, num_lo);
- return true;
- }
- *q = num_hi / den_hi;
- *rem = time_internal::MakeDuration(num_hi % den_hi, num_lo);
- return true;
- }
- if (num_lo != 0) {
- num_hi += 1;
- }
- int64_t quotient = num_hi / den_hi;
- int64_t rem_sec = num_hi % den_hi;
- if (rem_sec > 0) {
- rem_sec -= den_hi;
- quotient += 1;
- }
- if (num_lo != 0) {
- rem_sec -= 1;
- }
- *q = quotient;
- *rem = time_internal::MakeDuration(rem_sec, num_lo);
- return true;
- }
-
- return false;
-}
-
-} // namespace
-
-namespace time_internal {
-
-// The 'satq' argument indicates whether the quotient should saturate at the
-// bounds of int64_t. If it does saturate, the difference will spill over to
-// the remainder. If it does not saturate, the remainder remain accurate,
-// but the returned quotient will over/underflow int64_t and should not be used.
-int64_t IDivDuration(bool satq, const Duration num, const Duration den,
+
+// Note: The overflow detection in this function is done using greater/less *or
+// equal* because kint64max/min is too large to be represented exactly in a
+// double (which only has 53 bits of precision). In order to avoid assigning to
+// rep->hi a double value that is too large for an int64_t (and therefore is
+// undefined), we must consider computations that equal kint64max/min as a
+// double as overflow cases.
+inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) {
+ double c = a_hi + b_hi;
+ if (c >= static_cast<double>(kint64max)) {
+ *d = InfiniteDuration();
+ return false;
+ }
+ if (c <= static_cast<double>(kint64min)) {
+ *d = -InfiniteDuration();
+ return false;
+ }
+ *d = time_internal::MakeDuration(c, time_internal::GetRepLo(*d));
+ return true;
+}
+
+// A functor that's similar to std::multiplies<T>, except this returns the max
+// T value instead of overflowing. This is only defined for uint128.
+template <typename Ignored>
+struct SafeMultiply {
+ uint128 operator()(uint128 a, uint128 b) const {
+ // b hi is always zero because it originated as an int64_t.
+ assert(Uint128High64(b) == 0);
+ // Fastpath to avoid the expensive overflow check with division.
+ if (Uint128High64(a) == 0) {
+ return (((Uint128Low64(a) | Uint128Low64(b)) >> 32) == 0)
+ ? static_cast<uint128>(Uint128Low64(a) * Uint128Low64(b))
+ : a * b;
+ }
+ return b == 0 ? b : (a > kuint128max / b) ? kuint128max : a * b;
+ }
+};
+
+// Scales (i.e., multiplies or divides, depending on the Operation template)
+// the Duration d by the int64_t r.
+template <template <typename> class Operation>
+inline Duration ScaleFixed(Duration d, int64_t r) {
+ const uint128 a = MakeU128Ticks(d);
+ const uint128 b = MakeU128(r);
+ const uint128 q = Operation<uint128>()(a, b);
+ const bool is_neg = (time_internal::GetRepHi(d) < 0) != (r < 0);
+ return MakeDurationFromU128(q, is_neg);
+}
+
+// Scales (i.e., multiplies or divides, depending on the Operation template)
+// the Duration d by the double r.
+template <template <typename> class Operation>
+inline Duration ScaleDouble(Duration d, double r) {
+ Operation<double> op;
+ double hi_doub = op(time_internal::GetRepHi(d), r);
+ double lo_doub = op(time_internal::GetRepLo(d), r);
+
+ double hi_int = 0;
+ double hi_frac = std::modf(hi_doub, &hi_int);
+
+ // Moves hi's fractional bits to lo.
+ lo_doub /= kTicksPerSecond;
+ lo_doub += hi_frac;
+
+ double lo_int = 0;
+ double lo_frac = std::modf(lo_doub, &lo_int);
+
+ // Rolls lo into hi if necessary.
+ int64_t lo64 = Round(lo_frac * kTicksPerSecond);
+
+ Duration ans;
+ if (!SafeAddRepHi(hi_int, lo_int, &ans)) return ans;
+ int64_t hi64 = time_internal::GetRepHi(ans);
+ if (!SafeAddRepHi(hi64, lo64 / kTicksPerSecond, &ans)) return ans;
+ hi64 = time_internal::GetRepHi(ans);
+ lo64 %= kTicksPerSecond;
+ NormalizeTicks(&hi64, &lo64);
+ return time_internal::MakeDuration(hi64, lo64);
+}
+
+// Tries to divide num by den as fast as possible by looking for common, easy
+// cases. If the division was done, the quotient is in *q and the remainder is
+// in *rem and true will be returned.
+inline bool IDivFastPath(const Duration num, const Duration den, int64_t* q,
+ Duration* rem) {
+ // Bail if num or den is an infinity.
+ if (time_internal::IsInfiniteDuration(num) ||
+ time_internal::IsInfiniteDuration(den))
+ return false;
+
+ int64_t num_hi = time_internal::GetRepHi(num);
+ uint32_t num_lo = time_internal::GetRepLo(num);
+ int64_t den_hi = time_internal::GetRepHi(den);
+ uint32_t den_lo = time_internal::GetRepLo(den);
+
+ if (den_hi == 0 && den_lo == kTicksPerNanosecond) {
+ // Dividing by 1ns
+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000000) {
+ *q = num_hi * 1000000000 + num_lo / kTicksPerNanosecond;
+ *rem = time_internal::MakeDuration(0, num_lo % den_lo);
+ return true;
+ }
+ } else if (den_hi == 0 && den_lo == 100 * kTicksPerNanosecond) {
+ // Dividing by 100ns (common when converting to Universal time)
+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 10000000) {
+ *q = num_hi * 10000000 + num_lo / (100 * kTicksPerNanosecond);
+ *rem = time_internal::MakeDuration(0, num_lo % den_lo);
+ return true;
+ }
+ } else if (den_hi == 0 && den_lo == 1000 * kTicksPerNanosecond) {
+ // Dividing by 1us
+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000) {
+ *q = num_hi * 1000000 + num_lo / (1000 * kTicksPerNanosecond);
+ *rem = time_internal::MakeDuration(0, num_lo % den_lo);
+ return true;
+ }
+ } else if (den_hi == 0 && den_lo == 1000000 * kTicksPerNanosecond) {
+ // Dividing by 1ms
+ if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000) {
+ *q = num_hi * 1000 + num_lo / (1000000 * kTicksPerNanosecond);
+ *rem = time_internal::MakeDuration(0, num_lo % den_lo);
+ return true;
+ }
+ } else if (den_hi > 0 && den_lo == 0) {
+ // Dividing by positive multiple of 1s
+ if (num_hi >= 0) {
+ if (den_hi == 1) {
+ *q = num_hi;
+ *rem = time_internal::MakeDuration(0, num_lo);
+ return true;
+ }
+ *q = num_hi / den_hi;
+ *rem = time_internal::MakeDuration(num_hi % den_hi, num_lo);
+ return true;
+ }
+ if (num_lo != 0) {
+ num_hi += 1;
+ }
+ int64_t quotient = num_hi / den_hi;
+ int64_t rem_sec = num_hi % den_hi;
+ if (rem_sec > 0) {
+ rem_sec -= den_hi;
+ quotient += 1;
+ }
+ if (num_lo != 0) {
+ rem_sec -= 1;
+ }
+ *q = quotient;
+ *rem = time_internal::MakeDuration(rem_sec, num_lo);
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+namespace time_internal {
+
+// The 'satq' argument indicates whether the quotient should saturate at the
+// bounds of int64_t. If it does saturate, the difference will spill over to
+// the remainder. If it does not saturate, the remainder remain accurate,
+// but the returned quotient will over/underflow int64_t and should not be used.
+int64_t IDivDuration(bool satq, const Duration num, const Duration den,
Duration* rem) {
- int64_t q = 0;
- if (IDivFastPath(num, den, &q, rem)) {
- return q;
- }
-
- const bool num_neg = num < ZeroDuration();
- const bool den_neg = den < ZeroDuration();
- const bool quotient_neg = num_neg != den_neg;
-
- if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) {
- *rem = num_neg ? -InfiniteDuration() : InfiniteDuration();
- return quotient_neg ? kint64min : kint64max;
- }
- if (time_internal::IsInfiniteDuration(den)) {
- *rem = num;
- return 0;
- }
-
- const uint128 a = MakeU128Ticks(num);
- const uint128 b = MakeU128Ticks(den);
- uint128 quotient128 = a / b;
-
- if (satq) {
- // Limits the quotient to the range of int64_t.
- if (quotient128 > uint128(static_cast<uint64_t>(kint64max))) {
- quotient128 = quotient_neg ? uint128(static_cast<uint64_t>(kint64min))
- : uint128(static_cast<uint64_t>(kint64max));
- }
- }
-
- const uint128 remainder128 = a - quotient128 * b;
- *rem = MakeDurationFromU128(remainder128, num_neg);
-
- if (!quotient_neg || quotient128 == 0) {
- return Uint128Low64(quotient128) & kint64max;
- }
- // The quotient needs to be negated, but we need to carefully handle
- // quotient128s with the top bit on.
- return -static_cast<int64_t>(Uint128Low64(quotient128 - 1) & kint64max) - 1;
-}
-
-} // namespace time_internal
-
-//
-// Additive operators.
-//
-
-Duration& Duration::operator+=(Duration rhs) {
- if (time_internal::IsInfiniteDuration(*this)) return *this;
- if (time_internal::IsInfiniteDuration(rhs)) return *this = rhs;
- const int64_t orig_rep_hi = rep_hi_;
- rep_hi_ =
- DecodeTwosComp(EncodeTwosComp(rep_hi_) + EncodeTwosComp(rhs.rep_hi_));
- if (rep_lo_ >= kTicksPerSecond - rhs.rep_lo_) {
- rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) + 1);
- rep_lo_ -= kTicksPerSecond;
- }
- rep_lo_ += rhs.rep_lo_;
- if (rhs.rep_hi_ < 0 ? rep_hi_ > orig_rep_hi : rep_hi_ < orig_rep_hi) {
- return *this = rhs.rep_hi_ < 0 ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this;
-}
-
-Duration& Duration::operator-=(Duration rhs) {
- if (time_internal::IsInfiniteDuration(*this)) return *this;
- if (time_internal::IsInfiniteDuration(rhs)) {
- return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
- }
- const int64_t orig_rep_hi = rep_hi_;
- rep_hi_ =
- DecodeTwosComp(EncodeTwosComp(rep_hi_) - EncodeTwosComp(rhs.rep_hi_));
- if (rep_lo_ < rhs.rep_lo_) {
- rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) - 1);
- rep_lo_ += kTicksPerSecond;
- }
- rep_lo_ -= rhs.rep_lo_;
- if (rhs.rep_hi_ < 0 ? rep_hi_ < orig_rep_hi : rep_hi_ > orig_rep_hi) {
- return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this;
-}
-
-//
-// Multiplicative operators.
-//
-
-Duration& Duration::operator*=(int64_t r) {
- if (time_internal::IsInfiniteDuration(*this)) {
- const bool is_neg = (r < 0) != (rep_hi_ < 0);
- return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this = ScaleFixed<SafeMultiply>(*this, r);
-}
-
-Duration& Duration::operator*=(double r) {
- if (time_internal::IsInfiniteDuration(*this) || !IsFinite(r)) {
- const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
- return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this = ScaleDouble<std::multiplies>(*this, r);
-}
-
-Duration& Duration::operator/=(int64_t r) {
- if (time_internal::IsInfiniteDuration(*this) || r == 0) {
- const bool is_neg = (r < 0) != (rep_hi_ < 0);
- return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this = ScaleFixed<std::divides>(*this, r);
-}
-
-Duration& Duration::operator/=(double r) {
- if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) {
- const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
- return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
- }
- return *this = ScaleDouble<std::divides>(*this, r);
-}
-
-Duration& Duration::operator%=(Duration rhs) {
- time_internal::IDivDuration(false, *this, rhs, this);
- return *this;
-}
-
-double FDivDuration(Duration num, Duration den) {
- // Arithmetic with infinity is sticky.
- if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) {
- return (num < ZeroDuration()) == (den < ZeroDuration())
- ? std::numeric_limits<double>::infinity()
- : -std::numeric_limits<double>::infinity();
- }
- if (time_internal::IsInfiniteDuration(den)) return 0.0;
-
- double a =
- static_cast<double>(time_internal::GetRepHi(num)) * kTicksPerSecond +
- time_internal::GetRepLo(num);
- double b =
- static_cast<double>(time_internal::GetRepHi(den)) * kTicksPerSecond +
- time_internal::GetRepLo(den);
- return a / b;
-}
-
-//
-// Trunc/Floor/Ceil.
-//
-
-Duration Trunc(Duration d, Duration unit) {
- return d - (d % unit);
-}
-
-Duration Floor(const Duration d, const Duration unit) {
+ int64_t q = 0;
+ if (IDivFastPath(num, den, &q, rem)) {
+ return q;
+ }
+
+ const bool num_neg = num < ZeroDuration();
+ const bool den_neg = den < ZeroDuration();
+ const bool quotient_neg = num_neg != den_neg;
+
+ if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) {
+ *rem = num_neg ? -InfiniteDuration() : InfiniteDuration();
+ return quotient_neg ? kint64min : kint64max;
+ }
+ if (time_internal::IsInfiniteDuration(den)) {
+ *rem = num;
+ return 0;
+ }
+
+ const uint128 a = MakeU128Ticks(num);
+ const uint128 b = MakeU128Ticks(den);
+ uint128 quotient128 = a / b;
+
+ if (satq) {
+ // Limits the quotient to the range of int64_t.
+ if (quotient128 > uint128(static_cast<uint64_t>(kint64max))) {
+ quotient128 = quotient_neg ? uint128(static_cast<uint64_t>(kint64min))
+ : uint128(static_cast<uint64_t>(kint64max));
+ }
+ }
+
+ const uint128 remainder128 = a - quotient128 * b;
+ *rem = MakeDurationFromU128(remainder128, num_neg);
+
+ if (!quotient_neg || quotient128 == 0) {
+ return Uint128Low64(quotient128) & kint64max;
+ }
+ // The quotient needs to be negated, but we need to carefully handle
+ // quotient128s with the top bit on.
+ return -static_cast<int64_t>(Uint128Low64(quotient128 - 1) & kint64max) - 1;
+}
+
+} // namespace time_internal
+
+//
+// Additive operators.
+//
+
+Duration& Duration::operator+=(Duration rhs) {
+ if (time_internal::IsInfiniteDuration(*this)) return *this;
+ if (time_internal::IsInfiniteDuration(rhs)) return *this = rhs;
+ const int64_t orig_rep_hi = rep_hi_;
+ rep_hi_ =
+ DecodeTwosComp(EncodeTwosComp(rep_hi_) + EncodeTwosComp(rhs.rep_hi_));
+ if (rep_lo_ >= kTicksPerSecond - rhs.rep_lo_) {
+ rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) + 1);
+ rep_lo_ -= kTicksPerSecond;
+ }
+ rep_lo_ += rhs.rep_lo_;
+ if (rhs.rep_hi_ < 0 ? rep_hi_ > orig_rep_hi : rep_hi_ < orig_rep_hi) {
+ return *this = rhs.rep_hi_ < 0 ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this;
+}
+
+Duration& Duration::operator-=(Duration rhs) {
+ if (time_internal::IsInfiniteDuration(*this)) return *this;
+ if (time_internal::IsInfiniteDuration(rhs)) {
+ return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
+ }
+ const int64_t orig_rep_hi = rep_hi_;
+ rep_hi_ =
+ DecodeTwosComp(EncodeTwosComp(rep_hi_) - EncodeTwosComp(rhs.rep_hi_));
+ if (rep_lo_ < rhs.rep_lo_) {
+ rep_hi_ = DecodeTwosComp(EncodeTwosComp(rep_hi_) - 1);
+ rep_lo_ += kTicksPerSecond;
+ }
+ rep_lo_ -= rhs.rep_lo_;
+ if (rhs.rep_hi_ < 0 ? rep_hi_ < orig_rep_hi : rep_hi_ > orig_rep_hi) {
+ return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this;
+}
+
+//
+// Multiplicative operators.
+//
+
+Duration& Duration::operator*=(int64_t r) {
+ if (time_internal::IsInfiniteDuration(*this)) {
+ const bool is_neg = (r < 0) != (rep_hi_ < 0);
+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this = ScaleFixed<SafeMultiply>(*this, r);
+}
+
+Duration& Duration::operator*=(double r) {
+ if (time_internal::IsInfiniteDuration(*this) || !IsFinite(r)) {
+ const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this = ScaleDouble<std::multiplies>(*this, r);
+}
+
+Duration& Duration::operator/=(int64_t r) {
+ if (time_internal::IsInfiniteDuration(*this) || r == 0) {
+ const bool is_neg = (r < 0) != (rep_hi_ < 0);
+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this = ScaleFixed<std::divides>(*this, r);
+}
+
+Duration& Duration::operator/=(double r) {
+ if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) {
+ const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
+ return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
+ }
+ return *this = ScaleDouble<std::divides>(*this, r);
+}
+
+Duration& Duration::operator%=(Duration rhs) {
+ time_internal::IDivDuration(false, *this, rhs, this);
+ return *this;
+}
+
+double FDivDuration(Duration num, Duration den) {
+ // Arithmetic with infinity is sticky.
+ if (time_internal::IsInfiniteDuration(num) || den == ZeroDuration()) {
+ return (num < ZeroDuration()) == (den < ZeroDuration())
+ ? std::numeric_limits<double>::infinity()
+ : -std::numeric_limits<double>::infinity();
+ }
+ if (time_internal::IsInfiniteDuration(den)) return 0.0;
+
+ double a =
+ static_cast<double>(time_internal::GetRepHi(num)) * kTicksPerSecond +
+ time_internal::GetRepLo(num);
+ double b =
+ static_cast<double>(time_internal::GetRepHi(den)) * kTicksPerSecond +
+ time_internal::GetRepLo(den);
+ return a / b;
+}
+
+//
+// Trunc/Floor/Ceil.
+//
+
+Duration Trunc(Duration d, Duration unit) {
+ return d - (d % unit);
+}
+
+Duration Floor(const Duration d, const Duration unit) {
const y_absl::Duration td = Trunc(d, unit);
- return td <= d ? td : td - AbsDuration(unit);
-}
-
-Duration Ceil(const Duration d, const Duration unit) {
+ return td <= d ? td : td - AbsDuration(unit);
+}
+
+Duration Ceil(const Duration d, const Duration unit) {
const y_absl::Duration td = Trunc(d, unit);
- return td >= d ? td : td + AbsDuration(unit);
-}
-
-//
-// Factory functions.
-//
-
-Duration DurationFromTimespec(timespec ts) {
- if (static_cast<uint64_t>(ts.tv_nsec) < 1000 * 1000 * 1000) {
- int64_t ticks = ts.tv_nsec * kTicksPerNanosecond;
- return time_internal::MakeDuration(ts.tv_sec, ticks);
- }
- return Seconds(ts.tv_sec) + Nanoseconds(ts.tv_nsec);
-}
-
-Duration DurationFromTimeval(timeval tv) {
- if (static_cast<uint64_t>(tv.tv_usec) < 1000 * 1000) {
- int64_t ticks = tv.tv_usec * 1000 * kTicksPerNanosecond;
- return time_internal::MakeDuration(tv.tv_sec, ticks);
- }
- return Seconds(tv.tv_sec) + Microseconds(tv.tv_usec);
-}
-
-//
-// Conversion to other duration types.
-//
-
-int64_t ToInt64Nanoseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 33 == 0) {
- return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
- (time_internal::GetRepLo(d) / kTicksPerNanosecond);
- }
- return d / Nanoseconds(1);
-}
-int64_t ToInt64Microseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 43 == 0) {
- return (time_internal::GetRepHi(d) * 1000 * 1000) +
- (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000));
- }
- return d / Microseconds(1);
-}
-int64_t ToInt64Milliseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 53 == 0) {
- return (time_internal::GetRepHi(d) * 1000) +
- (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000 * 1000));
- }
- return d / Milliseconds(1);
-}
-int64_t ToInt64Seconds(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi;
-}
-int64_t ToInt64Minutes(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi / 60;
-}
-int64_t ToInt64Hours(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi / (60 * 60);
-}
-
-double ToDoubleNanoseconds(Duration d) {
- return FDivDuration(d, Nanoseconds(1));
-}
-double ToDoubleMicroseconds(Duration d) {
- return FDivDuration(d, Microseconds(1));
-}
-double ToDoubleMilliseconds(Duration d) {
- return FDivDuration(d, Milliseconds(1));
-}
-double ToDoubleSeconds(Duration d) {
- return FDivDuration(d, Seconds(1));
-}
-double ToDoubleMinutes(Duration d) {
- return FDivDuration(d, Minutes(1));
-}
-double ToDoubleHours(Duration d) {
- return FDivDuration(d, Hours(1));
-}
-
-timespec ToTimespec(Duration d) {
- timespec ts;
- if (!time_internal::IsInfiniteDuration(d)) {
- int64_t rep_hi = time_internal::GetRepHi(d);
- uint32_t rep_lo = time_internal::GetRepLo(d);
- if (rep_hi < 0) {
- // Tweak the fields so that unsigned division of rep_lo
- // maps to truncation (towards zero) for the timespec.
- rep_lo += kTicksPerNanosecond - 1;
- if (rep_lo >= kTicksPerSecond) {
- rep_hi += 1;
- rep_lo -= kTicksPerSecond;
- }
- }
- ts.tv_sec = rep_hi;
- if (ts.tv_sec == rep_hi) { // no time_t narrowing
- ts.tv_nsec = rep_lo / kTicksPerNanosecond;
- return ts;
- }
- }
- if (d >= ZeroDuration()) {
- ts.tv_sec = std::numeric_limits<time_t>::max();
- ts.tv_nsec = 1000 * 1000 * 1000 - 1;
- } else {
- ts.tv_sec = std::numeric_limits<time_t>::min();
- ts.tv_nsec = 0;
- }
- return ts;
-}
-
-timeval ToTimeval(Duration d) {
- timeval tv;
- timespec ts = ToTimespec(d);
- if (ts.tv_sec < 0) {
- // Tweak the fields so that positive division of tv_nsec
- // maps to truncation (towards zero) for the timeval.
- ts.tv_nsec += 1000 - 1;
- if (ts.tv_nsec >= 1000 * 1000 * 1000) {
- ts.tv_sec += 1;
- ts.tv_nsec -= 1000 * 1000 * 1000;
- }
- }
- tv.tv_sec = ts.tv_sec;
- if (tv.tv_sec != ts.tv_sec) { // narrowing
- if (ts.tv_sec < 0) {
- tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
- tv.tv_usec = 0;
- } else {
- tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
- tv.tv_usec = 1000 * 1000 - 1;
- }
- return tv;
- }
- tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t
- return tv;
-}
-
-std::chrono::nanoseconds ToChronoNanoseconds(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::nanoseconds>(d);
-}
-std::chrono::microseconds ToChronoMicroseconds(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::microseconds>(d);
-}
-std::chrono::milliseconds ToChronoMilliseconds(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::milliseconds>(d);
-}
-std::chrono::seconds ToChronoSeconds(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::seconds>(d);
-}
-std::chrono::minutes ToChronoMinutes(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::minutes>(d);
-}
-std::chrono::hours ToChronoHours(Duration d) {
- return time_internal::ToChronoDuration<std::chrono::hours>(d);
-}
-
-//
-// To/From string formatting.
-//
-
-namespace {
-
-// Formats a positive 64-bit integer in the given field width. Note that
-// it is up to the caller of Format64() to ensure that there is sufficient
-// space before ep to hold the conversion.
-char* Format64(char* ep, int width, int64_t v) {
- do {
- --width;
- *--ep = '0' + (v % 10); // contiguous digits
- } while (v /= 10);
- while (--width >= 0) *--ep = '0'; // zero pad
- return ep;
-}
-
-// Helpers for FormatDuration() that format 'n' and append it to 'out'
-// followed by the given 'unit'. If 'n' formats to "0", nothing is
-// appended (not even the unit).
-
-// A type that encapsulates how to display a value of a particular unit. For
-// values that are displayed with fractional parts, the precision indicates
-// where to round the value. The precision varies with the display unit because
-// a Duration can hold only quarters of a nanosecond, so displaying information
-// beyond that is just noise.
-//
-// For example, a microsecond value of 42.00025xxxxx should not display beyond 5
-// fractional digits, because it is in the noise of what a Duration can
-// represent.
-struct DisplayUnit {
+ return td >= d ? td : td + AbsDuration(unit);
+}
+
+//
+// Factory functions.
+//
+
+Duration DurationFromTimespec(timespec ts) {
+ if (static_cast<uint64_t>(ts.tv_nsec) < 1000 * 1000 * 1000) {
+ int64_t ticks = ts.tv_nsec * kTicksPerNanosecond;
+ return time_internal::MakeDuration(ts.tv_sec, ticks);
+ }
+ return Seconds(ts.tv_sec) + Nanoseconds(ts.tv_nsec);
+}
+
+Duration DurationFromTimeval(timeval tv) {
+ if (static_cast<uint64_t>(tv.tv_usec) < 1000 * 1000) {
+ int64_t ticks = tv.tv_usec * 1000 * kTicksPerNanosecond;
+ return time_internal::MakeDuration(tv.tv_sec, ticks);
+ }
+ return Seconds(tv.tv_sec) + Microseconds(tv.tv_usec);
+}
+
+//
+// Conversion to other duration types.
+//
+
+int64_t ToInt64Nanoseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 33 == 0) {
+ return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
+ (time_internal::GetRepLo(d) / kTicksPerNanosecond);
+ }
+ return d / Nanoseconds(1);
+}
+int64_t ToInt64Microseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 43 == 0) {
+ return (time_internal::GetRepHi(d) * 1000 * 1000) +
+ (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000));
+ }
+ return d / Microseconds(1);
+}
+int64_t ToInt64Milliseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 53 == 0) {
+ return (time_internal::GetRepHi(d) * 1000) +
+ (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000 * 1000));
+ }
+ return d / Milliseconds(1);
+}
+int64_t ToInt64Seconds(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi;
+}
+int64_t ToInt64Minutes(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi / 60;
+}
+int64_t ToInt64Hours(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi / (60 * 60);
+}
+
+double ToDoubleNanoseconds(Duration d) {
+ return FDivDuration(d, Nanoseconds(1));
+}
+double ToDoubleMicroseconds(Duration d) {
+ return FDivDuration(d, Microseconds(1));
+}
+double ToDoubleMilliseconds(Duration d) {
+ return FDivDuration(d, Milliseconds(1));
+}
+double ToDoubleSeconds(Duration d) {
+ return FDivDuration(d, Seconds(1));
+}
+double ToDoubleMinutes(Duration d) {
+ return FDivDuration(d, Minutes(1));
+}
+double ToDoubleHours(Duration d) {
+ return FDivDuration(d, Hours(1));
+}
+
+timespec ToTimespec(Duration d) {
+ timespec ts;
+ if (!time_internal::IsInfiniteDuration(d)) {
+ int64_t rep_hi = time_internal::GetRepHi(d);
+ uint32_t rep_lo = time_internal::GetRepLo(d);
+ if (rep_hi < 0) {
+ // Tweak the fields so that unsigned division of rep_lo
+ // maps to truncation (towards zero) for the timespec.
+ rep_lo += kTicksPerNanosecond - 1;
+ if (rep_lo >= kTicksPerSecond) {
+ rep_hi += 1;
+ rep_lo -= kTicksPerSecond;
+ }
+ }
+ ts.tv_sec = rep_hi;
+ if (ts.tv_sec == rep_hi) { // no time_t narrowing
+ ts.tv_nsec = rep_lo / kTicksPerNanosecond;
+ return ts;
+ }
+ }
+ if (d >= ZeroDuration()) {
+ ts.tv_sec = std::numeric_limits<time_t>::max();
+ ts.tv_nsec = 1000 * 1000 * 1000 - 1;
+ } else {
+ ts.tv_sec = std::numeric_limits<time_t>::min();
+ ts.tv_nsec = 0;
+ }
+ return ts;
+}
+
+timeval ToTimeval(Duration d) {
+ timeval tv;
+ timespec ts = ToTimespec(d);
+ if (ts.tv_sec < 0) {
+ // Tweak the fields so that positive division of tv_nsec
+ // maps to truncation (towards zero) for the timeval.
+ ts.tv_nsec += 1000 - 1;
+ if (ts.tv_nsec >= 1000 * 1000 * 1000) {
+ ts.tv_sec += 1;
+ ts.tv_nsec -= 1000 * 1000 * 1000;
+ }
+ }
+ tv.tv_sec = ts.tv_sec;
+ if (tv.tv_sec != ts.tv_sec) { // narrowing
+ if (ts.tv_sec < 0) {
+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
+ tv.tv_usec = 1000 * 1000 - 1;
+ }
+ return tv;
+ }
+ tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t
+ return tv;
+}
+
+std::chrono::nanoseconds ToChronoNanoseconds(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::nanoseconds>(d);
+}
+std::chrono::microseconds ToChronoMicroseconds(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::microseconds>(d);
+}
+std::chrono::milliseconds ToChronoMilliseconds(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::milliseconds>(d);
+}
+std::chrono::seconds ToChronoSeconds(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::seconds>(d);
+}
+std::chrono::minutes ToChronoMinutes(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::minutes>(d);
+}
+std::chrono::hours ToChronoHours(Duration d) {
+ return time_internal::ToChronoDuration<std::chrono::hours>(d);
+}
+
+//
+// To/From string formatting.
+//
+
+namespace {
+
+// Formats a positive 64-bit integer in the given field width. Note that
+// it is up to the caller of Format64() to ensure that there is sufficient
+// space before ep to hold the conversion.
+char* Format64(char* ep, int width, int64_t v) {
+ do {
+ --width;
+ *--ep = '0' + (v % 10); // contiguous digits
+ } while (v /= 10);
+ while (--width >= 0) *--ep = '0'; // zero pad
+ return ep;
+}
+
+// Helpers for FormatDuration() that format 'n' and append it to 'out'
+// followed by the given 'unit'. If 'n' formats to "0", nothing is
+// appended (not even the unit).
+
+// A type that encapsulates how to display a value of a particular unit. For
+// values that are displayed with fractional parts, the precision indicates
+// where to round the value. The precision varies with the display unit because
+// a Duration can hold only quarters of a nanosecond, so displaying information
+// beyond that is just noise.
+//
+// For example, a microsecond value of 42.00025xxxxx should not display beyond 5
+// fractional digits, because it is in the noise of what a Duration can
+// represent.
+struct DisplayUnit {
y_absl::string_view abbr;
- int prec;
- double pow10;
-};
+ int prec;
+ double pow10;
+};
ABSL_CONST_INIT const DisplayUnit kDisplayNano = {"ns", 2, 1e2};
ABSL_CONST_INIT const DisplayUnit kDisplayMicro = {"us", 5, 1e5};
ABSL_CONST_INIT const DisplayUnit kDisplayMilli = {"ms", 8, 1e8};
@@ -722,123 +722,123 @@ ABSL_CONST_INIT const DisplayUnit kDisplaySec = {"s", 11, 1e11};
ABSL_CONST_INIT const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored
ABSL_CONST_INIT const DisplayUnit kDisplayHour = {"h", -1,
0.0}; // prec ignored
-
+
void AppendNumberUnit(TString* out, int64_t n, DisplayUnit unit) {
- char buf[sizeof("2562047788015216")]; // hours in max duration
- char* const ep = buf + sizeof(buf);
- char* bp = Format64(ep, 0, n);
- if (*bp != '0' || bp + 1 != ep) {
- out->append(bp, ep - bp);
+ char buf[sizeof("2562047788015216")]; // hours in max duration
+ char* const ep = buf + sizeof(buf);
+ char* bp = Format64(ep, 0, n);
+ if (*bp != '0' || bp + 1 != ep) {
+ out->append(bp, ep - bp);
out->append(unit.abbr.data(), unit.abbr.size());
- }
-}
-
-// Note: unit.prec is limited to double's digits10 value (typically 15) so it
-// always fits in buf[].
+ }
+}
+
+// Note: unit.prec is limited to double's digits10 value (typically 15) so it
+// always fits in buf[].
void AppendNumberUnit(TString* out, double n, DisplayUnit unit) {
constexpr int kBufferSize = std::numeric_limits<double>::digits10;
const int prec = std::min(kBufferSize, unit.prec);
char buf[kBufferSize]; // also large enough to hold integer part
- char* ep = buf + sizeof(buf);
- double d = 0;
- int64_t frac_part = Round(std::modf(n, &d) * unit.pow10);
- int64_t int_part = d;
- if (int_part != 0 || frac_part != 0) {
- char* bp = Format64(ep, 0, int_part); // always < 1000
- out->append(bp, ep - bp);
- if (frac_part != 0) {
- out->push_back('.');
- bp = Format64(ep, prec, frac_part);
- while (ep[-1] == '0') --ep;
- out->append(bp, ep - bp);
- }
+ char* ep = buf + sizeof(buf);
+ double d = 0;
+ int64_t frac_part = Round(std::modf(n, &d) * unit.pow10);
+ int64_t int_part = d;
+ if (int_part != 0 || frac_part != 0) {
+ char* bp = Format64(ep, 0, int_part); // always < 1000
+ out->append(bp, ep - bp);
+ if (frac_part != 0) {
+ out->push_back('.');
+ bp = Format64(ep, prec, frac_part);
+ while (ep[-1] == '0') --ep;
+ out->append(bp, ep - bp);
+ }
out->append(unit.abbr.data(), unit.abbr.size());
- }
-}
-
-} // namespace
-
-// From Go's doc at https://golang.org/pkg/time/#Duration.String
-// [FormatDuration] returns a string representing the duration in the
-// form "72h3m0.5s". Leading zero units are omitted. As a special
-// case, durations less than one second format use a smaller unit
-// (milli-, micro-, or nanoseconds) to ensure that the leading digit
+ }
+}
+
+} // namespace
+
+// From Go's doc at https://golang.org/pkg/time/#Duration.String
+// [FormatDuration] returns a string representing the duration in the
+// form "72h3m0.5s". Leading zero units are omitted. As a special
+// case, durations less than one second format use a smaller unit
+// (milli-, micro-, or nanoseconds) to ensure that the leading digit
// is non-zero.
// Unlike Go, we format the zero duration as 0, with no unit.
TString FormatDuration(Duration d) {
- const Duration min_duration = Seconds(kint64min);
- if (d == min_duration) {
- // Avoid needing to negate kint64min by directly returning what the
- // following code should produce in that case.
- return "-2562047788015215h30m8s";
- }
+ const Duration min_duration = Seconds(kint64min);
+ if (d == min_duration) {
+ // Avoid needing to negate kint64min by directly returning what the
+ // following code should produce in that case.
+ return "-2562047788015215h30m8s";
+ }
TString s;
- if (d < ZeroDuration()) {
- s.append("-");
- d = -d;
- }
- if (d == InfiniteDuration()) {
- s.append("inf");
- } else if (d < Seconds(1)) {
- // Special case for durations with a magnitude < 1 second. The duration
- // is printed as a fraction of a single unit, e.g., "1.2ms".
- if (d < Microseconds(1)) {
- AppendNumberUnit(&s, FDivDuration(d, Nanoseconds(1)), kDisplayNano);
- } else if (d < Milliseconds(1)) {
- AppendNumberUnit(&s, FDivDuration(d, Microseconds(1)), kDisplayMicro);
- } else {
- AppendNumberUnit(&s, FDivDuration(d, Milliseconds(1)), kDisplayMilli);
- }
- } else {
- AppendNumberUnit(&s, IDivDuration(d, Hours(1), &d), kDisplayHour);
- AppendNumberUnit(&s, IDivDuration(d, Minutes(1), &d), kDisplayMin);
- AppendNumberUnit(&s, FDivDuration(d, Seconds(1)), kDisplaySec);
- }
- if (s.empty() || s == "-") {
- s = "0";
- }
- return s;
-}
-
-namespace {
-
-// A helper for ParseDuration() that parses a leading number from the given
-// string and stores the result in *int_part/*frac_part/*frac_scale. The
-// given string pointer is modified to point to the first unconsumed char.
+ if (d < ZeroDuration()) {
+ s.append("-");
+ d = -d;
+ }
+ if (d == InfiniteDuration()) {
+ s.append("inf");
+ } else if (d < Seconds(1)) {
+ // Special case for durations with a magnitude < 1 second. The duration
+ // is printed as a fraction of a single unit, e.g., "1.2ms".
+ if (d < Microseconds(1)) {
+ AppendNumberUnit(&s, FDivDuration(d, Nanoseconds(1)), kDisplayNano);
+ } else if (d < Milliseconds(1)) {
+ AppendNumberUnit(&s, FDivDuration(d, Microseconds(1)), kDisplayMicro);
+ } else {
+ AppendNumberUnit(&s, FDivDuration(d, Milliseconds(1)), kDisplayMilli);
+ }
+ } else {
+ AppendNumberUnit(&s, IDivDuration(d, Hours(1), &d), kDisplayHour);
+ AppendNumberUnit(&s, IDivDuration(d, Minutes(1), &d), kDisplayMin);
+ AppendNumberUnit(&s, FDivDuration(d, Seconds(1)), kDisplaySec);
+ }
+ if (s.empty() || s == "-") {
+ s = "0";
+ }
+ return s;
+}
+
+namespace {
+
+// A helper for ParseDuration() that parses a leading number from the given
+// string and stores the result in *int_part/*frac_part/*frac_scale. The
+// given string pointer is modified to point to the first unconsumed char.
bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part,
- int64_t* frac_part, int64_t* frac_scale) {
- *int_part = 0;
- *frac_part = 0;
- *frac_scale = 1; // invariant: *frac_part < *frac_scale
- const char* start = *dpp;
+ int64_t* frac_part, int64_t* frac_scale) {
+ *int_part = 0;
+ *frac_part = 0;
+ *frac_scale = 1; // invariant: *frac_part < *frac_scale
+ const char* start = *dpp;
for (; *dpp != ep; *dpp += 1) {
- const int d = **dpp - '0'; // contiguous digits
+ const int d = **dpp - '0'; // contiguous digits
if (d < 0 || 10 <= d) break;
- if (*int_part > kint64max / 10) return false;
- *int_part *= 10;
- if (*int_part > kint64max - d) return false;
- *int_part += d;
- }
- const bool int_part_empty = (*dpp == start);
+ if (*int_part > kint64max / 10) return false;
+ *int_part *= 10;
+ if (*int_part > kint64max - d) return false;
+ *int_part += d;
+ }
+ const bool int_part_empty = (*dpp == start);
if (*dpp == ep || **dpp != '.') return !int_part_empty;
for (*dpp += 1; *dpp != ep; *dpp += 1) {
- const int d = **dpp - '0'; // contiguous digits
+ const int d = **dpp - '0'; // contiguous digits
if (d < 0 || 10 <= d) break;
- if (*frac_scale <= kint64max / 10) {
- *frac_part *= 10;
- *frac_part += d;
- *frac_scale *= 10;
- }
- }
- return !int_part_empty || *frac_scale != 1;
-}
-
-// A helper for ParseDuration() that parses a leading unit designator (e.g.,
-// ns, us, ms, s, m, h) from the given string and stores the resulting unit
-// in "*unit". The given string pointer is modified to point to the first
-// unconsumed char.
+ if (*frac_scale <= kint64max / 10) {
+ *frac_part *= 10;
+ *frac_part += d;
+ *frac_scale *= 10;
+ }
+ }
+ return !int_part_empty || *frac_scale != 1;
+}
+
+// A helper for ParseDuration() that parses a leading unit designator (e.g.,
+// ns, us, ms, s, m, h) from the given string and stores the resulting unit
+// in "*unit". The given string pointer is modified to point to the first
+// unconsumed char.
bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) {
size_t size = end - *start;
switch (size) {
@@ -888,67 +888,67 @@ bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) {
default:
return false;
}
- }
-}
-
-} // namespace
-
-// From Go's doc at https://golang.org/pkg/time/#ParseDuration
-// [ParseDuration] parses a duration string. A duration string is
-// a possibly signed sequence of decimal numbers, each with optional
-// fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m".
-// Valid time units are "ns", "us" "ms", "s", "m", "h".
+ }
+}
+
+} // namespace
+
+// From Go's doc at https://golang.org/pkg/time/#ParseDuration
+// [ParseDuration] parses a duration string. A duration string is
+// a possibly signed sequence of decimal numbers, each with optional
+// fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m".
+// Valid time units are "ns", "us" "ms", "s", "m", "h".
bool ParseDuration(y_absl::string_view dur_sv, Duration* d) {
- int sign = 1;
+ int sign = 1;
if (y_absl::ConsumePrefix(&dur_sv, "-")) {
sign = -1;
} else {
y_absl::ConsumePrefix(&dur_sv, "+");
- }
+ }
if (dur_sv.empty()) return false;
-
+
// Special case for a string of "0".
if (dur_sv == "0") {
- *d = ZeroDuration();
- return true;
- }
-
+ *d = ZeroDuration();
+ return true;
+ }
+
if (dur_sv == "inf") {
- *d = sign * InfiniteDuration();
- return true;
- }
-
+ *d = sign * InfiniteDuration();
+ return true;
+ }
+
const char* start = dur_sv.data();
const char* end = start + dur_sv.size();
- Duration dur;
+ Duration dur;
while (start != end) {
- int64_t int_part;
- int64_t frac_part;
- int64_t frac_scale;
- Duration unit;
+ int64_t int_part;
+ int64_t frac_part;
+ int64_t frac_scale;
+ Duration unit;
if (!ConsumeDurationNumber(&start, end, &int_part, &frac_part,
&frac_scale) ||
!ConsumeDurationUnit(&start, end, &unit)) {
- return false;
- }
- if (int_part != 0) dur += sign * int_part * unit;
- if (frac_part != 0) dur += sign * frac_part * unit / frac_scale;
- }
- *d = dur;
- return true;
-}
-
+ return false;
+ }
+ if (int_part != 0) dur += sign * int_part * unit;
+ if (frac_part != 0) dur += sign * frac_part * unit / frac_scale;
+ }
+ *d = dur;
+ return true;
+}
+
bool AbslParseFlag(y_absl::string_view text, Duration* dst, TString*) {
return ParseDuration(text, dst);
-}
-
+}
+
TString AbslUnparseFlag(Duration d) { return FormatDuration(d); }
bool ParseFlag(const TString& text, Duration* dst, TString* ) {
- return ParseDuration(text, dst);
-}
-
+ return ParseDuration(text, dst);
+}
+
TString UnparseFlag(Duration d) { return FormatDuration(d); }
-
+
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/format.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/format.cc
index 39c0191963..c75e4ec21a 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/format.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/format.cc
@@ -1,109 +1,109 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string.h>
-
-#include <cctype>
-#include <cstdint>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string.h>
+
+#include <cctype>
+#include <cstdint>
+
#include "y_absl/strings/match.h"
#include "y_absl/strings/string_view.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
#include "y_absl/time/time.h"
-
+
namespace cctz = y_absl::time_internal::cctz;
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
+
ABSL_DLL extern const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
-
+
ABSL_DLL extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z";
ABSL_DLL extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z";
-
-namespace {
-
-const char kInfiniteFutureStr[] = "infinite-future";
-const char kInfinitePastStr[] = "infinite-past";
-
-struct cctz_parts {
- cctz::time_point<cctz::seconds> sec;
- cctz::detail::femtoseconds fem;
-};
-
-inline cctz::time_point<cctz::seconds> unix_epoch() {
- return std::chrono::time_point_cast<cctz::seconds>(
- std::chrono::system_clock::from_time_t(0));
-}
-
-// Splits a Time into seconds and femtoseconds, which can be used with CCTZ.
-// Requires that 't' is finite. See duration.cc for details about rep_hi and
-// rep_lo.
+
+namespace {
+
+const char kInfiniteFutureStr[] = "infinite-future";
+const char kInfinitePastStr[] = "infinite-past";
+
+struct cctz_parts {
+ cctz::time_point<cctz::seconds> sec;
+ cctz::detail::femtoseconds fem;
+};
+
+inline cctz::time_point<cctz::seconds> unix_epoch() {
+ return std::chrono::time_point_cast<cctz::seconds>(
+ std::chrono::system_clock::from_time_t(0));
+}
+
+// Splits a Time into seconds and femtoseconds, which can be used with CCTZ.
+// Requires that 't' is finite. See duration.cc for details about rep_hi and
+// rep_lo.
cctz_parts Split(y_absl::Time t) {
- const auto d = time_internal::ToUnixDuration(t);
- const int64_t rep_hi = time_internal::GetRepHi(d);
- const int64_t rep_lo = time_internal::GetRepLo(d);
- const auto sec = unix_epoch() + cctz::seconds(rep_hi);
- const auto fem = cctz::detail::femtoseconds(rep_lo * (1000 * 1000 / 4));
- return {sec, fem};
-}
-
-// Joins the given seconds and femtoseconds into a Time. See duration.cc for
-// details about rep_hi and rep_lo.
+ const auto d = time_internal::ToUnixDuration(t);
+ const int64_t rep_hi = time_internal::GetRepHi(d);
+ const int64_t rep_lo = time_internal::GetRepLo(d);
+ const auto sec = unix_epoch() + cctz::seconds(rep_hi);
+ const auto fem = cctz::detail::femtoseconds(rep_lo * (1000 * 1000 / 4));
+ return {sec, fem};
+}
+
+// Joins the given seconds and femtoseconds into a Time. See duration.cc for
+// details about rep_hi and rep_lo.
y_absl::Time Join(const cctz_parts& parts) {
- const int64_t rep_hi = (parts.sec - unix_epoch()).count();
- const uint32_t rep_lo = parts.fem.count() / (1000 * 1000 / 4);
- const auto d = time_internal::MakeDuration(rep_hi, rep_lo);
- return time_internal::FromUnixDuration(d);
-}
-
-} // namespace
-
+ const int64_t rep_hi = (parts.sec - unix_epoch()).count();
+ const uint32_t rep_lo = parts.fem.count() / (1000 * 1000 / 4);
+ const auto d = time_internal::MakeDuration(rep_hi, rep_lo);
+ return time_internal::FromUnixDuration(d);
+}
+
+} // namespace
+
TString FormatTime(y_absl::string_view format, y_absl::Time t,
y_absl::TimeZone tz) {
if (t == y_absl::InfiniteFuture()) return TString(kInfiniteFutureStr);
if (t == y_absl::InfinitePast()) return TString(kInfinitePastStr);
- const auto parts = Split(t);
+ const auto parts = Split(t);
return cctz::detail::format(TString(format), parts.sec, parts.fem,
- cctz::time_zone(tz));
-}
-
+ cctz::time_zone(tz));
+}
+
TString FormatTime(y_absl::Time t, y_absl::TimeZone tz) {
- return FormatTime(RFC3339_full, t, tz);
-}
-
+ return FormatTime(RFC3339_full, t, tz);
+}
+
TString FormatTime(y_absl::Time t) {
return y_absl::FormatTime(RFC3339_full, t, y_absl::LocalTimeZone());
-}
-
+}
+
bool ParseTime(y_absl::string_view format, y_absl::string_view input,
y_absl::Time* time, TString* err) {
return y_absl::ParseTime(format, input, y_absl::UTCTimeZone(), time, err);
-}
-
-// If the input string does not contain an explicit UTC offset, interpret
-// the fields with respect to the given TimeZone.
+}
+
+// If the input string does not contain an explicit UTC offset, interpret
+// the fields with respect to the given TimeZone.
bool ParseTime(y_absl::string_view format, y_absl::string_view input,
y_absl::TimeZone tz, y_absl::Time* time, TString* err) {
auto strip_leading_space = [](y_absl::string_view* sv) {
while (!sv->empty()) {
if (!std::isspace(sv->front())) return;
sv->remove_prefix(1);
- }
+ }
};
-
+
// Portable toolchains means we don't get nice constexpr here.
struct Literal {
const char* name;
@@ -124,37 +124,37 @@ bool ParseTime(y_absl::string_view format, y_absl::string_view input,
*time = lit.value;
return true;
}
- }
- }
-
+ }
+ }
+
TString error;
- cctz_parts parts;
+ cctz_parts parts;
const bool b =
cctz::detail::parse(TString(format), TString(input),
cctz::time_zone(tz), &parts.sec, &parts.fem, &error);
- if (b) {
- *time = Join(parts);
- } else if (err != nullptr) {
- *err = error;
- }
- return b;
-}
-
+ if (b) {
+ *time = Join(parts);
+ } else if (err != nullptr) {
+ *err = error;
+ }
+ return b;
+}
+
// Functions required to support y_absl::Time flags.
bool AbslParseFlag(y_absl::string_view text, y_absl::Time* t, TString* error) {
return y_absl::ParseTime(RFC3339_full, text, y_absl::UTCTimeZone(), t, error);
-}
-
+}
+
TString AbslUnparseFlag(y_absl::Time t) {
return y_absl::FormatTime(RFC3339_full, t, y_absl::UTCTimeZone());
-}
+}
bool ParseFlag(const TString& text, y_absl::Time* t, TString* error) {
return y_absl::ParseTime(RFC3339_full, text, y_absl::UTCTimeZone(), t, error);
-}
-
+}
+
TString UnparseFlag(y_absl::Time t) {
return y_absl::FormatTime(RFC3339_full, t, y_absl::UTCTimeZone());
-}
-
+}
+
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time.h
index 9382ecc231..be60a54dbe 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time.h
@@ -1,332 +1,332 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
-#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
+#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time_detail.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// The term "civil time" refers to the legally recognized human-scale time
-// that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil
-// time follows the Gregorian Calendar and is a time-zone-independent concept.
-// A "date" is perhaps the most common example of a civil time (represented in
-// this library as cctz::civil_day). This library provides six classes and a
-// handful of functions that help with rounding, iterating, and arithmetic on
-// civil times while avoiding complications like daylight-saving time (DST).
-//
-// The following six classes form the core of this civil-time library:
-//
-// * civil_second
-// * civil_minute
-// * civil_hour
-// * civil_day
-// * civil_month
-// * civil_year
-//
-// Each class is a simple value type with the same interface for construction
-// and the same six accessors for each of the civil fields (year, month, day,
-// hour, minute, and second, aka YMDHMS). These classes differ only in their
-// alignment, which is indicated by the type name and specifies the field on
-// which arithmetic operates.
-//
-// Each class can be constructed by passing up to six optional integer
-// arguments representing the YMDHMS fields (in that order) to the
-// constructor. Omitted fields are assigned their minimum valid value. Hours,
-// minutes, and seconds will be set to 0, month and day will be set to 1, and
-// since there is no minimum valid year, it will be set to 1970. So, a
-// default-constructed civil-time object will have YMDHMS fields representing
-// "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g.,
-// October 32 -> November 1) so that all civil-time objects represent valid
-// values.
-//
-// Each civil-time class is aligned to the civil-time field indicated in the
-// class's name after normalization. Alignment is performed by setting all the
-// inferior fields to their minimum valid value (as described above). The
-// following are examples of how each of the six types would align the fields
-// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
-// string format used here is not important; it's just a shorthand way of
-// showing the six YMDHMS fields.)
-//
-// civil_second 2015-11-22 12:34:56
-// civil_minute 2015-11-22 12:34:00
-// civil_hour 2015-11-22 12:00:00
-// civil_day 2015-11-22 00:00:00
-// civil_month 2015-11-01 00:00:00
-// civil_year 2015-01-01 00:00:00
-//
-// Each civil-time type performs arithmetic on the field to which it is
-// aligned. This means that adding 1 to a civil_day increments the day field
-// (normalizing as necessary), and subtracting 7 from a civil_month operates
-// on the month field (normalizing as necessary). All arithmetic produces a
-// valid civil time. Difference requires two similarly aligned civil-time
-// objects and returns the scalar answer in units of the objects' alignment.
-// For example, the difference between two civil_hour objects will give an
-// answer in units of civil hours.
-//
-// In addition to the six civil-time types just described, there are
-// a handful of helper functions and algorithms for performing common
-// calculations. These are described below.
-//
-// Note: In C++14 and later, this library is usable in a constexpr context.
-//
-// CONSTRUCTION:
-//
-// Each of the civil-time types can be constructed in two ways: by directly
-// passing to the constructor up to six (optional) integers representing the
-// YMDHMS fields, or by copying the YMDHMS fields from a differently aligned
-// civil-time type.
-//
-// civil_day default_value; // 1970-01-01 00:00:00
-//
-// civil_day a(2015, 2, 3); // 2015-02-03 00:00:00
-// civil_day b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00
-// civil_day c(2015); // 2015-01-01 00:00:00
-//
-// civil_second ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06
-// civil_minute mm(ss); // 2015-02-03 04:05:00
-// civil_hour hh(mm); // 2015-02-03 04:00:00
-// civil_day d(hh); // 2015-02-03 00:00:00
-// civil_month m(d); // 2015-02-01 00:00:00
-// civil_year y(m); // 2015-01-01 00:00:00
-//
-// m = civil_month(y); // 2015-01-01 00:00:00
-// d = civil_day(m); // 2015-01-01 00:00:00
-// hh = civil_hour(d); // 2015-01-01 00:00:00
-// mm = civil_minute(hh); // 2015-01-01 00:00:00
-// ss = civil_second(mm); // 2015-01-01 00:00:00
-//
-// ALIGNMENT CONVERSION:
-//
-// The alignment of a civil-time object cannot change, but the object may be
-// used to construct a new object with a different alignment. This is referred
-// to as "realigning". When realigning to a type with the same or more
-// precision (e.g., civil_day -> civil_second), the conversion may be
-// performed implicitly since no information is lost. However, if information
-// could be discarded (e.g., civil_second -> civil_day), the conversion must
-// be explicit at the call site.
-//
-// void fun(const civil_day& day);
-//
-// civil_second cs;
-// fun(cs); // Won't compile because data may be discarded
-// fun(civil_day(cs)); // OK: explicit conversion
-//
-// civil_day cd;
-// fun(cd); // OK: no conversion needed
-//
-// civil_month cm;
-// fun(cm); // OK: implicit conversion to civil_day
-//
-// NORMALIZATION:
-//
-// Integer arguments passed to the constructor may be out-of-range, in which
-// case they are normalized to produce a valid civil-time object. This enables
-// natural arithmetic on constructor arguments without worrying about the
-// field's range. Normalization guarantees that there are no invalid
-// civil-time objects.
-//
-// civil_day d(2016, 10, 32); // Out-of-range day; normalized to 2016-11-01
-//
-// Note: If normalization is undesired, you can signal an error by comparing
-// the constructor arguments to the normalized values returned by the YMDHMS
-// properties.
-//
-// PROPERTIES:
-//
-// All civil-time types have accessors for all six of the civil-time fields:
-// year, month, day, hour, minute, and second. Recall that fields inferior to
-// the type's alignment will be set to their minimum valid value.
-//
-// civil_day d(2015, 6, 28);
-// // d.year() == 2015
-// // d.month() == 6
-// // d.day() == 28
-// // d.hour() == 0
-// // d.minute() == 0
-// // d.second() == 0
-//
-// COMPARISON:
-//
-// Comparison always considers all six YMDHMS fields, regardless of the type's
-// alignment. Comparison between differently aligned civil-time types is
-// allowed.
-//
-// civil_day feb_3(2015, 2, 3); // 2015-02-03 00:00:00
-// civil_day mar_4(2015, 3, 4); // 2015-03-04 00:00:00
-// // feb_3 < mar_4
-// // civil_year(feb_3) == civil_year(mar_4)
-//
-// civil_second feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00
-// // feb_3 < feb_3_noon
-// // feb_3 == civil_day(feb_3_noon)
-//
-// // Iterates all the days of February 2015.
-// for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) {
-// // ...
-// }
-//
-// STREAMING:
-//
-// Each civil-time type may be sent to an output stream using operator<<().
-// The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields
-// inferior to the type's alignment are omitted.
-//
-// civil_second cs(2015, 2, 3, 4, 5, 6);
-// std::cout << cs << "\n"; // Outputs: 2015-02-03T04:05:06
-//
-// civil_day cd(cs);
-// std::cout << cd << "\n"; // Outputs: 2015-02-03
-//
-// civil_year cy(cs);
-// std::cout << cy << "\n"; // Outputs: 2015
-//
-// ARITHMETIC:
-//
-// Civil-time types support natural arithmetic operators such as addition,
-// subtraction, and difference. Arithmetic operates on the civil-time field
-// indicated in the type's name. Difference requires arguments with the same
-// alignment and returns the answer in units of the alignment.
-//
-// civil_day a(2015, 2, 3);
-// ++a; // 2015-02-04 00:00:00
-// --a; // 2015-02-03 00:00:00
-// civil_day b = a + 1; // 2015-02-04 00:00:00
-// civil_day c = 1 + b; // 2015-02-05 00:00:00
-// int n = c - a; // n = 2 (civil days)
-// int m = c - civil_month(c); // Won't compile: different types.
-//
-// EXAMPLE: Adding a month to January 31.
-//
-// One of the classic questions that arises when considering a civil-time
-// library (or a date library or a date/time library) is this: "What happens
-// when you add a month to January 31?" This is an interesting question
-// because there could be a number of possible answers:
-//
-// 1. March 3 (or 2 if a leap year). This may make sense if the operation
-// wants the equivalent of February 31.
-// 2. February 28 (or 29 if a leap year). This may make sense if the operation
-// wants the last day of January to go to the last day of February.
-// 3. Error. The caller may get some error, an exception, an invalid date
-// object, or maybe false is returned. This may make sense because there is
-// no single unambiguously correct answer to the question.
-//
-// Practically speaking, any answer that is not what the programmer intended
-// is the wrong answer.
-//
-// This civil-time library avoids the problem by making it impossible to ask
-// ambiguous questions. All civil-time objects are aligned to a particular
-// civil-field boundary (such as aligned to a year, month, day, hour, minute,
-// or second), and arithmetic operates on the field to which the object is
-// aligned. This means that in order to "add a month" the object must first be
-// aligned to a month boundary, which is equivalent to the first day of that
-// month.
-//
-// Of course, there are ways to compute an answer the question at hand using
-// this civil-time library, but they require the programmer to be explicit
-// about the answer they expect. To illustrate, let's see how to compute all
-// three of the above possible answers to the question of "Jan 31 plus 1
-// month":
-//
-// const civil_day d(2015, 1, 31);
-//
-// // Answer 1:
-// // Add 1 to the month field in the constructor, and rely on normalization.
-// const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day());
-// // ans_normalized == 2015-03-03 (aka Feb 31)
-//
-// // Answer 2:
-// // Add 1 to month field, capping to the end of next month.
-// const auto next_month = civil_month(d) + 1;
-// const auto last_day_of_next_month = civil_day(next_month + 1) - 1;
-// const auto ans_capped = std::min(ans_normalized, last_day_of_next_month);
-// // ans_capped == 2015-02-28
-//
-// // Answer 3:
-// // Signal an error if the normalized answer is not in next month.
-// if (civil_month(ans_normalized) != next_month) {
-// // error, month overflow
-// }
-//
-using civil_year = detail::civil_year;
-using civil_month = detail::civil_month;
-using civil_day = detail::civil_day;
-using civil_hour = detail::civil_hour;
-using civil_minute = detail::civil_minute;
-using civil_second = detail::civil_second;
-
-// An enum class with members monday, tuesday, wednesday, thursday, friday,
-// saturday, and sunday. These enum values may be sent to an output stream
-// using operator<<(). The result is the full weekday name in English with a
-// leading capital letter.
-//
-// weekday wd = weekday::thursday;
-// std::cout << wd << "\n"; // Outputs: Thursday
-//
-using detail::weekday;
-
-// Returns the weekday for the given civil-time value.
-//
-// civil_day a(2015, 8, 13);
-// weekday wd = get_weekday(a); // wd == weekday::thursday
-//
-using detail::get_weekday;
-
-// Returns the civil_day that strictly follows or precedes the given
-// civil_day, and that falls on the given weekday.
-//
-// For example, given:
-//
-// August 2015
-// Su Mo Tu We Th Fr Sa
-// 1
-// 2 3 4 5 6 7 8
-// 9 10 11 12 13 14 15
-// 16 17 18 19 20 21 22
-// 23 24 25 26 27 28 29
-// 30 31
-//
-// civil_day a(2015, 8, 13); // get_weekday(a) == weekday::thursday
-// civil_day b = next_weekday(a, weekday::thursday); // b = 2015-08-20
-// civil_day c = prev_weekday(a, weekday::thursday); // c = 2015-08-06
-//
-// civil_day d = ...
-// // Gets the following Thursday if d is not already Thursday
-// civil_day thurs1 = next_weekday(d - 1, weekday::thursday);
-// // Gets the previous Thursday if d is not already Thursday
-// civil_day thurs2 = prev_weekday(d + 1, weekday::thursday);
-//
-using detail::next_weekday;
-using detail::prev_weekday;
-
-// Returns the day-of-year for the given civil-time value.
-//
-// civil_day a(2015, 1, 1);
-// int yd_jan_1 = get_yearday(a); // yd_jan_1 = 1
-// civil_day b(2015, 12, 31);
-// int yd_dec_31 = get_yearday(b); // yd_dec_31 = 365
-//
-using detail::get_yearday;
-
-} // namespace cctz
-} // namespace time_internal
+namespace time_internal {
+namespace cctz {
+
+// The term "civil time" refers to the legally recognized human-scale time
+// that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil
+// time follows the Gregorian Calendar and is a time-zone-independent concept.
+// A "date" is perhaps the most common example of a civil time (represented in
+// this library as cctz::civil_day). This library provides six classes and a
+// handful of functions that help with rounding, iterating, and arithmetic on
+// civil times while avoiding complications like daylight-saving time (DST).
+//
+// The following six classes form the core of this civil-time library:
+//
+// * civil_second
+// * civil_minute
+// * civil_hour
+// * civil_day
+// * civil_month
+// * civil_year
+//
+// Each class is a simple value type with the same interface for construction
+// and the same six accessors for each of the civil fields (year, month, day,
+// hour, minute, and second, aka YMDHMS). These classes differ only in their
+// alignment, which is indicated by the type name and specifies the field on
+// which arithmetic operates.
+//
+// Each class can be constructed by passing up to six optional integer
+// arguments representing the YMDHMS fields (in that order) to the
+// constructor. Omitted fields are assigned their minimum valid value. Hours,
+// minutes, and seconds will be set to 0, month and day will be set to 1, and
+// since there is no minimum valid year, it will be set to 1970. So, a
+// default-constructed civil-time object will have YMDHMS fields representing
+// "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g.,
+// October 32 -> November 1) so that all civil-time objects represent valid
+// values.
+//
+// Each civil-time class is aligned to the civil-time field indicated in the
+// class's name after normalization. Alignment is performed by setting all the
+// inferior fields to their minimum valid value (as described above). The
+// following are examples of how each of the six types would align the fields
+// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
+// string format used here is not important; it's just a shorthand way of
+// showing the six YMDHMS fields.)
+//
+// civil_second 2015-11-22 12:34:56
+// civil_minute 2015-11-22 12:34:00
+// civil_hour 2015-11-22 12:00:00
+// civil_day 2015-11-22 00:00:00
+// civil_month 2015-11-01 00:00:00
+// civil_year 2015-01-01 00:00:00
+//
+// Each civil-time type performs arithmetic on the field to which it is
+// aligned. This means that adding 1 to a civil_day increments the day field
+// (normalizing as necessary), and subtracting 7 from a civil_month operates
+// on the month field (normalizing as necessary). All arithmetic produces a
+// valid civil time. Difference requires two similarly aligned civil-time
+// objects and returns the scalar answer in units of the objects' alignment.
+// For example, the difference between two civil_hour objects will give an
+// answer in units of civil hours.
+//
+// In addition to the six civil-time types just described, there are
+// a handful of helper functions and algorithms for performing common
+// calculations. These are described below.
+//
+// Note: In C++14 and later, this library is usable in a constexpr context.
+//
+// CONSTRUCTION:
+//
+// Each of the civil-time types can be constructed in two ways: by directly
+// passing to the constructor up to six (optional) integers representing the
+// YMDHMS fields, or by copying the YMDHMS fields from a differently aligned
+// civil-time type.
+//
+// civil_day default_value; // 1970-01-01 00:00:00
+//
+// civil_day a(2015, 2, 3); // 2015-02-03 00:00:00
+// civil_day b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00
+// civil_day c(2015); // 2015-01-01 00:00:00
+//
+// civil_second ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06
+// civil_minute mm(ss); // 2015-02-03 04:05:00
+// civil_hour hh(mm); // 2015-02-03 04:00:00
+// civil_day d(hh); // 2015-02-03 00:00:00
+// civil_month m(d); // 2015-02-01 00:00:00
+// civil_year y(m); // 2015-01-01 00:00:00
+//
+// m = civil_month(y); // 2015-01-01 00:00:00
+// d = civil_day(m); // 2015-01-01 00:00:00
+// hh = civil_hour(d); // 2015-01-01 00:00:00
+// mm = civil_minute(hh); // 2015-01-01 00:00:00
+// ss = civil_second(mm); // 2015-01-01 00:00:00
+//
+// ALIGNMENT CONVERSION:
+//
+// The alignment of a civil-time object cannot change, but the object may be
+// used to construct a new object with a different alignment. This is referred
+// to as "realigning". When realigning to a type with the same or more
+// precision (e.g., civil_day -> civil_second), the conversion may be
+// performed implicitly since no information is lost. However, if information
+// could be discarded (e.g., civil_second -> civil_day), the conversion must
+// be explicit at the call site.
+//
+// void fun(const civil_day& day);
+//
+// civil_second cs;
+// fun(cs); // Won't compile because data may be discarded
+// fun(civil_day(cs)); // OK: explicit conversion
+//
+// civil_day cd;
+// fun(cd); // OK: no conversion needed
+//
+// civil_month cm;
+// fun(cm); // OK: implicit conversion to civil_day
+//
+// NORMALIZATION:
+//
+// Integer arguments passed to the constructor may be out-of-range, in which
+// case they are normalized to produce a valid civil-time object. This enables
+// natural arithmetic on constructor arguments without worrying about the
+// field's range. Normalization guarantees that there are no invalid
+// civil-time objects.
+//
+// civil_day d(2016, 10, 32); // Out-of-range day; normalized to 2016-11-01
+//
+// Note: If normalization is undesired, you can signal an error by comparing
+// the constructor arguments to the normalized values returned by the YMDHMS
+// properties.
+//
+// PROPERTIES:
+//
+// All civil-time types have accessors for all six of the civil-time fields:
+// year, month, day, hour, minute, and second. Recall that fields inferior to
+// the type's alignment will be set to their minimum valid value.
+//
+// civil_day d(2015, 6, 28);
+// // d.year() == 2015
+// // d.month() == 6
+// // d.day() == 28
+// // d.hour() == 0
+// // d.minute() == 0
+// // d.second() == 0
+//
+// COMPARISON:
+//
+// Comparison always considers all six YMDHMS fields, regardless of the type's
+// alignment. Comparison between differently aligned civil-time types is
+// allowed.
+//
+// civil_day feb_3(2015, 2, 3); // 2015-02-03 00:00:00
+// civil_day mar_4(2015, 3, 4); // 2015-03-04 00:00:00
+// // feb_3 < mar_4
+// // civil_year(feb_3) == civil_year(mar_4)
+//
+// civil_second feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00
+// // feb_3 < feb_3_noon
+// // feb_3 == civil_day(feb_3_noon)
+//
+// // Iterates all the days of February 2015.
+// for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) {
+// // ...
+// }
+//
+// STREAMING:
+//
+// Each civil-time type may be sent to an output stream using operator<<().
+// The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields
+// inferior to the type's alignment are omitted.
+//
+// civil_second cs(2015, 2, 3, 4, 5, 6);
+// std::cout << cs << "\n"; // Outputs: 2015-02-03T04:05:06
+//
+// civil_day cd(cs);
+// std::cout << cd << "\n"; // Outputs: 2015-02-03
+//
+// civil_year cy(cs);
+// std::cout << cy << "\n"; // Outputs: 2015
+//
+// ARITHMETIC:
+//
+// Civil-time types support natural arithmetic operators such as addition,
+// subtraction, and difference. Arithmetic operates on the civil-time field
+// indicated in the type's name. Difference requires arguments with the same
+// alignment and returns the answer in units of the alignment.
+//
+// civil_day a(2015, 2, 3);
+// ++a; // 2015-02-04 00:00:00
+// --a; // 2015-02-03 00:00:00
+// civil_day b = a + 1; // 2015-02-04 00:00:00
+// civil_day c = 1 + b; // 2015-02-05 00:00:00
+// int n = c - a; // n = 2 (civil days)
+// int m = c - civil_month(c); // Won't compile: different types.
+//
+// EXAMPLE: Adding a month to January 31.
+//
+// One of the classic questions that arises when considering a civil-time
+// library (or a date library or a date/time library) is this: "What happens
+// when you add a month to January 31?" This is an interesting question
+// because there could be a number of possible answers:
+//
+// 1. March 3 (or 2 if a leap year). This may make sense if the operation
+// wants the equivalent of February 31.
+// 2. February 28 (or 29 if a leap year). This may make sense if the operation
+// wants the last day of January to go to the last day of February.
+// 3. Error. The caller may get some error, an exception, an invalid date
+// object, or maybe false is returned. This may make sense because there is
+// no single unambiguously correct answer to the question.
+//
+// Practically speaking, any answer that is not what the programmer intended
+// is the wrong answer.
+//
+// This civil-time library avoids the problem by making it impossible to ask
+// ambiguous questions. All civil-time objects are aligned to a particular
+// civil-field boundary (such as aligned to a year, month, day, hour, minute,
+// or second), and arithmetic operates on the field to which the object is
+// aligned. This means that in order to "add a month" the object must first be
+// aligned to a month boundary, which is equivalent to the first day of that
+// month.
+//
+// Of course, there are ways to compute an answer the question at hand using
+// this civil-time library, but they require the programmer to be explicit
+// about the answer they expect. To illustrate, let's see how to compute all
+// three of the above possible answers to the question of "Jan 31 plus 1
+// month":
+//
+// const civil_day d(2015, 1, 31);
+//
+// // Answer 1:
+// // Add 1 to the month field in the constructor, and rely on normalization.
+// const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day());
+// // ans_normalized == 2015-03-03 (aka Feb 31)
+//
+// // Answer 2:
+// // Add 1 to month field, capping to the end of next month.
+// const auto next_month = civil_month(d) + 1;
+// const auto last_day_of_next_month = civil_day(next_month + 1) - 1;
+// const auto ans_capped = std::min(ans_normalized, last_day_of_next_month);
+// // ans_capped == 2015-02-28
+//
+// // Answer 3:
+// // Signal an error if the normalized answer is not in next month.
+// if (civil_month(ans_normalized) != next_month) {
+// // error, month overflow
+// }
+//
+using civil_year = detail::civil_year;
+using civil_month = detail::civil_month;
+using civil_day = detail::civil_day;
+using civil_hour = detail::civil_hour;
+using civil_minute = detail::civil_minute;
+using civil_second = detail::civil_second;
+
+// An enum class with members monday, tuesday, wednesday, thursday, friday,
+// saturday, and sunday. These enum values may be sent to an output stream
+// using operator<<(). The result is the full weekday name in English with a
+// leading capital letter.
+//
+// weekday wd = weekday::thursday;
+// std::cout << wd << "\n"; // Outputs: Thursday
+//
+using detail::weekday;
+
+// Returns the weekday for the given civil-time value.
+//
+// civil_day a(2015, 8, 13);
+// weekday wd = get_weekday(a); // wd == weekday::thursday
+//
+using detail::get_weekday;
+
+// Returns the civil_day that strictly follows or precedes the given
+// civil_day, and that falls on the given weekday.
+//
+// For example, given:
+//
+// August 2015
+// Su Mo Tu We Th Fr Sa
+// 1
+// 2 3 4 5 6 7 8
+// 9 10 11 12 13 14 15
+// 16 17 18 19 20 21 22
+// 23 24 25 26 27 28 29
+// 30 31
+//
+// civil_day a(2015, 8, 13); // get_weekday(a) == weekday::thursday
+// civil_day b = next_weekday(a, weekday::thursday); // b = 2015-08-20
+// civil_day c = prev_weekday(a, weekday::thursday); // c = 2015-08-06
+//
+// civil_day d = ...
+// // Gets the following Thursday if d is not already Thursday
+// civil_day thurs1 = next_weekday(d - 1, weekday::thursday);
+// // Gets the previous Thursday if d is not already Thursday
+// civil_day thurs2 = prev_weekday(d + 1, weekday::thursday);
+//
+using detail::next_weekday;
+using detail::prev_weekday;
+
+// Returns the day-of-year for the given civil-time value.
+//
+// civil_day a(2015, 1, 1);
+// int yd_jan_1 = get_yearday(a); // yd_jan_1 = 1
+// civil_day b(2015, 12, 31);
+// int yd_dec_31 = get_yearday(b); // yd_dec_31 = 365
+//
+using detail::get_yearday;
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time_detail.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time_detail.h
index d8b4e1ac1c..0e71a7cd33 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time_detail.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -1,491 +1,491 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
-#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
-
-#include <cstdint>
-#include <limits>
-#include <ostream>
-#include <type_traits>
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
+#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
+
+#include <cstdint>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
#include "y_absl/base/config.h"
-// Disable constexpr support unless we are in C++14 mode.
-#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
-#define CONSTEXPR_D constexpr // data
-#define CONSTEXPR_F constexpr // function
-#define CONSTEXPR_M constexpr // member
-#else
-#define CONSTEXPR_D const
-#define CONSTEXPR_F inline
-#define CONSTEXPR_M
-#endif
-
+// Disable constexpr support unless we are in C++14 mode.
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
+#define CONSTEXPR_D constexpr // data
+#define CONSTEXPR_F constexpr // function
+#define CONSTEXPR_M constexpr // member
+#else
+#define CONSTEXPR_D const
+#define CONSTEXPR_F inline
+#define CONSTEXPR_M
+#endif
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// Support years that at least span the range of 64-bit time_t values.
-using year_t = std::int_fast64_t;
-
-// Type alias that indicates an argument is not normalized (e.g., the
-// constructor parameters and operands/results of addition/subtraction).
-using diff_t = std::int_fast64_t;
-
-namespace detail {
-
-// Type aliases that indicate normalized argument values.
-using month_t = std::int_fast8_t; // [1:12]
-using day_t = std::int_fast8_t; // [1:31]
-using hour_t = std::int_fast8_t; // [0:23]
-using minute_t = std::int_fast8_t; // [0:59]
-using second_t = std::int_fast8_t; // [0:59]
-
-// Normalized civil-time fields: Y-M-D HH:MM:SS.
-struct fields {
+namespace time_internal {
+namespace cctz {
+
+// Support years that at least span the range of 64-bit time_t values.
+using year_t = std::int_fast64_t;
+
+// Type alias that indicates an argument is not normalized (e.g., the
+// constructor parameters and operands/results of addition/subtraction).
+using diff_t = std::int_fast64_t;
+
+namespace detail {
+
+// Type aliases that indicate normalized argument values.
+using month_t = std::int_fast8_t; // [1:12]
+using day_t = std::int_fast8_t; // [1:31]
+using hour_t = std::int_fast8_t; // [0:23]
+using minute_t = std::int_fast8_t; // [0:59]
+using second_t = std::int_fast8_t; // [0:59]
+
+// Normalized civil-time fields: Y-M-D HH:MM:SS.
+struct fields {
CONSTEXPR_M fields(year_t year, month_t month, day_t day, hour_t hour,
minute_t minute, second_t second)
- : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {}
- std::int_least64_t y;
- std::int_least8_t m;
- std::int_least8_t d;
- std::int_least8_t hh;
- std::int_least8_t mm;
- std::int_least8_t ss;
-};
-
-struct second_tag {};
-struct minute_tag : second_tag {};
-struct hour_tag : minute_tag {};
-struct day_tag : hour_tag {};
-struct month_tag : day_tag {};
-struct year_tag : month_tag {};
-
-////////////////////////////////////////////////////////////////////////
-
-// Field normalization (without avoidable overflow).
-
-namespace impl {
-
-CONSTEXPR_F bool is_leap_year(year_t y) noexcept {
- return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
-}
-CONSTEXPR_F int year_index(year_t y, month_t m) noexcept {
- return (static_cast<int>((y + (m > 2)) % 400) + 400) % 400;
-}
-CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept {
- const int yi = year_index(y, m);
- return 36524 + (yi == 0 || yi > 300);
-}
-CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept {
- const int yi = year_index(y, m);
- return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96);
-}
-CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept {
- return is_leap_year(y + (m > 2)) ? 366 : 365;
-}
-CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {
- CONSTEXPR_D int k_days_per_month[1 + 12] = {
- -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // non leap year
- };
- return k_days_per_month[m] + (m == 2 && is_leap_year(y));
-}
-
+ : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {}
+ std::int_least64_t y;
+ std::int_least8_t m;
+ std::int_least8_t d;
+ std::int_least8_t hh;
+ std::int_least8_t mm;
+ std::int_least8_t ss;
+};
+
+struct second_tag {};
+struct minute_tag : second_tag {};
+struct hour_tag : minute_tag {};
+struct day_tag : hour_tag {};
+struct month_tag : day_tag {};
+struct year_tag : month_tag {};
+
+////////////////////////////////////////////////////////////////////////
+
+// Field normalization (without avoidable overflow).
+
+namespace impl {
+
+CONSTEXPR_F bool is_leap_year(year_t y) noexcept {
+ return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
+}
+CONSTEXPR_F int year_index(year_t y, month_t m) noexcept {
+ return (static_cast<int>((y + (m > 2)) % 400) + 400) % 400;
+}
+CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept {
+ const int yi = year_index(y, m);
+ return 36524 + (yi == 0 || yi > 300);
+}
+CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept {
+ const int yi = year_index(y, m);
+ return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96);
+}
+CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept {
+ return is_leap_year(y + (m > 2)) ? 366 : 365;
+}
+CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {
+ CONSTEXPR_D int k_days_per_month[1 + 12] = {
+ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // non leap year
+ };
+ return k_days_per_month[m] + (m == 2 && is_leap_year(y));
+}
+
CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh,
minute_t mm, second_t ss) noexcept {
year_t ey = y % 400;
const year_t oey = ey;
ey += (cd / 146097) * 400;
- cd %= 146097;
- if (cd < 0) {
+ cd %= 146097;
+ if (cd < 0) {
ey -= 400;
- cd += 146097;
- }
+ cd += 146097;
+ }
ey += (d / 146097) * 400;
- d = d % 146097 + cd;
- if (d > 0) {
- if (d > 146097) {
+ d = d % 146097 + cd;
+ if (d > 0) {
+ if (d > 146097) {
ey += 400;
- d -= 146097;
- }
- } else {
- if (d > -365) {
- // We often hit the previous year when stepping a civil time backwards,
- // so special case it to avoid counting up by 100/4/1-year chunks.
+ d -= 146097;
+ }
+ } else {
+ if (d > -365) {
+ // We often hit the previous year when stepping a civil time backwards,
+ // so special case it to avoid counting up by 100/4/1-year chunks.
ey -= 1;
d += days_per_year(ey, m);
- } else {
+ } else {
ey -= 400;
- d += 146097;
- }
- }
- if (d > 365) {
+ d += 146097;
+ }
+ }
+ if (d > 365) {
for (;;) {
int n = days_per_century(ey, m);
if (d <= n) break;
- d -= n;
+ d -= n;
ey += 100;
- }
+ }
for (;;) {
int n = days_per_4years(ey, m);
if (d <= n) break;
- d -= n;
+ d -= n;
ey += 4;
- }
+ }
for (;;) {
int n = days_per_year(ey, m);
if (d <= n) break;
- d -= n;
+ d -= n;
++ey;
- }
- }
- if (d > 28) {
+ }
+ }
+ if (d > 28) {
for (;;) {
int n = days_per_month(ey, m);
if (d <= n) break;
- d -= n;
- if (++m > 12) {
+ d -= n;
+ if (++m > 12) {
++ey;
- m = 1;
- }
- }
- }
+ m = 1;
+ }
+ }
+ }
return fields(y + (ey - oey), m, static_cast<day_t>(d), hh, mm, ss);
-}
+}
CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh,
minute_t mm, second_t ss) noexcept {
- if (m != 12) {
- y += m / 12;
- m %= 12;
- if (m <= 0) {
- y -= 1;
- m += 12;
- }
- }
- return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss);
-}
+ if (m != 12) {
+ y += m / 12;
+ m %= 12;
+ if (m <= 0) {
+ y -= 1;
+ m += 12;
+ }
+ }
+ return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss);
+}
CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh,
minute_t mm, second_t ss) noexcept {
- cd += hh / 24;
- hh %= 24;
- if (hh < 0) {
- cd -= 1;
- hh += 24;
- }
- return n_mon(y, m, d, cd, static_cast<hour_t>(hh), mm, ss);
-}
-CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
- diff_t mm, second_t ss) noexcept {
- ch += mm / 60;
- mm %= 60;
- if (mm < 0) {
- ch -= 1;
- mm += 60;
- }
- return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24,
- static_cast<minute_t>(mm), ss);
-}
-CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
- diff_t ss) noexcept {
- // Optimization for when (non-constexpr) fields are already normalized.
- if (0 <= ss && ss < 60) {
- const second_t nss = static_cast<second_t>(ss);
- if (0 <= mm && mm < 60) {
- const minute_t nmm = static_cast<minute_t>(mm);
- if (0 <= hh && hh < 24) {
- const hour_t nhh = static_cast<hour_t>(hh);
- if (1 <= d && d <= 28 && 1 <= m && m <= 12) {
- const day_t nd = static_cast<day_t>(d);
- const month_t nm = static_cast<month_t>(m);
- return fields(y, nm, nd, nhh, nmm, nss);
- }
- return n_mon(y, m, d, 0, nhh, nmm, nss);
- }
- return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss);
- }
- return n_min(y, m, d, hh, mm / 60, mm % 60, nss);
- }
- diff_t cm = ss / 60;
- ss %= 60;
- if (ss < 0) {
- cm -= 1;
- ss += 60;
- }
- return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60,
- static_cast<second_t>(ss));
-}
-
-} // namespace impl
-
-////////////////////////////////////////////////////////////////////////
-
-// Increments the indicated (normalized) field by "n".
-CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept {
- return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60);
-}
-CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept {
- return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss);
-}
-CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept {
- return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss);
-}
-CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept {
- return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss);
-}
-CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept {
- return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss);
-}
-CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept {
- return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-namespace impl {
-
-// Returns (v * f + a) but avoiding intermediate overflow when possible.
-CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept {
- return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f;
-}
-
-// Map a (normalized) Y/M/D to the number of days before/after 1970-01-01.
-// Probably overflows for years outside [-292277022656:292277026595].
-CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept {
- const diff_t eyear = (m <= 2) ? y - 1 : y;
- const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400;
- const diff_t yoe = eyear - era * 400;
- const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
- const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
- return era * 146097 + doe - 719468;
-}
-
-// Returns the difference in days between two normalized Y-M-D tuples.
-// ymd_ord() will encounter integer overflow given extreme year values,
-// yet the difference between two such extreme values may actually be
-// small, so we take a little care to avoid overflow when possible by
-// exploiting the 146097-day cycle.
+ cd += hh / 24;
+ hh %= 24;
+ if (hh < 0) {
+ cd -= 1;
+ hh += 24;
+ }
+ return n_mon(y, m, d, cd, static_cast<hour_t>(hh), mm, ss);
+}
+CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
+ diff_t mm, second_t ss) noexcept {
+ ch += mm / 60;
+ mm %= 60;
+ if (mm < 0) {
+ ch -= 1;
+ mm += 60;
+ }
+ return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24,
+ static_cast<minute_t>(mm), ss);
+}
+CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
+ diff_t ss) noexcept {
+ // Optimization for when (non-constexpr) fields are already normalized.
+ if (0 <= ss && ss < 60) {
+ const second_t nss = static_cast<second_t>(ss);
+ if (0 <= mm && mm < 60) {
+ const minute_t nmm = static_cast<minute_t>(mm);
+ if (0 <= hh && hh < 24) {
+ const hour_t nhh = static_cast<hour_t>(hh);
+ if (1 <= d && d <= 28 && 1 <= m && m <= 12) {
+ const day_t nd = static_cast<day_t>(d);
+ const month_t nm = static_cast<month_t>(m);
+ return fields(y, nm, nd, nhh, nmm, nss);
+ }
+ return n_mon(y, m, d, 0, nhh, nmm, nss);
+ }
+ return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss);
+ }
+ return n_min(y, m, d, hh, mm / 60, mm % 60, nss);
+ }
+ diff_t cm = ss / 60;
+ ss %= 60;
+ if (ss < 0) {
+ cm -= 1;
+ ss += 60;
+ }
+ return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60,
+ static_cast<second_t>(ss));
+}
+
+} // namespace impl
+
+////////////////////////////////////////////////////////////////////////
+
+// Increments the indicated (normalized) field by "n".
+CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept {
+ return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60);
+}
+CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept {
+ return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss);
+}
+CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept {
+ return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss);
+}
+CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept {
+ return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss);
+}
+CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept {
+ return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss);
+}
+CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept {
+ return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+namespace impl {
+
+// Returns (v * f + a) but avoiding intermediate overflow when possible.
+CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept {
+ return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f;
+}
+
+// Map a (normalized) Y/M/D to the number of days before/after 1970-01-01.
+// Probably overflows for years outside [-292277022656:292277026595].
+CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept {
+ const diff_t eyear = (m <= 2) ? y - 1 : y;
+ const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400;
+ const diff_t yoe = eyear - era * 400;
+ const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
+ const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
+ return era * 146097 + doe - 719468;
+}
+
+// Returns the difference in days between two normalized Y-M-D tuples.
+// ymd_ord() will encounter integer overflow given extreme year values,
+// yet the difference between two such extreme values may actually be
+// small, so we take a little care to avoid overflow when possible by
+// exploiting the 146097-day cycle.
CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2,
month_t m2, day_t d2) noexcept {
- const diff_t a_c4_off = y1 % 400;
- const diff_t b_c4_off = y2 % 400;
- diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off);
- diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2);
- if (c4_diff > 0 && delta < 0) {
- delta += 2 * 146097;
- c4_diff -= 2 * 400;
- } else if (c4_diff < 0 && delta > 0) {
- delta -= 2 * 146097;
- c4_diff += 2 * 400;
- }
- return (c4_diff / 400 * 146097) + delta;
-}
-
-} // namespace impl
-
-// Returns the difference between fields structs using the indicated unit.
-CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept {
- return f1.y - f2.y;
-}
-CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept {
- return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m));
-}
-CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept {
- return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d);
-}
-CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept {
- return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh));
-}
-CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept {
- return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm));
-}
-CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept {
- return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-// Aligns the (normalized) fields struct to the indicated field.
+ const diff_t a_c4_off = y1 % 400;
+ const diff_t b_c4_off = y2 % 400;
+ diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off);
+ diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2);
+ if (c4_diff > 0 && delta < 0) {
+ delta += 2 * 146097;
+ c4_diff -= 2 * 400;
+ } else if (c4_diff < 0 && delta > 0) {
+ delta -= 2 * 146097;
+ c4_diff += 2 * 400;
+ }
+ return (c4_diff / 400 * 146097) + delta;
+}
+
+} // namespace impl
+
+// Returns the difference between fields structs using the indicated unit.
+CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept {
+ return f1.y - f2.y;
+}
+CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept {
+ return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m));
+}
+CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept {
+ return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d);
+}
+CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept {
+ return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh));
+}
+CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept {
+ return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm));
+}
+CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept {
+ return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// Aligns the (normalized) fields struct to the indicated field.
CONSTEXPR_F fields align(second_tag, fields f) noexcept { return f; }
-CONSTEXPR_F fields align(minute_tag, fields f) noexcept {
- return fields{f.y, f.m, f.d, f.hh, f.mm, 0};
-}
-CONSTEXPR_F fields align(hour_tag, fields f) noexcept {
- return fields{f.y, f.m, f.d, f.hh, 0, 0};
-}
-CONSTEXPR_F fields align(day_tag, fields f) noexcept {
- return fields{f.y, f.m, f.d, 0, 0, 0};
-}
-CONSTEXPR_F fields align(month_tag, fields f) noexcept {
- return fields{f.y, f.m, 1, 0, 0, 0};
-}
-CONSTEXPR_F fields align(year_tag, fields f) noexcept {
- return fields{f.y, 1, 1, 0, 0, 0};
-}
-
-////////////////////////////////////////////////////////////////////////
-
-namespace impl {
-
-template <typename H>
-H AbslHashValueImpl(second_tag, H h, fields f) {
- return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss);
-}
-template <typename H>
-H AbslHashValueImpl(minute_tag, H h, fields f) {
- return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm);
-}
-template <typename H>
-H AbslHashValueImpl(hour_tag, H h, fields f) {
- return H::combine(std::move(h), f.y, f.m, f.d, f.hh);
-}
-template <typename H>
-H AbslHashValueImpl(day_tag, H h, fields f) {
- return H::combine(std::move(h), f.y, f.m, f.d);
-}
-template <typename H>
-H AbslHashValueImpl(month_tag, H h, fields f) {
- return H::combine(std::move(h), f.y, f.m);
-}
-template <typename H>
-H AbslHashValueImpl(year_tag, H h, fields f) {
- return H::combine(std::move(h), f.y);
-}
-
-} // namespace impl
-
-////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-class civil_time {
- public:
- explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1,
- diff_t hh = 0, diff_t mm = 0,
- diff_t ss = 0) noexcept
- : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {}
-
- CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {}
- civil_time(const civil_time&) = default;
- civil_time& operator=(const civil_time&) = default;
-
- // Conversion between civil times of different alignment. Conversion to
- // a more precise alignment is allowed implicitly (e.g., day -> hour),
- // but conversion where information is discarded must be explicit
- // (e.g., second -> minute).
- template <typename U, typename S>
- using preserves_data =
- typename std::enable_if<std::is_base_of<U, S>::value>::type;
- template <typename U>
- CONSTEXPR_M civil_time(const civil_time<U>& ct,
- preserves_data<T, U>* = nullptr) noexcept
- : civil_time(ct.f_) {}
- template <typename U>
- explicit CONSTEXPR_M civil_time(const civil_time<U>& ct,
- preserves_data<U, T>* = nullptr) noexcept
- : civil_time(ct.f_) {}
-
- // Factories for the maximum/minimum representable civil_time.
+CONSTEXPR_F fields align(minute_tag, fields f) noexcept {
+ return fields{f.y, f.m, f.d, f.hh, f.mm, 0};
+}
+CONSTEXPR_F fields align(hour_tag, fields f) noexcept {
+ return fields{f.y, f.m, f.d, f.hh, 0, 0};
+}
+CONSTEXPR_F fields align(day_tag, fields f) noexcept {
+ return fields{f.y, f.m, f.d, 0, 0, 0};
+}
+CONSTEXPR_F fields align(month_tag, fields f) noexcept {
+ return fields{f.y, f.m, 1, 0, 0, 0};
+}
+CONSTEXPR_F fields align(year_tag, fields f) noexcept {
+ return fields{f.y, 1, 1, 0, 0, 0};
+}
+
+////////////////////////////////////////////////////////////////////////
+
+namespace impl {
+
+template <typename H>
+H AbslHashValueImpl(second_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss);
+}
+template <typename H>
+H AbslHashValueImpl(minute_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm);
+}
+template <typename H>
+H AbslHashValueImpl(hour_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y, f.m, f.d, f.hh);
+}
+template <typename H>
+H AbslHashValueImpl(day_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y, f.m, f.d);
+}
+template <typename H>
+H AbslHashValueImpl(month_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y, f.m);
+}
+template <typename H>
+H AbslHashValueImpl(year_tag, H h, fields f) {
+ return H::combine(std::move(h), f.y);
+}
+
+} // namespace impl
+
+////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+class civil_time {
+ public:
+ explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1,
+ diff_t hh = 0, diff_t mm = 0,
+ diff_t ss = 0) noexcept
+ : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {}
+
+ CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {}
+ civil_time(const civil_time&) = default;
+ civil_time& operator=(const civil_time&) = default;
+
+ // Conversion between civil times of different alignment. Conversion to
+ // a more precise alignment is allowed implicitly (e.g., day -> hour),
+ // but conversion where information is discarded must be explicit
+ // (e.g., second -> minute).
+ template <typename U, typename S>
+ using preserves_data =
+ typename std::enable_if<std::is_base_of<U, S>::value>::type;
+ template <typename U>
+ CONSTEXPR_M civil_time(const civil_time<U>& ct,
+ preserves_data<T, U>* = nullptr) noexcept
+ : civil_time(ct.f_) {}
+ template <typename U>
+ explicit CONSTEXPR_M civil_time(const civil_time<U>& ct,
+ preserves_data<U, T>* = nullptr) noexcept
+ : civil_time(ct.f_) {}
+
+ // Factories for the maximum/minimum representable civil_time.
static CONSTEXPR_F civil_time(max)() {
- const auto max_year = (std::numeric_limits<std::int_least64_t>::max)();
- return civil_time(max_year, 12, 31, 23, 59, 59);
- }
+ const auto max_year = (std::numeric_limits<std::int_least64_t>::max)();
+ return civil_time(max_year, 12, 31, 23, 59, 59);
+ }
static CONSTEXPR_F civil_time(min)() {
- const auto min_year = (std::numeric_limits<std::int_least64_t>::min)();
- return civil_time(min_year, 1, 1, 0, 0, 0);
- }
-
- // Field accessors. Note: All but year() return an int.
- CONSTEXPR_M year_t year() const noexcept { return f_.y; }
- CONSTEXPR_M int month() const noexcept { return f_.m; }
- CONSTEXPR_M int day() const noexcept { return f_.d; }
- CONSTEXPR_M int hour() const noexcept { return f_.hh; }
- CONSTEXPR_M int minute() const noexcept { return f_.mm; }
- CONSTEXPR_M int second() const noexcept { return f_.ss; }
-
- // Assigning arithmetic.
- CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept {
+ const auto min_year = (std::numeric_limits<std::int_least64_t>::min)();
+ return civil_time(min_year, 1, 1, 0, 0, 0);
+ }
+
+ // Field accessors. Note: All but year() return an int.
+ CONSTEXPR_M year_t year() const noexcept { return f_.y; }
+ CONSTEXPR_M int month() const noexcept { return f_.m; }
+ CONSTEXPR_M int day() const noexcept { return f_.d; }
+ CONSTEXPR_M int hour() const noexcept { return f_.hh; }
+ CONSTEXPR_M int minute() const noexcept { return f_.mm; }
+ CONSTEXPR_M int second() const noexcept { return f_.ss; }
+
+ // Assigning arithmetic.
+ CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept {
return *this = *this + n;
- }
- CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept {
+ }
+ CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept {
return *this = *this - n;
- }
+ }
CONSTEXPR_M civil_time& operator++() noexcept { return *this += 1; }
- CONSTEXPR_M civil_time operator++(int) noexcept {
- const civil_time a = *this;
- ++*this;
- return a;
- }
+ CONSTEXPR_M civil_time operator++(int) noexcept {
+ const civil_time a = *this;
+ ++*this;
+ return a;
+ }
CONSTEXPR_M civil_time& operator--() noexcept { return *this -= 1; }
- CONSTEXPR_M civil_time operator--(int) noexcept {
- const civil_time a = *this;
- --*this;
- return a;
- }
-
- // Binary arithmetic operators.
- friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept {
+ CONSTEXPR_M civil_time operator--(int) noexcept {
+ const civil_time a = *this;
+ --*this;
+ return a;
+ }
+
+ // Binary arithmetic operators.
+ friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept {
return civil_time(step(T{}, a.f_, n));
- }
- friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept {
+ }
+ friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept {
return a + n;
- }
- friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept {
+ }
+ friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept {
return n != (std::numeric_limits<diff_t>::min)()
? civil_time(step(T{}, a.f_, -n))
: civil_time(step(T{}, step(T{}, a.f_, -(n + 1)), 1));
- }
- friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept {
- return difference(T{}, lhs.f_, rhs.f_);
- }
-
- template <typename H>
- friend H AbslHashValue(H h, civil_time a) {
- return impl::AbslHashValueImpl(T{}, std::move(h), a.f_);
- }
-
- private:
- // All instantiations of this template are allowed to call the following
- // private constructor and access the private fields member.
- template <typename U>
- friend class civil_time;
-
- // The designated constructor that all others eventually call.
- explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {}
-
- fields f_;
-};
-
-// Disallows difference between differently aligned types.
-// auto n = civil_day(...) - civil_hour(...); // would be confusing.
-template <typename T, typename U>
-CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete;
-
-using civil_year = civil_time<year_tag>;
-using civil_month = civil_time<month_tag>;
-using civil_day = civil_time<day_tag>;
-using civil_hour = civil_time<hour_tag>;
-using civil_minute = civil_time<minute_tag>;
-using civil_second = civil_time<second_tag>;
-
-////////////////////////////////////////////////////////////////////////
-
-// Relational operators that work with differently aligned objects.
-// Always compares all six fields.
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
+ }
+ friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept {
+ return difference(T{}, lhs.f_, rhs.f_);
+ }
+
+ template <typename H>
+ friend H AbslHashValue(H h, civil_time a) {
+ return impl::AbslHashValueImpl(T{}, std::move(h), a.f_);
+ }
+
+ private:
+ // All instantiations of this template are allowed to call the following
+ // private constructor and access the private fields member.
+ template <typename U>
+ friend class civil_time;
+
+ // The designated constructor that all others eventually call.
+ explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {}
+
+ fields f_;
+};
+
+// Disallows difference between differently aligned types.
+// auto n = civil_day(...) - civil_hour(...); // would be confusing.
+template <typename T, typename U>
+CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete;
+
+using civil_year = civil_time<year_tag>;
+using civil_month = civil_time<month_tag>;
+using civil_day = civil_time<day_tag>;
+using civil_hour = civil_time<hour_tag>;
+using civil_minute = civil_time<minute_tag>;
+using civil_second = civil_time<second_tag>;
+
+////////////////////////////////////////////////////////////////////////
+
+// Relational operators that work with differently aligned objects.
+// Always compares all six fields.
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
return (
lhs.year() < rhs.year() ||
(lhs.year() == rhs.year() &&
@@ -497,132 +497,132 @@ CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
(lhs.minute() < rhs.minute() ||
(lhs.minute() == rhs.minute() &&
(lhs.second() < rhs.second())))))))))));
-}
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
- return !(rhs < lhs);
-}
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
- return !(lhs < rhs);
-}
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator>(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
- return rhs < lhs;
-}
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator==(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
- return lhs.year() == rhs.year() && lhs.month() == rhs.month() &&
- lhs.day() == rhs.day() && lhs.hour() == rhs.hour() &&
- lhs.minute() == rhs.minute() && lhs.second() == rhs.second();
-}
-template <typename T1, typename T2>
-CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs,
- const civil_time<T2>& rhs) noexcept {
- return !(lhs == rhs);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-enum class weekday {
- monday,
- tuesday,
- wednesday,
- thursday,
- friday,
- saturday,
- sunday,
-};
-
-CONSTEXPR_F weekday get_weekday(const civil_second& cs) noexcept {
- CONSTEXPR_D weekday k_weekday_by_mon_off[13] = {
- weekday::monday, weekday::tuesday, weekday::wednesday,
- weekday::thursday, weekday::friday, weekday::saturday,
- weekday::sunday, weekday::monday, weekday::tuesday,
- weekday::wednesday, weekday::thursday, weekday::friday,
- weekday::saturday,
- };
- CONSTEXPR_D int k_weekday_offsets[1 + 12] = {
- -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4,
- };
- year_t wd = 2400 + (cs.year() % 400) - (cs.month() < 3);
- wd += wd / 4 - wd / 100 + wd / 400;
- wd += k_weekday_offsets[cs.month()] + cs.day();
- return k_weekday_by_mon_off[wd % 7 + 6];
-}
-
-////////////////////////////////////////////////////////////////////////
-
-CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
- CONSTEXPR_D weekday k_weekdays_forw[14] = {
- weekday::monday, weekday::tuesday, weekday::wednesday,
- weekday::thursday, weekday::friday, weekday::saturday,
- weekday::sunday, weekday::monday, weekday::tuesday,
- weekday::wednesday, weekday::thursday, weekday::friday,
- weekday::saturday, weekday::sunday,
- };
- weekday base = get_weekday(cd);
- for (int i = 0;; ++i) {
- if (base == k_weekdays_forw[i]) {
- for (int j = i + 1;; ++j) {
- if (wd == k_weekdays_forw[j]) {
- return cd + (j - i);
- }
- }
- }
- }
-}
-
-CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
- CONSTEXPR_D weekday k_weekdays_back[14] = {
- weekday::sunday, weekday::saturday, weekday::friday,
- weekday::thursday, weekday::wednesday, weekday::tuesday,
- weekday::monday, weekday::sunday, weekday::saturday,
- weekday::friday, weekday::thursday, weekday::wednesday,
- weekday::tuesday, weekday::monday,
- };
- weekday base = get_weekday(cd);
- for (int i = 0;; ++i) {
- if (base == k_weekdays_back[i]) {
- for (int j = i + 1;; ++j) {
- if (wd == k_weekdays_back[j]) {
- return cd - (j - i);
- }
- }
- }
- }
-}
-
-CONSTEXPR_F int get_yearday(const civil_second& cs) noexcept {
- CONSTEXPR_D int k_month_offsets[1 + 12] = {
- -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
- };
- const int feb29 = (cs.month() > 2 && impl::is_leap_year(cs.year()));
- return k_month_offsets[cs.month()] + feb29 + cs.day();
-}
-
-////////////////////////////////////////////////////////////////////////
-
-std::ostream& operator<<(std::ostream& os, const civil_year& y);
-std::ostream& operator<<(std::ostream& os, const civil_month& m);
-std::ostream& operator<<(std::ostream& os, const civil_day& d);
-std::ostream& operator<<(std::ostream& os, const civil_hour& h);
-std::ostream& operator<<(std::ostream& os, const civil_minute& m);
-std::ostream& operator<<(std::ostream& os, const civil_second& s);
-std::ostream& operator<<(std::ostream& os, weekday wd);
-
-} // namespace detail
-} // namespace cctz
-} // namespace time_internal
+}
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
+ return !(rhs < lhs);
+}
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
+ return !(lhs < rhs);
+}
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator>(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
+ return rhs < lhs;
+}
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator==(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
+ return lhs.year() == rhs.year() && lhs.month() == rhs.month() &&
+ lhs.day() == rhs.day() && lhs.hour() == rhs.hour() &&
+ lhs.minute() == rhs.minute() && lhs.second() == rhs.second();
+}
+template <typename T1, typename T2>
+CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs,
+ const civil_time<T2>& rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+enum class weekday {
+ monday,
+ tuesday,
+ wednesday,
+ thursday,
+ friday,
+ saturday,
+ sunday,
+};
+
+CONSTEXPR_F weekday get_weekday(const civil_second& cs) noexcept {
+ CONSTEXPR_D weekday k_weekday_by_mon_off[13] = {
+ weekday::monday, weekday::tuesday, weekday::wednesday,
+ weekday::thursday, weekday::friday, weekday::saturday,
+ weekday::sunday, weekday::monday, weekday::tuesday,
+ weekday::wednesday, weekday::thursday, weekday::friday,
+ weekday::saturday,
+ };
+ CONSTEXPR_D int k_weekday_offsets[1 + 12] = {
+ -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4,
+ };
+ year_t wd = 2400 + (cs.year() % 400) - (cs.month() < 3);
+ wd += wd / 4 - wd / 100 + wd / 400;
+ wd += k_weekday_offsets[cs.month()] + cs.day();
+ return k_weekday_by_mon_off[wd % 7 + 6];
+}
+
+////////////////////////////////////////////////////////////////////////
+
+CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
+ CONSTEXPR_D weekday k_weekdays_forw[14] = {
+ weekday::monday, weekday::tuesday, weekday::wednesday,
+ weekday::thursday, weekday::friday, weekday::saturday,
+ weekday::sunday, weekday::monday, weekday::tuesday,
+ weekday::wednesday, weekday::thursday, weekday::friday,
+ weekday::saturday, weekday::sunday,
+ };
+ weekday base = get_weekday(cd);
+ for (int i = 0;; ++i) {
+ if (base == k_weekdays_forw[i]) {
+ for (int j = i + 1;; ++j) {
+ if (wd == k_weekdays_forw[j]) {
+ return cd + (j - i);
+ }
+ }
+ }
+ }
+}
+
+CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
+ CONSTEXPR_D weekday k_weekdays_back[14] = {
+ weekday::sunday, weekday::saturday, weekday::friday,
+ weekday::thursday, weekday::wednesday, weekday::tuesday,
+ weekday::monday, weekday::sunday, weekday::saturday,
+ weekday::friday, weekday::thursday, weekday::wednesday,
+ weekday::tuesday, weekday::monday,
+ };
+ weekday base = get_weekday(cd);
+ for (int i = 0;; ++i) {
+ if (base == k_weekdays_back[i]) {
+ for (int j = i + 1;; ++j) {
+ if (wd == k_weekdays_back[j]) {
+ return cd - (j - i);
+ }
+ }
+ }
+ }
+}
+
+CONSTEXPR_F int get_yearday(const civil_second& cs) noexcept {
+ CONSTEXPR_D int k_month_offsets[1 + 12] = {
+ -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+ };
+ const int feb29 = (cs.month() > 2 && impl::is_leap_year(cs.year()));
+ return k_month_offsets[cs.month()] + feb29 + cs.day();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+std::ostream& operator<<(std::ostream& os, const civil_year& y);
+std::ostream& operator<<(std::ostream& os, const civil_month& m);
+std::ostream& operator<<(std::ostream& os, const civil_day& d);
+std::ostream& operator<<(std::ostream& os, const civil_hour& h);
+std::ostream& operator<<(std::ostream& os, const civil_minute& m);
+std::ostream& operator<<(std::ostream& os, const civil_second& s);
+std::ostream& operator<<(std::ostream& os, weekday wd);
+
+} // namespace detail
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#undef CONSTEXPR_M
-#undef CONSTEXPR_F
-#undef CONSTEXPR_D
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
+
+#undef CONSTEXPR_M
+#undef CONSTEXPR_F
+#undef CONSTEXPR_D
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h
index 8026041c62..524654df4b 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h
@@ -1,272 +1,272 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// A library for translating between absolute times (represented by
-// std::chrono::time_points of the std::chrono::system_clock) and civil
-// times (represented by cctz::civil_second) using the rules defined by
-// a time zone (cctz::time_zone).
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
-
-#include <chrono>
-#include <cstdint>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// A library for translating between absolute times (represented by
+// std::chrono::time_points of the std::chrono::system_clock) and civil
+// times (represented by cctz::civil_second) using the rules defined by
+// a time zone (cctz::time_zone).
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
+
+#include <chrono>
+#include <cstdint>
#include <limits>
#include <util/generic/string.h>
-#include <utility>
-
+#include <utility>
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// Convenience aliases. Not intended as public API points.
-template <typename D>
-using time_point = std::chrono::time_point<std::chrono::system_clock, D>;
-using seconds = std::chrono::duration<std::int_fast64_t>;
-using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead.
-
-namespace detail {
-template <typename D>
+namespace time_internal {
+namespace cctz {
+
+// Convenience aliases. Not intended as public API points.
+template <typename D>
+using time_point = std::chrono::time_point<std::chrono::system_clock, D>;
+using seconds = std::chrono::duration<std::int_fast64_t>;
+using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead.
+
+namespace detail {
+template <typename D>
std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp);
std::pair<time_point<seconds>, seconds> split_seconds(
const time_point<seconds>& tp);
-} // namespace detail
-
-// cctz::time_zone is an opaque, small, value-type class representing a
-// geo-political region within which particular rules are used for mapping
-// between absolute and civil times. Time zones are named using the TZ
-// identifiers from the IANA Time Zone Database, such as "America/Los_Angeles"
-// or "Australia/Sydney". Time zones are created from factory functions such
-// as load_time_zone(). Note: strings like "PST" and "EDT" are not valid TZ
-// identifiers.
-//
-// Example:
-// cctz::time_zone utc = cctz::utc_time_zone();
-// cctz::time_zone pst = cctz::fixed_time_zone(std::chrono::hours(-8));
-// cctz::time_zone loc = cctz::local_time_zone();
-// cctz::time_zone lax;
-// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
-//
-// See also:
-// - http://www.iana.org/time-zones
-// - https://en.wikipedia.org/wiki/Zoneinfo
-class time_zone {
- public:
- time_zone() : time_zone(nullptr) {} // Equivalent to UTC
- time_zone(const time_zone&) = default;
- time_zone& operator=(const time_zone&) = default;
-
+} // namespace detail
+
+// cctz::time_zone is an opaque, small, value-type class representing a
+// geo-political region within which particular rules are used for mapping
+// between absolute and civil times. Time zones are named using the TZ
+// identifiers from the IANA Time Zone Database, such as "America/Los_Angeles"
+// or "Australia/Sydney". Time zones are created from factory functions such
+// as load_time_zone(). Note: strings like "PST" and "EDT" are not valid TZ
+// identifiers.
+//
+// Example:
+// cctz::time_zone utc = cctz::utc_time_zone();
+// cctz::time_zone pst = cctz::fixed_time_zone(std::chrono::hours(-8));
+// cctz::time_zone loc = cctz::local_time_zone();
+// cctz::time_zone lax;
+// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
+//
+// See also:
+// - http://www.iana.org/time-zones
+// - https://en.wikipedia.org/wiki/Zoneinfo
+class time_zone {
+ public:
+ time_zone() : time_zone(nullptr) {} // Equivalent to UTC
+ time_zone(const time_zone&) = default;
+ time_zone& operator=(const time_zone&) = default;
+
TString name() const;
-
- // An absolute_lookup represents the civil time (cctz::civil_second) within
- // this time_zone at the given absolute time (time_point). There are
- // additionally a few other fields that may be useful when working with
- // older APIs, such as std::tm.
- //
- // Example:
- // const cctz::time_zone tz = ...
- // const auto tp = std::chrono::system_clock::now();
- // const cctz::time_zone::absolute_lookup al = tz.lookup(tp);
- struct absolute_lookup {
- civil_second cs;
- // Note: The following fields exist for backward compatibility with older
- // APIs. Accessing these fields directly is a sign of imprudent logic in
- // the calling code. Modern time-related code should only access this data
- // indirectly by way of cctz::format().
- int offset; // civil seconds east of UTC
- bool is_dst; // is offset non-standard?
- const char* abbr; // time-zone abbreviation (e.g., "PST")
- };
- absolute_lookup lookup(const time_point<seconds>& tp) const;
- template <typename D>
- absolute_lookup lookup(const time_point<D>& tp) const {
- return lookup(detail::split_seconds(tp).first);
- }
-
- // A civil_lookup represents the absolute time(s) (time_point) that
- // correspond to the given civil time (cctz::civil_second) within this
- // time_zone. Usually the given civil time represents a unique instant
- // in time, in which case the conversion is unambiguous. However,
- // within this time zone, the given civil time may be skipped (e.g.,
- // during a positive UTC offset shift), or repeated (e.g., during a
- // negative UTC offset shift). To account for these possibilities,
- // civil_lookup is richer than just a single time_point.
- //
- // In all cases the civil_lookup::kind enum will indicate the nature
- // of the given civil-time argument, and the pre, trans, and post
- // members will give the absolute time answers using the pre-transition
- // offset, the transition point itself, and the post-transition offset,
- // respectively (all three times are equal if kind == UNIQUE). If any
- // of these three absolute times is outside the representable range of a
- // time_point<seconds> the field is set to its maximum/minimum value.
- //
- // Example:
- // cctz::time_zone lax;
- // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
- //
- // // A unique civil time.
- // auto jan01 = lax.lookup(cctz::civil_second(2011, 1, 1, 0, 0, 0));
- // // jan01.kind == cctz::time_zone::civil_lookup::UNIQUE
- // // jan01.pre is 2011/01/01 00:00:00 -0800
- // // jan01.trans is 2011/01/01 00:00:00 -0800
- // // jan01.post is 2011/01/01 00:00:00 -0800
- //
- // // A Spring DST transition, when there is a gap in civil time.
- // auto mar13 = lax.lookup(cctz::civil_second(2011, 3, 13, 2, 15, 0));
- // // mar13.kind == cctz::time_zone::civil_lookup::SKIPPED
- // // mar13.pre is 2011/03/13 03:15:00 -0700
- // // mar13.trans is 2011/03/13 03:00:00 -0700
- // // mar13.post is 2011/03/13 01:15:00 -0800
- //
- // // A Fall DST transition, when civil times are repeated.
- // auto nov06 = lax.lookup(cctz::civil_second(2011, 11, 6, 1, 15, 0));
- // // nov06.kind == cctz::time_zone::civil_lookup::REPEATED
- // // nov06.pre is 2011/11/06 01:15:00 -0700
- // // nov06.trans is 2011/11/06 01:00:00 -0800
- // // nov06.post is 2011/11/06 01:15:00 -0800
- struct civil_lookup {
- enum civil_kind {
- UNIQUE, // the civil time was singular (pre == trans == post)
- SKIPPED, // the civil time did not exist (pre >= trans > post)
- REPEATED, // the civil time was ambiguous (pre < trans <= post)
- } kind;
- time_point<seconds> pre; // uses the pre-transition offset
- time_point<seconds> trans; // instant of civil-offset change
- time_point<seconds> post; // uses the post-transition offset
- };
- civil_lookup lookup(const civil_second& cs) const;
-
- // Finds the time of the next/previous offset change in this time zone.
- //
- // By definition, next_transition(tp, &trans) returns false when tp has
- // its maximum value, and prev_transition(tp, &trans) returns false
- // when tp has its minimum value. If the zone has no transitions, the
- // result will also be false no matter what the argument.
- //
- // Otherwise, when tp has its minimum value, next_transition(tp, &trans)
- // returns true and sets trans to the first recorded transition. Chains
- // of calls to next_transition()/prev_transition() will eventually return
- // false, but it is unspecified exactly when next_transition(tp, &trans)
- // jumps to false, or what time is set by prev_transition(tp, &trans) for
- // a very distant tp.
- //
- // Note: Enumeration of time-zone transitions is for informational purposes
- // only. Modern time-related code should not care about when offset changes
- // occur.
- //
- // Example:
- // cctz::time_zone nyc;
- // if (!cctz::load_time_zone("America/New_York", &nyc)) { ... }
- // const auto now = std::chrono::system_clock::now();
- // auto tp = cctz::time_point<cctz::seconds>::min();
- // cctz::time_zone::civil_transition trans;
- // while (tp <= now && nyc.next_transition(tp, &trans)) {
- // // transition: trans.from -> trans.to
- // tp = nyc.lookup(trans.to).trans;
- // }
- struct civil_transition {
- civil_second from; // the civil time we jump from
- civil_second to; // the civil time we jump to
- };
- bool next_transition(const time_point<seconds>& tp,
- civil_transition* trans) const;
- template <typename D>
+
+ // An absolute_lookup represents the civil time (cctz::civil_second) within
+ // this time_zone at the given absolute time (time_point). There are
+ // additionally a few other fields that may be useful when working with
+ // older APIs, such as std::tm.
+ //
+ // Example:
+ // const cctz::time_zone tz = ...
+ // const auto tp = std::chrono::system_clock::now();
+ // const cctz::time_zone::absolute_lookup al = tz.lookup(tp);
+ struct absolute_lookup {
+ civil_second cs;
+ // Note: The following fields exist for backward compatibility with older
+ // APIs. Accessing these fields directly is a sign of imprudent logic in
+ // the calling code. Modern time-related code should only access this data
+ // indirectly by way of cctz::format().
+ int offset; // civil seconds east of UTC
+ bool is_dst; // is offset non-standard?
+ const char* abbr; // time-zone abbreviation (e.g., "PST")
+ };
+ absolute_lookup lookup(const time_point<seconds>& tp) const;
+ template <typename D>
+ absolute_lookup lookup(const time_point<D>& tp) const {
+ return lookup(detail::split_seconds(tp).first);
+ }
+
+ // A civil_lookup represents the absolute time(s) (time_point) that
+ // correspond to the given civil time (cctz::civil_second) within this
+ // time_zone. Usually the given civil time represents a unique instant
+ // in time, in which case the conversion is unambiguous. However,
+ // within this time zone, the given civil time may be skipped (e.g.,
+ // during a positive UTC offset shift), or repeated (e.g., during a
+ // negative UTC offset shift). To account for these possibilities,
+ // civil_lookup is richer than just a single time_point.
+ //
+ // In all cases the civil_lookup::kind enum will indicate the nature
+ // of the given civil-time argument, and the pre, trans, and post
+ // members will give the absolute time answers using the pre-transition
+ // offset, the transition point itself, and the post-transition offset,
+ // respectively (all three times are equal if kind == UNIQUE). If any
+ // of these three absolute times is outside the representable range of a
+ // time_point<seconds> the field is set to its maximum/minimum value.
+ //
+ // Example:
+ // cctz::time_zone lax;
+ // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
+ //
+ // // A unique civil time.
+ // auto jan01 = lax.lookup(cctz::civil_second(2011, 1, 1, 0, 0, 0));
+ // // jan01.kind == cctz::time_zone::civil_lookup::UNIQUE
+ // // jan01.pre is 2011/01/01 00:00:00 -0800
+ // // jan01.trans is 2011/01/01 00:00:00 -0800
+ // // jan01.post is 2011/01/01 00:00:00 -0800
+ //
+ // // A Spring DST transition, when there is a gap in civil time.
+ // auto mar13 = lax.lookup(cctz::civil_second(2011, 3, 13, 2, 15, 0));
+ // // mar13.kind == cctz::time_zone::civil_lookup::SKIPPED
+ // // mar13.pre is 2011/03/13 03:15:00 -0700
+ // // mar13.trans is 2011/03/13 03:00:00 -0700
+ // // mar13.post is 2011/03/13 01:15:00 -0800
+ //
+ // // A Fall DST transition, when civil times are repeated.
+ // auto nov06 = lax.lookup(cctz::civil_second(2011, 11, 6, 1, 15, 0));
+ // // nov06.kind == cctz::time_zone::civil_lookup::REPEATED
+ // // nov06.pre is 2011/11/06 01:15:00 -0700
+ // // nov06.trans is 2011/11/06 01:00:00 -0800
+ // // nov06.post is 2011/11/06 01:15:00 -0800
+ struct civil_lookup {
+ enum civil_kind {
+ UNIQUE, // the civil time was singular (pre == trans == post)
+ SKIPPED, // the civil time did not exist (pre >= trans > post)
+ REPEATED, // the civil time was ambiguous (pre < trans <= post)
+ } kind;
+ time_point<seconds> pre; // uses the pre-transition offset
+ time_point<seconds> trans; // instant of civil-offset change
+ time_point<seconds> post; // uses the post-transition offset
+ };
+ civil_lookup lookup(const civil_second& cs) const;
+
+ // Finds the time of the next/previous offset change in this time zone.
+ //
+ // By definition, next_transition(tp, &trans) returns false when tp has
+ // its maximum value, and prev_transition(tp, &trans) returns false
+ // when tp has its minimum value. If the zone has no transitions, the
+ // result will also be false no matter what the argument.
+ //
+ // Otherwise, when tp has its minimum value, next_transition(tp, &trans)
+ // returns true and sets trans to the first recorded transition. Chains
+ // of calls to next_transition()/prev_transition() will eventually return
+ // false, but it is unspecified exactly when next_transition(tp, &trans)
+ // jumps to false, or what time is set by prev_transition(tp, &trans) for
+ // a very distant tp.
+ //
+ // Note: Enumeration of time-zone transitions is for informational purposes
+ // only. Modern time-related code should not care about when offset changes
+ // occur.
+ //
+ // Example:
+ // cctz::time_zone nyc;
+ // if (!cctz::load_time_zone("America/New_York", &nyc)) { ... }
+ // const auto now = std::chrono::system_clock::now();
+ // auto tp = cctz::time_point<cctz::seconds>::min();
+ // cctz::time_zone::civil_transition trans;
+ // while (tp <= now && nyc.next_transition(tp, &trans)) {
+ // // transition: trans.from -> trans.to
+ // tp = nyc.lookup(trans.to).trans;
+ // }
+ struct civil_transition {
+ civil_second from; // the civil time we jump from
+ civil_second to; // the civil time we jump to
+ };
+ bool next_transition(const time_point<seconds>& tp,
+ civil_transition* trans) const;
+ template <typename D>
bool next_transition(const time_point<D>& tp, civil_transition* trans) const {
- return next_transition(detail::split_seconds(tp).first, trans);
- }
- bool prev_transition(const time_point<seconds>& tp,
- civil_transition* trans) const;
- template <typename D>
+ return next_transition(detail::split_seconds(tp).first, trans);
+ }
+ bool prev_transition(const time_point<seconds>& tp,
+ civil_transition* trans) const;
+ template <typename D>
bool prev_transition(const time_point<D>& tp, civil_transition* trans) const {
- return prev_transition(detail::split_seconds(tp).first, trans);
- }
-
- // version() and description() provide additional information about the
- // time zone. The content of each of the returned strings is unspecified,
- // however, when the IANA Time Zone Database is the underlying data source
+ return prev_transition(detail::split_seconds(tp).first, trans);
+ }
+
+ // version() and description() provide additional information about the
+ // time zone. The content of each of the returned strings is unspecified,
+ // however, when the IANA Time Zone Database is the underlying data source
// the version() string will be in the familar form (e.g, "2018e") or
- // empty when unavailable.
- //
- // Note: These functions are for informational or testing purposes only.
+ // empty when unavailable.
+ //
+ // Note: These functions are for informational or testing purposes only.
TString version() const; // empty when unknown
TString description() const;
-
- // Relational operators.
- friend bool operator==(time_zone lhs, time_zone rhs) {
- return &lhs.effective_impl() == &rhs.effective_impl();
- }
+
+ // Relational operators.
+ friend bool operator==(time_zone lhs, time_zone rhs) {
+ return &lhs.effective_impl() == &rhs.effective_impl();
+ }
friend bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); }
-
- template <typename H>
- friend H AbslHashValue(H h, time_zone tz) {
- return H::combine(std::move(h), &tz.effective_impl());
- }
-
- class Impl;
-
- private:
- explicit time_zone(const Impl* impl) : impl_(impl) {}
- const Impl& effective_impl() const; // handles implicit UTC
- const Impl* impl_;
-};
-
-// Loads the named time zone. May perform I/O on the initial load.
-// If the name is invalid, or some other kind of error occurs, returns
-// false and "*tz" is set to the UTC time zone.
+
+ template <typename H>
+ friend H AbslHashValue(H h, time_zone tz) {
+ return H::combine(std::move(h), &tz.effective_impl());
+ }
+
+ class Impl;
+
+ private:
+ explicit time_zone(const Impl* impl) : impl_(impl) {}
+ const Impl& effective_impl() const; // handles implicit UTC
+ const Impl* impl_;
+};
+
+// Loads the named time zone. May perform I/O on the initial load.
+// If the name is invalid, or some other kind of error occurs, returns
+// false and "*tz" is set to the UTC time zone.
bool load_time_zone(const TString& name, time_zone* tz);
-
-// Returns a time_zone representing UTC. Cannot fail.
-time_zone utc_time_zone();
-
-// Returns a time zone that is a fixed offset (seconds east) from UTC.
-// Note: If the absolute value of the offset is greater than 24 hours
-// you'll get UTC (i.e., zero offset) instead.
-time_zone fixed_time_zone(const seconds& offset);
-
-// Returns a time zone representing the local time zone. Falls back to UTC.
-// Note: local_time_zone.name() may only be something like "localtime".
-time_zone local_time_zone();
-
-// Returns the civil time (cctz::civil_second) within the given time zone at
-// the given absolute time (time_point). Since the additional fields provided
-// by the time_zone::absolute_lookup struct should rarely be needed in modern
-// code, this convert() function is simpler and should be preferred.
-template <typename D>
-inline civil_second convert(const time_point<D>& tp, const time_zone& tz) {
- return tz.lookup(tp).cs;
-}
-
-// Returns the absolute time (time_point) that corresponds to the given civil
-// time within the given time zone. If the civil time is not unique (i.e., if
-// it was either repeated or non-existent), then the returned time_point is
-// the best estimate that preserves relative order. That is, this function
-// guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz).
-inline time_point<seconds> convert(const civil_second& cs,
- const time_zone& tz) {
- const time_zone::civil_lookup cl = tz.lookup(cs);
- if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans;
- return cl.pre;
-}
-
-namespace detail {
-using femtoseconds = std::chrono::duration<std::int_fast64_t, std::femto>;
+
+// Returns a time_zone representing UTC. Cannot fail.
+time_zone utc_time_zone();
+
+// Returns a time zone that is a fixed offset (seconds east) from UTC.
+// Note: If the absolute value of the offset is greater than 24 hours
+// you'll get UTC (i.e., zero offset) instead.
+time_zone fixed_time_zone(const seconds& offset);
+
+// Returns a time zone representing the local time zone. Falls back to UTC.
+// Note: local_time_zone.name() may only be something like "localtime".
+time_zone local_time_zone();
+
+// Returns the civil time (cctz::civil_second) within the given time zone at
+// the given absolute time (time_point). Since the additional fields provided
+// by the time_zone::absolute_lookup struct should rarely be needed in modern
+// code, this convert() function is simpler and should be preferred.
+template <typename D>
+inline civil_second convert(const time_point<D>& tp, const time_zone& tz) {
+ return tz.lookup(tp).cs;
+}
+
+// Returns the absolute time (time_point) that corresponds to the given civil
+// time within the given time zone. If the civil time is not unique (i.e., if
+// it was either repeated or non-existent), then the returned time_point is
+// the best estimate that preserves relative order. That is, this function
+// guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz).
+inline time_point<seconds> convert(const civil_second& cs,
+ const time_zone& tz) {
+ const time_zone::civil_lookup cl = tz.lookup(cs);
+ if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans;
+ return cl.pre;
+}
+
+namespace detail {
+using femtoseconds = std::chrono::duration<std::int_fast64_t, std::femto>;
TString format(const TString&, const time_point<seconds>&,
- const femtoseconds&, const time_zone&);
+ const femtoseconds&, const time_zone&);
bool parse(const TString&, const TString&, const time_zone&,
time_point<seconds>*, femtoseconds*, TString* err = nullptr);
template <typename Rep, std::intmax_t Denom>
@@ -283,96 +283,96 @@ bool join_seconds(
time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp);
bool join_seconds(const time_point<seconds>& sec, const femtoseconds&,
time_point<seconds>* tpp);
-} // namespace detail
-
-// Formats the given time_point in the given cctz::time_zone according to
-// the provided format string. Uses strftime()-like formatting options,
-// with the following extensions:
-//
-// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
-// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
-// - %E#S - Seconds with # digits of fractional precision
-// - %E*S - Seconds with full fractional precision (a literal '*')
-// - %E#f - Fractional seconds with # digits of precision
-// - %E*f - Fractional seconds with full precision (a literal '*')
-// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+} // namespace detail
+
+// Formats the given time_point in the given cctz::time_zone according to
+// the provided format string. Uses strftime()-like formatting options,
+// with the following extensions:
+//
+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
+// - %E#S - Seconds with # digits of fractional precision
+// - %E*S - Seconds with full fractional precision (a literal '*')
+// - %E#f - Fractional seconds with # digits of precision
+// - %E*f - Fractional seconds with full precision (a literal '*')
+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
// - %ET - The RFC3339 "date-time" separator "T"
-//
-// Note that %E0S behaves like %S, and %E0f produces no characters. In
-// contrast %E*f always produces at least one digit, which may be '0'.
-//
-// Note that %Y produces as many characters as it takes to fully render the
-// year. A year outside of [-999:9999] when formatted with %E4Y will produce
-// more than four characters, just like %Y.
-//
-// Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z)
-// so that the resulting string uniquely identifies an absolute time.
-//
-// Example:
-// cctz::time_zone lax;
-// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
-// auto tp = cctz::convert(cctz::civil_second(2013, 1, 2, 3, 4, 5), lax);
+//
+// Note that %E0S behaves like %S, and %E0f produces no characters. In
+// contrast %E*f always produces at least one digit, which may be '0'.
+//
+// Note that %Y produces as many characters as it takes to fully render the
+// year. A year outside of [-999:9999] when formatted with %E4Y will produce
+// more than four characters, just like %Y.
+//
+// Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z)
+// so that the resulting string uniquely identifies an absolute time.
+//
+// Example:
+// cctz::time_zone lax;
+// if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
+// auto tp = cctz::convert(cctz::civil_second(2013, 1, 2, 3, 4, 5), lax);
// TString f = cctz::format("%H:%M:%S", tp, lax); // "03:04:05"
-// f = cctz::format("%H:%M:%E3S", tp, lax); // "03:04:05.000"
-template <typename D>
+// f = cctz::format("%H:%M:%E3S", tp, lax); // "03:04:05.000"
+template <typename D>
inline TString format(const TString& fmt, const time_point<D>& tp,
- const time_zone& tz) {
- const auto p = detail::split_seconds(tp);
- const auto n = std::chrono::duration_cast<detail::femtoseconds>(p.second);
- return detail::format(fmt, p.first, n, tz);
-}
-
-// Parses an input string according to the provided format string and
-// returns the corresponding time_point. Uses strftime()-like formatting
-// options, with the same extensions as cctz::format(), but with the
-// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
+ const time_zone& tz) {
+ const auto p = detail::split_seconds(tp);
+ const auto n = std::chrono::duration_cast<detail::femtoseconds>(p.second);
+ return detail::format(fmt, p.first, n, tz);
+}
+
+// Parses an input string according to the provided format string and
+// returns the corresponding time_point. Uses strftime()-like formatting
+// options, with the same extensions as cctz::format(), but with the
+// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
// and %E*z also accept the same inputs, which (along with %z) includes
// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'.
-//
-// %Y consumes as many numeric characters as it can, so the matching data
-// should always be terminated with a non-numeric. %E4Y always consumes
-// exactly four characters, including any sign.
-//
-// Unspecified fields are taken from the default date and time of ...
-//
-// "1970-01-01 00:00:00.0 +0000"
-//
-// For example, parsing a string of "15:45" (%H:%M) will return a time_point
-// that represents "1970-01-01 15:45:00.0 +0000".
-//
-// Note that parse() returns time instants, so it makes most sense to parse
-// fully-specified date/time strings that include a UTC offset (%z, %Ez, or
-// %E*z).
-//
-// Note also that parse() only heeds the fields year, month, day, hour,
-// minute, (fractional) second, and UTC offset. Other fields, like weekday (%a
-// or %A), while parsed for syntactic validity, are ignored in the conversion.
-//
-// Date and time fields that are out-of-range will be treated as errors rather
-// than normalizing them like cctz::civil_second() would do. For example, it
-// is an error to parse the date "Oct 32, 2013" because 32 is out of range.
-//
-// A second of ":60" is normalized to ":00" of the following minute with
-// fractional seconds discarded. The following table shows how the given
-// seconds and subseconds will be parsed:
-//
-// "59.x" -> 59.x // exact
-// "60.x" -> 00.0 // normalized
-// "00.x" -> 00.x // exact
-//
-// Errors are indicated by returning false.
-//
-// Example:
-// const cctz::time_zone tz = ...
-// std::chrono::system_clock::time_point tp;
-// if (cctz::parse("%Y-%m-%d", "2015-10-09", tz, &tp)) {
-// ...
-// }
-template <typename D>
+//
+// %Y consumes as many numeric characters as it can, so the matching data
+// should always be terminated with a non-numeric. %E4Y always consumes
+// exactly four characters, including any sign.
+//
+// Unspecified fields are taken from the default date and time of ...
+//
+// "1970-01-01 00:00:00.0 +0000"
+//
+// For example, parsing a string of "15:45" (%H:%M) will return a time_point
+// that represents "1970-01-01 15:45:00.0 +0000".
+//
+// Note that parse() returns time instants, so it makes most sense to parse
+// fully-specified date/time strings that include a UTC offset (%z, %Ez, or
+// %E*z).
+//
+// Note also that parse() only heeds the fields year, month, day, hour,
+// minute, (fractional) second, and UTC offset. Other fields, like weekday (%a
+// or %A), while parsed for syntactic validity, are ignored in the conversion.
+//
+// Date and time fields that are out-of-range will be treated as errors rather
+// than normalizing them like cctz::civil_second() would do. For example, it
+// is an error to parse the date "Oct 32, 2013" because 32 is out of range.
+//
+// A second of ":60" is normalized to ":00" of the following minute with
+// fractional seconds discarded. The following table shows how the given
+// seconds and subseconds will be parsed:
+//
+// "59.x" -> 59.x // exact
+// "60.x" -> 00.0 // normalized
+// "00.x" -> 00.x // exact
+//
+// Errors are indicated by returning false.
+//
+// Example:
+// const cctz::time_zone tz = ...
+// std::chrono::system_clock::time_point tp;
+// if (cctz::parse("%Y-%m-%d", "2015-10-09", tz, &tp)) {
+// ...
+// }
+template <typename D>
inline bool parse(const TString& fmt, const TString& input,
- const time_zone& tz, time_point<D>* tpp) {
- time_point<seconds> sec;
- detail::femtoseconds fs;
+ const time_zone& tz, time_point<D>* tpp) {
+ time_point<seconds> sec;
+ detail::femtoseconds fs;
return detail::parse(fmt, input, tz, &sec, &fs) &&
detail::join_seconds(sec, fs, tpp);
}
@@ -391,10 +391,10 @@ std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) {
if (sub.count() < 0) {
sec -= seconds(1);
sub += seconds(1);
- }
+ }
return {sec, std::chrono::duration_cast<D>(sub)};
-}
-
+}
+
inline std::pair<time_point<seconds>, seconds> split_seconds(
const time_point<seconds>& tp) {
return {tp, seconds::zero()};
@@ -451,9 +451,9 @@ inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&,
}
} // namespace detail
-} // namespace cctz
-} // namespace time_internal
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/zone_info_source.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/zone_info_source.h
index 1786370bc3..fd6dc4bbb0 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/zone_info_source.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/zone_info_source.h
@@ -1,102 +1,102 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
-#define ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
-
-#include <cstddef>
-#include <functional>
-#include <memory>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
+#define ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
+
+#include <cstddef>
+#include <functional>
+#include <memory>
#include <util/generic/string.h>
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// A stdio-like interface for providing zoneinfo data for a particular zone.
-class ZoneInfoSource {
- public:
- virtual ~ZoneInfoSource();
-
- virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread()
+namespace time_internal {
+namespace cctz {
+
+// A stdio-like interface for providing zoneinfo data for a particular zone.
+class ZoneInfoSource {
+ public:
+ virtual ~ZoneInfoSource();
+
+ virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread()
virtual int Skip(std::size_t offset) = 0; // like fseek()
-
- // Until the zoneinfo data supports versioning information, we provide
- // a way for a ZoneInfoSource to indicate it out-of-band. The default
+
+ // Until the zoneinfo data supports versioning information, we provide
+ // a way for a ZoneInfoSource to indicate it out-of-band. The default
// implementation returns an empty string.
virtual TString Version() const;
-};
-
-} // namespace cctz
-} // namespace time_internal
+};
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz_extension {
-
-// A function-pointer type for a factory that returns a ZoneInfoSource
-// given the name of a time zone and a fallback factory. Returns null
-// when the data for the named zone cannot be found.
-using ZoneInfoSourceFactory =
+namespace time_internal {
+namespace cctz_extension {
+
+// A function-pointer type for a factory that returns a ZoneInfoSource
+// given the name of a time zone and a fallback factory. Returns null
+// when the data for the named zone cannot be found.
+using ZoneInfoSourceFactory =
std::unique_ptr<y_absl::time_internal::cctz::ZoneInfoSource> (*)(
const TString&,
const std::function<std::unique_ptr<
y_absl::time_internal::cctz::ZoneInfoSource>(const TString&)>&);
-
-// The user can control the mapping of zone names to zoneinfo data by
-// providing a definition for cctz_extension::zone_info_source_factory.
-// For example, given functions my_factory() and my_other_factory() that
-// can return a ZoneInfoSource for a named zone, we could inject them into
-// cctz::load_time_zone() with:
-//
-// namespace cctz_extension {
-// namespace {
-// std::unique_ptr<cctz::ZoneInfoSource> CustomFactory(
+
+// The user can control the mapping of zone names to zoneinfo data by
+// providing a definition for cctz_extension::zone_info_source_factory.
+// For example, given functions my_factory() and my_other_factory() that
+// can return a ZoneInfoSource for a named zone, we could inject them into
+// cctz::load_time_zone() with:
+//
+// namespace cctz_extension {
+// namespace {
+// std::unique_ptr<cctz::ZoneInfoSource> CustomFactory(
// const TString& name,
-// const std::function<std::unique_ptr<cctz::ZoneInfoSource>(
+// const std::function<std::unique_ptr<cctz::ZoneInfoSource>(
// const TString& name)>& fallback_factory) {
-// if (auto zip = my_factory(name)) return zip;
-// if (auto zip = fallback_factory(name)) return zip;
-// if (auto zip = my_other_factory(name)) return zip;
-// return nullptr;
-// }
-// } // namespace
-// ZoneInfoSourceFactory zone_info_source_factory = CustomFactory;
-// } // namespace cctz_extension
-//
-// This might be used, say, to use zoneinfo data embedded in the program,
-// or read from a (possibly compressed) file archive, or both.
-//
-// cctz_extension::zone_info_source_factory() will be called:
-// (1) from the same thread as the cctz::load_time_zone() call,
-// (2) only once for any zone name, and
-// (3) serially (i.e., no concurrent execution).
-//
-// The fallback factory obtains zoneinfo data by reading files in ${TZDIR},
-// and it is used automatically when no zone_info_source_factory definition
-// is linked into the program.
-extern ZoneInfoSourceFactory zone_info_source_factory;
-
-} // namespace cctz_extension
-} // namespace time_internal
+// if (auto zip = my_factory(name)) return zip;
+// if (auto zip = fallback_factory(name)) return zip;
+// if (auto zip = my_other_factory(name)) return zip;
+// return nullptr;
+// }
+// } // namespace
+// ZoneInfoSourceFactory zone_info_source_factory = CustomFactory;
+// } // namespace cctz_extension
+//
+// This might be used, say, to use zoneinfo data embedded in the program,
+// or read from a (possibly compressed) file archive, or both.
+//
+// cctz_extension::zone_info_source_factory() will be called:
+// (1) from the same thread as the cctz::load_time_zone() call,
+// (2) only once for any zone name, and
+// (3) serially (i.e., no concurrent execution).
+//
+// The fallback factory obtains zoneinfo data by reading files in ${TZDIR},
+// and it is used automatically when no zone_info_source_factory definition
+// is linked into the program.
+extern ZoneInfoSourceFactory zone_info_source_factory;
+
+} // namespace cctz_extension
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/civil_time_detail.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/civil_time_detail.cc
index 74c48f005c..61dbfc96ab 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/civil_time_detail.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/civil_time_detail.cc
@@ -1,94 +1,94 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "y_absl/time/internal/cctz/include/cctz/civil_time_detail.h"
-
-#include <iomanip>
-#include <ostream>
-#include <sstream>
-
+
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-namespace detail {
-
-// Output stream operators output a format matching YYYY-MM-DDThh:mm:ss,
-// while omitting fields inferior to the type's alignment. For example,
-// civil_day is formatted only as YYYY-MM-DD.
-std::ostream& operator<<(std::ostream& os, const civil_year& y) {
- std::stringstream ss;
- ss << y.year(); // No padding.
- return os << ss.str();
-}
-std::ostream& operator<<(std::ostream& os, const civil_month& m) {
- std::stringstream ss;
- ss << civil_year(m) << '-';
- ss << std::setfill('0') << std::setw(2) << m.month();
- return os << ss.str();
-}
-std::ostream& operator<<(std::ostream& os, const civil_day& d) {
- std::stringstream ss;
- ss << civil_month(d) << '-';
- ss << std::setfill('0') << std::setw(2) << d.day();
- return os << ss.str();
-}
-std::ostream& operator<<(std::ostream& os, const civil_hour& h) {
- std::stringstream ss;
- ss << civil_day(h) << 'T';
- ss << std::setfill('0') << std::setw(2) << h.hour();
- return os << ss.str();
-}
-std::ostream& operator<<(std::ostream& os, const civil_minute& m) {
- std::stringstream ss;
- ss << civil_hour(m) << ':';
- ss << std::setfill('0') << std::setw(2) << m.minute();
- return os << ss.str();
-}
-std::ostream& operator<<(std::ostream& os, const civil_second& s) {
- std::stringstream ss;
- ss << civil_minute(s) << ':';
- ss << std::setfill('0') << std::setw(2) << s.second();
- return os << ss.str();
-}
-
-////////////////////////////////////////////////////////////////////////
-
-std::ostream& operator<<(std::ostream& os, weekday wd) {
- switch (wd) {
- case weekday::monday:
- return os << "Monday";
- case weekday::tuesday:
- return os << "Tuesday";
- case weekday::wednesday:
- return os << "Wednesday";
- case weekday::thursday:
- return os << "Thursday";
- case weekday::friday:
- return os << "Friday";
- case weekday::saturday:
- return os << "Saturday";
- case weekday::sunday:
- return os << "Sunday";
- }
- return os; // Should never get here, but -Wreturn-type may warn without this.
-}
-
-} // namespace detail
-} // namespace cctz
-} // namespace time_internal
+namespace time_internal {
+namespace cctz {
+namespace detail {
+
+// Output stream operators output a format matching YYYY-MM-DDThh:mm:ss,
+// while omitting fields inferior to the type's alignment. For example,
+// civil_day is formatted only as YYYY-MM-DD.
+std::ostream& operator<<(std::ostream& os, const civil_year& y) {
+ std::stringstream ss;
+ ss << y.year(); // No padding.
+ return os << ss.str();
+}
+std::ostream& operator<<(std::ostream& os, const civil_month& m) {
+ std::stringstream ss;
+ ss << civil_year(m) << '-';
+ ss << std::setfill('0') << std::setw(2) << m.month();
+ return os << ss.str();
+}
+std::ostream& operator<<(std::ostream& os, const civil_day& d) {
+ std::stringstream ss;
+ ss << civil_month(d) << '-';
+ ss << std::setfill('0') << std::setw(2) << d.day();
+ return os << ss.str();
+}
+std::ostream& operator<<(std::ostream& os, const civil_hour& h) {
+ std::stringstream ss;
+ ss << civil_day(h) << 'T';
+ ss << std::setfill('0') << std::setw(2) << h.hour();
+ return os << ss.str();
+}
+std::ostream& operator<<(std::ostream& os, const civil_minute& m) {
+ std::stringstream ss;
+ ss << civil_hour(m) << ':';
+ ss << std::setfill('0') << std::setw(2) << m.minute();
+ return os << ss.str();
+}
+std::ostream& operator<<(std::ostream& os, const civil_second& s) {
+ std::stringstream ss;
+ ss << civil_minute(s) << ':';
+ ss << std::setfill('0') << std::setw(2) << s.second();
+ return os << ss.str();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+std::ostream& operator<<(std::ostream& os, weekday wd) {
+ switch (wd) {
+ case weekday::monday:
+ return os << "Monday";
+ case weekday::tuesday:
+ return os << "Tuesday";
+ case weekday::wednesday:
+ return os << "Wednesday";
+ case weekday::thursday:
+ return os << "Thursday";
+ case weekday::friday:
+ return os << "Friday";
+ case weekday::saturday:
+ return os << "Saturday";
+ case weekday::sunday:
+ return os << "Sunday";
+ }
+ return os; // Should never get here, but -Wreturn-type may warn without this.
+}
+
+} // namespace detail
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc
index 74c77e4dba..3a22cbea1d 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -1,140 +1,140 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "time_zone_fixed.h"
-
-#include <algorithm>
-#include <cassert>
-#include <chrono>
-#include <cstring>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "time_zone_fixed.h"
+
+#include <algorithm>
+#include <cassert>
+#include <chrono>
+#include <cstring>
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-namespace {
-
-// The prefix used for the internal names of fixed-offset zones.
-const char kFixedZonePrefix[] = "Fixed/UTC";
-
-const char kDigits[] = "0123456789";
-
-char* Format02d(char* p, int v) {
- *p++ = kDigits[(v / 10) % 10];
- *p++ = kDigits[v % 10];
- return p;
-}
-
-int Parse02d(const char* p) {
- if (const char* ap = std::strchr(kDigits, *p)) {
- int v = static_cast<int>(ap - kDigits);
- if (const char* bp = std::strchr(kDigits, *++p)) {
- return (v * 10) + static_cast<int>(bp - kDigits);
- }
- }
- return -1;
-}
-
-} // namespace
-
+namespace time_internal {
+namespace cctz {
+
+namespace {
+
+// The prefix used for the internal names of fixed-offset zones.
+const char kFixedZonePrefix[] = "Fixed/UTC";
+
+const char kDigits[] = "0123456789";
+
+char* Format02d(char* p, int v) {
+ *p++ = kDigits[(v / 10) % 10];
+ *p++ = kDigits[v % 10];
+ return p;
+}
+
+int Parse02d(const char* p) {
+ if (const char* ap = std::strchr(kDigits, *p)) {
+ int v = static_cast<int>(ap - kDigits);
+ if (const char* bp = std::strchr(kDigits, *++p)) {
+ return (v * 10) + static_cast<int>(bp - kDigits);
+ }
+ }
+ return -1;
+}
+
+} // namespace
+
bool FixedOffsetFromName(const TString& name, seconds* offset) {
if (name == "UTC" || name == "UTC0") {
- *offset = seconds::zero();
- return true;
- }
-
- const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
- const char* const ep = kFixedZonePrefix + prefix_len;
- if (name.size() != prefix_len + 9) // <prefix>+99:99:99
- return false;
+ *offset = seconds::zero();
+ return true;
+ }
+
+ const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
+ const char* const ep = kFixedZonePrefix + prefix_len;
+ if (name.size() != prefix_len + 9) // <prefix>+99:99:99
+ return false;
if (!std::equal(kFixedZonePrefix, ep, name.begin())) return false;
- const char* np = name.data() + prefix_len;
+ const char* np = name.data() + prefix_len;
if (np[0] != '+' && np[0] != '-') return false;
- if (np[3] != ':' || np[6] != ':') // see note below about large offsets
- return false;
-
- int hours = Parse02d(np + 1);
- if (hours == -1) return false;
- int mins = Parse02d(np + 4);
- if (mins == -1) return false;
- int secs = Parse02d(np + 7);
- if (secs == -1) return false;
-
- secs += ((hours * 60) + mins) * 60;
- if (secs > 24 * 60 * 60) return false; // outside supported offset range
- *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west
- return true;
-}
-
+ if (np[3] != ':' || np[6] != ':') // see note below about large offsets
+ return false;
+
+ int hours = Parse02d(np + 1);
+ if (hours == -1) return false;
+ int mins = Parse02d(np + 4);
+ if (mins == -1) return false;
+ int secs = Parse02d(np + 7);
+ if (secs == -1) return false;
+
+ secs += ((hours * 60) + mins) * 60;
+ if (secs > 24 * 60 * 60) return false; // outside supported offset range
+ *offset = seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west
+ return true;
+}
+
TString FixedOffsetToName(const seconds& offset) {
- if (offset == seconds::zero()) return "UTC";
- if (offset < std::chrono::hours(-24) || offset > std::chrono::hours(24)) {
- // We don't support fixed-offset zones more than 24 hours
- // away from UTC to avoid complications in rendering such
- // offsets and to (somewhat) limit the total number of zones.
- return "UTC";
- }
+ if (offset == seconds::zero()) return "UTC";
+ if (offset < std::chrono::hours(-24) || offset > std::chrono::hours(24)) {
+ // We don't support fixed-offset zones more than 24 hours
+ // away from UTC to avoid complications in rendering such
+ // offsets and to (somewhat) limit the total number of zones.
+ return "UTC";
+ }
int offset_seconds = static_cast<int>(offset.count());
const char sign = (offset_seconds < 0 ? '-' : '+');
int offset_minutes = offset_seconds / 60;
offset_seconds %= 60;
- if (sign == '-') {
+ if (sign == '-') {
if (offset_seconds > 0) {
offset_seconds -= 60;
offset_minutes += 1;
- }
+ }
offset_seconds = -offset_seconds;
offset_minutes = -offset_minutes;
- }
+ }
int offset_hours = offset_minutes / 60;
offset_minutes %= 60;
- const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
- char buf[prefix_len + sizeof("-24:00:00")];
- char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
- *ep++ = sign;
+ const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
+ char buf[prefix_len + sizeof("-24:00:00")];
+ char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
+ *ep++ = sign;
ep = Format02d(ep, offset_hours);
- *ep++ = ':';
+ *ep++ = ':';
ep = Format02d(ep, offset_minutes);
- *ep++ = ':';
+ *ep++ = ':';
ep = Format02d(ep, offset_seconds);
- *ep++ = '\0';
- assert(ep == buf + sizeof(buf));
- return buf;
-}
-
+ *ep++ = '\0';
+ assert(ep == buf + sizeof(buf));
+ return buf;
+}
+
TString FixedOffsetToAbbr(const seconds& offset) {
TString abbr = FixedOffsetToName(offset);
- const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
- if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99
- abbr.erase(0, prefix_len); // +99:99:99
- abbr.erase(6, 1); // +99:9999
- abbr.erase(3, 1); // +999999
- if (abbr[5] == '0' && abbr[6] == '0') { // +999900
- abbr.erase(5, 2); // +9999
- if (abbr[3] == '0' && abbr[4] == '0') { // +9900
- abbr.erase(3, 2); // +99
- }
- }
- }
- return abbr;
-}
-
-} // namespace cctz
-} // namespace time_internal
+ const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
+ if (abbr.size() == prefix_len + 9) { // <prefix>+99:99:99
+ abbr.erase(0, prefix_len); // +99:99:99
+ abbr.erase(6, 1); // +99:9999
+ abbr.erase(3, 1); // +999999
+ if (abbr[5] == '0' && abbr[6] == '0') { // +999900
+ abbr.erase(5, 2); // +9999
+ if (abbr[3] == '0' && abbr[4] == '0') { // +9900
+ abbr.erase(3, 2); // +99
+ }
+ }
+ }
+ return abbr;
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.h
index 5f8065e902..39b24e5a32 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.h
@@ -1,52 +1,52 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
+
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// Helper functions for dealing with the names and abbreviations
-// of time zones that are a fixed offset (seconds east) from UTC.
-// FixedOffsetFromName() extracts the offset from a valid fixed-offset
-// name, while FixedOffsetToName() and FixedOffsetToAbbr() generate
-// the canonical zone name and abbreviation respectively for the given
-// offset.
-//
-// A fixed-offset name looks like "Fixed/UTC<+-><hours>:<mins>:<secs>".
-// Its abbreviation is of the form "UTC(<+->H?H(MM(SS)?)?)?" where the
-// optional pieces are omitted when their values are zero. (Note that
-// the sign is the opposite of that used in a POSIX TZ specification.)
-//
-// Note: FixedOffsetFromName() fails on syntax errors or when the parsed
-// offset exceeds 24 hours. FixedOffsetToName() and FixedOffsetToAbbr()
-// both produce "UTC" when the argument offset exceeds 24 hours.
+namespace time_internal {
+namespace cctz {
+
+// Helper functions for dealing with the names and abbreviations
+// of time zones that are a fixed offset (seconds east) from UTC.
+// FixedOffsetFromName() extracts the offset from a valid fixed-offset
+// name, while FixedOffsetToName() and FixedOffsetToAbbr() generate
+// the canonical zone name and abbreviation respectively for the given
+// offset.
+//
+// A fixed-offset name looks like "Fixed/UTC<+-><hours>:<mins>:<secs>".
+// Its abbreviation is of the form "UTC(<+->H?H(MM(SS)?)?)?" where the
+// optional pieces are omitted when their values are zero. (Note that
+// the sign is the opposite of that used in a POSIX TZ specification.)
+//
+// Note: FixedOffsetFromName() fails on syntax errors or when the parsed
+// offset exceeds 24 hours. FixedOffsetToName() and FixedOffsetToAbbr()
+// both produce "UTC" when the argument offset exceeds 24 hours.
bool FixedOffsetFromName(const TString& name, seconds* offset);
TString FixedOffsetToName(const seconds& offset);
TString FixedOffsetToAbbr(const seconds& offset);
-
-} // namespace cctz
-} // namespace time_internal
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_format.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_format.cc
index 2dbff0e03d..2f9597018b 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_format.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_format.cc
@@ -1,72 +1,72 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#if !defined(HAS_STRPTIME)
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#if !defined(HAS_STRPTIME)
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#define HAS_STRPTIME 1 // assume everyone has strptime() except windows
-#endif
#endif
-
-#if defined(HAS_STRPTIME) && HAS_STRPTIME
+#endif
+
+#if defined(HAS_STRPTIME) && HAS_STRPTIME
#if !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE // Definedness suffices for strptime.
-#endif
#endif
-
+#endif
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
-// Include time.h directly since, by C++ standards, ctime doesn't have to
-// declare strptime.
-#include <time.h>
-
-#include <cctype>
-#include <chrono>
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <ctime>
-#include <limits>
+
+// Include time.h directly since, by C++ standards, ctime doesn't have to
+// declare strptime.
+#include <time.h>
+
+#include <cctype>
+#include <chrono>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <ctime>
+#include <limits>
#include <util/generic/string.h>
-#include <vector>
-#if !HAS_STRPTIME
-#include <iomanip>
-#include <sstream>
-#endif
-
+#include <vector>
+#if !HAS_STRPTIME
+#include <iomanip>
+#include <sstream>
+#endif
+
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
-#include "time_zone_if.h"
-
+#include "time_zone_if.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-namespace detail {
-
-namespace {
-
-#if !HAS_STRPTIME
-// Build a strptime() using C++11's std::get_time().
-char* strptime(const char* s, const char* fmt, std::tm* tm) {
- std::istringstream input(s);
- input >> std::get_time(tm, fmt);
- if (input.fail()) return nullptr;
- return const_cast<char*>(s) +
- (input.eof() ? strlen(s) : static_cast<std::size_t>(input.tellg()));
-}
-#endif
-
+namespace time_internal {
+namespace cctz {
+namespace detail {
+
+namespace {
+
+#if !HAS_STRPTIME
+// Build a strptime() using C++11's std::get_time().
+char* strptime(const char* s, const char* fmt, std::tm* tm) {
+ std::istringstream input(s);
+ input >> std::get_time(tm, fmt);
+ if (input.fail()) return nullptr;
+ return const_cast<char*>(s) +
+ (input.eof() ? strlen(s) : static_cast<std::size_t>(input.tellg()));
+}
+#endif
+
// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0).
int ToTmWday(weekday wd) {
switch (wd) {
@@ -109,29 +109,29 @@ weekday FromTmWday(int tm_wday) {
return weekday::sunday; /*NOTREACHED*/
}
-std::tm ToTM(const time_zone::absolute_lookup& al) {
- std::tm tm{};
- tm.tm_sec = al.cs.second();
- tm.tm_min = al.cs.minute();
- tm.tm_hour = al.cs.hour();
- tm.tm_mday = al.cs.day();
- tm.tm_mon = al.cs.month() - 1;
-
- // Saturate tm.tm_year is cases of over/underflow.
- if (al.cs.year() < std::numeric_limits<int>::min() + 1900) {
- tm.tm_year = std::numeric_limits<int>::min();
- } else if (al.cs.year() - 1900 > std::numeric_limits<int>::max()) {
- tm.tm_year = std::numeric_limits<int>::max();
- } else {
- tm.tm_year = static_cast<int>(al.cs.year() - 1900);
- }
-
+std::tm ToTM(const time_zone::absolute_lookup& al) {
+ std::tm tm{};
+ tm.tm_sec = al.cs.second();
+ tm.tm_min = al.cs.minute();
+ tm.tm_hour = al.cs.hour();
+ tm.tm_mday = al.cs.day();
+ tm.tm_mon = al.cs.month() - 1;
+
+ // Saturate tm.tm_year is cases of over/underflow.
+ if (al.cs.year() < std::numeric_limits<int>::min() + 1900) {
+ tm.tm_year = std::numeric_limits<int>::min();
+ } else if (al.cs.year() - 1900 > std::numeric_limits<int>::max()) {
+ tm.tm_year = std::numeric_limits<int>::max();
+ } else {
+ tm.tm_year = static_cast<int>(al.cs.year() - 1900);
+ }
+
tm.tm_wday = ToTmWday(get_weekday(al.cs));
- tm.tm_yday = get_yearday(al.cs) - 1;
- tm.tm_isdst = al.is_dst ? 1 : 0;
- return tm;
-}
-
+ tm.tm_yday = get_yearday(al.cs) - 1;
+ tm.tm_isdst = al.is_dst ? 1 : 0;
+ return tm;
+}
+
// Returns the week of the year [0:53] given a civil day and the day on
// which weeks are defined to start.
int ToWeek(const civil_day& cd, weekday week_start) {
@@ -139,270 +139,270 @@ int ToWeek(const civil_day& cd, weekday week_start) {
return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7);
}
-const char kDigits[] = "0123456789";
-
-// Formats a 64-bit integer in the given field width. Note that it is up
-// to the caller of Format64() [and Format02d()/FormatOffset()] to ensure
-// that there is sufficient space before ep to hold the conversion.
-char* Format64(char* ep, int width, std::int_fast64_t v) {
- bool neg = false;
- if (v < 0) {
- --width;
- neg = true;
- if (v == std::numeric_limits<std::int_fast64_t>::min()) {
- // Avoid negating minimum value.
- std::int_fast64_t last_digit = -(v % 10);
- v /= 10;
- if (last_digit < 0) {
- ++v;
- last_digit += 10;
- }
- --width;
- *--ep = kDigits[last_digit];
- }
- v = -v;
- }
- do {
- --width;
- *--ep = kDigits[v % 10];
- } while (v /= 10);
- while (--width >= 0) *--ep = '0'; // zero pad
- if (neg) *--ep = '-';
- return ep;
-}
-
-// Formats [0 .. 99] as %02d.
-char* Format02d(char* ep, int v) {
- *--ep = kDigits[v % 10];
- *--ep = kDigits[(v / 10) % 10];
- return ep;
-}
-
-// Formats a UTC offset, like +00:00.
-char* FormatOffset(char* ep, int offset, const char* mode) {
- // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and
- // generate a "negative zero" when we're formatting a zero offset
- // as the result of a failed load_time_zone().
- char sign = '+';
- if (offset < 0) {
- offset = -offset; // bounded by 24h so no overflow
- sign = '-';
- }
- const int seconds = offset % 60;
- const int minutes = (offset /= 60) % 60;
- const int hours = offset /= 60;
- const char sep = mode[0];
- const bool ext = (sep != '\0' && mode[1] == '*');
- const bool ccc = (ext && mode[2] == ':');
- if (ext && (!ccc || seconds != 0)) {
- ep = Format02d(ep, seconds);
- *--ep = sep;
- } else {
- // If we're not rendering seconds, sub-minute negative offsets
- // should get a positive sign (e.g., offset=-10s => "+00:00").
- if (hours == 0 && minutes == 0) sign = '+';
- }
- if (!ccc || minutes != 0 || seconds != 0) {
- ep = Format02d(ep, minutes);
- if (sep != '\0') *--ep = sep;
- }
- ep = Format02d(ep, hours);
- *--ep = sign;
- return ep;
-}
-
-// Formats a std::tm using strftime(3).
+const char kDigits[] = "0123456789";
+
+// Formats a 64-bit integer in the given field width. Note that it is up
+// to the caller of Format64() [and Format02d()/FormatOffset()] to ensure
+// that there is sufficient space before ep to hold the conversion.
+char* Format64(char* ep, int width, std::int_fast64_t v) {
+ bool neg = false;
+ if (v < 0) {
+ --width;
+ neg = true;
+ if (v == std::numeric_limits<std::int_fast64_t>::min()) {
+ // Avoid negating minimum value.
+ std::int_fast64_t last_digit = -(v % 10);
+ v /= 10;
+ if (last_digit < 0) {
+ ++v;
+ last_digit += 10;
+ }
+ --width;
+ *--ep = kDigits[last_digit];
+ }
+ v = -v;
+ }
+ do {
+ --width;
+ *--ep = kDigits[v % 10];
+ } while (v /= 10);
+ while (--width >= 0) *--ep = '0'; // zero pad
+ if (neg) *--ep = '-';
+ return ep;
+}
+
+// Formats [0 .. 99] as %02d.
+char* Format02d(char* ep, int v) {
+ *--ep = kDigits[v % 10];
+ *--ep = kDigits[(v / 10) % 10];
+ return ep;
+}
+
+// Formats a UTC offset, like +00:00.
+char* FormatOffset(char* ep, int offset, const char* mode) {
+ // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and
+ // generate a "negative zero" when we're formatting a zero offset
+ // as the result of a failed load_time_zone().
+ char sign = '+';
+ if (offset < 0) {
+ offset = -offset; // bounded by 24h so no overflow
+ sign = '-';
+ }
+ const int seconds = offset % 60;
+ const int minutes = (offset /= 60) % 60;
+ const int hours = offset /= 60;
+ const char sep = mode[0];
+ const bool ext = (sep != '\0' && mode[1] == '*');
+ const bool ccc = (ext && mode[2] == ':');
+ if (ext && (!ccc || seconds != 0)) {
+ ep = Format02d(ep, seconds);
+ *--ep = sep;
+ } else {
+ // If we're not rendering seconds, sub-minute negative offsets
+ // should get a positive sign (e.g., offset=-10s => "+00:00").
+ if (hours == 0 && minutes == 0) sign = '+';
+ }
+ if (!ccc || minutes != 0 || seconds != 0) {
+ ep = Format02d(ep, minutes);
+ if (sep != '\0') *--ep = sep;
+ }
+ ep = Format02d(ep, hours);
+ *--ep = sign;
+ return ep;
+}
+
+// Formats a std::tm using strftime(3).
void FormatTM(TString* out, const TString& fmt, const std::tm& tm) {
- // strftime(3) returns the number of characters placed in the output
- // array (which may be 0 characters). It also returns 0 to indicate
- // an error, like the array wasn't large enough. To accommodate this,
+ // strftime(3) returns the number of characters placed in the output
+ // array (which may be 0 characters). It also returns 0 to indicate
+ // an error, like the array wasn't large enough. To accommodate this,
// the following code grows the buffer size from 2x the format string
- // length up to 32x.
- for (std::size_t i = 2; i != 32; i *= 2) {
- std::size_t buf_size = fmt.size() * i;
- std::vector<char> buf(buf_size);
- if (std::size_t len = strftime(&buf[0], buf_size, fmt.c_str(), &tm)) {
- out->append(&buf[0], len);
- return;
- }
- }
-}
-
-// Used for %E#S/%E#f specifiers and for data values in parse().
-template <typename T>
-const char* ParseInt(const char* dp, int width, T min, T max, T* vp) {
- if (dp != nullptr) {
- const T kmin = std::numeric_limits<T>::min();
- bool erange = false;
- bool neg = false;
- T value = 0;
- if (*dp == '-') {
- neg = true;
- if (width <= 0 || --width != 0) {
- ++dp;
- } else {
- dp = nullptr; // width was 1
- }
- }
- if (const char* const bp = dp) {
- while (const char* cp = strchr(kDigits, *dp)) {
- int d = static_cast<int>(cp - kDigits);
- if (d >= 10) break;
- if (value < kmin / 10) {
- erange = true;
- break;
- }
- value *= 10;
- if (value < kmin + d) {
- erange = true;
- break;
- }
- value -= d;
- dp += 1;
- if (width > 0 && --width == 0) break;
- }
- if (dp != bp && !erange && (neg || value != kmin)) {
- if (!neg || value != 0) {
- if (!neg) value = -value; // make positive
- if (min <= value && value <= max) {
- *vp = value;
- } else {
- dp = nullptr;
- }
- } else {
- dp = nullptr;
- }
- } else {
- dp = nullptr;
- }
- }
- }
- return dp;
-}
-
-// The number of base-10 digits that can be represented by a signed 64-bit
-// integer. That is, 10^kDigits10_64 <= 2^63 - 1 < 10^(kDigits10_64 + 1).
-const int kDigits10_64 = 18;
-
-// 10^n for everything that can be represented by a signed 64-bit integer.
-const std::int_fast64_t kExp10[kDigits10_64 + 1] = {
- 1,
- 10,
- 100,
- 1000,
- 10000,
- 100000,
- 1000000,
- 10000000,
- 100000000,
- 1000000000,
- 10000000000,
- 100000000000,
- 1000000000000,
- 10000000000000,
- 100000000000000,
- 1000000000000000,
- 10000000000000000,
- 100000000000000000,
- 1000000000000000000,
-};
-
-} // namespace
-
-// Uses strftime(3) to format the given Time. The following extended format
-// specifiers are also supported:
-//
-// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
-// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
-// - %E#S - Seconds with # digits of fractional precision
-// - %E*S - Seconds with full fractional precision (a literal '*')
-// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+ // length up to 32x.
+ for (std::size_t i = 2; i != 32; i *= 2) {
+ std::size_t buf_size = fmt.size() * i;
+ std::vector<char> buf(buf_size);
+ if (std::size_t len = strftime(&buf[0], buf_size, fmt.c_str(), &tm)) {
+ out->append(&buf[0], len);
+ return;
+ }
+ }
+}
+
+// Used for %E#S/%E#f specifiers and for data values in parse().
+template <typename T>
+const char* ParseInt(const char* dp, int width, T min, T max, T* vp) {
+ if (dp != nullptr) {
+ const T kmin = std::numeric_limits<T>::min();
+ bool erange = false;
+ bool neg = false;
+ T value = 0;
+ if (*dp == '-') {
+ neg = true;
+ if (width <= 0 || --width != 0) {
+ ++dp;
+ } else {
+ dp = nullptr; // width was 1
+ }
+ }
+ if (const char* const bp = dp) {
+ while (const char* cp = strchr(kDigits, *dp)) {
+ int d = static_cast<int>(cp - kDigits);
+ if (d >= 10) break;
+ if (value < kmin / 10) {
+ erange = true;
+ break;
+ }
+ value *= 10;
+ if (value < kmin + d) {
+ erange = true;
+ break;
+ }
+ value -= d;
+ dp += 1;
+ if (width > 0 && --width == 0) break;
+ }
+ if (dp != bp && !erange && (neg || value != kmin)) {
+ if (!neg || value != 0) {
+ if (!neg) value = -value; // make positive
+ if (min <= value && value <= max) {
+ *vp = value;
+ } else {
+ dp = nullptr;
+ }
+ } else {
+ dp = nullptr;
+ }
+ } else {
+ dp = nullptr;
+ }
+ }
+ }
+ return dp;
+}
+
+// The number of base-10 digits that can be represented by a signed 64-bit
+// integer. That is, 10^kDigits10_64 <= 2^63 - 1 < 10^(kDigits10_64 + 1).
+const int kDigits10_64 = 18;
+
+// 10^n for everything that can be represented by a signed 64-bit integer.
+const std::int_fast64_t kExp10[kDigits10_64 + 1] = {
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+ 100000,
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+ 10000000000,
+ 100000000000,
+ 1000000000000,
+ 10000000000000,
+ 100000000000000,
+ 1000000000000000,
+ 10000000000000000,
+ 100000000000000000,
+ 1000000000000000000,
+};
+
+} // namespace
+
+// Uses strftime(3) to format the given Time. The following extended format
+// specifiers are also supported:
+//
+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
+// - %E#S - Seconds with # digits of fractional precision
+// - %E*S - Seconds with full fractional precision (a literal '*')
+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
// - %ET - The RFC3339 "date-time" separator "T"
-//
-// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
-// handled internally for performance reasons. strftime(3) is slow due to
-// a POSIX requirement to respect changes to ${TZ}.
-//
-// The TZ/GNU %s extension is handled internally because strftime() has
-// to use mktime() to generate it, and that assumes the local time zone.
-//
-// We also handle the %z and %Z specifiers to accommodate platforms that do
-// not support the tm_gmtoff and tm_zone extensions to std::tm.
-//
-// Requires that zero() <= fs < seconds(1).
+//
+// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
+// handled internally for performance reasons. strftime(3) is slow due to
+// a POSIX requirement to respect changes to ${TZ}.
+//
+// The TZ/GNU %s extension is handled internally because strftime() has
+// to use mktime() to generate it, and that assumes the local time zone.
+//
+// We also handle the %z and %Z specifiers to accommodate platforms that do
+// not support the tm_gmtoff and tm_zone extensions to std::tm.
+//
+// Requires that zero() <= fs < seconds(1).
TString format(const TString& format, const time_point<seconds>& tp,
- const detail::femtoseconds& fs, const time_zone& tz) {
+ const detail::femtoseconds& fs, const time_zone& tz) {
TString result;
- result.reserve(format.size()); // A reasonable guess for the result size.
- const time_zone::absolute_lookup al = tz.lookup(tp);
- const std::tm tm = ToTM(al);
-
- // Scratch buffer for internal conversions.
- char buf[3 + kDigits10_64]; // enough for longest conversion
- char* const ep = buf + sizeof(buf);
- char* bp; // works back from ep
-
- // Maintain three, disjoint subsequences that span format.
- // [format.begin() ... pending) : already formatted into result
- // [pending ... cur) : formatting pending, but no special cases
- // [cur ... format.end()) : unexamined
- // Initially, everything is in the unexamined part.
- const char* pending = format.c_str(); // NUL terminated
- const char* cur = pending;
- const char* end = pending + format.length();
-
- while (cur != end) { // while something is unexamined
- // Moves cur to the next percent sign.
- const char* start = cur;
- while (cur != end && *cur != '%') ++cur;
-
- // If the new pending text is all ordinary, copy it out.
- if (cur != start && pending == start) {
- result.append(pending, static_cast<std::size_t>(cur - pending));
- pending = start = cur;
- }
-
- // Span the sequential percent signs.
- const char* percent = cur;
- while (cur != end && *cur == '%') ++cur;
-
- // If the new pending text is all percents, copy out one
- // percent for every matched pair, then skip those pairs.
- if (cur != start && pending == start) {
- std::size_t escaped = static_cast<std::size_t>(cur - pending) / 2;
- result.append(pending, escaped);
- pending += escaped * 2;
- // Also copy out a single trailing percent.
- if (pending != cur && cur == end) {
- result.push_back(*pending++);
- }
- }
-
- // Loop unless we have an unescaped percent.
- if (cur == end || (cur - percent) % 2 == 0) continue;
-
- // Simple specifiers that we handle ourselves.
+ result.reserve(format.size()); // A reasonable guess for the result size.
+ const time_zone::absolute_lookup al = tz.lookup(tp);
+ const std::tm tm = ToTM(al);
+
+ // Scratch buffer for internal conversions.
+ char buf[3 + kDigits10_64]; // enough for longest conversion
+ char* const ep = buf + sizeof(buf);
+ char* bp; // works back from ep
+
+ // Maintain three, disjoint subsequences that span format.
+ // [format.begin() ... pending) : already formatted into result
+ // [pending ... cur) : formatting pending, but no special cases
+ // [cur ... format.end()) : unexamined
+ // Initially, everything is in the unexamined part.
+ const char* pending = format.c_str(); // NUL terminated
+ const char* cur = pending;
+ const char* end = pending + format.length();
+
+ while (cur != end) { // while something is unexamined
+ // Moves cur to the next percent sign.
+ const char* start = cur;
+ while (cur != end && *cur != '%') ++cur;
+
+ // If the new pending text is all ordinary, copy it out.
+ if (cur != start && pending == start) {
+ result.append(pending, static_cast<std::size_t>(cur - pending));
+ pending = start = cur;
+ }
+
+ // Span the sequential percent signs.
+ const char* percent = cur;
+ while (cur != end && *cur == '%') ++cur;
+
+ // If the new pending text is all percents, copy out one
+ // percent for every matched pair, then skip those pairs.
+ if (cur != start && pending == start) {
+ std::size_t escaped = static_cast<std::size_t>(cur - pending) / 2;
+ result.append(pending, escaped);
+ pending += escaped * 2;
+ // Also copy out a single trailing percent.
+ if (pending != cur && cur == end) {
+ result.push_back(*pending++);
+ }
+ }
+
+ // Loop unless we have an unescaped percent.
+ if (cur == end || (cur - percent) % 2 == 0) continue;
+
+ // Simple specifiers that we handle ourselves.
if (strchr("YmdeUuWwHMSzZs%", *cur)) {
- if (cur - 1 != pending) {
+ if (cur - 1 != pending) {
FormatTM(&result, TString(pending, cur - 1), tm);
- }
- switch (*cur) {
- case 'Y':
- // This avoids the tm.tm_year overflow problem for %Y, however
- // tm.tm_year will still be used by other specifiers like %D.
- bp = Format64(ep, 0, al.cs.year());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'm':
- bp = Format02d(ep, al.cs.month());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'd':
- case 'e':
- bp = Format02d(ep, al.cs.day());
- if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
+ }
+ switch (*cur) {
+ case 'Y':
+ // This avoids the tm.tm_year overflow problem for %Y, however
+ // tm.tm_year will still be used by other specifiers like %D.
+ bp = Format64(ep, 0, al.cs.year());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'm':
+ bp = Format02d(ep, al.cs.month());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'd':
+ case 'e':
+ bp = Format02d(ep, al.cs.day());
+ if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
case 'U':
bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday));
result.append(bp, static_cast<std::size_t>(ep - bp));
@@ -419,79 +419,79 @@ TString format(const TString& format, const time_point<seconds>& tp,
bp = Format64(ep, 0, tm.tm_wday);
result.append(bp, static_cast<std::size_t>(ep - bp));
break;
- case 'H':
- bp = Format02d(ep, al.cs.hour());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'M':
- bp = Format02d(ep, al.cs.minute());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'S':
- bp = Format02d(ep, al.cs.second());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'z':
- bp = FormatOffset(ep, al.offset, "");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case 'Z':
- result.append(al.abbr);
- break;
- case 's':
- bp = Format64(ep, 0, ToUnixSeconds(tp));
- result.append(bp, static_cast<std::size_t>(ep - bp));
- break;
- case '%':
- result.push_back('%');
- break;
- }
- pending = ++cur;
- continue;
- }
-
- // More complex specifiers that we handle ourselves.
- if (*cur == ':' && cur + 1 != end) {
- if (*(cur + 1) == 'z') {
- // Formats %:z.
- if (cur - 1 != pending) {
+ case 'H':
+ bp = Format02d(ep, al.cs.hour());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'M':
+ bp = Format02d(ep, al.cs.minute());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'S':
+ bp = Format02d(ep, al.cs.second());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'z':
+ bp = FormatOffset(ep, al.offset, "");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case 'Z':
+ result.append(al.abbr);
+ break;
+ case 's':
+ bp = Format64(ep, 0, ToUnixSeconds(tp));
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ break;
+ case '%':
+ result.push_back('%');
+ break;
+ }
+ pending = ++cur;
+ continue;
+ }
+
+ // More complex specifiers that we handle ourselves.
+ if (*cur == ':' && cur + 1 != end) {
+ if (*(cur + 1) == 'z') {
+ // Formats %:z.
+ if (cur - 1 != pending) {
FormatTM(&result, TString(pending, cur - 1), tm);
- }
- bp = FormatOffset(ep, al.offset, ":");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur += 2;
- continue;
- }
- if (*(cur + 1) == ':' && cur + 2 != end) {
- if (*(cur + 2) == 'z') {
- // Formats %::z.
- if (cur - 1 != pending) {
+ }
+ bp = FormatOffset(ep, al.offset, ":");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur += 2;
+ continue;
+ }
+ if (*(cur + 1) == ':' && cur + 2 != end) {
+ if (*(cur + 2) == 'z') {
+ // Formats %::z.
+ if (cur - 1 != pending) {
FormatTM(&result, TString(pending, cur - 1), tm);
- }
- bp = FormatOffset(ep, al.offset, ":*");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur += 3;
- continue;
- }
- if (*(cur + 2) == ':' && cur + 3 != end) {
- if (*(cur + 3) == 'z') {
- // Formats %:::z.
- if (cur - 1 != pending) {
+ }
+ bp = FormatOffset(ep, al.offset, ":*");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur += 3;
+ continue;
+ }
+ if (*(cur + 2) == ':' && cur + 3 != end) {
+ if (*(cur + 3) == 'z') {
+ // Formats %:::z.
+ if (cur - 1 != pending) {
FormatTM(&result, TString(pending, cur - 1), tm);
- }
- bp = FormatOffset(ep, al.offset, ":*:");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur += 4;
- continue;
- }
- }
- }
- }
-
- // Loop if there is no E modifier.
- if (*cur != 'E' || ++cur == end) continue;
-
- // Format our extensions.
+ }
+ bp = FormatOffset(ep, al.offset, ":*:");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur += 4;
+ continue;
+ }
+ }
+ }
+ }
+
+ // Loop if there is no E modifier.
+ if (*cur != 'E' || ++cur == end) continue;
+
+ // Format our extensions.
if (*cur == 'T') {
// Formats %ET.
if (cur - 2 != pending) {
@@ -500,159 +500,159 @@ TString format(const TString& format, const time_point<seconds>& tp,
result.append("T");
pending = ++cur;
} else if (*cur == 'z') {
- // Formats %Ez.
- if (cur - 2 != pending) {
+ // Formats %Ez.
+ if (cur - 2 != pending) {
FormatTM(&result, TString(pending, cur - 2), tm);
- }
- bp = FormatOffset(ep, al.offset, ":");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = ++cur;
- } else if (*cur == '*' && cur + 1 != end && *(cur + 1) == 'z') {
- // Formats %E*z.
- if (cur - 2 != pending) {
+ }
+ bp = FormatOffset(ep, al.offset, ":");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = ++cur;
+ } else if (*cur == '*' && cur + 1 != end && *(cur + 1) == 'z') {
+ // Formats %E*z.
+ if (cur - 2 != pending) {
FormatTM(&result, TString(pending, cur - 2), tm);
- }
- bp = FormatOffset(ep, al.offset, ":*");
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur += 2;
- } else if (*cur == '*' && cur + 1 != end &&
- (*(cur + 1) == 'S' || *(cur + 1) == 'f')) {
- // Formats %E*S or %E*F.
- if (cur - 2 != pending) {
+ }
+ bp = FormatOffset(ep, al.offset, ":*");
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur += 2;
+ } else if (*cur == '*' && cur + 1 != end &&
+ (*(cur + 1) == 'S' || *(cur + 1) == 'f')) {
+ // Formats %E*S or %E*F.
+ if (cur - 2 != pending) {
FormatTM(&result, TString(pending, cur - 2), tm);
- }
- char* cp = ep;
- bp = Format64(cp, 15, fs.count());
- while (cp != bp && cp[-1] == '0') --cp;
- switch (*(cur + 1)) {
- case 'S':
- if (cp != bp) *--bp = '.';
- bp = Format02d(bp, al.cs.second());
- break;
- case 'f':
- if (cp == bp) *--bp = '0';
- break;
- }
- result.append(bp, static_cast<std::size_t>(cp - bp));
- pending = cur += 2;
- } else if (*cur == '4' && cur + 1 != end && *(cur + 1) == 'Y') {
- // Formats %E4Y.
- if (cur - 2 != pending) {
+ }
+ char* cp = ep;
+ bp = Format64(cp, 15, fs.count());
+ while (cp != bp && cp[-1] == '0') --cp;
+ switch (*(cur + 1)) {
+ case 'S':
+ if (cp != bp) *--bp = '.';
+ bp = Format02d(bp, al.cs.second());
+ break;
+ case 'f':
+ if (cp == bp) *--bp = '0';
+ break;
+ }
+ result.append(bp, static_cast<std::size_t>(cp - bp));
+ pending = cur += 2;
+ } else if (*cur == '4' && cur + 1 != end && *(cur + 1) == 'Y') {
+ // Formats %E4Y.
+ if (cur - 2 != pending) {
FormatTM(&result, TString(pending, cur - 2), tm);
- }
- bp = Format64(ep, 4, al.cs.year());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur += 2;
- } else if (std::isdigit(*cur)) {
- // Possibly found %E#S or %E#f.
- int n = 0;
- if (const char* np = ParseInt(cur, 0, 0, 1024, &n)) {
- if (*np == 'S' || *np == 'f') {
- // Formats %E#S or %E#f.
- if (cur - 2 != pending) {
+ }
+ bp = Format64(ep, 4, al.cs.year());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur += 2;
+ } else if (std::isdigit(*cur)) {
+ // Possibly found %E#S or %E#f.
+ int n = 0;
+ if (const char* np = ParseInt(cur, 0, 0, 1024, &n)) {
+ if (*np == 'S' || *np == 'f') {
+ // Formats %E#S or %E#f.
+ if (cur - 2 != pending) {
FormatTM(&result, TString(pending, cur - 2), tm);
- }
- bp = ep;
- if (n > 0) {
- if (n > kDigits10_64) n = kDigits10_64;
+ }
+ bp = ep;
+ if (n > 0) {
+ if (n > kDigits10_64) n = kDigits10_64;
bp = Format64(bp, n,
(n > 15) ? fs.count() * kExp10[n - 15]
: fs.count() / kExp10[15 - n]);
- if (*np == 'S') *--bp = '.';
- }
- if (*np == 'S') bp = Format02d(bp, al.cs.second());
- result.append(bp, static_cast<std::size_t>(ep - bp));
- pending = cur = ++np;
- }
- }
- }
- }
-
- // Formats any remaining data.
- if (end != pending) {
+ if (*np == 'S') *--bp = '.';
+ }
+ if (*np == 'S') bp = Format02d(bp, al.cs.second());
+ result.append(bp, static_cast<std::size_t>(ep - bp));
+ pending = cur = ++np;
+ }
+ }
+ }
+ }
+
+ // Formats any remaining data.
+ if (end != pending) {
FormatTM(&result, TString(pending, end), tm);
- }
-
- return result;
-}
-
-namespace {
-
-const char* ParseOffset(const char* dp, const char* mode, int* offset) {
- if (dp != nullptr) {
- const char first = *dp++;
- if (first == '+' || first == '-') {
- char sep = mode[0];
- int hours = 0;
- int minutes = 0;
- int seconds = 0;
- const char* ap = ParseInt(dp, 2, 0, 23, &hours);
- if (ap != nullptr && ap - dp == 2) {
- dp = ap;
- if (sep != '\0' && *ap == sep) ++ap;
- const char* bp = ParseInt(ap, 2, 0, 59, &minutes);
- if (bp != nullptr && bp - ap == 2) {
- dp = bp;
- if (sep != '\0' && *bp == sep) ++bp;
- const char* cp = ParseInt(bp, 2, 0, 59, &seconds);
- if (cp != nullptr && cp - bp == 2) dp = cp;
- }
- *offset = ((hours * 60 + minutes) * 60) + seconds;
- if (first == '-') *offset = -*offset;
- } else {
- dp = nullptr;
- }
+ }
+
+ return result;
+}
+
+namespace {
+
+const char* ParseOffset(const char* dp, const char* mode, int* offset) {
+ if (dp != nullptr) {
+ const char first = *dp++;
+ if (first == '+' || first == '-') {
+ char sep = mode[0];
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
+ const char* ap = ParseInt(dp, 2, 0, 23, &hours);
+ if (ap != nullptr && ap - dp == 2) {
+ dp = ap;
+ if (sep != '\0' && *ap == sep) ++ap;
+ const char* bp = ParseInt(ap, 2, 0, 59, &minutes);
+ if (bp != nullptr && bp - ap == 2) {
+ dp = bp;
+ if (sep != '\0' && *bp == sep) ++bp;
+ const char* cp = ParseInt(bp, 2, 0, 59, &seconds);
+ if (cp != nullptr && cp - bp == 2) dp = cp;
+ }
+ *offset = ((hours * 60 + minutes) * 60) + seconds;
+ if (first == '-') *offset = -*offset;
+ } else {
+ dp = nullptr;
+ }
} else if (first == 'Z' || first == 'z') { // Zulu
- *offset = 0;
- } else {
- dp = nullptr;
- }
- }
- return dp;
-}
-
+ *offset = 0;
+ } else {
+ dp = nullptr;
+ }
+ }
+ return dp;
+}
+
const char* ParseZone(const char* dp, TString* zone) {
- zone->clear();
- if (dp != nullptr) {
- while (*dp != '\0' && !std::isspace(*dp)) zone->push_back(*dp++);
- if (zone->empty()) dp = nullptr;
- }
- return dp;
-}
-
-const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) {
- if (dp != nullptr) {
- std::int_fast64_t v = 0;
- std::int_fast64_t exp = 0;
- const char* const bp = dp;
- while (const char* cp = strchr(kDigits, *dp)) {
- int d = static_cast<int>(cp - kDigits);
- if (d >= 10) break;
- if (exp < 15) {
- exp += 1;
- v *= 10;
- v += d;
- }
- ++dp;
- }
- if (dp != bp) {
- v *= kExp10[15 - exp];
- *subseconds = detail::femtoseconds(v);
- } else {
- dp = nullptr;
- }
- }
- return dp;
-}
-
-// Parses a string into a std::tm using strptime(3).
-const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
- if (dp != nullptr) {
- dp = strptime(dp, fmt, tm);
- }
- return dp;
-}
-
+ zone->clear();
+ if (dp != nullptr) {
+ while (*dp != '\0' && !std::isspace(*dp)) zone->push_back(*dp++);
+ if (zone->empty()) dp = nullptr;
+ }
+ return dp;
+}
+
+const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) {
+ if (dp != nullptr) {
+ std::int_fast64_t v = 0;
+ std::int_fast64_t exp = 0;
+ const char* const bp = dp;
+ while (const char* cp = strchr(kDigits, *dp)) {
+ int d = static_cast<int>(cp - kDigits);
+ if (d >= 10) break;
+ if (exp < 15) {
+ exp += 1;
+ v *= 10;
+ v += d;
+ }
+ ++dp;
+ }
+ if (dp != bp) {
+ v *= kExp10[15 - exp];
+ *subseconds = detail::femtoseconds(v);
+ } else {
+ dp = nullptr;
+ }
+ }
+ return dp;
+}
+
+// Parses a string into a std::tm using strptime(3).
+const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
+ if (dp != nullptr) {
+ dp = strptime(dp, fmt, tm);
+ }
+ return dp;
+}
+
// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday,
// and the day on which weeks are defined to start. Returns false if year
// would need to move outside its bounds.
@@ -673,102 +673,102 @@ bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) {
return true;
}
-} // namespace
-
-// Uses strptime(3) to parse the given input. Supports the same extended
-// format specifiers as format(), although %E#S and %E*S are treated
-// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept
+} // namespace
+
+// Uses strptime(3) to parse the given input. Supports the same extended
+// format specifiers as format(), although %E#S and %E*S are treated
+// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept
// the same inputs. %ET accepts either 'T' or 't'.
-//
-// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
-// handled internally so that we can normally avoid strptime() altogether
-// (which is particularly helpful when the native implementation is broken).
-//
-// The TZ/GNU %s extension is handled internally because strptime() has to
-// use localtime_r() to generate it, and that assumes the local time zone.
-//
-// We also handle the %z specifier to accommodate platforms that do not
-// support the tm_gmtoff extension to std::tm. %Z is parsed but ignored.
+//
+// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
+// handled internally so that we can normally avoid strptime() altogether
+// (which is particularly helpful when the native implementation is broken).
+//
+// The TZ/GNU %s extension is handled internally because strptime() has to
+// use localtime_r() to generate it, and that assumes the local time zone.
+//
+// We also handle the %z specifier to accommodate platforms that do not
+// support the tm_gmtoff extension to std::tm. %Z is parsed but ignored.
bool parse(const TString& format, const TString& input,
- const time_zone& tz, time_point<seconds>* sec,
+ const time_zone& tz, time_point<seconds>* sec,
detail::femtoseconds* fs, TString* err) {
- // The unparsed input.
- const char* data = input.c_str(); // NUL terminated
-
- // Skips leading whitespace.
- while (std::isspace(*data)) ++data;
-
- const year_t kyearmax = std::numeric_limits<year_t>::max();
- const year_t kyearmin = std::numeric_limits<year_t>::min();
-
- // Sets default values for unspecified fields.
- bool saw_year = false;
- year_t year = 1970;
- std::tm tm{};
- tm.tm_year = 1970 - 1900;
- tm.tm_mon = 1 - 1; // Jan
- tm.tm_mday = 1;
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- tm.tm_wday = 4; // Thu
- tm.tm_yday = 0;
- tm.tm_isdst = 0;
- auto subseconds = detail::femtoseconds::zero();
- bool saw_offset = false;
- int offset = 0; // No offset from passed tz.
+ // The unparsed input.
+ const char* data = input.c_str(); // NUL terminated
+
+ // Skips leading whitespace.
+ while (std::isspace(*data)) ++data;
+
+ const year_t kyearmax = std::numeric_limits<year_t>::max();
+ const year_t kyearmin = std::numeric_limits<year_t>::min();
+
+ // Sets default values for unspecified fields.
+ bool saw_year = false;
+ year_t year = 1970;
+ std::tm tm{};
+ tm.tm_year = 1970 - 1900;
+ tm.tm_mon = 1 - 1; // Jan
+ tm.tm_mday = 1;
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ tm.tm_wday = 4; // Thu
+ tm.tm_yday = 0;
+ tm.tm_isdst = 0;
+ auto subseconds = detail::femtoseconds::zero();
+ bool saw_offset = false;
+ int offset = 0; // No offset from passed tz.
TString zone = "UTC";
-
- const char* fmt = format.c_str(); // NUL terminated
- bool twelve_hour = false;
- bool afternoon = false;
+
+ const char* fmt = format.c_str(); // NUL terminated
+ bool twelve_hour = false;
+ bool afternoon = false;
int week_num = -1;
weekday week_start = weekday::sunday;
-
- bool saw_percent_s = false;
- std::int_fast64_t percent_s = 0;
-
- // Steps through format, one specifier at a time.
- while (data != nullptr && *fmt != '\0') {
- if (std::isspace(*fmt)) {
- while (std::isspace(*data)) ++data;
- while (std::isspace(*++fmt)) continue;
- continue;
- }
-
- if (*fmt != '%') {
- if (*data == *fmt) {
- ++data;
- ++fmt;
- } else {
- data = nullptr;
- }
- continue;
- }
-
- const char* percent = fmt;
- if (*++fmt == '\0') {
- data = nullptr;
- continue;
- }
- switch (*fmt++) {
- case 'Y':
- // Symmetrically with FormatTime(), directly handing %Y avoids the
- // tm.tm_year overflow problem. However, tm.tm_year will still be
- // used by other specifiers like %D.
- data = ParseInt(data, 0, kyearmin, kyearmax, &year);
- if (data != nullptr) saw_year = true;
- continue;
- case 'm':
- data = ParseInt(data, 2, 1, 12, &tm.tm_mon);
- if (data != nullptr) tm.tm_mon -= 1;
+
+ bool saw_percent_s = false;
+ std::int_fast64_t percent_s = 0;
+
+ // Steps through format, one specifier at a time.
+ while (data != nullptr && *fmt != '\0') {
+ if (std::isspace(*fmt)) {
+ while (std::isspace(*data)) ++data;
+ while (std::isspace(*++fmt)) continue;
+ continue;
+ }
+
+ if (*fmt != '%') {
+ if (*data == *fmt) {
+ ++data;
+ ++fmt;
+ } else {
+ data = nullptr;
+ }
+ continue;
+ }
+
+ const char* percent = fmt;
+ if (*++fmt == '\0') {
+ data = nullptr;
+ continue;
+ }
+ switch (*fmt++) {
+ case 'Y':
+ // Symmetrically with FormatTime(), directly handing %Y avoids the
+ // tm.tm_year overflow problem. However, tm.tm_year will still be
+ // used by other specifiers like %D.
+ data = ParseInt(data, 0, kyearmin, kyearmax, &year);
+ if (data != nullptr) saw_year = true;
+ continue;
+ case 'm':
+ data = ParseInt(data, 2, 1, 12, &tm.tm_mon);
+ if (data != nullptr) tm.tm_mon -= 1;
week_num = -1;
- continue;
- case 'd':
- case 'e':
- data = ParseInt(data, 2, 1, 31, &tm.tm_mday);
+ continue;
+ case 'd':
+ case 'e':
+ data = ParseInt(data, 2, 1, 31, &tm.tm_mday);
week_num = -1;
- continue;
+ continue;
case 'U':
data = ParseInt(data, 0, 0, 53, &week_num);
week_start = weekday::sunday;
@@ -784,54 +784,54 @@ bool parse(const TString& format, const TString& input,
case 'w':
data = ParseInt(data, 0, 0, 6, &tm.tm_wday);
continue;
- case 'H':
- data = ParseInt(data, 2, 0, 23, &tm.tm_hour);
- twelve_hour = false;
- continue;
- case 'M':
- data = ParseInt(data, 2, 0, 59, &tm.tm_min);
- continue;
- case 'S':
- data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
- continue;
- case 'I':
- case 'l':
- case 'r': // probably uses %I
- twelve_hour = true;
- break;
- case 'R': // uses %H
- case 'T': // uses %H
- case 'c': // probably uses %H
- case 'X': // probably uses %H
- twelve_hour = false;
- break;
- case 'z':
- data = ParseOffset(data, "", &offset);
- if (data != nullptr) saw_offset = true;
- continue;
- case 'Z': // ignored; zone abbreviations are ambiguous
- data = ParseZone(data, &zone);
- continue;
- case 's':
+ case 'H':
+ data = ParseInt(data, 2, 0, 23, &tm.tm_hour);
+ twelve_hour = false;
+ continue;
+ case 'M':
+ data = ParseInt(data, 2, 0, 59, &tm.tm_min);
+ continue;
+ case 'S':
+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
+ continue;
+ case 'I':
+ case 'l':
+ case 'r': // probably uses %I
+ twelve_hour = true;
+ break;
+ case 'R': // uses %H
+ case 'T': // uses %H
+ case 'c': // probably uses %H
+ case 'X': // probably uses %H
+ twelve_hour = false;
+ break;
+ case 'z':
+ data = ParseOffset(data, "", &offset);
+ if (data != nullptr) saw_offset = true;
+ continue;
+ case 'Z': // ignored; zone abbreviations are ambiguous
+ data = ParseZone(data, &zone);
+ continue;
+ case 's':
data =
ParseInt(data, 0, std::numeric_limits<std::int_fast64_t>::min(),
std::numeric_limits<std::int_fast64_t>::max(), &percent_s);
- if (data != nullptr) saw_percent_s = true;
- continue;
- case ':':
- if (fmt[0] == 'z' ||
- (fmt[0] == ':' &&
- (fmt[1] == 'z' || (fmt[1] == ':' && fmt[2] == 'z')))) {
- data = ParseOffset(data, ":", &offset);
- if (data != nullptr) saw_offset = true;
- fmt += (fmt[0] == 'z') ? 1 : (fmt[1] == 'z') ? 2 : 3;
- continue;
- }
- break;
- case '%':
- data = (*data == '%' ? data + 1 : nullptr);
- continue;
- case 'E':
+ if (data != nullptr) saw_percent_s = true;
+ continue;
+ case ':':
+ if (fmt[0] == 'z' ||
+ (fmt[0] == ':' &&
+ (fmt[1] == 'z' || (fmt[1] == ':' && fmt[2] == 'z')))) {
+ data = ParseOffset(data, ":", &offset);
+ if (data != nullptr) saw_offset = true;
+ fmt += (fmt[0] == 'z') ? 1 : (fmt[1] == 'z') ? 2 : 3;
+ continue;
+ }
+ break;
+ case '%':
+ data = (*data == '%' ? data + 1 : nullptr);
+ continue;
+ case 'E':
if (fmt[0] == 'T') {
if (*data == 'T' || *data == 't') {
++data;
@@ -841,138 +841,138 @@ bool parse(const TString& format, const TString& input,
}
continue;
}
- if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) {
- data = ParseOffset(data, ":", &offset);
- if (data != nullptr) saw_offset = true;
- fmt += (fmt[0] == 'z') ? 1 : 2;
- continue;
- }
- if (fmt[0] == '*' && fmt[1] == 'S') {
- data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
- if (data != nullptr && *data == '.') {
- data = ParseSubSeconds(data + 1, &subseconds);
- }
- fmt += 2;
- continue;
- }
- if (fmt[0] == '*' && fmt[1] == 'f') {
- if (data != nullptr && std::isdigit(*data)) {
- data = ParseSubSeconds(data, &subseconds);
- }
- fmt += 2;
- continue;
- }
- if (fmt[0] == '4' && fmt[1] == 'Y') {
- const char* bp = data;
- data = ParseInt(data, 4, year_t{-999}, year_t{9999}, &year);
- if (data != nullptr) {
- if (data - bp == 4) {
- saw_year = true;
- } else {
- data = nullptr; // stopped too soon
- }
- }
- fmt += 2;
- continue;
- }
- if (std::isdigit(*fmt)) {
- int n = 0; // value ignored
- if (const char* np = ParseInt(fmt, 0, 0, 1024, &n)) {
- if (*np == 'S') {
- data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
- if (data != nullptr && *data == '.') {
- data = ParseSubSeconds(data + 1, &subseconds);
- }
- fmt = ++np;
- continue;
- }
- if (*np == 'f') {
- if (data != nullptr && std::isdigit(*data)) {
- data = ParseSubSeconds(data, &subseconds);
- }
- fmt = ++np;
- continue;
- }
- }
- }
- if (*fmt == 'c') twelve_hour = false; // probably uses %H
- if (*fmt == 'X') twelve_hour = false; // probably uses %H
- if (*fmt != '\0') ++fmt;
- break;
- case 'O':
- if (*fmt == 'H') twelve_hour = false;
- if (*fmt == 'I') twelve_hour = true;
- if (*fmt != '\0') ++fmt;
- break;
- }
-
- // Parses the current specifier.
- const char* orig_data = data;
+ if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) {
+ data = ParseOffset(data, ":", &offset);
+ if (data != nullptr) saw_offset = true;
+ fmt += (fmt[0] == 'z') ? 1 : 2;
+ continue;
+ }
+ if (fmt[0] == '*' && fmt[1] == 'S') {
+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
+ if (data != nullptr && *data == '.') {
+ data = ParseSubSeconds(data + 1, &subseconds);
+ }
+ fmt += 2;
+ continue;
+ }
+ if (fmt[0] == '*' && fmt[1] == 'f') {
+ if (data != nullptr && std::isdigit(*data)) {
+ data = ParseSubSeconds(data, &subseconds);
+ }
+ fmt += 2;
+ continue;
+ }
+ if (fmt[0] == '4' && fmt[1] == 'Y') {
+ const char* bp = data;
+ data = ParseInt(data, 4, year_t{-999}, year_t{9999}, &year);
+ if (data != nullptr) {
+ if (data - bp == 4) {
+ saw_year = true;
+ } else {
+ data = nullptr; // stopped too soon
+ }
+ }
+ fmt += 2;
+ continue;
+ }
+ if (std::isdigit(*fmt)) {
+ int n = 0; // value ignored
+ if (const char* np = ParseInt(fmt, 0, 0, 1024, &n)) {
+ if (*np == 'S') {
+ data = ParseInt(data, 2, 0, 60, &tm.tm_sec);
+ if (data != nullptr && *data == '.') {
+ data = ParseSubSeconds(data + 1, &subseconds);
+ }
+ fmt = ++np;
+ continue;
+ }
+ if (*np == 'f') {
+ if (data != nullptr && std::isdigit(*data)) {
+ data = ParseSubSeconds(data, &subseconds);
+ }
+ fmt = ++np;
+ continue;
+ }
+ }
+ }
+ if (*fmt == 'c') twelve_hour = false; // probably uses %H
+ if (*fmt == 'X') twelve_hour = false; // probably uses %H
+ if (*fmt != '\0') ++fmt;
+ break;
+ case 'O':
+ if (*fmt == 'H') twelve_hour = false;
+ if (*fmt == 'I') twelve_hour = true;
+ if (*fmt != '\0') ++fmt;
+ break;
+ }
+
+ // Parses the current specifier.
+ const char* orig_data = data;
TString spec(percent, static_cast<std::size_t>(fmt - percent));
- data = ParseTM(data, spec.c_str(), &tm);
-
- // If we successfully parsed %p we need to remember whether the result
- // was AM or PM so that we can adjust tm_hour before time_zone::lookup().
- // So reparse the input with a known AM hour, and check if it is shifted
- // to a PM hour.
- if (spec == "%p" && data != nullptr) {
+ data = ParseTM(data, spec.c_str(), &tm);
+
+ // If we successfully parsed %p we need to remember whether the result
+ // was AM or PM so that we can adjust tm_hour before time_zone::lookup().
+ // So reparse the input with a known AM hour, and check if it is shifted
+ // to a PM hour.
+ if (spec == "%p" && data != nullptr) {
TString test_input = "1";
- test_input.append(orig_data, static_cast<std::size_t>(data - orig_data));
- const char* test_data = test_input.c_str();
- std::tm tmp{};
- ParseTM(test_data, "%I%p", &tmp);
- afternoon = (tmp.tm_hour == 13);
- }
- }
-
- // Adjust a 12-hour tm_hour value if it should be in the afternoon.
- if (twelve_hour && afternoon && tm.tm_hour < 12) {
- tm.tm_hour += 12;
- }
-
- if (data == nullptr) {
- if (err != nullptr) *err = "Failed to parse input";
- return false;
- }
-
- // Skip any remaining whitespace.
- while (std::isspace(*data)) ++data;
-
+ test_input.append(orig_data, static_cast<std::size_t>(data - orig_data));
+ const char* test_data = test_input.c_str();
+ std::tm tmp{};
+ ParseTM(test_data, "%I%p", &tmp);
+ afternoon = (tmp.tm_hour == 13);
+ }
+ }
+
+ // Adjust a 12-hour tm_hour value if it should be in the afternoon.
+ if (twelve_hour && afternoon && tm.tm_hour < 12) {
+ tm.tm_hour += 12;
+ }
+
+ if (data == nullptr) {
+ if (err != nullptr) *err = "Failed to parse input";
+ return false;
+ }
+
+ // Skip any remaining whitespace.
+ while (std::isspace(*data)) ++data;
+
// parse() must consume the entire input string.
- if (*data != '\0') {
- if (err != nullptr) *err = "Illegal trailing data in input string";
- return false;
- }
-
- // If we saw %s then we ignore anything else and return that time.
- if (saw_percent_s) {
- *sec = FromUnixSeconds(percent_s);
- *fs = detail::femtoseconds::zero();
- return true;
- }
-
- // If we saw %z, %Ez, or %E*z then we want to interpret the parsed fields
- // in UTC and then shift by that offset. Otherwise we want to interpret
- // the fields directly in the passed time_zone.
- time_zone ptz = saw_offset ? utc_time_zone() : tz;
-
- // Allows a leap second of 60 to normalize forward to the following ":00".
- if (tm.tm_sec == 60) {
- tm.tm_sec -= 1;
- offset -= 1;
- subseconds = detail::femtoseconds::zero();
- }
-
- if (!saw_year) {
- year = year_t{tm.tm_year};
- if (year > kyearmax - 1900) {
- // Platform-dependent, maybe unreachable.
- if (err != nullptr) *err = "Out-of-range year";
- return false;
- }
- year += 1900;
- }
-
+ if (*data != '\0') {
+ if (err != nullptr) *err = "Illegal trailing data in input string";
+ return false;
+ }
+
+ // If we saw %s then we ignore anything else and return that time.
+ if (saw_percent_s) {
+ *sec = FromUnixSeconds(percent_s);
+ *fs = detail::femtoseconds::zero();
+ return true;
+ }
+
+ // If we saw %z, %Ez, or %E*z then we want to interpret the parsed fields
+ // in UTC and then shift by that offset. Otherwise we want to interpret
+ // the fields directly in the passed time_zone.
+ time_zone ptz = saw_offset ? utc_time_zone() : tz;
+
+ // Allows a leap second of 60 to normalize forward to the following ":00".
+ if (tm.tm_sec == 60) {
+ tm.tm_sec -= 1;
+ offset -= 1;
+ subseconds = detail::femtoseconds::zero();
+ }
+
+ if (!saw_year) {
+ year = year_t{tm.tm_year};
+ if (year > kyearmax - 1900) {
+ // Platform-dependent, maybe unreachable.
+ if (err != nullptr) *err = "Out-of-range year";
+ return false;
+ }
+ year += 1900;
+ }
+
// Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number.
if (week_num != -1) {
if (!FromWeek(week_num, week_start, &year, &tm)) {
@@ -981,49 +981,49 @@ bool parse(const TString& format, const TString& input,
}
}
- const int month = tm.tm_mon + 1;
- civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
-
- // parse() should not allow normalization. Due to the restricted field
- // ranges above (see ParseInt()), the only possibility is for days to roll
- // into months. That is, parsing "Sep 31" should not produce "Oct 1".
- if (cs.month() != month || cs.day() != tm.tm_mday) {
- if (err != nullptr) *err = "Out-of-range field";
- return false;
- }
-
- // Accounts for the offset adjustment before converting to absolute time.
- if ((offset < 0 && cs > civil_second::max() + offset) ||
- (offset > 0 && cs < civil_second::min() + offset)) {
- if (err != nullptr) *err = "Out-of-range field";
- return false;
- }
- cs -= offset;
-
- const auto tp = ptz.lookup(cs).pre;
- // Checks for overflow/underflow and returns an error as necessary.
- if (tp == time_point<seconds>::max()) {
- const auto al = ptz.lookup(time_point<seconds>::max());
- if (cs > al.cs) {
- if (err != nullptr) *err = "Out-of-range field";
- return false;
- }
- }
- if (tp == time_point<seconds>::min()) {
- const auto al = ptz.lookup(time_point<seconds>::min());
- if (cs < al.cs) {
- if (err != nullptr) *err = "Out-of-range field";
- return false;
- }
- }
-
- *sec = tp;
- *fs = subseconds;
- return true;
-}
-
-} // namespace detail
-} // namespace cctz
-} // namespace time_internal
+ const int month = tm.tm_mon + 1;
+ civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ // parse() should not allow normalization. Due to the restricted field
+ // ranges above (see ParseInt()), the only possibility is for days to roll
+ // into months. That is, parsing "Sep 31" should not produce "Oct 1".
+ if (cs.month() != month || cs.day() != tm.tm_mday) {
+ if (err != nullptr) *err = "Out-of-range field";
+ return false;
+ }
+
+ // Accounts for the offset adjustment before converting to absolute time.
+ if ((offset < 0 && cs > civil_second::max() + offset) ||
+ (offset > 0 && cs < civil_second::min() + offset)) {
+ if (err != nullptr) *err = "Out-of-range field";
+ return false;
+ }
+ cs -= offset;
+
+ const auto tp = ptz.lookup(cs).pre;
+ // Checks for overflow/underflow and returns an error as necessary.
+ if (tp == time_point<seconds>::max()) {
+ const auto al = ptz.lookup(time_point<seconds>::max());
+ if (cs > al.cs) {
+ if (err != nullptr) *err = "Out-of-range field";
+ return false;
+ }
+ }
+ if (tp == time_point<seconds>::min()) {
+ const auto al = ptz.lookup(time_point<seconds>::min());
+ if (cs < al.cs) {
+ if (err != nullptr) *err = "Out-of-range field";
+ return false;
+ }
+ }
+
+ *sec = tp;
+ *fs = subseconds;
+ return true;
+}
+
+} // namespace detail
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.cc
index c4df17f050..2fe6d23c71 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.cc
@@ -1,45 +1,45 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "time_zone_if.h"
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "time_zone_if.h"
#include "y_absl/base/config.h"
-#include "time_zone_info.h"
-#include "time_zone_libc.h"
-
+#include "time_zone_info.h"
+#include "time_zone_libc.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
+namespace time_internal {
+namespace cctz {
+
std::unique_ptr<TimeZoneIf> TimeZoneIf::Load(const TString& name) {
- // Support "libc:localtime" and "libc:*" to access the legacy
- // localtime and UTC support respectively from the C library.
- if (name.compare(0, 5, "libc:") == 0) {
- return std::unique_ptr<TimeZoneIf>(new TimeZoneLibC(name.substr(5)));
- }
-
- // Otherwise use the "zoneinfo" implementation by default.
- std::unique_ptr<TimeZoneInfo> tz(new TimeZoneInfo);
- if (!tz->Load(name)) tz.reset();
- return std::unique_ptr<TimeZoneIf>(tz.release());
-}
-
-// Defined out-of-line to avoid emitting a weak vtable in all TUs.
-TimeZoneIf::~TimeZoneIf() {}
-
-} // namespace cctz
-} // namespace time_internal
+ // Support "libc:localtime" and "libc:*" to access the legacy
+ // localtime and UTC support respectively from the C library.
+ if (name.compare(0, 5, "libc:") == 0) {
+ return std::unique_ptr<TimeZoneIf>(new TimeZoneLibC(name.substr(5)));
+ }
+
+ // Otherwise use the "zoneinfo" implementation by default.
+ std::unique_ptr<TimeZoneInfo> tz(new TimeZoneInfo);
+ if (!tz->Load(name)) tz.reset();
+ return std::unique_ptr<TimeZoneIf>(tz.release());
+}
+
+// Defined out-of-line to avoid emitting a weak vtable in all TUs.
+TimeZoneIf::~TimeZoneIf() {}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h
index 639891e772..10312badc2 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h
@@ -1,77 +1,77 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
-
-#include <chrono>
-#include <cstdint>
-#include <memory>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
+
+#include <chrono>
+#include <cstdint>
+#include <memory>
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// A simple interface used to hide time-zone complexities from time_zone::Impl.
-// Subclasses implement the functions for civil-time conversions in the zone.
-class TimeZoneIf {
- public:
- // A factory function for TimeZoneIf implementations.
+namespace time_internal {
+namespace cctz {
+
+// A simple interface used to hide time-zone complexities from time_zone::Impl.
+// Subclasses implement the functions for civil-time conversions in the zone.
+class TimeZoneIf {
+ public:
+ // A factory function for TimeZoneIf implementations.
static std::unique_ptr<TimeZoneIf> Load(const TString& name);
-
- virtual ~TimeZoneIf();
-
- virtual time_zone::absolute_lookup BreakTime(
- const time_point<seconds>& tp) const = 0;
+
+ virtual ~TimeZoneIf();
+
+ virtual time_zone::absolute_lookup BreakTime(
+ const time_point<seconds>& tp) const = 0;
virtual time_zone::civil_lookup MakeTime(const civil_second& cs) const = 0;
-
- virtual bool NextTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const = 0;
- virtual bool PrevTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const = 0;
-
+
+ virtual bool NextTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const = 0;
+ virtual bool PrevTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const = 0;
+
virtual TString Version() const = 0;
virtual TString Description() const = 0;
-
- protected:
- TimeZoneIf() {}
-};
-
-// Convert between time_point<seconds> and a count of seconds since the
-// Unix epoch. We assume that the std::chrono::system_clock and the
+
+ protected:
+ TimeZoneIf() {}
+};
+
+// Convert between time_point<seconds> and a count of seconds since the
+// Unix epoch. We assume that the std::chrono::system_clock and the
// Unix clock are second aligned, and that the results are representable.
// (That is, that they share an epoch, which is required since C++20.)
-inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) {
- return (tp - std::chrono::time_point_cast<seconds>(
+inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) {
+ return (tp - std::chrono::time_point_cast<seconds>(
std::chrono::system_clock::from_time_t(0)))
.count();
-}
-inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) {
- return std::chrono::time_point_cast<seconds>(
+}
+inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) {
+ return std::chrono::time_point_cast<seconds>(
std::chrono::system_clock::from_time_t(0)) +
seconds(t);
-}
-
-} // namespace cctz
-} // namespace time_internal
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.cc
index 02a1e1a17e..3810defe3c 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.cc
@@ -1,113 +1,113 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "time_zone_impl.h"
-
-#include <deque>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "time_zone_impl.h"
+
+#include <deque>
#include <memory>
-#include <mutex>
+#include <mutex>
#include <util/generic/string.h>
-#include <unordered_map>
-#include <utility>
-
+#include <unordered_map>
+#include <utility>
+
#include "y_absl/base/config.h"
-#include "time_zone_fixed.h"
-
+#include "time_zone_fixed.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-namespace {
-
-// time_zone::Impls are linked into a map to support fast lookup by name.
-using TimeZoneImplByName =
+namespace time_internal {
+namespace cctz {
+
+namespace {
+
+// time_zone::Impls are linked into a map to support fast lookup by name.
+using TimeZoneImplByName =
std::unordered_map<TString, const time_zone::Impl*>;
-TimeZoneImplByName* time_zone_map = nullptr;
-
-// Mutual exclusion for time_zone_map.
-std::mutex& TimeZoneMutex() {
- // This mutex is intentionally "leaked" to avoid the static deinitialization
- // order fiasco (std::mutex's destructor is not trivial on many platforms).
- static std::mutex* time_zone_mutex = new std::mutex;
- return *time_zone_mutex;
-}
-
-} // namespace
-
+TimeZoneImplByName* time_zone_map = nullptr;
+
+// Mutual exclusion for time_zone_map.
+std::mutex& TimeZoneMutex() {
+ // This mutex is intentionally "leaked" to avoid the static deinitialization
+ // order fiasco (std::mutex's destructor is not trivial on many platforms).
+ static std::mutex* time_zone_mutex = new std::mutex;
+ return *time_zone_mutex;
+}
+
+} // namespace
+
time_zone time_zone::Impl::UTC() { return time_zone(UTCImpl()); }
-
+
bool time_zone::Impl::LoadTimeZone(const TString& name, time_zone* tz) {
const Impl* const utc_impl = UTCImpl();
-
+
// Check for UTC (which is never a key in time_zone_map).
- auto offset = seconds::zero();
- if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) {
- *tz = time_zone(utc_impl);
- return true;
- }
-
+ auto offset = seconds::zero();
+ if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) {
+ *tz = time_zone(utc_impl);
+ return true;
+ }
+
// Check whether the time zone has already been loaded.
- {
- std::lock_guard<std::mutex> lock(TimeZoneMutex());
- if (time_zone_map != nullptr) {
- TimeZoneImplByName::const_iterator itr = time_zone_map->find(name);
- if (itr != time_zone_map->end()) {
- *tz = time_zone(itr->second);
- return itr->second != utc_impl;
- }
- }
- }
-
+ {
+ std::lock_guard<std::mutex> lock(TimeZoneMutex());
+ if (time_zone_map != nullptr) {
+ TimeZoneImplByName::const_iterator itr = time_zone_map->find(name);
+ if (itr != time_zone_map->end()) {
+ *tz = time_zone(itr->second);
+ return itr->second != utc_impl;
+ }
+ }
+ }
+
// Load the new time zone (outside the lock).
std::unique_ptr<const Impl> new_impl(new Impl(name));
// Add the new time zone to the map.
- std::lock_guard<std::mutex> lock(TimeZoneMutex());
- if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName;
- const Impl*& impl = (*time_zone_map)[name];
+ std::lock_guard<std::mutex> lock(TimeZoneMutex());
+ if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName;
+ const Impl*& impl = (*time_zone_map)[name];
if (impl == nullptr) { // this thread won any load race
impl = new_impl->zone_ ? new_impl.release() : utc_impl;
- }
- *tz = time_zone(impl);
- return impl != utc_impl;
-}
-
-void time_zone::Impl::ClearTimeZoneMapTestOnly() {
- std::lock_guard<std::mutex> lock(TimeZoneMutex());
- if (time_zone_map != nullptr) {
- // Existing time_zone::Impl* entries are in the wild, so we can't delete
- // them. Instead, we move them to a private container, where they are
- // logically unreachable but not "leaked". Future requests will result
- // in reloading the data.
- static auto* cleared = new std::deque<const time_zone::Impl*>;
- for (const auto& element : *time_zone_map) {
- cleared->push_back(element.second);
- }
- time_zone_map->clear();
- }
-}
-
+ }
+ *tz = time_zone(impl);
+ return impl != utc_impl;
+}
+
+void time_zone::Impl::ClearTimeZoneMapTestOnly() {
+ std::lock_guard<std::mutex> lock(TimeZoneMutex());
+ if (time_zone_map != nullptr) {
+ // Existing time_zone::Impl* entries are in the wild, so we can't delete
+ // them. Instead, we move them to a private container, where they are
+ // logically unreachable but not "leaked". Future requests will result
+ // in reloading the data.
+ static auto* cleared = new std::deque<const time_zone::Impl*>;
+ for (const auto& element : *time_zone_map) {
+ cleared->push_back(element.second);
+ }
+ time_zone_map->clear();
+ }
+}
+
time_zone::Impl::Impl(const TString& name)
: name_(name), zone_(TimeZoneIf::Load(name_)) {}
-
-const time_zone::Impl* time_zone::Impl::UTCImpl() {
+
+const time_zone::Impl* time_zone::Impl::UTCImpl() {
static const Impl* utc_impl = new Impl("UTC"); // never fails
- return utc_impl;
-}
-
-} // namespace cctz
-} // namespace time_internal
+ return utc_impl;
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.h
index 1a18623e3c..c014ab41df 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_impl.h
@@ -1,93 +1,93 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
-
-#include <memory>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
+
+#include <memory>
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-#include "time_zone_if.h"
-#include "time_zone_info.h"
-
+#include "time_zone_if.h"
+#include "time_zone_info.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// time_zone::Impl is the internal object referenced by a cctz::time_zone.
-class time_zone::Impl {
- public:
- // The UTC time zone. Also used for other time zones that fail to load.
- static time_zone UTC();
-
- // Load a named time zone. Returns false if the name is invalid, or if
- // some other kind of error occurs. Note that loading "UTC" never fails.
+namespace time_internal {
+namespace cctz {
+
+// time_zone::Impl is the internal object referenced by a cctz::time_zone.
+class time_zone::Impl {
+ public:
+ // The UTC time zone. Also used for other time zones that fail to load.
+ static time_zone UTC();
+
+ // Load a named time zone. Returns false if the name is invalid, or if
+ // some other kind of error occurs. Note that loading "UTC" never fails.
static bool LoadTimeZone(const TString& name, time_zone* tz);
-
- // Clears the map of cached time zones. Primarily for use in benchmarks
- // that gauge the performance of loading/parsing the time-zone data.
- static void ClearTimeZoneMapTestOnly();
-
- // The primary key is the time-zone ID (e.g., "America/New_York").
+
+ // Clears the map of cached time zones. Primarily for use in benchmarks
+ // that gauge the performance of loading/parsing the time-zone data.
+ static void ClearTimeZoneMapTestOnly();
+
+ // The primary key is the time-zone ID (e.g., "America/New_York").
const TString& Name() const {
- // TODO: It would nice if the zoneinfo data included the zone name.
- return name_;
- }
-
- // Breaks a time_point down to civil-time components in this time zone.
- time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const {
- return zone_->BreakTime(tp);
- }
-
- // Converts the civil-time components in this time zone into a time_point.
- // That is, the opposite of BreakTime(). The requested civil time may be
- // ambiguous or illegal due to a change of UTC offset.
- time_zone::civil_lookup MakeTime(const civil_second& cs) const {
- return zone_->MakeTime(cs);
- }
-
- // Finds the time of the next/previous offset change in this time zone.
- bool NextTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const {
- return zone_->NextTransition(tp, trans);
- }
- bool PrevTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const {
- return zone_->PrevTransition(tp, trans);
- }
-
+ // TODO: It would nice if the zoneinfo data included the zone name.
+ return name_;
+ }
+
+ // Breaks a time_point down to civil-time components in this time zone.
+ time_zone::absolute_lookup BreakTime(const time_point<seconds>& tp) const {
+ return zone_->BreakTime(tp);
+ }
+
+ // Converts the civil-time components in this time zone into a time_point.
+ // That is, the opposite of BreakTime(). The requested civil time may be
+ // ambiguous or illegal due to a change of UTC offset.
+ time_zone::civil_lookup MakeTime(const civil_second& cs) const {
+ return zone_->MakeTime(cs);
+ }
+
+ // Finds the time of the next/previous offset change in this time zone.
+ bool NextTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const {
+ return zone_->NextTransition(tp, trans);
+ }
+ bool PrevTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const {
+ return zone_->PrevTransition(tp, trans);
+ }
+
// Returns an implementation-defined version string for this time zone.
TString Version() const { return zone_->Version(); }
-
- // Returns an implementation-defined description of this time zone.
+
+ // Returns an implementation-defined description of this time zone.
TString Description() const { return zone_->Description(); }
-
- private:
+
+ private:
explicit Impl(const TString& name);
- static const Impl* UTCImpl();
-
+ static const Impl* UTCImpl();
+
const TString name_;
- std::unique_ptr<TimeZoneIf> zone_;
-};
-
-} // namespace cctz
-} // namespace time_internal
+ std::unique_ptr<TimeZoneIf> zone_;
+};
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc
index 1e04f60b49..72f7bdc3ca 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc
@@ -1,89 +1,89 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This file implements the TimeZoneIf interface using the "zoneinfo"
-// data provided by the IANA Time Zone Database (i.e., the only real game
-// in town).
-//
-// TimeZoneInfo represents the history of UTC-offset changes within a time
-// zone. Most changes are due to daylight-saving rules, but occasionally
-// shifts are made to the time-zone's base offset. The database only attempts
-// to be definitive for times since 1970, so be wary of local-time conversions
-// before that. Also, rule and zone-boundary changes are made at the whim
-// of governments, so the conversion of future times needs to be taken with
-// a grain of salt.
-//
-// For more information see tzfile(5), http://www.iana.org/time-zones, or
-// https://en.wikipedia.org/wiki/Zoneinfo.
-//
-// Note that we assume the proleptic Gregorian calendar and 60-second
-// minutes throughout.
-
-#include "time_zone_info.h"
-
-#include <algorithm>
-#include <cassert>
-#include <chrono>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file implements the TimeZoneIf interface using the "zoneinfo"
+// data provided by the IANA Time Zone Database (i.e., the only real game
+// in town).
+//
+// TimeZoneInfo represents the history of UTC-offset changes within a time
+// zone. Most changes are due to daylight-saving rules, but occasionally
+// shifts are made to the time-zone's base offset. The database only attempts
+// to be definitive for times since 1970, so be wary of local-time conversions
+// before that. Also, rule and zone-boundary changes are made at the whim
+// of governments, so the conversion of future times needs to be taken with
+// a grain of salt.
+//
+// For more information see tzfile(5), http://www.iana.org/time-zones, or
+// https://en.wikipedia.org/wiki/Zoneinfo.
+//
+// Note that we assume the proleptic Gregorian calendar and 60-second
+// minutes throughout.
+
+#include "time_zone_info.h"
+
+#include <algorithm>
+#include <cassert>
+#include <chrono>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <fstream>
-#include <functional>
-#include <memory>
-#include <sstream>
+#include <functional>
+#include <memory>
+#include <sstream>
#include <util/generic/string.h>
#include <utility>
-
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
-#include "time_zone_fixed.h"
-#include "time_zone_posix.h"
-
+#include "time_zone_fixed.h"
+#include "time_zone_posix.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-namespace {
-
-inline bool IsLeap(year_t year) {
- return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
-}
-
-// The number of days in non-leap and leap years respectively.
-const std::int_least32_t kDaysPerYear[2] = {365, 366};
-
-// The day offsets of the beginning of each (1-based) month in non-leap and
-// leap years respectively (e.g., 335 days before December in a leap year).
-const std::int_least16_t kMonthOffsets[2][1 + 12 + 1] = {
+namespace time_internal {
+namespace cctz {
+
+namespace {
+
+inline bool IsLeap(year_t year) {
+ return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
+}
+
+// The number of days in non-leap and leap years respectively.
+const std::int_least32_t kDaysPerYear[2] = {365, 366};
+
+// The day offsets of the beginning of each (1-based) month in non-leap and
+// leap years respectively (e.g., 335 days before December in a leap year).
+const std::int_least16_t kMonthOffsets[2][1 + 12 + 1] = {
{-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
{-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366},
-};
-
-// We reject leap-second encoded zoneinfo and so assume 60-second minutes.
-const std::int_least32_t kSecsPerDay = 24 * 60 * 60;
-
-// 400-year chunks always have 146097 days (20871 weeks).
-const std::int_least64_t kSecsPer400Years = 146097LL * kSecsPerDay;
-
-// Like kDaysPerYear[] but scaled up by a factor of kSecsPerDay.
-const std::int_least32_t kSecsPerYear[2] = {
+};
+
+// We reject leap-second encoded zoneinfo and so assume 60-second minutes.
+const std::int_least32_t kSecsPerDay = 24 * 60 * 60;
+
+// 400-year chunks always have 146097 days (20871 weeks).
+const std::int_least64_t kSecsPer400Years = 146097LL * kSecsPerDay;
+
+// Like kDaysPerYear[] but scaled up by a factor of kSecsPerDay.
+const std::int_least32_t kSecsPerYear[2] = {
365 * kSecsPerDay,
366 * kSecsPerDay,
-};
-
+};
+
// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat).
inline int ToPosixWeekday(weekday wd) {
switch (wd) {
@@ -105,195 +105,195 @@ inline int ToPosixWeekday(weekday wd) {
return 0; /*NOTREACHED*/
}
-// Single-byte, unsigned numeric values are encoded directly.
-inline std::uint_fast8_t Decode8(const char* cp) {
- return static_cast<std::uint_fast8_t>(*cp) & 0xff;
-}
-
-// Multi-byte, numeric values are encoded using a MSB first,
-// twos-complement representation. These helpers decode, from
-// the given address, 4-byte and 8-byte values respectively.
-// Note: If int_fastXX_t == intXX_t and this machine is not
-// twos complement, then there will be at least one input value
-// we cannot represent.
-std::int_fast32_t Decode32(const char* cp) {
- std::uint_fast32_t v = 0;
- for (int i = 0; i != (32 / 8); ++i) v = (v << 8) | Decode8(cp++);
- const std::int_fast32_t s32max = 0x7fffffff;
- const auto s32maxU = static_cast<std::uint_fast32_t>(s32max);
- if (v <= s32maxU) return static_cast<std::int_fast32_t>(v);
- return static_cast<std::int_fast32_t>(v - s32maxU - 1) - s32max - 1;
-}
-
-std::int_fast64_t Decode64(const char* cp) {
- std::uint_fast64_t v = 0;
- for (int i = 0; i != (64 / 8); ++i) v = (v << 8) | Decode8(cp++);
- const std::int_fast64_t s64max = 0x7fffffffffffffff;
- const auto s64maxU = static_cast<std::uint_fast64_t>(s64max);
- if (v <= s64maxU) return static_cast<std::int_fast64_t>(v);
- return static_cast<std::int_fast64_t>(v - s64maxU - 1) - s64max - 1;
-}
-
-// Generate a year-relative offset for a PosixTransition.
-std::int_fast64_t TransOffset(bool leap_year, int jan1_weekday,
- const PosixTransition& pt) {
- std::int_fast64_t days = 0;
- switch (pt.date.fmt) {
- case PosixTransition::J: {
- days = pt.date.j.day;
- if (!leap_year || days < kMonthOffsets[1][3]) days -= 1;
- break;
- }
- case PosixTransition::N: {
- days = pt.date.n.day;
- break;
- }
- case PosixTransition::M: {
- const bool last_week = (pt.date.m.week == 5);
- days = kMonthOffsets[leap_year][pt.date.m.month + last_week];
- const std::int_fast64_t weekday = (jan1_weekday + days) % 7;
- if (last_week) {
- days -= (weekday + 7 - 1 - pt.date.m.weekday) % 7 + 1;
- } else {
- days += (pt.date.m.weekday + 7 - weekday) % 7;
- days += (pt.date.m.week - 1) * 7;
- }
- break;
- }
- }
- return (days * kSecsPerDay) + pt.time.offset;
-}
-
-inline time_zone::civil_lookup MakeUnique(const time_point<seconds>& tp) {
- time_zone::civil_lookup cl;
- cl.kind = time_zone::civil_lookup::UNIQUE;
- cl.pre = cl.trans = cl.post = tp;
- return cl;
-}
-
-inline time_zone::civil_lookup MakeUnique(std::int_fast64_t unix_time) {
- return MakeUnique(FromUnixSeconds(unix_time));
-}
-
-inline time_zone::civil_lookup MakeSkipped(const Transition& tr,
- const civil_second& cs) {
- time_zone::civil_lookup cl;
- cl.kind = time_zone::civil_lookup::SKIPPED;
- cl.pre = FromUnixSeconds(tr.unix_time - 1 + (cs - tr.prev_civil_sec));
- cl.trans = FromUnixSeconds(tr.unix_time);
- cl.post = FromUnixSeconds(tr.unix_time - (tr.civil_sec - cs));
- return cl;
-}
-
-inline time_zone::civil_lookup MakeRepeated(const Transition& tr,
- const civil_second& cs) {
- time_zone::civil_lookup cl;
- cl.kind = time_zone::civil_lookup::REPEATED;
- cl.pre = FromUnixSeconds(tr.unix_time - 1 - (tr.prev_civil_sec - cs));
- cl.trans = FromUnixSeconds(tr.unix_time);
- cl.post = FromUnixSeconds(tr.unix_time + (cs - tr.civil_sec));
- return cl;
-}
-
-inline civil_second YearShift(const civil_second& cs, year_t shift) {
+// Single-byte, unsigned numeric values are encoded directly.
+inline std::uint_fast8_t Decode8(const char* cp) {
+ return static_cast<std::uint_fast8_t>(*cp) & 0xff;
+}
+
+// Multi-byte, numeric values are encoded using a MSB first,
+// twos-complement representation. These helpers decode, from
+// the given address, 4-byte and 8-byte values respectively.
+// Note: If int_fastXX_t == intXX_t and this machine is not
+// twos complement, then there will be at least one input value
+// we cannot represent.
+std::int_fast32_t Decode32(const char* cp) {
+ std::uint_fast32_t v = 0;
+ for (int i = 0; i != (32 / 8); ++i) v = (v << 8) | Decode8(cp++);
+ const std::int_fast32_t s32max = 0x7fffffff;
+ const auto s32maxU = static_cast<std::uint_fast32_t>(s32max);
+ if (v <= s32maxU) return static_cast<std::int_fast32_t>(v);
+ return static_cast<std::int_fast32_t>(v - s32maxU - 1) - s32max - 1;
+}
+
+std::int_fast64_t Decode64(const char* cp) {
+ std::uint_fast64_t v = 0;
+ for (int i = 0; i != (64 / 8); ++i) v = (v << 8) | Decode8(cp++);
+ const std::int_fast64_t s64max = 0x7fffffffffffffff;
+ const auto s64maxU = static_cast<std::uint_fast64_t>(s64max);
+ if (v <= s64maxU) return static_cast<std::int_fast64_t>(v);
+ return static_cast<std::int_fast64_t>(v - s64maxU - 1) - s64max - 1;
+}
+
+// Generate a year-relative offset for a PosixTransition.
+std::int_fast64_t TransOffset(bool leap_year, int jan1_weekday,
+ const PosixTransition& pt) {
+ std::int_fast64_t days = 0;
+ switch (pt.date.fmt) {
+ case PosixTransition::J: {
+ days = pt.date.j.day;
+ if (!leap_year || days < kMonthOffsets[1][3]) days -= 1;
+ break;
+ }
+ case PosixTransition::N: {
+ days = pt.date.n.day;
+ break;
+ }
+ case PosixTransition::M: {
+ const bool last_week = (pt.date.m.week == 5);
+ days = kMonthOffsets[leap_year][pt.date.m.month + last_week];
+ const std::int_fast64_t weekday = (jan1_weekday + days) % 7;
+ if (last_week) {
+ days -= (weekday + 7 - 1 - pt.date.m.weekday) % 7 + 1;
+ } else {
+ days += (pt.date.m.weekday + 7 - weekday) % 7;
+ days += (pt.date.m.week - 1) * 7;
+ }
+ break;
+ }
+ }
+ return (days * kSecsPerDay) + pt.time.offset;
+}
+
+inline time_zone::civil_lookup MakeUnique(const time_point<seconds>& tp) {
+ time_zone::civil_lookup cl;
+ cl.kind = time_zone::civil_lookup::UNIQUE;
+ cl.pre = cl.trans = cl.post = tp;
+ return cl;
+}
+
+inline time_zone::civil_lookup MakeUnique(std::int_fast64_t unix_time) {
+ return MakeUnique(FromUnixSeconds(unix_time));
+}
+
+inline time_zone::civil_lookup MakeSkipped(const Transition& tr,
+ const civil_second& cs) {
+ time_zone::civil_lookup cl;
+ cl.kind = time_zone::civil_lookup::SKIPPED;
+ cl.pre = FromUnixSeconds(tr.unix_time - 1 + (cs - tr.prev_civil_sec));
+ cl.trans = FromUnixSeconds(tr.unix_time);
+ cl.post = FromUnixSeconds(tr.unix_time - (tr.civil_sec - cs));
+ return cl;
+}
+
+inline time_zone::civil_lookup MakeRepeated(const Transition& tr,
+ const civil_second& cs) {
+ time_zone::civil_lookup cl;
+ cl.kind = time_zone::civil_lookup::REPEATED;
+ cl.pre = FromUnixSeconds(tr.unix_time - 1 - (tr.prev_civil_sec - cs));
+ cl.trans = FromUnixSeconds(tr.unix_time);
+ cl.post = FromUnixSeconds(tr.unix_time + (cs - tr.civil_sec));
+ return cl;
+}
+
+inline civil_second YearShift(const civil_second& cs, year_t shift) {
return civil_second(cs.year() + shift, cs.month(), cs.day(), cs.hour(),
cs.minute(), cs.second());
-}
-
-} // namespace
-
-// What (no leap-seconds) UTC+seconds zoneinfo would look like.
-bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) {
- transition_types_.resize(1);
- TransitionType& tt(transition_types_.back());
- tt.utc_offset = static_cast<std::int_least32_t>(offset.count());
- tt.is_dst = false;
- tt.abbr_index = 0;
-
+}
+
+} // namespace
+
+// What (no leap-seconds) UTC+seconds zoneinfo would look like.
+bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) {
+ transition_types_.resize(1);
+ TransitionType& tt(transition_types_.back());
+ tt.utc_offset = static_cast<std::int_least32_t>(offset.count());
+ tt.is_dst = false;
+ tt.abbr_index = 0;
+
// We temporarily add some redundant, contemporary (2015 through 2025)
- // transitions for performance reasons. See TimeZoneInfo::LocalTime().
- // TODO: Fix the performance issue and remove the extra transitions.
- transitions_.clear();
- transitions_.reserve(12);
- for (const std::int_fast64_t unix_time : {
+ // transitions for performance reasons. See TimeZoneInfo::LocalTime().
+ // TODO: Fix the performance issue and remove the extra transitions.
+ transitions_.clear();
+ transitions_.reserve(12);
+ for (const std::int_fast64_t unix_time : {
-(1LL << 59), // a "first half" transition
- 1420070400LL, // 2015-01-01T00:00:00+00:00
- 1451606400LL, // 2016-01-01T00:00:00+00:00
- 1483228800LL, // 2017-01-01T00:00:00+00:00
- 1514764800LL, // 2018-01-01T00:00:00+00:00
- 1546300800LL, // 2019-01-01T00:00:00+00:00
- 1577836800LL, // 2020-01-01T00:00:00+00:00
- 1609459200LL, // 2021-01-01T00:00:00+00:00
- 1640995200LL, // 2022-01-01T00:00:00+00:00
- 1672531200LL, // 2023-01-01T00:00:00+00:00
+ 1420070400LL, // 2015-01-01T00:00:00+00:00
+ 1451606400LL, // 2016-01-01T00:00:00+00:00
+ 1483228800LL, // 2017-01-01T00:00:00+00:00
+ 1514764800LL, // 2018-01-01T00:00:00+00:00
+ 1546300800LL, // 2019-01-01T00:00:00+00:00
+ 1577836800LL, // 2020-01-01T00:00:00+00:00
+ 1609459200LL, // 2021-01-01T00:00:00+00:00
+ 1640995200LL, // 2022-01-01T00:00:00+00:00
+ 1672531200LL, // 2023-01-01T00:00:00+00:00
1704067200LL, // 2024-01-01T00:00:00+00:00
1735689600LL, // 2025-01-01T00:00:00+00:00
- }) {
- Transition& tr(*transitions_.emplace(transitions_.end()));
- tr.unix_time = unix_time;
- tr.type_index = 0;
- tr.civil_sec = LocalTime(tr.unix_time, tt).cs;
- tr.prev_civil_sec = tr.civil_sec - 1;
- }
-
- default_transition_type_ = 0;
- abbreviations_ = FixedOffsetToAbbr(offset);
+ }) {
+ Transition& tr(*transitions_.emplace(transitions_.end()));
+ tr.unix_time = unix_time;
+ tr.type_index = 0;
+ tr.civil_sec = LocalTime(tr.unix_time, tt).cs;
+ tr.prev_civil_sec = tr.civil_sec - 1;
+ }
+
+ default_transition_type_ = 0;
+ abbreviations_ = FixedOffsetToAbbr(offset);
abbreviations_.append(1, '\0');
future_spec_.clear(); // never needed for a fixed-offset zone
- extended_ = false;
-
- tt.civil_max = LocalTime(seconds::max().count(), tt).cs;
- tt.civil_min = LocalTime(seconds::min().count(), tt).cs;
-
- transitions_.shrink_to_fit();
- return true;
-}
-
-// Builds the in-memory header using the raw bytes from the file.
-bool TimeZoneInfo::Header::Build(const tzhead& tzh) {
- std::int_fast32_t v;
- if ((v = Decode32(tzh.tzh_timecnt)) < 0) return false;
- timecnt = static_cast<std::size_t>(v);
- if ((v = Decode32(tzh.tzh_typecnt)) < 0) return false;
- typecnt = static_cast<std::size_t>(v);
- if ((v = Decode32(tzh.tzh_charcnt)) < 0) return false;
- charcnt = static_cast<std::size_t>(v);
- if ((v = Decode32(tzh.tzh_leapcnt)) < 0) return false;
- leapcnt = static_cast<std::size_t>(v);
- if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false;
- ttisstdcnt = static_cast<std::size_t>(v);
- if ((v = Decode32(tzh.tzh_ttisutcnt)) < 0) return false;
- ttisutcnt = static_cast<std::size_t>(v);
- return true;
-}
-
-// How many bytes of data are associated with this header. The result
-// depends upon whether this is a section with 4-byte or 8-byte times.
-std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const {
- std::size_t len = 0;
- len += (time_len + 1) * timecnt; // unix_time + type_index
- len += (4 + 1 + 1) * typecnt; // utc_offset + is_dst + abbr_index
- len += 1 * charcnt; // abbreviations
- len += (time_len + 4) * leapcnt; // leap-time + TAI-UTC
- len += 1 * ttisstdcnt; // UTC/local indicators
- len += 1 * ttisutcnt; // standard/wall indicators
- return len;
-}
-
-// zic(8) can generate no-op transitions when a zone changes rules at an
-// instant when there is actually no discontinuity. So we check whether
-// two transitions have equivalent types (same offset/is_dst/abbr).
-bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index,
- std::uint_fast8_t tt2_index) const {
- if (tt1_index == tt2_index) return true;
- const TransitionType& tt1(transition_types_[tt1_index]);
- const TransitionType& tt2(transition_types_[tt2_index]);
+ extended_ = false;
+
+ tt.civil_max = LocalTime(seconds::max().count(), tt).cs;
+ tt.civil_min = LocalTime(seconds::min().count(), tt).cs;
+
+ transitions_.shrink_to_fit();
+ return true;
+}
+
+// Builds the in-memory header using the raw bytes from the file.
+bool TimeZoneInfo::Header::Build(const tzhead& tzh) {
+ std::int_fast32_t v;
+ if ((v = Decode32(tzh.tzh_timecnt)) < 0) return false;
+ timecnt = static_cast<std::size_t>(v);
+ if ((v = Decode32(tzh.tzh_typecnt)) < 0) return false;
+ typecnt = static_cast<std::size_t>(v);
+ if ((v = Decode32(tzh.tzh_charcnt)) < 0) return false;
+ charcnt = static_cast<std::size_t>(v);
+ if ((v = Decode32(tzh.tzh_leapcnt)) < 0) return false;
+ leapcnt = static_cast<std::size_t>(v);
+ if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false;
+ ttisstdcnt = static_cast<std::size_t>(v);
+ if ((v = Decode32(tzh.tzh_ttisutcnt)) < 0) return false;
+ ttisutcnt = static_cast<std::size_t>(v);
+ return true;
+}
+
+// How many bytes of data are associated with this header. The result
+// depends upon whether this is a section with 4-byte or 8-byte times.
+std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const {
+ std::size_t len = 0;
+ len += (time_len + 1) * timecnt; // unix_time + type_index
+ len += (4 + 1 + 1) * typecnt; // utc_offset + is_dst + abbr_index
+ len += 1 * charcnt; // abbreviations
+ len += (time_len + 4) * leapcnt; // leap-time + TAI-UTC
+ len += 1 * ttisstdcnt; // UTC/local indicators
+ len += 1 * ttisutcnt; // standard/wall indicators
+ return len;
+}
+
+// zic(8) can generate no-op transitions when a zone changes rules at an
+// instant when there is actually no discontinuity. So we check whether
+// two transitions have equivalent types (same offset/is_dst/abbr).
+bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index,
+ std::uint_fast8_t tt2_index) const {
+ if (tt1_index == tt2_index) return true;
+ const TransitionType& tt1(transition_types_[tt1_index]);
+ const TransitionType& tt2(transition_types_[tt2_index]);
if (tt1.utc_offset != tt2.utc_offset) return false;
- if (tt1.is_dst != tt2.is_dst) return false;
- if (tt1.abbr_index != tt2.abbr_index) return false;
- return true;
-}
-
+ if (tt1.is_dst != tt2.is_dst) return false;
+ if (tt1.abbr_index != tt2.abbr_index) return false;
+ return true;
+}
+
// Find/make a transition type with these attributes.
bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
const TString& abbr,
@@ -326,38 +326,38 @@ bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
return true;
}
-// Use the POSIX-TZ-environment-variable-style string to handle times
-// in years after the last transition stored in the zoneinfo data.
+// Use the POSIX-TZ-environment-variable-style string to handle times
+// in years after the last transition stored in the zoneinfo data.
bool TimeZoneInfo::ExtendTransitions() {
- extended_ = false;
+ extended_ = false;
if (future_spec_.empty()) return true; // last transition prevails
-
- PosixTimeZone posix;
+
+ PosixTimeZone posix;
if (!ParsePosixSpec(future_spec_, &posix)) return false;
-
+
// Find transition type for the future std specification.
std::uint_least8_t std_ti;
if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti))
return false;
-
+
if (posix.dst_abbr.empty()) { // std only
// The future specification should match the last transition, and
// that means that handling the future will fall out naturally.
return EquivTransitions(transitions_.back().type_index, std_ti);
- }
-
+ }
+
// Find transition type for the future dst specification.
std::uint_least8_t dst_ti;
if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti))
return false;
-
- // Extend the transitions for an additional 400 years using the
- // future specification. Years beyond those can be handled by
- // mapping back to a cycle-equivalent year within that range.
+
+ // Extend the transitions for an additional 400 years using the
+ // future specification. Years beyond those can be handled by
+ // mapping back to a cycle-equivalent year within that range.
// We may need two additional transitions for the current year.
transitions_.reserve(transitions_.size() + 400 * 2 + 2);
- extended_ = true;
-
+ extended_ = true;
+
const Transition& last(transitions_.back());
const std::int_fast64_t last_time = last.unix_time;
const TransitionType& last_tt(transition_types_[last.type_index]);
@@ -366,7 +366,7 @@ bool TimeZoneInfo::ExtendTransitions() {
const civil_second jan1(last_year_);
std::int_fast64_t jan1_time = jan1 - civil_second();
int jan1_weekday = ToPosixWeekday(get_weekday(jan1));
-
+
Transition dst = {0, dst_ti, civil_second(), civil_second()};
Transition std = {0, std_ti, civil_second(), civil_second()};
for (const year_t limit = last_year_ + 400;; ++last_year_) {
@@ -381,161 +381,161 @@ bool TimeZoneInfo::ExtendTransitions() {
transitions_.push_back(*tb);
}
if (last_year_ == limit) break;
- jan1_time += kSecsPerYear[leap_year];
- jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7;
+ jan1_time += kSecsPerYear[leap_year];
+ jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7;
leap_year = !leap_year && IsLeap(last_year_ + 1);
- }
+ }
return true;
-}
-
+}
+
bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
- // Read and validate the header.
- tzhead tzh;
+ // Read and validate the header.
+ tzhead tzh;
if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false;
- if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0)
- return false;
- Header hdr;
+ if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0)
+ return false;
+ Header hdr;
if (!hdr.Build(tzh)) return false;
- std::size_t time_len = 4;
- if (tzh.tzh_version[0] != '\0') {
- // Skip the 4-byte data.
+ std::size_t time_len = 4;
+ if (tzh.tzh_version[0] != '\0') {
+ // Skip the 4-byte data.
if (zip->Skip(hdr.DataLength(time_len)) != 0) return false;
- // Read and validate the header for the 8-byte data.
+ // Read and validate the header for the 8-byte data.
if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false;
- if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0)
- return false;
+ if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0)
+ return false;
if (tzh.tzh_version[0] == '\0') return false;
if (!hdr.Build(tzh)) return false;
- time_len = 8;
- }
+ time_len = 8;
+ }
if (hdr.typecnt == 0) return false;
- if (hdr.leapcnt != 0) {
- // This code assumes 60-second minutes so we do not want
- // the leap-second encoded zoneinfo. We could reverse the
- // compensation, but the "right" encoding is rarely used
- // so currently we simply reject such data.
- return false;
- }
+ if (hdr.leapcnt != 0) {
+ // This code assumes 60-second minutes so we do not want
+ // the leap-second encoded zoneinfo. We could reverse the
+ // compensation, but the "right" encoding is rarely used
+ // so currently we simply reject such data.
+ return false;
+ }
if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false;
if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) return false;
-
- // Read the data into a local buffer.
- std::size_t len = hdr.DataLength(time_len);
- std::vector<char> tbuf(len);
+
+ // Read the data into a local buffer.
+ std::size_t len = hdr.DataLength(time_len);
+ std::vector<char> tbuf(len);
if (zip->Read(tbuf.data(), len) != len) return false;
- const char* bp = tbuf.data();
-
- // Decode and validate the transitions.
+ const char* bp = tbuf.data();
+
+ // Decode and validate the transitions.
transitions_.reserve(hdr.timecnt + 2);
- transitions_.resize(hdr.timecnt);
- for (std::size_t i = 0; i != hdr.timecnt; ++i) {
- transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp);
- bp += time_len;
- if (i != 0) {
- // Check that the transitions are ordered by time (as zic guarantees).
- if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i]))
- return false; // out of order
- }
- }
- bool seen_type_0 = false;
- for (std::size_t i = 0; i != hdr.timecnt; ++i) {
- transitions_[i].type_index = Decode8(bp++);
+ transitions_.resize(hdr.timecnt);
+ for (std::size_t i = 0; i != hdr.timecnt; ++i) {
+ transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp);
+ bp += time_len;
+ if (i != 0) {
+ // Check that the transitions are ordered by time (as zic guarantees).
+ if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i]))
+ return false; // out of order
+ }
+ }
+ bool seen_type_0 = false;
+ for (std::size_t i = 0; i != hdr.timecnt; ++i) {
+ transitions_[i].type_index = Decode8(bp++);
if (transitions_[i].type_index >= hdr.typecnt) return false;
if (transitions_[i].type_index == 0) seen_type_0 = true;
- }
-
- // Decode and validate the transition types.
+ }
+
+ // Decode and validate the transition types.
transition_types_.reserve(hdr.typecnt + 2);
- transition_types_.resize(hdr.typecnt);
- for (std::size_t i = 0; i != hdr.typecnt; ++i) {
- transition_types_[i].utc_offset =
- static_cast<std::int_least32_t>(Decode32(bp));
- if (transition_types_[i].utc_offset >= kSecsPerDay ||
- transition_types_[i].utc_offset <= -kSecsPerDay)
- return false;
- bp += 4;
- transition_types_[i].is_dst = (Decode8(bp++) != 0);
- transition_types_[i].abbr_index = Decode8(bp++);
+ transition_types_.resize(hdr.typecnt);
+ for (std::size_t i = 0; i != hdr.typecnt; ++i) {
+ transition_types_[i].utc_offset =
+ static_cast<std::int_least32_t>(Decode32(bp));
+ if (transition_types_[i].utc_offset >= kSecsPerDay ||
+ transition_types_[i].utc_offset <= -kSecsPerDay)
+ return false;
+ bp += 4;
+ transition_types_[i].is_dst = (Decode8(bp++) != 0);
+ transition_types_[i].abbr_index = Decode8(bp++);
if (transition_types_[i].abbr_index >= hdr.charcnt) return false;
- }
-
- // Determine the before-first-transition type.
- default_transition_type_ = 0;
- if (seen_type_0 && hdr.timecnt != 0) {
- std::uint_fast8_t index = 0;
- if (transition_types_[0].is_dst) {
- index = transitions_[0].type_index;
+ }
+
+ // Determine the before-first-transition type.
+ default_transition_type_ = 0;
+ if (seen_type_0 && hdr.timecnt != 0) {
+ std::uint_fast8_t index = 0;
+ if (transition_types_[0].is_dst) {
+ index = transitions_[0].type_index;
while (index != 0 && transition_types_[index].is_dst) --index;
- }
+ }
while (index != hdr.typecnt && transition_types_[index].is_dst) ++index;
if (index != hdr.typecnt) default_transition_type_ = index;
- }
-
- // Copy all the abbreviations.
+ }
+
+ // Copy all the abbreviations.
abbreviations_.reserve(hdr.charcnt + 10);
- abbreviations_.assign(bp, hdr.charcnt);
- bp += hdr.charcnt;
-
- // Skip the unused portions. We've already dispensed with leap-second
- // encoded zoneinfo. The ttisstd/ttisgmt indicators only apply when
- // interpreting a POSIX spec that does not include start/end rules, and
- // that isn't the case here (see "zic -p").
- bp += (8 + 4) * hdr.leapcnt; // leap-time + TAI-UTC
- bp += 1 * hdr.ttisstdcnt; // UTC/local indicators
- bp += 1 * hdr.ttisutcnt; // standard/wall indicators
- assert(bp == tbuf.data() + tbuf.size());
-
- future_spec_.clear();
- if (tzh.tzh_version[0] != '\0') {
- // Snarf up the NL-enclosed future POSIX spec. Note
- // that version '3' files utilize an extended format.
- auto get_char = [](ZoneInfoSource* azip) -> int {
- unsigned char ch; // all non-EOF results are positive
- return (azip->Read(&ch, 1) == 1) ? ch : EOF;
- };
+ abbreviations_.assign(bp, hdr.charcnt);
+ bp += hdr.charcnt;
+
+ // Skip the unused portions. We've already dispensed with leap-second
+ // encoded zoneinfo. The ttisstd/ttisgmt indicators only apply when
+ // interpreting a POSIX spec that does not include start/end rules, and
+ // that isn't the case here (see "zic -p").
+ bp += (8 + 4) * hdr.leapcnt; // leap-time + TAI-UTC
+ bp += 1 * hdr.ttisstdcnt; // UTC/local indicators
+ bp += 1 * hdr.ttisutcnt; // standard/wall indicators
+ assert(bp == tbuf.data() + tbuf.size());
+
+ future_spec_.clear();
+ if (tzh.tzh_version[0] != '\0') {
+ // Snarf up the NL-enclosed future POSIX spec. Note
+ // that version '3' files utilize an extended format.
+ auto get_char = [](ZoneInfoSource* azip) -> int {
+ unsigned char ch; // all non-EOF results are positive
+ return (azip->Read(&ch, 1) == 1) ? ch : EOF;
+ };
if (get_char(zip) != '\n') return false;
- for (int c = get_char(zip); c != '\n'; c = get_char(zip)) {
+ for (int c = get_char(zip); c != '\n'; c = get_char(zip)) {
if (c == EOF) return false;
- future_spec_.push_back(static_cast<char>(c));
- }
- }
-
- // We don't check for EOF so that we're forwards compatible.
-
- // If we did not find version information during the standard loading
- // process (as of tzh_version '3' that is unsupported), then ask the
+ future_spec_.push_back(static_cast<char>(c));
+ }
+ }
+
+ // We don't check for EOF so that we're forwards compatible.
+
+ // If we did not find version information during the standard loading
+ // process (as of tzh_version '3' that is unsupported), then ask the
// ZoneInfoSource for any out-of-bound version string it may be privy to.
- if (version_.empty()) {
- version_ = zip->Version();
- }
-
- // Trim redundant transitions. zic may have added these to work around
- // differences between the glibc and reference implementations (see
- // zic.c:dontmerge) and the Qt library (see zic.c:WORK_AROUND_QTBUG_53071).
- // For us, they just get in the way when we do future_spec_ extension.
- while (hdr.timecnt > 1) {
- if (!EquivTransitions(transitions_[hdr.timecnt - 1].type_index,
- transitions_[hdr.timecnt - 2].type_index)) {
- break;
- }
- hdr.timecnt -= 1;
- }
- transitions_.resize(hdr.timecnt);
-
- // Ensure that there is always a transition in the first half of the
+ if (version_.empty()) {
+ version_ = zip->Version();
+ }
+
+ // Trim redundant transitions. zic may have added these to work around
+ // differences between the glibc and reference implementations (see
+ // zic.c:dontmerge) and the Qt library (see zic.c:WORK_AROUND_QTBUG_53071).
+ // For us, they just get in the way when we do future_spec_ extension.
+ while (hdr.timecnt > 1) {
+ if (!EquivTransitions(transitions_[hdr.timecnt - 1].type_index,
+ transitions_[hdr.timecnt - 2].type_index)) {
+ break;
+ }
+ hdr.timecnt -= 1;
+ }
+ transitions_.resize(hdr.timecnt);
+
+ // Ensure that there is always a transition in the first half of the
// time line (the second half is handled below) so that the signed
// difference between a civil_second and the civil_second of its
// previous transition is always representable, without overflow.
- if (transitions_.empty() || transitions_.front().unix_time >= 0) {
- Transition& tr(*transitions_.emplace(transitions_.begin()));
+ if (transitions_.empty() || transitions_.front().unix_time >= 0) {
+ Transition& tr(*transitions_.emplace(transitions_.begin()));
tr.unix_time = -(1LL << 59); // -18267312070-10-26T17:01:52+00:00
- tr.type_index = default_transition_type_;
- }
-
- // Extend the transitions using the future specification.
+ tr.type_index = default_transition_type_;
+ }
+
+ // Extend the transitions using the future specification.
if (!ExtendTransitions()) return false;
-
+
// Ensure that there is always a transition in the second half of the
// time line (the first half is handled above) so that the signed
// difference between a civil_second and the civil_second of its
@@ -548,167 +548,167 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
tr.type_index = type_index;
}
- // Compute the local civil time for each transition and the preceding
- // second. These will be used for reverse conversions in MakeTime().
- const TransitionType* ttp = &transition_types_[default_transition_type_];
- for (std::size_t i = 0; i != transitions_.size(); ++i) {
- Transition& tr(transitions_[i]);
- tr.prev_civil_sec = LocalTime(tr.unix_time, *ttp).cs - 1;
- ttp = &transition_types_[tr.type_index];
- tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs;
- if (i != 0) {
- // Check that the transitions are ordered by civil time. Essentially
- // this means that an offset change cannot cross another such change.
- // No one does this in practice, and we depend on it in MakeTime().
- if (!Transition::ByCivilTime()(transitions_[i - 1], tr))
- return false; // out of order
- }
- }
-
- // Compute the maximum/minimum civil times that can be converted to a
- // time_point<seconds> for each of the zone's transition types.
- for (auto& tt : transition_types_) {
- tt.civil_max = LocalTime(seconds::max().count(), tt).cs;
- tt.civil_min = LocalTime(seconds::min().count(), tt).cs;
- }
-
- transitions_.shrink_to_fit();
- return true;
-}
-
-namespace {
-
+ // Compute the local civil time for each transition and the preceding
+ // second. These will be used for reverse conversions in MakeTime().
+ const TransitionType* ttp = &transition_types_[default_transition_type_];
+ for (std::size_t i = 0; i != transitions_.size(); ++i) {
+ Transition& tr(transitions_[i]);
+ tr.prev_civil_sec = LocalTime(tr.unix_time, *ttp).cs - 1;
+ ttp = &transition_types_[tr.type_index];
+ tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs;
+ if (i != 0) {
+ // Check that the transitions are ordered by civil time. Essentially
+ // this means that an offset change cannot cross another such change.
+ // No one does this in practice, and we depend on it in MakeTime().
+ if (!Transition::ByCivilTime()(transitions_[i - 1], tr))
+ return false; // out of order
+ }
+ }
+
+ // Compute the maximum/minimum civil times that can be converted to a
+ // time_point<seconds> for each of the zone's transition types.
+ for (auto& tt : transition_types_) {
+ tt.civil_max = LocalTime(seconds::max().count(), tt).cs;
+ tt.civil_min = LocalTime(seconds::min().count(), tt).cs;
+ }
+
+ transitions_.shrink_to_fit();
+ return true;
+}
+
+namespace {
+
using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>;
-// fopen(3) adaptor.
+// fopen(3) adaptor.
inline FilePtr FOpen(const char* path, const char* mode) {
-#if defined(_MSC_VER)
- FILE* fp;
- if (fopen_s(&fp, path, mode) != 0) fp = nullptr;
+#if defined(_MSC_VER)
+ FILE* fp;
+ if (fopen_s(&fp, path, mode) != 0) fp = nullptr;
return FilePtr(fp, fclose);
-#else
+#else
// TODO: Enable the close-on-exec flag.
return FilePtr(fopen(path, mode), fclose);
-#endif
-}
-
-// A stdio(3)-backed implementation of ZoneInfoSource.
-class FileZoneInfoSource : public ZoneInfoSource {
- public:
+#endif
+}
+
+// A stdio(3)-backed implementation of ZoneInfoSource.
+class FileZoneInfoSource : public ZoneInfoSource {
+ public:
static std::unique_ptr<ZoneInfoSource> Open(const TString& name);
-
- std::size_t Read(void* ptr, std::size_t size) override {
- size = std::min(size, len_);
- std::size_t nread = fread(ptr, 1, size, fp_.get());
- len_ -= nread;
- return nread;
- }
- int Skip(std::size_t offset) override {
- offset = std::min(offset, len_);
- int rc = fseek(fp_.get(), static_cast<long>(offset), SEEK_CUR);
- if (rc == 0) len_ -= offset;
- return rc;
- }
+
+ std::size_t Read(void* ptr, std::size_t size) override {
+ size = std::min(size, len_);
+ std::size_t nread = fread(ptr, 1, size, fp_.get());
+ len_ -= nread;
+ return nread;
+ }
+ int Skip(std::size_t offset) override {
+ offset = std::min(offset, len_);
+ int rc = fseek(fp_.get(), static_cast<long>(offset), SEEK_CUR);
+ if (rc == 0) len_ -= offset;
+ return rc;
+ }
TString Version() const override {
- // TODO: It would nice if the zoneinfo data included the tzdb version.
+ // TODO: It would nice if the zoneinfo data included the tzdb version.
return TString();
- }
-
- protected:
- explicit FileZoneInfoSource(
+ }
+
+ protected:
+ explicit FileZoneInfoSource(
FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max())
: fp_(std::move(fp)), len_(len) {}
-
- private:
+
+ private:
FilePtr fp_;
- std::size_t len_;
-};
-
-std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
+ std::size_t len_;
+};
+
+std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
const TString& name) {
- // Use of the "file:" prefix is intended for testing purposes only.
- const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
-
- // Map the time-zone name to a path name.
+ // Use of the "file:" prefix is intended for testing purposes only.
+ const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
+
+ // Map the time-zone name to a path name.
TString path;
- if (pos == name.size() || name[pos] != '/') {
- const char* tzdir = "/usr/share/zoneinfo";
- char* tzdir_env = nullptr;
-#if defined(_MSC_VER)
- _dupenv_s(&tzdir_env, nullptr, "TZDIR");
-#else
- tzdir_env = std::getenv("TZDIR");
-#endif
- if (tzdir_env && *tzdir_env) tzdir = tzdir_env;
- path += tzdir;
- path += '/';
-#if defined(_MSC_VER)
- free(tzdir_env);
-#endif
- }
+ if (pos == name.size() || name[pos] != '/') {
+ const char* tzdir = "/usr/share/zoneinfo";
+ char* tzdir_env = nullptr;
+#if defined(_MSC_VER)
+ _dupenv_s(&tzdir_env, nullptr, "TZDIR");
+#else
+ tzdir_env = std::getenv("TZDIR");
+#endif
+ if (tzdir_env && *tzdir_env) tzdir = tzdir_env;
+ path += tzdir;
+ path += '/';
+#if defined(_MSC_VER)
+ free(tzdir_env);
+#endif
+ }
path.append(name, pos, TString::npos);
-
- // Open the zoneinfo file.
+
+ // Open the zoneinfo file.
auto fp = FOpen(path.c_str(), "rb");
- if (fp == nullptr) return nullptr;
+ if (fp == nullptr) return nullptr;
return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp)));
-}
-
-class AndroidZoneInfoSource : public FileZoneInfoSource {
- public:
+}
+
+class AndroidZoneInfoSource : public FileZoneInfoSource {
+ public:
static std::unique_ptr<ZoneInfoSource> Open(const TString& name);
TString Version() const override { return version_; }
-
- private:
+
+ private:
explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len,
TString version)
: FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {}
TString version_;
-};
-
-std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
+};
+
+std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
const TString& name) {
- // Use of the "file:" prefix is intended for testing purposes only.
- const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
-
- // See Android's libc/tzcode/bionic.cpp for additional information.
- for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata",
- "/system/usr/share/zoneinfo/tzdata"}) {
+ // Use of the "file:" prefix is intended for testing purposes only.
+ const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
+
+ // See Android's libc/tzcode/bionic.cpp for additional information.
+ for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata",
+ "/system/usr/share/zoneinfo/tzdata"}) {
auto fp = FOpen(tzdata, "rb");
if (fp == nullptr) continue;
-
- char hbuf[24]; // covers header.zonetab_offset too
- if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue;
- if (strncmp(hbuf, "tzdata", 6) != 0) continue;
- const char* vers = (hbuf[11] == '\0') ? hbuf + 6 : "";
- const std::int_fast32_t index_offset = Decode32(hbuf + 12);
- const std::int_fast32_t data_offset = Decode32(hbuf + 16);
- if (index_offset < 0 || data_offset < index_offset) continue;
- if (fseek(fp.get(), static_cast<long>(index_offset), SEEK_SET) != 0)
- continue;
-
- char ebuf[52]; // covers entry.unused too
- const std::size_t index_size =
- static_cast<std::size_t>(data_offset - index_offset);
- const std::size_t zonecnt = index_size / sizeof(ebuf);
- if (zonecnt * sizeof(ebuf) != index_size) continue;
- for (std::size_t i = 0; i != zonecnt; ++i) {
- if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break;
- const std::int_fast32_t start = data_offset + Decode32(ebuf + 40);
- const std::int_fast32_t length = Decode32(ebuf + 44);
- if (start < 0 || length < 0) break;
- ebuf[40] = '\0'; // ensure zone name is NUL terminated
- if (strcmp(name.c_str() + pos, ebuf) == 0) {
- if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break;
- return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource(
+
+ char hbuf[24]; // covers header.zonetab_offset too
+ if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue;
+ if (strncmp(hbuf, "tzdata", 6) != 0) continue;
+ const char* vers = (hbuf[11] == '\0') ? hbuf + 6 : "";
+ const std::int_fast32_t index_offset = Decode32(hbuf + 12);
+ const std::int_fast32_t data_offset = Decode32(hbuf + 16);
+ if (index_offset < 0 || data_offset < index_offset) continue;
+ if (fseek(fp.get(), static_cast<long>(index_offset), SEEK_SET) != 0)
+ continue;
+
+ char ebuf[52]; // covers entry.unused too
+ const std::size_t index_size =
+ static_cast<std::size_t>(data_offset - index_offset);
+ const std::size_t zonecnt = index_size / sizeof(ebuf);
+ if (zonecnt * sizeof(ebuf) != index_size) continue;
+ for (std::size_t i = 0; i != zonecnt; ++i) {
+ if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break;
+ const std::int_fast32_t start = data_offset + Decode32(ebuf + 40);
+ const std::int_fast32_t length = Decode32(ebuf + 44);
+ if (start < 0 || length < 0) break;
+ ebuf[40] = '\0'; // ensure zone name is NUL terminated
+ if (strcmp(name.c_str() + pos, ebuf) == 0) {
+ if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break;
+ return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource(
std::move(fp), static_cast<std::size_t>(length), vers));
- }
- }
- }
-
- return nullptr;
-}
-
+ }
+ }
+ }
+
+ return nullptr;
+}
+
// A zoneinfo source for use inside Fuchsia components. This attempts to
// read zoneinfo files from one of several known paths in a component's
// incoming namespace. [Config data][1] is preferred, but package-specific
@@ -772,256 +772,256 @@ std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open(
return nullptr;
}
-} // namespace
-
+} // namespace
+
bool TimeZoneInfo::Load(const TString& name) {
- // We can ensure that the loading of UTC or any other fixed-offset
- // zone never fails because the simple, fixed-offset state can be
- // internally generated. Note that this depends on our choice to not
- // accept leap-second encoded ("right") zoneinfo.
- auto offset = seconds::zero();
- if (FixedOffsetFromName(name, &offset)) {
- return ResetToBuiltinUTC(offset);
- }
-
- // Find and use a ZoneInfoSource to load the named zone.
- auto zip = cctz_extension::zone_info_source_factory(
+ // We can ensure that the loading of UTC or any other fixed-offset
+ // zone never fails because the simple, fixed-offset state can be
+ // internally generated. Note that this depends on our choice to not
+ // accept leap-second encoded ("right") zoneinfo.
+ auto offset = seconds::zero();
+ if (FixedOffsetFromName(name, &offset)) {
+ return ResetToBuiltinUTC(offset);
+ }
+
+ // Find and use a ZoneInfoSource to load the named zone.
+ auto zip = cctz_extension::zone_info_source_factory(
name, [](const TString& n) -> std::unique_ptr<ZoneInfoSource> {
if (auto z = FileZoneInfoSource::Open(n)) return z;
if (auto z = AndroidZoneInfoSource::Open(n)) return z;
if (auto z = FuchsiaZoneInfoSource::Open(n)) return z;
- return nullptr;
- });
+ return nullptr;
+ });
return zip != nullptr && Load(zip.get());
-}
-
-// BreakTime() translation for a particular transition type.
-time_zone::absolute_lookup TimeZoneInfo::LocalTime(
- std::int_fast64_t unix_time, const TransitionType& tt) const {
- // A civil time in "+offset" looks like (time+offset) in UTC.
- // Note: We perform two additions in the civil_second domain to
- // sidestep the chance of overflow in (unix_time + tt.utc_offset).
+}
+
+// BreakTime() translation for a particular transition type.
+time_zone::absolute_lookup TimeZoneInfo::LocalTime(
+ std::int_fast64_t unix_time, const TransitionType& tt) const {
+ // A civil time in "+offset" looks like (time+offset) in UTC.
+ // Note: We perform two additions in the civil_second domain to
+ // sidestep the chance of overflow in (unix_time + tt.utc_offset).
return {(civil_second() + unix_time) + tt.utc_offset, tt.utc_offset,
tt.is_dst, &*abbreviations_.begin() + tt.abbr_index};
-}
-
-// BreakTime() translation for a particular transition.
+}
+
+// BreakTime() translation for a particular transition.
time_zone::absolute_lookup TimeZoneInfo::LocalTime(std::int_fast64_t unix_time,
const Transition& tr) const {
- const TransitionType& tt = transition_types_[tr.type_index];
- // Note: (unix_time - tr.unix_time) will never overflow as we
- // have ensured that there is always a "nearby" transition.
- return {tr.civil_sec + (unix_time - tr.unix_time), // TODO: Optimize.
+ const TransitionType& tt = transition_types_[tr.type_index];
+ // Note: (unix_time - tr.unix_time) will never overflow as we
+ // have ensured that there is always a "nearby" transition.
+ return {tr.civil_sec + (unix_time - tr.unix_time), // TODO: Optimize.
tt.utc_offset, tt.is_dst, &*abbreviations_.begin() + tt.abbr_index};
-}
-
-// MakeTime() translation with a conversion-preserving +N * 400-year shift.
-time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs,
- year_t c4_shift) const {
- assert(last_year_ - 400 < cs.year() && cs.year() <= last_year_);
- time_zone::civil_lookup cl = MakeTime(cs);
- if (c4_shift > seconds::max().count() / kSecsPer400Years) {
- cl.pre = cl.trans = cl.post = time_point<seconds>::max();
- } else {
- const auto offset = seconds(c4_shift * kSecsPer400Years);
- const auto limit = time_point<seconds>::max() - offset;
- for (auto* tp : {&cl.pre, &cl.trans, &cl.post}) {
- if (*tp > limit) {
- *tp = time_point<seconds>::max();
- } else {
- *tp += offset;
- }
- }
- }
- return cl;
-}
-
-time_zone::absolute_lookup TimeZoneInfo::BreakTime(
- const time_point<seconds>& tp) const {
- std::int_fast64_t unix_time = ToUnixSeconds(tp);
- const std::size_t timecnt = transitions_.size();
- assert(timecnt != 0); // We always add a transition.
-
- if (unix_time < transitions_[0].unix_time) {
- return LocalTime(unix_time, transition_types_[default_transition_type_]);
- }
- if (unix_time >= transitions_[timecnt - 1].unix_time) {
- // After the last transition. If we extended the transitions using
- // future_spec_, shift back to a supported year using the 400-year
- // cycle of calendaric equivalence and then compensate accordingly.
- if (extended_) {
- const std::int_fast64_t diff =
- unix_time - transitions_[timecnt - 1].unix_time;
- const year_t shift = diff / kSecsPer400Years + 1;
- const auto d = seconds(shift * kSecsPer400Years);
- time_zone::absolute_lookup al = BreakTime(tp - d);
- al.cs = YearShift(al.cs, shift * 400);
- return al;
- }
- return LocalTime(unix_time, transitions_[timecnt - 1]);
- }
-
- const std::size_t hint = local_time_hint_.load(std::memory_order_relaxed);
- if (0 < hint && hint < timecnt) {
- if (transitions_[hint - 1].unix_time <= unix_time) {
- if (unix_time < transitions_[hint].unix_time) {
- return LocalTime(unix_time, transitions_[hint - 1]);
- }
- }
- }
-
- const Transition target = {unix_time, 0, civil_second(), civil_second()};
- const Transition* begin = &transitions_[0];
- const Transition* tr = std::upper_bound(begin, begin + timecnt, target,
- Transition::ByUnixTime());
- local_time_hint_.store(static_cast<std::size_t>(tr - begin),
- std::memory_order_relaxed);
- return LocalTime(unix_time, *--tr);
-}
-
-time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const {
- const std::size_t timecnt = transitions_.size();
- assert(timecnt != 0); // We always add a transition.
-
- // Find the first transition after our target civil time.
- const Transition* tr = nullptr;
- const Transition* begin = &transitions_[0];
- const Transition* end = begin + timecnt;
- if (cs < begin->civil_sec) {
- tr = begin;
- } else if (cs >= transitions_[timecnt - 1].civil_sec) {
- tr = end;
- } else {
- const std::size_t hint = time_local_hint_.load(std::memory_order_relaxed);
- if (0 < hint && hint < timecnt) {
- if (transitions_[hint - 1].civil_sec <= cs) {
- if (cs < transitions_[hint].civil_sec) {
- tr = begin + hint;
- }
- }
- }
- if (tr == nullptr) {
- const Transition target = {0, 0, cs, civil_second()};
- tr = std::upper_bound(begin, end, target, Transition::ByCivilTime());
- time_local_hint_.store(static_cast<std::size_t>(tr - begin),
- std::memory_order_relaxed);
- }
- }
-
- if (tr == begin) {
- if (tr->prev_civil_sec >= cs) {
- // Before first transition, so use the default offset.
- const TransitionType& tt(transition_types_[default_transition_type_]);
- if (cs < tt.civil_min) return MakeUnique(time_point<seconds>::min());
- return MakeUnique(cs - (civil_second() + tt.utc_offset));
- }
- // tr->prev_civil_sec < cs < tr->civil_sec
- return MakeSkipped(*tr, cs);
- }
-
- if (tr == end) {
- if (cs > (--tr)->prev_civil_sec) {
- // After the last transition. If we extended the transitions using
- // future_spec_, shift back to a supported year using the 400-year
- // cycle of calendaric equivalence and then compensate accordingly.
- if (extended_ && cs.year() > last_year_) {
- const year_t shift = (cs.year() - last_year_ - 1) / 400 + 1;
- return TimeLocal(YearShift(cs, shift * -400), shift);
- }
- const TransitionType& tt(transition_types_[tr->type_index]);
- if (cs > tt.civil_max) return MakeUnique(time_point<seconds>::max());
- return MakeUnique(tr->unix_time + (cs - tr->civil_sec));
- }
- // tr->civil_sec <= cs <= tr->prev_civil_sec
- return MakeRepeated(*tr, cs);
- }
-
- if (tr->prev_civil_sec < cs) {
- // tr->prev_civil_sec < cs < tr->civil_sec
- return MakeSkipped(*tr, cs);
- }
-
- if (cs <= (--tr)->prev_civil_sec) {
- // tr->civil_sec <= cs <= tr->prev_civil_sec
- return MakeRepeated(*tr, cs);
- }
-
- // In between transitions.
- return MakeUnique(tr->unix_time + (cs - tr->civil_sec));
-}
-
+}
+
+// MakeTime() translation with a conversion-preserving +N * 400-year shift.
+time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs,
+ year_t c4_shift) const {
+ assert(last_year_ - 400 < cs.year() && cs.year() <= last_year_);
+ time_zone::civil_lookup cl = MakeTime(cs);
+ if (c4_shift > seconds::max().count() / kSecsPer400Years) {
+ cl.pre = cl.trans = cl.post = time_point<seconds>::max();
+ } else {
+ const auto offset = seconds(c4_shift * kSecsPer400Years);
+ const auto limit = time_point<seconds>::max() - offset;
+ for (auto* tp : {&cl.pre, &cl.trans, &cl.post}) {
+ if (*tp > limit) {
+ *tp = time_point<seconds>::max();
+ } else {
+ *tp += offset;
+ }
+ }
+ }
+ return cl;
+}
+
+time_zone::absolute_lookup TimeZoneInfo::BreakTime(
+ const time_point<seconds>& tp) const {
+ std::int_fast64_t unix_time = ToUnixSeconds(tp);
+ const std::size_t timecnt = transitions_.size();
+ assert(timecnt != 0); // We always add a transition.
+
+ if (unix_time < transitions_[0].unix_time) {
+ return LocalTime(unix_time, transition_types_[default_transition_type_]);
+ }
+ if (unix_time >= transitions_[timecnt - 1].unix_time) {
+ // After the last transition. If we extended the transitions using
+ // future_spec_, shift back to a supported year using the 400-year
+ // cycle of calendaric equivalence and then compensate accordingly.
+ if (extended_) {
+ const std::int_fast64_t diff =
+ unix_time - transitions_[timecnt - 1].unix_time;
+ const year_t shift = diff / kSecsPer400Years + 1;
+ const auto d = seconds(shift * kSecsPer400Years);
+ time_zone::absolute_lookup al = BreakTime(tp - d);
+ al.cs = YearShift(al.cs, shift * 400);
+ return al;
+ }
+ return LocalTime(unix_time, transitions_[timecnt - 1]);
+ }
+
+ const std::size_t hint = local_time_hint_.load(std::memory_order_relaxed);
+ if (0 < hint && hint < timecnt) {
+ if (transitions_[hint - 1].unix_time <= unix_time) {
+ if (unix_time < transitions_[hint].unix_time) {
+ return LocalTime(unix_time, transitions_[hint - 1]);
+ }
+ }
+ }
+
+ const Transition target = {unix_time, 0, civil_second(), civil_second()};
+ const Transition* begin = &transitions_[0];
+ const Transition* tr = std::upper_bound(begin, begin + timecnt, target,
+ Transition::ByUnixTime());
+ local_time_hint_.store(static_cast<std::size_t>(tr - begin),
+ std::memory_order_relaxed);
+ return LocalTime(unix_time, *--tr);
+}
+
+time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const {
+ const std::size_t timecnt = transitions_.size();
+ assert(timecnt != 0); // We always add a transition.
+
+ // Find the first transition after our target civil time.
+ const Transition* tr = nullptr;
+ const Transition* begin = &transitions_[0];
+ const Transition* end = begin + timecnt;
+ if (cs < begin->civil_sec) {
+ tr = begin;
+ } else if (cs >= transitions_[timecnt - 1].civil_sec) {
+ tr = end;
+ } else {
+ const std::size_t hint = time_local_hint_.load(std::memory_order_relaxed);
+ if (0 < hint && hint < timecnt) {
+ if (transitions_[hint - 1].civil_sec <= cs) {
+ if (cs < transitions_[hint].civil_sec) {
+ tr = begin + hint;
+ }
+ }
+ }
+ if (tr == nullptr) {
+ const Transition target = {0, 0, cs, civil_second()};
+ tr = std::upper_bound(begin, end, target, Transition::ByCivilTime());
+ time_local_hint_.store(static_cast<std::size_t>(tr - begin),
+ std::memory_order_relaxed);
+ }
+ }
+
+ if (tr == begin) {
+ if (tr->prev_civil_sec >= cs) {
+ // Before first transition, so use the default offset.
+ const TransitionType& tt(transition_types_[default_transition_type_]);
+ if (cs < tt.civil_min) return MakeUnique(time_point<seconds>::min());
+ return MakeUnique(cs - (civil_second() + tt.utc_offset));
+ }
+ // tr->prev_civil_sec < cs < tr->civil_sec
+ return MakeSkipped(*tr, cs);
+ }
+
+ if (tr == end) {
+ if (cs > (--tr)->prev_civil_sec) {
+ // After the last transition. If we extended the transitions using
+ // future_spec_, shift back to a supported year using the 400-year
+ // cycle of calendaric equivalence and then compensate accordingly.
+ if (extended_ && cs.year() > last_year_) {
+ const year_t shift = (cs.year() - last_year_ - 1) / 400 + 1;
+ return TimeLocal(YearShift(cs, shift * -400), shift);
+ }
+ const TransitionType& tt(transition_types_[tr->type_index]);
+ if (cs > tt.civil_max) return MakeUnique(time_point<seconds>::max());
+ return MakeUnique(tr->unix_time + (cs - tr->civil_sec));
+ }
+ // tr->civil_sec <= cs <= tr->prev_civil_sec
+ return MakeRepeated(*tr, cs);
+ }
+
+ if (tr->prev_civil_sec < cs) {
+ // tr->prev_civil_sec < cs < tr->civil_sec
+ return MakeSkipped(*tr, cs);
+ }
+
+ if (cs <= (--tr)->prev_civil_sec) {
+ // tr->civil_sec <= cs <= tr->prev_civil_sec
+ return MakeRepeated(*tr, cs);
+ }
+
+ // In between transitions.
+ return MakeUnique(tr->unix_time + (cs - tr->civil_sec));
+}
+
TString TimeZoneInfo::Version() const { return version_; }
-
+
TString TimeZoneInfo::Description() const {
- std::ostringstream oss;
- oss << "#trans=" << transitions_.size();
- oss << " #types=" << transition_types_.size();
- oss << " spec='" << future_spec_ << "'";
+ std::ostringstream oss;
+ oss << "#trans=" << transitions_.size();
+ oss << " #types=" << transition_types_.size();
+ oss << " spec='" << future_spec_ << "'";
return oss.str().c_str();
-}
-
-bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const {
- if (transitions_.empty()) return false;
- const Transition* begin = &transitions_[0];
- const Transition* end = begin + transitions_.size();
- if (begin->unix_time <= -(1LL << 59)) {
+}
+
+bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const {
+ if (transitions_.empty()) return false;
+ const Transition* begin = &transitions_[0];
+ const Transition* end = begin + transitions_.size();
+ if (begin->unix_time <= -(1LL << 59)) {
// Do not report the BIG_BANG found in some zoneinfo data as it is
// really a sentinel, not a transition. See pre-2018f tz/zic.c.
- ++begin;
- }
- std::int_fast64_t unix_time = ToUnixSeconds(tp);
- const Transition target = {unix_time, 0, civil_second(), civil_second()};
+ ++begin;
+ }
+ std::int_fast64_t unix_time = ToUnixSeconds(tp);
+ const Transition target = {unix_time, 0, civil_second(), civil_second()};
const Transition* tr =
std::upper_bound(begin, end, target, Transition::ByUnixTime());
- for (; tr != end; ++tr) { // skip no-op transitions
- std::uint_fast8_t prev_type_index =
- (tr == begin) ? default_transition_type_ : tr[-1].type_index;
- if (!EquivTransitions(prev_type_index, tr[0].type_index)) break;
- }
- // When tr == end we return false, ignoring future_spec_.
- if (tr == end) return false;
- trans->from = tr->prev_civil_sec + 1;
- trans->to = tr->civil_sec;
- return true;
-}
-
-bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const {
- if (transitions_.empty()) return false;
- const Transition* begin = &transitions_[0];
- const Transition* end = begin + transitions_.size();
- if (begin->unix_time <= -(1LL << 59)) {
+ for (; tr != end; ++tr) { // skip no-op transitions
+ std::uint_fast8_t prev_type_index =
+ (tr == begin) ? default_transition_type_ : tr[-1].type_index;
+ if (!EquivTransitions(prev_type_index, tr[0].type_index)) break;
+ }
+ // When tr == end we return false, ignoring future_spec_.
+ if (tr == end) return false;
+ trans->from = tr->prev_civil_sec + 1;
+ trans->to = tr->civil_sec;
+ return true;
+}
+
+bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const {
+ if (transitions_.empty()) return false;
+ const Transition* begin = &transitions_[0];
+ const Transition* end = begin + transitions_.size();
+ if (begin->unix_time <= -(1LL << 59)) {
// Do not report the BIG_BANG found in some zoneinfo data as it is
// really a sentinel, not a transition. See pre-2018f tz/zic.c.
- ++begin;
- }
- std::int_fast64_t unix_time = ToUnixSeconds(tp);
- if (FromUnixSeconds(unix_time) != tp) {
- if (unix_time == std::numeric_limits<std::int_fast64_t>::max()) {
- if (end == begin) return false; // Ignore future_spec_.
- trans->from = (--end)->prev_civil_sec + 1;
- trans->to = end->civil_sec;
- return true;
- }
- unix_time += 1; // ceils
- }
- const Transition target = {unix_time, 0, civil_second(), civil_second()};
+ ++begin;
+ }
+ std::int_fast64_t unix_time = ToUnixSeconds(tp);
+ if (FromUnixSeconds(unix_time) != tp) {
+ if (unix_time == std::numeric_limits<std::int_fast64_t>::max()) {
+ if (end == begin) return false; // Ignore future_spec_.
+ trans->from = (--end)->prev_civil_sec + 1;
+ trans->to = end->civil_sec;
+ return true;
+ }
+ unix_time += 1; // ceils
+ }
+ const Transition target = {unix_time, 0, civil_second(), civil_second()};
const Transition* tr =
std::lower_bound(begin, end, target, Transition::ByUnixTime());
- for (; tr != begin; --tr) { // skip no-op transitions
- std::uint_fast8_t prev_type_index =
- (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index;
- if (!EquivTransitions(prev_type_index, tr[-1].type_index)) break;
- }
- // When tr == end we return the "last" transition, ignoring future_spec_.
- if (tr == begin) return false;
- trans->from = (--tr)->prev_civil_sec + 1;
- trans->to = tr->civil_sec;
- return true;
-}
-
-} // namespace cctz
-} // namespace time_internal
+ for (; tr != begin; --tr) { // skip no-op transitions
+ std::uint_fast8_t prev_type_index =
+ (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index;
+ if (!EquivTransitions(prev_type_index, tr[-1].type_index)) break;
+ }
+ // When tr == end we return the "last" transition, ignoring future_spec_.
+ if (tr == begin) return false;
+ trans->from = (--tr)->prev_civil_sec + 1;
+ trans->to = tr->civil_sec;
+ return true;
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.h
index e8ac22d67f..e55fd51847 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.h
@@ -1,137 +1,137 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
-
-#include <atomic>
-#include <cstddef>
-#include <cstdint>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
+
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
#include <util/generic/string.h>
-#include <vector>
-
+#include <vector>
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
#include "y_absl/time/internal/cctz/include/cctz/zone_info_source.h"
-#include "time_zone_if.h"
-#include "tzfile.h"
-
+#include "time_zone_if.h"
+#include "tzfile.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// A transition to a new UTC offset.
-struct Transition {
- std::int_least64_t unix_time; // the instant of this transition
- std::uint_least8_t type_index; // index of the transition type
- civil_second civil_sec; // local civil time of transition
- civil_second prev_civil_sec; // local civil time one second earlier
-
- struct ByUnixTime {
- inline bool operator()(const Transition& lhs, const Transition& rhs) const {
- return lhs.unix_time < rhs.unix_time;
- }
- };
- struct ByCivilTime {
- inline bool operator()(const Transition& lhs, const Transition& rhs) const {
- return lhs.civil_sec < rhs.civil_sec;
- }
- };
-};
-
-// The characteristics of a particular transition.
-struct TransitionType {
- std::int_least32_t utc_offset; // the new prevailing UTC offset
- civil_second civil_max; // max convertible civil time for offset
- civil_second civil_min; // min convertible civil time for offset
- bool is_dst; // did we move into daylight-saving time
- std::uint_least8_t abbr_index; // index of the new abbreviation
-};
-
-// A time zone backed by the IANA Time Zone Database (zoneinfo).
-class TimeZoneInfo : public TimeZoneIf {
- public:
- TimeZoneInfo() = default;
- TimeZoneInfo(const TimeZoneInfo&) = delete;
- TimeZoneInfo& operator=(const TimeZoneInfo&) = delete;
-
- // Loads the zoneinfo for the given name, returning true if successful.
+namespace time_internal {
+namespace cctz {
+
+// A transition to a new UTC offset.
+struct Transition {
+ std::int_least64_t unix_time; // the instant of this transition
+ std::uint_least8_t type_index; // index of the transition type
+ civil_second civil_sec; // local civil time of transition
+ civil_second prev_civil_sec; // local civil time one second earlier
+
+ struct ByUnixTime {
+ inline bool operator()(const Transition& lhs, const Transition& rhs) const {
+ return lhs.unix_time < rhs.unix_time;
+ }
+ };
+ struct ByCivilTime {
+ inline bool operator()(const Transition& lhs, const Transition& rhs) const {
+ return lhs.civil_sec < rhs.civil_sec;
+ }
+ };
+};
+
+// The characteristics of a particular transition.
+struct TransitionType {
+ std::int_least32_t utc_offset; // the new prevailing UTC offset
+ civil_second civil_max; // max convertible civil time for offset
+ civil_second civil_min; // min convertible civil time for offset
+ bool is_dst; // did we move into daylight-saving time
+ std::uint_least8_t abbr_index; // index of the new abbreviation
+};
+
+// A time zone backed by the IANA Time Zone Database (zoneinfo).
+class TimeZoneInfo : public TimeZoneIf {
+ public:
+ TimeZoneInfo() = default;
+ TimeZoneInfo(const TimeZoneInfo&) = delete;
+ TimeZoneInfo& operator=(const TimeZoneInfo&) = delete;
+
+ // Loads the zoneinfo for the given name, returning true if successful.
bool Load(const TString& name);
-
- // TimeZoneIf implementations.
- time_zone::absolute_lookup BreakTime(
- const time_point<seconds>& tp) const override;
+
+ // TimeZoneIf implementations.
+ time_zone::absolute_lookup BreakTime(
+ const time_point<seconds>& tp) const override;
time_zone::civil_lookup MakeTime(const civil_second& cs) const override;
- bool NextTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const override;
- bool PrevTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const override;
+ bool NextTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const override;
+ bool PrevTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const override;
TString Version() const override;
TString Description() const override;
-
- private:
+
+ private:
struct Header { // counts of:
- std::size_t timecnt; // transition times
- std::size_t typecnt; // transition types
- std::size_t charcnt; // zone abbreviation characters
- std::size_t leapcnt; // leap seconds (we expect none)
- std::size_t ttisstdcnt; // UTC/local indicators (unused)
- std::size_t ttisutcnt; // standard/wall indicators (unused)
-
- bool Build(const tzhead& tzh);
- std::size_t DataLength(std::size_t time_len) const;
- };
-
+ std::size_t timecnt; // transition times
+ std::size_t typecnt; // transition types
+ std::size_t charcnt; // zone abbreviation characters
+ std::size_t leapcnt; // leap seconds (we expect none)
+ std::size_t ttisstdcnt; // UTC/local indicators (unused)
+ std::size_t ttisutcnt; // standard/wall indicators (unused)
+
+ bool Build(const tzhead& tzh);
+ std::size_t DataLength(std::size_t time_len) const;
+ };
+
bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
const TString& abbr, std::uint_least8_t* index);
- bool EquivTransitions(std::uint_fast8_t tt1_index,
- std::uint_fast8_t tt2_index) const;
+ bool EquivTransitions(std::uint_fast8_t tt1_index,
+ std::uint_fast8_t tt2_index) const;
bool ExtendTransitions();
-
- bool ResetToBuiltinUTC(const seconds& offset);
+
+ bool ResetToBuiltinUTC(const seconds& offset);
bool Load(ZoneInfoSource* zip);
-
- // Helpers for BreakTime() and MakeTime().
- time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
- const TransitionType& tt) const;
- time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
- const Transition& tr) const;
- time_zone::civil_lookup TimeLocal(const civil_second& cs,
- year_t c4_shift) const;
-
- std::vector<Transition> transitions_; // ordered by unix_time and civil_sec
- std::vector<TransitionType> transition_types_; // distinct transition types
+
+ // Helpers for BreakTime() and MakeTime().
+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
+ const TransitionType& tt) const;
+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
+ const Transition& tr) const;
+ time_zone::civil_lookup TimeLocal(const civil_second& cs,
+ year_t c4_shift) const;
+
+ std::vector<Transition> transitions_; // ordered by unix_time and civil_sec
+ std::vector<TransitionType> transition_types_; // distinct transition types
std::uint_fast8_t default_transition_type_; // for before first transition
TString abbreviations_; // all the NUL-terminated abbreviations
-
+
TString version_; // the tzdata version if available
TString future_spec_; // for after the last zic transition
- bool extended_; // future_spec_ was used to generate transitions
- year_t last_year_; // the final year of the generated transitions
-
- // We remember the transitions found during the last BreakTime() and
- // MakeTime() calls. If the next request is for the same transition we
- // will avoid re-searching.
- mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint
- mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint
-};
-
-} // namespace cctz
-} // namespace time_internal
+ bool extended_; // future_spec_ was used to generate transitions
+ year_t last_year_; // the final year of the generated transitions
+
+ // We remember the transitions found during the last BreakTime() and
+ // MakeTime() calls. If the next request is for the same transition we
+ // will avoid re-searching.
+ mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint
+ mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint
+};
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.cc
index 50a83453bb..a73832fc29 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.cc
@@ -1,32 +1,32 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#if defined(_WIN32) || defined(_WIN64)
-#define _CRT_SECURE_NO_WARNINGS 1
-#endif
-
-#include "time_zone_libc.h"
-
-#include <chrono>
-#include <ctime>
-#include <limits>
-#include <utility>
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#if defined(_WIN32) || defined(_WIN64)
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+
+#include "time_zone_libc.h"
+
+#include <chrono>
+#include <ctime>
+#include <limits>
+#include <utility>
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
+
#if defined(_AIX)
extern "C" {
extern long altzone;
@@ -35,281 +35,281 @@ extern long altzone;
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-namespace {
-
-#if defined(_WIN32) || defined(_WIN64)
-// Uses the globals: '_timezone', '_dstbias' and '_tzname'.
-auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) {
- const bool is_dst = tm.tm_isdst > 0;
- return _timezone + (is_dst ? _dstbias : 0);
-}
-auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) {
- const bool is_dst = tm.tm_isdst > 0;
- return _tzname[is_dst];
-}
+namespace time_internal {
+namespace cctz {
+
+namespace {
+
+#if defined(_WIN32) || defined(_WIN64)
+// Uses the globals: '_timezone', '_dstbias' and '_tzname'.
+auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return _timezone + (is_dst ? _dstbias : 0);
+}
+auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return _tzname[is_dst];
+}
#elif defined(__sun) || defined(_AIX)
-// Uses the globals: 'timezone', 'altzone' and 'tzname'.
-auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) {
- const bool is_dst = tm.tm_isdst > 0;
- return is_dst ? altzone : timezone;
-}
-auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
- const bool is_dst = tm.tm_isdst > 0;
- return tzname[is_dst];
-}
-#elif defined(__native_client__) || defined(__myriad2__) || \
- defined(__EMSCRIPTEN__)
-// Uses the globals: 'timezone' and 'tzname'.
-auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) {
- const bool is_dst = tm.tm_isdst > 0;
- return _timezone + (is_dst ? 60 * 60 : 0);
-}
-auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
- const bool is_dst = tm.tm_isdst > 0;
- return tzname[is_dst];
-}
-#else
-// Adapt to different spellings of the struct std::tm extension fields.
-#if defined(tm_gmtoff)
-auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) {
- return tm.tm_gmtoff;
-}
-#elif defined(__tm_gmtoff)
-auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) {
- return tm.__tm_gmtoff;
-}
-#else
-template <typename T>
-auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) {
- return tm.tm_gmtoff;
-}
-template <typename T>
-auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) {
- return tm.__tm_gmtoff;
-}
-#endif // tm_gmtoff
-#if defined(tm_zone)
+// Uses the globals: 'timezone', 'altzone' and 'tzname'.
+auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return is_dst ? altzone : timezone;
+}
+auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return tzname[is_dst];
+}
+#elif defined(__native_client__) || defined(__myriad2__) || \
+ defined(__EMSCRIPTEN__)
+// Uses the globals: 'timezone' and 'tzname'.
+auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return _timezone + (is_dst ? 60 * 60 : 0);
+}
+auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
+ const bool is_dst = tm.tm_isdst > 0;
+ return tzname[is_dst];
+}
+#else
+// Adapt to different spellings of the struct std::tm extension fields.
+#if defined(tm_gmtoff)
+auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) {
+ return tm.tm_gmtoff;
+}
+#elif defined(__tm_gmtoff)
+auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) {
+ return tm.__tm_gmtoff;
+}
+#else
+template <typename T>
+auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) {
+ return tm.tm_gmtoff;
+}
+template <typename T>
+auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) {
+ return tm.__tm_gmtoff;
+}
+#endif // tm_gmtoff
+#if defined(tm_zone)
auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { return tm.tm_zone; }
-#elif defined(__tm_zone)
-auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) {
- return tm.__tm_zone;
-}
-#else
-template <typename T>
-auto tm_zone(const T& tm) -> decltype(tm.tm_zone) {
- return tm.tm_zone;
-}
-template <typename T>
-auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) {
- return tm.__tm_zone;
-}
-#endif // tm_zone
-#endif
-
+#elif defined(__tm_zone)
+auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) {
+ return tm.__tm_zone;
+}
+#else
+template <typename T>
+auto tm_zone(const T& tm) -> decltype(tm.tm_zone) {
+ return tm.tm_zone;
+}
+template <typename T>
+auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) {
+ return tm.__tm_zone;
+}
+#endif // tm_zone
+#endif
+
inline std::tm* gm_time(const std::time_t* timep, std::tm* result) {
-#if defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN32) || defined(_WIN64)
return gmtime_s(result, timep) ? nullptr : result;
-#else
+#else
return gmtime_r(timep, result);
-#endif
-}
-
+#endif
+}
+
inline std::tm* local_time(const std::time_t* timep, std::tm* result) {
-#if defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN32) || defined(_WIN64)
return localtime_s(result, timep) ? nullptr : result;
-#else
+#else
return localtime_r(timep, result);
-#endif
-}
-
-// Converts a civil second and "dst" flag into a time_t and UTC offset.
-// Returns false if time_t cannot represent the requested civil second.
-// Caller must have already checked that cs.year() will fit into a tm_year.
-bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) {
- std::tm tm;
- tm.tm_year = static_cast<int>(cs.year() - year_t{1900});
- tm.tm_mon = cs.month() - 1;
- tm.tm_mday = cs.day();
- tm.tm_hour = cs.hour();
- tm.tm_min = cs.minute();
- tm.tm_sec = cs.second();
- tm.tm_isdst = is_dst;
- *t = std::mktime(&tm);
- if (*t == std::time_t{-1}) {
- std::tm tm2;
- const std::tm* tmp = local_time(t, &tm2);
- if (tmp == nullptr || tmp->tm_year != tm.tm_year ||
- tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday ||
- tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min ||
- tmp->tm_sec != tm.tm_sec) {
- // A true error (not just one second before the epoch).
- return false;
- }
- }
- *off = static_cast<int>(tm_gmtoff(tm));
- return true;
-}
-
-// Find the least time_t in [lo:hi] where local time matches offset, given:
-// (1) lo doesn't match, (2) hi does, and (3) there is only one transition.
-std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) {
- std::tm tm;
- while (lo + 1 != hi) {
- const std::time_t mid = lo + (hi - lo) / 2;
+#endif
+}
+
+// Converts a civil second and "dst" flag into a time_t and UTC offset.
+// Returns false if time_t cannot represent the requested civil second.
+// Caller must have already checked that cs.year() will fit into a tm_year.
+bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) {
+ std::tm tm;
+ tm.tm_year = static_cast<int>(cs.year() - year_t{1900});
+ tm.tm_mon = cs.month() - 1;
+ tm.tm_mday = cs.day();
+ tm.tm_hour = cs.hour();
+ tm.tm_min = cs.minute();
+ tm.tm_sec = cs.second();
+ tm.tm_isdst = is_dst;
+ *t = std::mktime(&tm);
+ if (*t == std::time_t{-1}) {
+ std::tm tm2;
+ const std::tm* tmp = local_time(t, &tm2);
+ if (tmp == nullptr || tmp->tm_year != tm.tm_year ||
+ tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday ||
+ tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min ||
+ tmp->tm_sec != tm.tm_sec) {
+ // A true error (not just one second before the epoch).
+ return false;
+ }
+ }
+ *off = static_cast<int>(tm_gmtoff(tm));
+ return true;
+}
+
+// Find the least time_t in [lo:hi] where local time matches offset, given:
+// (1) lo doesn't match, (2) hi does, and (3) there is only one transition.
+std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) {
+ std::tm tm;
+ while (lo + 1 != hi) {
+ const std::time_t mid = lo + (hi - lo) / 2;
std::tm* tmp = local_time(&mid, &tm);
if (tmp != nullptr) {
- if (tm_gmtoff(*tmp) == offset) {
- hi = mid;
- } else {
- lo = mid;
- }
- } else {
- // If std::tm cannot hold some result we resort to a linear search,
- // ignoring all failed conversions. Slow, but never really happens.
- while (++lo != hi) {
+ if (tm_gmtoff(*tmp) == offset) {
+ hi = mid;
+ } else {
+ lo = mid;
+ }
+ } else {
+ // If std::tm cannot hold some result we resort to a linear search,
+ // ignoring all failed conversions. Slow, but never really happens.
+ while (++lo != hi) {
tmp = local_time(&lo, &tm);
if (tmp != nullptr) {
- if (tm_gmtoff(*tmp) == offset) break;
- }
- }
- return lo;
- }
- }
- return hi;
-}
-
-} // namespace
-
+ if (tm_gmtoff(*tmp) == offset) break;
+ }
+ }
+ return lo;
+ }
+ }
+ return hi;
+}
+
+} // namespace
+
TimeZoneLibC::TimeZoneLibC(const TString& name)
- : local_(name == "localtime") {}
-
-time_zone::absolute_lookup TimeZoneLibC::BreakTime(
- const time_point<seconds>& tp) const {
- time_zone::absolute_lookup al;
- al.offset = 0;
- al.is_dst = false;
- al.abbr = "-00";
-
- const std::int_fast64_t s = ToUnixSeconds(tp);
-
- // If std::time_t cannot hold the input we saturate the output.
- if (s < std::numeric_limits<std::time_t>::min()) {
- al.cs = civil_second::min();
- return al;
- }
- if (s > std::numeric_limits<std::time_t>::max()) {
- al.cs = civil_second::max();
- return al;
- }
-
- const std::time_t t = static_cast<std::time_t>(s);
- std::tm tm;
- std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm);
-
- // If std::tm cannot hold the result we saturate the output.
- if (tmp == nullptr) {
- al.cs = (s < 0) ? civil_second::min() : civil_second::max();
- return al;
- }
-
- const year_t year = tmp->tm_year + year_t{1900};
+ : local_(name == "localtime") {}
+
+time_zone::absolute_lookup TimeZoneLibC::BreakTime(
+ const time_point<seconds>& tp) const {
+ time_zone::absolute_lookup al;
+ al.offset = 0;
+ al.is_dst = false;
+ al.abbr = "-00";
+
+ const std::int_fast64_t s = ToUnixSeconds(tp);
+
+ // If std::time_t cannot hold the input we saturate the output.
+ if (s < std::numeric_limits<std::time_t>::min()) {
+ al.cs = civil_second::min();
+ return al;
+ }
+ if (s > std::numeric_limits<std::time_t>::max()) {
+ al.cs = civil_second::max();
+ return al;
+ }
+
+ const std::time_t t = static_cast<std::time_t>(s);
+ std::tm tm;
+ std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm);
+
+ // If std::tm cannot hold the result we saturate the output.
+ if (tmp == nullptr) {
+ al.cs = (s < 0) ? civil_second::min() : civil_second::max();
+ return al;
+ }
+
+ const year_t year = tmp->tm_year + year_t{1900};
al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour,
tmp->tm_min, tmp->tm_sec);
- al.offset = static_cast<int>(tm_gmtoff(*tmp));
- al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz
- al.is_dst = tmp->tm_isdst > 0;
- return al;
-}
-
-time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const {
- if (!local_) {
- // If time_point<seconds> cannot hold the result we saturate.
- static const civil_second min_tp_cs =
- civil_second() + ToUnixSeconds(time_point<seconds>::min());
- static const civil_second max_tp_cs =
- civil_second() + ToUnixSeconds(time_point<seconds>::max());
+ al.offset = static_cast<int>(tm_gmtoff(*tmp));
+ al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz
+ al.is_dst = tmp->tm_isdst > 0;
+ return al;
+}
+
+time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const {
+ if (!local_) {
+ // If time_point<seconds> cannot hold the result we saturate.
+ static const civil_second min_tp_cs =
+ civil_second() + ToUnixSeconds(time_point<seconds>::min());
+ static const civil_second max_tp_cs =
+ civil_second() + ToUnixSeconds(time_point<seconds>::max());
const time_point<seconds> tp = (cs < min_tp_cs) ? time_point<seconds>::min()
: (cs > max_tp_cs)
? time_point<seconds>::max()
: FromUnixSeconds(cs - civil_second());
- return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
- }
-
- // If tm_year cannot hold the requested year we saturate the result.
- if (cs.year() < 0) {
- if (cs.year() < std::numeric_limits<int>::min() + year_t{1900}) {
- const time_point<seconds> tp = time_point<seconds>::min();
- return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
- }
- } else {
- if (cs.year() - year_t{1900} > std::numeric_limits<int>::max()) {
- const time_point<seconds> tp = time_point<seconds>::max();
- return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
- }
- }
-
- // We probe with "is_dst" values of 0 and 1 to try to distinguish unique
- // civil seconds from skipped or repeated ones. This is not always possible
- // however, as the "dst" flag does not change over some offset transitions.
- // We are also subject to the vagaries of mktime() implementations.
- std::time_t t0, t1;
- int offset0, offset1;
- if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) {
- if (t0 == t1) {
- // The civil time was singular (pre == trans == post).
- const time_point<seconds> tp = FromUnixSeconds(t0);
- return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
- }
-
- if (t0 > t1) {
- std::swap(t0, t1);
- std::swap(offset0, offset1);
- }
- const std::time_t tt = find_trans(t0, t1, offset1);
- const time_point<seconds> trans = FromUnixSeconds(tt);
-
- if (offset0 < offset1) {
- // The civil time did not exist (pre >= trans > post).
- const time_point<seconds> pre = FromUnixSeconds(t1);
- const time_point<seconds> post = FromUnixSeconds(t0);
- return {time_zone::civil_lookup::SKIPPED, pre, trans, post};
- }
-
- // The civil time was ambiguous (pre < trans <= post).
- const time_point<seconds> pre = FromUnixSeconds(t0);
- const time_point<seconds> post = FromUnixSeconds(t1);
- return {time_zone::civil_lookup::REPEATED, pre, trans, post};
- }
-
- // make_time() failed somehow so we saturate the result.
- const time_point<seconds> tp = (cs < civil_second())
- ? time_point<seconds>::min()
- : time_point<seconds>::max();
- return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
-}
-
-bool TimeZoneLibC::NextTransition(const time_point<seconds>&,
- time_zone::civil_transition*) const {
- return false;
-}
-
-bool TimeZoneLibC::PrevTransition(const time_point<seconds>&,
- time_zone::civil_transition*) const {
- return false;
-}
-
+ return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
+ }
+
+ // If tm_year cannot hold the requested year we saturate the result.
+ if (cs.year() < 0) {
+ if (cs.year() < std::numeric_limits<int>::min() + year_t{1900}) {
+ const time_point<seconds> tp = time_point<seconds>::min();
+ return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
+ }
+ } else {
+ if (cs.year() - year_t{1900} > std::numeric_limits<int>::max()) {
+ const time_point<seconds> tp = time_point<seconds>::max();
+ return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
+ }
+ }
+
+ // We probe with "is_dst" values of 0 and 1 to try to distinguish unique
+ // civil seconds from skipped or repeated ones. This is not always possible
+ // however, as the "dst" flag does not change over some offset transitions.
+ // We are also subject to the vagaries of mktime() implementations.
+ std::time_t t0, t1;
+ int offset0, offset1;
+ if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) {
+ if (t0 == t1) {
+ // The civil time was singular (pre == trans == post).
+ const time_point<seconds> tp = FromUnixSeconds(t0);
+ return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
+ }
+
+ if (t0 > t1) {
+ std::swap(t0, t1);
+ std::swap(offset0, offset1);
+ }
+ const std::time_t tt = find_trans(t0, t1, offset1);
+ const time_point<seconds> trans = FromUnixSeconds(tt);
+
+ if (offset0 < offset1) {
+ // The civil time did not exist (pre >= trans > post).
+ const time_point<seconds> pre = FromUnixSeconds(t1);
+ const time_point<seconds> post = FromUnixSeconds(t0);
+ return {time_zone::civil_lookup::SKIPPED, pre, trans, post};
+ }
+
+ // The civil time was ambiguous (pre < trans <= post).
+ const time_point<seconds> pre = FromUnixSeconds(t0);
+ const time_point<seconds> post = FromUnixSeconds(t1);
+ return {time_zone::civil_lookup::REPEATED, pre, trans, post};
+ }
+
+ // make_time() failed somehow so we saturate the result.
+ const time_point<seconds> tp = (cs < civil_second())
+ ? time_point<seconds>::min()
+ : time_point<seconds>::max();
+ return {time_zone::civil_lookup::UNIQUE, tp, tp, tp};
+}
+
+bool TimeZoneLibC::NextTransition(const time_point<seconds>&,
+ time_zone::civil_transition*) const {
+ return false;
+}
+
+bool TimeZoneLibC::PrevTransition(const time_point<seconds>&,
+ time_zone::civil_transition*) const {
+ return false;
+}
+
TString TimeZoneLibC::Version() const {
return TString(); // unknown
-}
-
+}
+
TString TimeZoneLibC::Description() const {
- return local_ ? "localtime" : "UTC";
-}
-
-} // namespace cctz
-} // namespace time_internal
+ return local_ ? "localtime" : "UTC";
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.h
index 724cdac939..fc926fecf7 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_libc.h
@@ -1,55 +1,55 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
+
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
-#include "time_zone_if.h"
-
+#include "time_zone_if.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3),
-// and which therefore only supports UTC and the local time zone.
-// TODO: Add support for fixed offsets from UTC.
-class TimeZoneLibC : public TimeZoneIf {
- public:
+namespace time_internal {
+namespace cctz {
+
+// A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3),
+// and which therefore only supports UTC and the local time zone.
+// TODO: Add support for fixed offsets from UTC.
+class TimeZoneLibC : public TimeZoneIf {
+ public:
explicit TimeZoneLibC(const TString& name);
-
- // TimeZoneIf implementations.
- time_zone::absolute_lookup BreakTime(
- const time_point<seconds>& tp) const override;
+
+ // TimeZoneIf implementations.
+ time_zone::absolute_lookup BreakTime(
+ const time_point<seconds>& tp) const override;
time_zone::civil_lookup MakeTime(const civil_second& cs) const override;
- bool NextTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const override;
- bool PrevTransition(const time_point<seconds>& tp,
- time_zone::civil_transition* trans) const override;
+ bool NextTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const override;
+ bool PrevTransition(const time_point<seconds>& tp,
+ time_zone::civil_transition* trans) const override;
TString Version() const override;
TString Description() const override;
-
- private:
- const bool local_; // localtime or UTC
-};
-
-} // namespace cctz
-} // namespace time_internal
+
+ private:
+ const bool local_; // localtime or UTC
+};
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc
index c62dfb5f2d..92c9208d6d 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc
@@ -1,33 +1,33 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "y_absl/base/config.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
-#if defined(__ANDROID__)
-#include <sys/system_properties.h>
-#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
-#include <dlfcn.h>
-#endif
-#endif
-
-#if defined(__APPLE__)
-#include <CoreFoundation/CFTimeZone.h>
-
-#include <vector>
-#endif
-
+
+#if defined(__ANDROID__)
+#include <sys/system_properties.h>
+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
+#include <dlfcn.h>
+#endif
+#endif
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CFTimeZone.h>
+
+#include <vector>
+#endif
+
#if defined(__Fuchsia__)
#error #include <fuchsia/intl/cpp/fidl.h>
#error #include <lib/async-loop/cpp/loop.h>
@@ -35,125 +35,125 @@
#error #include <zircon/types.h>
#endif
-#include <cstdlib>
-#include <cstring>
+#include <cstdlib>
+#include <cstring>
#include <util/generic/string.h>
-
-#include "time_zone_fixed.h"
-#include "time_zone_impl.h"
-
+
+#include "time_zone_fixed.h"
+#include "time_zone_impl.h"
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
-namespace {
-// Android 'L' removes __system_property_get() from the NDK, however
-// it is still a hidden symbol in libc so we use dlsym() to access it.
-// See Chromium's base/sys_info_android.cc for a similar example.
-
-using property_get_func = int (*)(const char*, char*);
-
-property_get_func LoadSystemPropertyGet() {
- int flag = RTLD_LAZY | RTLD_GLOBAL;
-#if defined(RTLD_NOLOAD)
- flag |= RTLD_NOLOAD; // libc.so should already be resident
-#endif
- if (void* handle = dlopen("libc.so", flag)) {
- void* sym = dlsym(handle, "__system_property_get");
- dlclose(handle);
- return reinterpret_cast<property_get_func>(sym);
- }
- return nullptr;
-}
-
-int __system_property_get(const char* name, char* value) {
- static property_get_func system_property_get = LoadSystemPropertyGet();
- return system_property_get ? system_property_get(name, value) : -1;
-}
-
-} // namespace
-#endif
-
+namespace time_internal {
+namespace cctz {
+
+#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
+namespace {
+// Android 'L' removes __system_property_get() from the NDK, however
+// it is still a hidden symbol in libc so we use dlsym() to access it.
+// See Chromium's base/sys_info_android.cc for a similar example.
+
+using property_get_func = int (*)(const char*, char*);
+
+property_get_func LoadSystemPropertyGet() {
+ int flag = RTLD_LAZY | RTLD_GLOBAL;
+#if defined(RTLD_NOLOAD)
+ flag |= RTLD_NOLOAD; // libc.so should already be resident
+#endif
+ if (void* handle = dlopen("libc.so", flag)) {
+ void* sym = dlsym(handle, "__system_property_get");
+ dlclose(handle);
+ return reinterpret_cast<property_get_func>(sym);
+ }
+ return nullptr;
+}
+
+int __system_property_get(const char* name, char* value) {
+ static property_get_func system_property_get = LoadSystemPropertyGet();
+ return system_property_get ? system_property_get(name, value) : -1;
+}
+
+} // namespace
+#endif
+
TString time_zone::name() const { return effective_impl().Name(); }
-
-time_zone::absolute_lookup time_zone::lookup(
- const time_point<seconds>& tp) const {
- return effective_impl().BreakTime(tp);
-}
-
-time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const {
- return effective_impl().MakeTime(cs);
-}
-
-bool time_zone::next_transition(const time_point<seconds>& tp,
- civil_transition* trans) const {
- return effective_impl().NextTransition(tp, trans);
-}
-
-bool time_zone::prev_transition(const time_point<seconds>& tp,
- civil_transition* trans) const {
- return effective_impl().PrevTransition(tp, trans);
-}
-
+
+time_zone::absolute_lookup time_zone::lookup(
+ const time_point<seconds>& tp) const {
+ return effective_impl().BreakTime(tp);
+}
+
+time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const {
+ return effective_impl().MakeTime(cs);
+}
+
+bool time_zone::next_transition(const time_point<seconds>& tp,
+ civil_transition* trans) const {
+ return effective_impl().NextTransition(tp, trans);
+}
+
+bool time_zone::prev_transition(const time_point<seconds>& tp,
+ civil_transition* trans) const {
+ return effective_impl().PrevTransition(tp, trans);
+}
+
TString time_zone::version() const { return effective_impl().Version(); }
-
+
TString time_zone::description() const {
- return effective_impl().Description();
-}
-
-const time_zone::Impl& time_zone::effective_impl() const {
- if (impl_ == nullptr) {
- // Dereferencing an implicit-UTC time_zone is expected to be
- // rare, so we don't mind paying a small synchronization cost.
- return *time_zone::Impl::UTC().impl_;
- }
- return *impl_;
-}
-
+ return effective_impl().Description();
+}
+
+const time_zone::Impl& time_zone::effective_impl() const {
+ if (impl_ == nullptr) {
+ // Dereferencing an implicit-UTC time_zone is expected to be
+ // rare, so we don't mind paying a small synchronization cost.
+ return *time_zone::Impl::UTC().impl_;
+ }
+ return *impl_;
+}
+
bool load_time_zone(const TString& name, time_zone* tz) {
- return time_zone::Impl::LoadTimeZone(name, tz);
-}
-
-time_zone utc_time_zone() {
- return time_zone::Impl::UTC(); // avoid name lookup
-}
-
-time_zone fixed_time_zone(const seconds& offset) {
- time_zone tz;
- load_time_zone(FixedOffsetToName(offset), &tz);
- return tz;
-}
-
-time_zone local_time_zone() {
- const char* zone = ":localtime";
-#if defined(__ANDROID__)
- char sysprop[PROP_VALUE_MAX];
- if (__system_property_get("persist.sys.timezone", sysprop) > 0) {
- zone = sysprop;
- }
-#endif
-#if defined(__APPLE__)
- std::vector<char> buffer;
- CFTimeZoneRef tz_default = CFTimeZoneCopyDefault();
- if (CFStringRef tz_name = CFTimeZoneGetName(tz_default)) {
- CFStringEncoding encoding = kCFStringEncodingUTF8;
- CFIndex length = CFStringGetLength(tz_name);
- buffer.resize(CFStringGetMaximumSizeForEncoding(length, encoding) + 1);
- if (CFStringGetCString(tz_name, &buffer[0], buffer.size(), encoding)) {
- zone = &buffer[0];
- }
- }
- CFRelease(tz_default);
-#endif
+ return time_zone::Impl::LoadTimeZone(name, tz);
+}
+
+time_zone utc_time_zone() {
+ return time_zone::Impl::UTC(); // avoid name lookup
+}
+
+time_zone fixed_time_zone(const seconds& offset) {
+ time_zone tz;
+ load_time_zone(FixedOffsetToName(offset), &tz);
+ return tz;
+}
+
+time_zone local_time_zone() {
+ const char* zone = ":localtime";
+#if defined(__ANDROID__)
+ char sysprop[PROP_VALUE_MAX];
+ if (__system_property_get("persist.sys.timezone", sysprop) > 0) {
+ zone = sysprop;
+ }
+#endif
+#if defined(__APPLE__)
+ std::vector<char> buffer;
+ CFTimeZoneRef tz_default = CFTimeZoneCopyDefault();
+ if (CFStringRef tz_name = CFTimeZoneGetName(tz_default)) {
+ CFStringEncoding encoding = kCFStringEncodingUTF8;
+ CFIndex length = CFStringGetLength(tz_name);
+ buffer.resize(CFStringGetMaximumSizeForEncoding(length, encoding) + 1);
+ if (CFStringGetCString(tz_name, &buffer[0], buffer.size(), encoding)) {
+ zone = &buffer[0];
+ }
+ }
+ CFRelease(tz_default);
+#endif
#if defined(__Fuchsia__)
TString primary_tz;
[&]() {
// Note: We can't use the synchronous FIDL API here because it doesn't
// allow timeouts; if the FIDL call failed, local_time_zone() would never
// return.
-
+
const zx::duration kTimeout = zx::msec(500);
// Don't attach to the thread because otherwise the thread's dispatcher
@@ -190,47 +190,47 @@ time_zone local_time_zone() {
}
#endif
- // Allow ${TZ} to override to default zone.
- char* tz_env = nullptr;
-#if defined(_MSC_VER)
- _dupenv_s(&tz_env, nullptr, "TZ");
-#else
- tz_env = std::getenv("TZ");
-#endif
- if (tz_env) zone = tz_env;
-
- // We only support the "[:]<zone-name>" form.
- if (*zone == ':') ++zone;
-
- // Map "localtime" to a system-specific name, but
- // allow ${LOCALTIME} to override the default name.
- char* localtime_env = nullptr;
- if (strcmp(zone, "localtime") == 0) {
-#if defined(_MSC_VER)
- // System-specific default is just "localtime".
- _dupenv_s(&localtime_env, nullptr, "LOCALTIME");
-#else
- zone = "/etc/localtime"; // System-specific default.
- localtime_env = std::getenv("LOCALTIME");
-#endif
- if (localtime_env) zone = localtime_env;
- }
-
+ // Allow ${TZ} to override to default zone.
+ char* tz_env = nullptr;
+#if defined(_MSC_VER)
+ _dupenv_s(&tz_env, nullptr, "TZ");
+#else
+ tz_env = std::getenv("TZ");
+#endif
+ if (tz_env) zone = tz_env;
+
+ // We only support the "[:]<zone-name>" form.
+ if (*zone == ':') ++zone;
+
+ // Map "localtime" to a system-specific name, but
+ // allow ${LOCALTIME} to override the default name.
+ char* localtime_env = nullptr;
+ if (strcmp(zone, "localtime") == 0) {
+#if defined(_MSC_VER)
+ // System-specific default is just "localtime".
+ _dupenv_s(&localtime_env, nullptr, "LOCALTIME");
+#else
+ zone = "/etc/localtime"; // System-specific default.
+ localtime_env = std::getenv("LOCALTIME");
+#endif
+ if (localtime_env) zone = localtime_env;
+ }
+
const TString name = zone;
-#if defined(_MSC_VER)
- free(localtime_env);
- free(tz_env);
-#endif
-
- time_zone tz;
- load_time_zone(name, &tz); // Falls back to UTC.
- // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and
- // arrange for %z to generate "-0000" when we don't know the local
- // offset because the load_time_zone() failed and we're using UTC.
- return tz;
-}
-
-} // namespace cctz
-} // namespace time_internal
+#if defined(_MSC_VER)
+ free(localtime_env);
+ free(tz_env);
+#endif
+
+ time_zone tz;
+ load_time_zone(name, &tz); // Falls back to UTC.
+ // TODO: Follow the RFC3339 "Unknown Local Offset Convention" and
+ // arrange for %z to generate "-0000" when we don't know the local
+ // offset because the load_time_zone() failed and we're using UTC.
+ return tz;
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.cc
index 5da69c47e2..4096503915 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.cc
@@ -1,159 +1,159 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "time_zone_posix.h"
-
-#include <cstddef>
-#include <cstring>
-#include <limits>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "time_zone_posix.h"
+
+#include <cstddef>
+#include <cstring>
+#include <limits>
#include <util/generic/string.h>
-
+
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-namespace {
-
-const char kDigits[] = "0123456789";
-
-const char* ParseInt(const char* p, int min, int max, int* vp) {
- int value = 0;
- const char* op = p;
- const int kMaxInt = std::numeric_limits<int>::max();
- for (; const char* dp = strchr(kDigits, *p); ++p) {
- int d = static_cast<int>(dp - kDigits);
- if (d >= 10) break; // '\0'
- if (value > kMaxInt / 10) return nullptr;
- value *= 10;
- if (value > kMaxInt - d) return nullptr;
- value += d;
- }
- if (p == op || value < min || value > max) return nullptr;
- *vp = value;
- return p;
-}
-
-// abbr = <.*?> | [^-+,\d]{3,}
+namespace time_internal {
+namespace cctz {
+
+namespace {
+
+const char kDigits[] = "0123456789";
+
+const char* ParseInt(const char* p, int min, int max, int* vp) {
+ int value = 0;
+ const char* op = p;
+ const int kMaxInt = std::numeric_limits<int>::max();
+ for (; const char* dp = strchr(kDigits, *p); ++p) {
+ int d = static_cast<int>(dp - kDigits);
+ if (d >= 10) break; // '\0'
+ if (value > kMaxInt / 10) return nullptr;
+ value *= 10;
+ if (value > kMaxInt - d) return nullptr;
+ value += d;
+ }
+ if (p == op || value < min || value > max) return nullptr;
+ *vp = value;
+ return p;
+}
+
+// abbr = <.*?> | [^-+,\d]{3,}
const char* ParseAbbr(const char* p, TString* abbr) {
- const char* op = p;
- if (*p == '<') { // special zoneinfo <...> form
- while (*++p != '>') {
- if (*p == '\0') return nullptr;
- }
- abbr->assign(op + 1, static_cast<std::size_t>(p - op) - 1);
- return ++p;
- }
- while (*p != '\0') {
- if (strchr("-+,", *p)) break;
- if (strchr(kDigits, *p)) break;
- ++p;
- }
- if (p - op < 3) return nullptr;
- abbr->assign(op, static_cast<std::size_t>(p - op));
- return p;
-}
-
-// offset = [+|-]hh[:mm[:ss]] (aggregated into single seconds value)
-const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign,
- std::int_fast32_t* offset) {
- if (p == nullptr) return nullptr;
- if (*p == '+' || *p == '-') {
- if (*p++ == '-') sign = -sign;
- }
- int hours = 0;
- int minutes = 0;
- int seconds = 0;
-
- p = ParseInt(p, min_hour, max_hour, &hours);
- if (p == nullptr) return nullptr;
- if (*p == ':') {
- p = ParseInt(p + 1, 0, 59, &minutes);
- if (p == nullptr) return nullptr;
- if (*p == ':') {
- p = ParseInt(p + 1, 0, 59, &seconds);
- if (p == nullptr) return nullptr;
- }
- }
- *offset = sign * ((((hours * 60) + minutes) * 60) + seconds);
- return p;
-}
-
-// datetime = ( Jn | n | Mm.w.d ) [ / offset ]
-const char* ParseDateTime(const char* p, PosixTransition* res) {
- if (p != nullptr && *p == ',') {
- if (*++p == 'M') {
- int month = 0;
- if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') {
- int week = 0;
- if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') {
- int weekday = 0;
- if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) {
- res->date.fmt = PosixTransition::M;
- res->date.m.month = static_cast<std::int_fast8_t>(month);
- res->date.m.week = static_cast<std::int_fast8_t>(week);
- res->date.m.weekday = static_cast<std::int_fast8_t>(weekday);
- }
- }
- }
- } else if (*p == 'J') {
- int day = 0;
- if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) {
- res->date.fmt = PosixTransition::J;
- res->date.j.day = static_cast<std::int_fast16_t>(day);
- }
- } else {
- int day = 0;
- if ((p = ParseInt(p, 0, 365, &day)) != nullptr) {
- res->date.fmt = PosixTransition::N;
- res->date.n.day = static_cast<std::int_fast16_t>(day);
- }
- }
- }
- if (p != nullptr) {
- res->time.offset = 2 * 60 * 60; // default offset is 02:00:00
- if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset);
- }
- return p;
-}
-
-} // namespace
-
-// spec = std offset [ dst [ offset ] , datetime , datetime ]
+ const char* op = p;
+ if (*p == '<') { // special zoneinfo <...> form
+ while (*++p != '>') {
+ if (*p == '\0') return nullptr;
+ }
+ abbr->assign(op + 1, static_cast<std::size_t>(p - op) - 1);
+ return ++p;
+ }
+ while (*p != '\0') {
+ if (strchr("-+,", *p)) break;
+ if (strchr(kDigits, *p)) break;
+ ++p;
+ }
+ if (p - op < 3) return nullptr;
+ abbr->assign(op, static_cast<std::size_t>(p - op));
+ return p;
+}
+
+// offset = [+|-]hh[:mm[:ss]] (aggregated into single seconds value)
+const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign,
+ std::int_fast32_t* offset) {
+ if (p == nullptr) return nullptr;
+ if (*p == '+' || *p == '-') {
+ if (*p++ == '-') sign = -sign;
+ }
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
+
+ p = ParseInt(p, min_hour, max_hour, &hours);
+ if (p == nullptr) return nullptr;
+ if (*p == ':') {
+ p = ParseInt(p + 1, 0, 59, &minutes);
+ if (p == nullptr) return nullptr;
+ if (*p == ':') {
+ p = ParseInt(p + 1, 0, 59, &seconds);
+ if (p == nullptr) return nullptr;
+ }
+ }
+ *offset = sign * ((((hours * 60) + minutes) * 60) + seconds);
+ return p;
+}
+
+// datetime = ( Jn | n | Mm.w.d ) [ / offset ]
+const char* ParseDateTime(const char* p, PosixTransition* res) {
+ if (p != nullptr && *p == ',') {
+ if (*++p == 'M') {
+ int month = 0;
+ if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') {
+ int week = 0;
+ if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') {
+ int weekday = 0;
+ if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) {
+ res->date.fmt = PosixTransition::M;
+ res->date.m.month = static_cast<std::int_fast8_t>(month);
+ res->date.m.week = static_cast<std::int_fast8_t>(week);
+ res->date.m.weekday = static_cast<std::int_fast8_t>(weekday);
+ }
+ }
+ }
+ } else if (*p == 'J') {
+ int day = 0;
+ if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) {
+ res->date.fmt = PosixTransition::J;
+ res->date.j.day = static_cast<std::int_fast16_t>(day);
+ }
+ } else {
+ int day = 0;
+ if ((p = ParseInt(p, 0, 365, &day)) != nullptr) {
+ res->date.fmt = PosixTransition::N;
+ res->date.n.day = static_cast<std::int_fast16_t>(day);
+ }
+ }
+ }
+ if (p != nullptr) {
+ res->time.offset = 2 * 60 * 60; // default offset is 02:00:00
+ if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset);
+ }
+ return p;
+}
+
+} // namespace
+
+// spec = std offset [ dst [ offset ] , datetime , datetime ]
bool ParsePosixSpec(const TString& spec, PosixTimeZone* res) {
- const char* p = spec.c_str();
- if (*p == ':') return false;
-
- p = ParseAbbr(p, &res->std_abbr);
- p = ParseOffset(p, 0, 24, -1, &res->std_offset);
- if (p == nullptr) return false;
- if (*p == '\0') return true;
-
- p = ParseAbbr(p, &res->dst_abbr);
- if (p == nullptr) return false;
- res->dst_offset = res->std_offset + (60 * 60); // default
- if (*p != ',') p = ParseOffset(p, 0, 24, -1, &res->dst_offset);
-
- p = ParseDateTime(p, &res->dst_start);
- p = ParseDateTime(p, &res->dst_end);
-
- return p != nullptr && *p == '\0';
-}
-
-} // namespace cctz
-} // namespace time_internal
+ const char* p = spec.c_str();
+ if (*p == ':') return false;
+
+ p = ParseAbbr(p, &res->std_abbr);
+ p = ParseOffset(p, 0, 24, -1, &res->std_offset);
+ if (p == nullptr) return false;
+ if (*p == '\0') return true;
+
+ p = ParseAbbr(p, &res->dst_abbr);
+ if (p == nullptr) return false;
+ res->dst_offset = res->std_offset + (60 * 60); // default
+ if (*p != ',') p = ParseOffset(p, 0, 24, -1, &res->dst_offset);
+
+ p = ParseDateTime(p, &res->dst_start);
+ p = ParseDateTime(p, &res->dst_end);
+
+ return p != nullptr && *p == '\0';
+}
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.h
index f136435930..e9de2b77ad 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_posix.h
@@ -1,132 +1,132 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in
-// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html.
-//
-// The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0",
-// which would be broken down as ...
-//
-// PosixTimeZone {
-// std_abbr = "PST"
-// std_offset = -28800
-// dst_abbr = "PDT"
-// dst_offset = -25200
-// dst_start = PosixTransition {
-// date {
-// m {
-// month = 3
-// week = 2
-// weekday = 0
-// }
-// }
-// time {
-// offset = 7200
-// }
-// }
-// dst_end = PosixTransition {
-// date {
-// m {
-// month = 11
-// week = 1
-// weekday = 0
-// }
-// }
-// time {
-// offset = 7200
-// }
-// }
-// }
-
-#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
-#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
-
-#include <cstdint>
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in
+// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html.
+//
+// The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0",
+// which would be broken down as ...
+//
+// PosixTimeZone {
+// std_abbr = "PST"
+// std_offset = -28800
+// dst_abbr = "PDT"
+// dst_offset = -25200
+// dst_start = PosixTransition {
+// date {
+// m {
+// month = 3
+// week = 2
+// weekday = 0
+// }
+// }
+// time {
+// offset = 7200
+// }
+// }
+// dst_end = PosixTransition {
+// date {
+// m {
+// month = 11
+// week = 1
+// weekday = 0
+// }
+// }
+// time {
+// offset = 7200
+// }
+// }
+// }
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
+
+#include <cstdint>
#include <util/generic/string.h>
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// The date/time of the transition. The date is specified as either:
-// (J) the Nth day of the year (1 <= N <= 365), excluding leap days, or
-// (N) the Nth day of the year (0 <= N <= 365), including leap days, or
-// (M) the Nth weekday of a month (e.g., the 2nd Sunday in March).
-// The time, specified as a day offset, identifies the particular moment
-// of the transition, and may be negative or >= 24h, and in which case
-// it would take us to another day, and perhaps week, or even month.
-struct PosixTransition {
- enum DateFormat { J, N, M };
-
- struct Date {
- struct NonLeapDay {
- std::int_fast16_t day; // day of non-leap year [1:365]
- };
- struct Day {
- std::int_fast16_t day; // day of year [0:365]
- };
- struct MonthWeekWeekday {
- std::int_fast8_t month; // month of year [1:12]
- std::int_fast8_t week; // week of month [1:5] (5==last)
- std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat
- };
-
- DateFormat fmt;
-
- union {
- NonLeapDay j;
- Day n;
- MonthWeekWeekday m;
- };
- };
-
- struct Time {
- std::int_fast32_t offset; // seconds before/after 00:00:00
- };
-
- Date date;
- Time time;
-};
-
-// The entirety of a POSIX-string specified time-zone rule. The standard
-// abbreviation and offset are always given. If the time zone includes
-// daylight saving, then the daylight abbrevation is non-empty and the
-// remaining fields are also valid. Note that the start/end transitions
-// are not ordered---in the southern hemisphere the transition to end
-// daylight time occurs first in any particular year.
-struct PosixTimeZone {
+namespace time_internal {
+namespace cctz {
+
+// The date/time of the transition. The date is specified as either:
+// (J) the Nth day of the year (1 <= N <= 365), excluding leap days, or
+// (N) the Nth day of the year (0 <= N <= 365), including leap days, or
+// (M) the Nth weekday of a month (e.g., the 2nd Sunday in March).
+// The time, specified as a day offset, identifies the particular moment
+// of the transition, and may be negative or >= 24h, and in which case
+// it would take us to another day, and perhaps week, or even month.
+struct PosixTransition {
+ enum DateFormat { J, N, M };
+
+ struct Date {
+ struct NonLeapDay {
+ std::int_fast16_t day; // day of non-leap year [1:365]
+ };
+ struct Day {
+ std::int_fast16_t day; // day of year [0:365]
+ };
+ struct MonthWeekWeekday {
+ std::int_fast8_t month; // month of year [1:12]
+ std::int_fast8_t week; // week of month [1:5] (5==last)
+ std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat
+ };
+
+ DateFormat fmt;
+
+ union {
+ NonLeapDay j;
+ Day n;
+ MonthWeekWeekday m;
+ };
+ };
+
+ struct Time {
+ std::int_fast32_t offset; // seconds before/after 00:00:00
+ };
+
+ Date date;
+ Time time;
+};
+
+// The entirety of a POSIX-string specified time-zone rule. The standard
+// abbreviation and offset are always given. If the time zone includes
+// daylight saving, then the daylight abbrevation is non-empty and the
+// remaining fields are also valid. Note that the start/end transitions
+// are not ordered---in the southern hemisphere the transition to end
+// daylight time occurs first in any particular year.
+struct PosixTimeZone {
TString std_abbr;
- std::int_fast32_t std_offset;
-
+ std::int_fast32_t std_offset;
+
TString dst_abbr;
- std::int_fast32_t dst_offset;
- PosixTransition dst_start;
- PosixTransition dst_end;
-};
-
-// Breaks down a POSIX time-zone specification into its constituent pieces,
-// filling in any missing values (DST offset, or start/end transition times)
-// with the standard-defined defaults. Returns false if the specification
-// could not be parsed (although some fields of *res may have been altered).
+ std::int_fast32_t dst_offset;
+ PosixTransition dst_start;
+ PosixTransition dst_end;
+};
+
+// Breaks down a POSIX time-zone specification into its constituent pieces,
+// filling in any missing values (DST offset, or start/end transition times)
+// with the standard-defined defaults. Returns false if the specification
+// could not be parsed (although some fields of *res may have been altered).
bool ParsePosixSpec(const TString& spec, PosixTimeZone* res);
-
-} // namespace cctz
-} // namespace time_internal
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h
index 1683a698cb..31e8598257 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h
@@ -1,47 +1,47 @@
-/* Layout and location of TZif files. */
-
-#ifndef TZFILE_H
-
-#define TZFILE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** Information about time zone files.
-*/
-
-#ifndef TZDIR
+/* Layout and location of TZif files. */
+
+#ifndef TZFILE_H
+
+#define TZFILE_H
+
+/*
+** This file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** This header is for use ONLY with the time conversion code.
+** There is no guarantee that it will remain unchanged,
+** or that it will remain at all.
+** Do NOT copy it to any system include directory.
+** Thank you!
+*/
+
+/*
+** Information about time zone files.
+*/
+
+#ifndef TZDIR
#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
-
-#ifndef TZDEFAULT
+
+#ifndef TZDEFAULT
#define TZDEFAULT "/etc/localtime"
-#endif /* !defined TZDEFAULT */
-
-#ifndef TZDEFRULES
+#endif /* !defined TZDEFAULT */
+
+#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
-#endif /* !defined TZDEFRULES */
-
-/* See Internet RFC 8536 for more details about the following format. */
-
-/*
-** Each file begins with. . .
-*/
-
+#endif /* !defined TZDEFRULES */
+
+/* See Internet RFC 8536 for more details about the following format. */
+
+/*
+** Each file begins with. . .
+*/
+
#define TZ_MAGIC "TZif"
-
-struct tzhead {
+
+struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */
char tzh_reserved[15]; /* reserved; must be zero */
@@ -51,72 +51,72 @@ struct tzhead {
char tzh_timecnt[4]; /* coded number of transition times */
char tzh_typecnt[4]; /* coded number of local time types */
char tzh_charcnt[4]; /* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-** tzh_timecnt (char [4])s coded transition times a la time(2)
-** tzh_timecnt (unsigned char)s types of local time starting at above
-** tzh_typecnt repetitions of
-** one (char [4]) coded UT offset in seconds
-** one (unsigned char) used to set tm_isdst
-** one (unsigned char) that's an abbreviation list index
-** tzh_charcnt (char)s '\0'-terminated zone abbreviations
-** tzh_leapcnt repetitions of
-** one (char [4]) coded leap second transition times
-** one (char [4]) total correction after above
-** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
-** time is standard time, if 0,
-** transition time is local (wall clock)
-** time; if absent, transition times are
-** assumed to be local time
-** tzh_ttisutcnt (char)s indexed by type; if 1, transition
-** time is UT, if 0, transition time is
-** local time; if absent, transition
-** times are assumed to be local time.
-** When this is 1, the corresponding
-** std/wall indicator must also be 1.
-*/
-
-/*
-** If tzh_version is '2' or greater, the above is followed by a second instance
-** of tzhead and a second instance of the data in which each coded transition
-** time uses 8 rather than 4 chars,
+};
+
+/*
+** . . .followed by. . .
+**
+** tzh_timecnt (char [4])s coded transition times a la time(2)
+** tzh_timecnt (unsigned char)s types of local time starting at above
+** tzh_typecnt repetitions of
+** one (char [4]) coded UT offset in seconds
+** one (unsigned char) used to set tm_isdst
+** one (unsigned char) that's an abbreviation list index
+** tzh_charcnt (char)s '\0'-terminated zone abbreviations
+** tzh_leapcnt repetitions of
+** one (char [4]) coded leap second transition times
+** one (char [4]) total correction after above
+** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
+** time is standard time, if 0,
+** transition time is local (wall clock)
+** time; if absent, transition times are
+** assumed to be local time
+** tzh_ttisutcnt (char)s indexed by type; if 1, transition
+** time is UT, if 0, transition time is
+** local time; if absent, transition
+** times are assumed to be local time.
+** When this is 1, the corresponding
+** std/wall indicator must also be 1.
+*/
+
+/*
+** If tzh_version is '2' or greater, the above is followed by a second instance
+** of tzhead and a second instance of the data in which each coded transition
+** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
-** instants after the last transition time stored in the file
-** (with nothing between the newlines if there is no POSIX representation for
-** such instants).
-**
-** If tz_version is '3' or greater, the above is extended as follows.
+** instants after the last transition time stored in the file
+** (with nothing between the newlines if there is no POSIX representation for
+** such instants).
+**
+** If tz_version is '3' or greater, the above is extended as follows.
** First, the POSIX TZ string's hour offset may range from -167
-** through 167 as compared to the POSIX-required 0 through 24.
-** Second, its DST start time may be January 1 at 00:00 and its stop
-** time December 31 at 24:00 plus the difference between DST and
-** standard time, indicating DST all year.
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-#ifndef TZ_MAX_TIMES
+** through 167 as compared to the POSIX-required 0 through 24.
+** Second, its DST start time may be January 1 at 00:00 and its stop
+** time December 31 at 24:00 plus the difference between DST and
+** standard time, indicating DST all year.
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+#ifndef TZ_MAX_TIMES
#define TZ_MAX_TIMES 2000
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZ_MAX_TYPES
-/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
+#endif /* !defined TZ_MAX_TIMES */
+
+#ifndef TZ_MAX_TYPES
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined TZ_MAX_TYPES */
-
-#ifndef TZ_MAX_CHARS
+
+#ifndef TZ_MAX_CHARS
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
#endif /* !defined TZ_MAX_CHARS */
-
-#ifndef TZ_MAX_LEAPS
+
+#ifndef TZ_MAX_LEAPS
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
-
-#endif /* !defined TZFILE_H */
+
+#endif /* !defined TZFILE_H */
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc
index 1b65bd6090..be58c20fb3 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc
@@ -1,70 +1,70 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#include "y_absl/time/internal/cctz/include/cctz/zone_info_source.h"
-
+
#include "y_absl/base/config.h"
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz {
-
-// Defined out-of-line to avoid emitting a weak vtable in all TUs.
-ZoneInfoSource::~ZoneInfoSource() {}
+namespace time_internal {
+namespace cctz {
+
+// Defined out-of-line to avoid emitting a weak vtable in all TUs.
+ZoneInfoSource::~ZoneInfoSource() {}
TString ZoneInfoSource::Version() const { return TString(); }
-
-} // namespace cctz
-} // namespace time_internal
+
+} // namespace cctz
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-namespace cctz_extension {
-
-namespace {
-
-// A default for cctz_extension::zone_info_source_factory, which simply
-// defers to the fallback factory.
+namespace time_internal {
+namespace cctz_extension {
+
+namespace {
+
+// A default for cctz_extension::zone_info_source_factory, which simply
+// defers to the fallback factory.
std::unique_ptr<y_absl::time_internal::cctz::ZoneInfoSource> DefaultFactory(
const TString& name,
const std::function<
std::unique_ptr<y_absl::time_internal::cctz::ZoneInfoSource>(
const TString& name)>& fallback_factory) {
- return fallback_factory(name);
-}
-
-} // namespace
-
-// A "weak" definition for cctz_extension::zone_info_source_factory.
-// The user may override this with their own "strong" definition (see
-// zone_info_source.h).
-#if !defined(__has_attribute)
-#define __has_attribute(x) 0
-#endif
-// MinGW is GCC on Windows, so while it asserts __has_attribute(weak), the
-// Windows linker cannot handle that. Nor does the MinGW compiler know how to
-// pass "#pragma comment(linker, ...)" to the Windows linker.
-#if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__)
+ return fallback_factory(name);
+}
+
+} // namespace
+
+// A "weak" definition for cctz_extension::zone_info_source_factory.
+// The user may override this with their own "strong" definition (see
+// zone_info_source.h).
+#if !defined(__has_attribute)
+#define __has_attribute(x) 0
+#endif
+// MinGW is GCC on Windows, so while it asserts __has_attribute(weak), the
+// Windows linker cannot handle that. Nor does the MinGW compiler know how to
+// pass "#pragma comment(linker, ...)" to the Windows linker.
+#if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__)
ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) =
DefaultFactory;
-#elif defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBCPP_VERSION)
-extern ZoneInfoSourceFactory zone_info_source_factory;
-extern ZoneInfoSourceFactory default_factory;
-ZoneInfoSourceFactory default_factory = DefaultFactory;
+#elif defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBCPP_VERSION)
+extern ZoneInfoSourceFactory zone_info_source_factory;
+extern ZoneInfoSourceFactory default_factory;
+ZoneInfoSourceFactory default_factory = DefaultFactory;
#if defined(_M_IX86) || defined(_M_ARM)
#pragma comment( \
linker, \
@@ -101,15 +101,15 @@ ZoneInfoSourceFactory default_factory = DefaultFactory;
"@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \
"@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \
"@@ZEA")
-#else
-#error Unsupported MSVC platform
-#endif // _M_<PLATFORM>
-#else
-// Make it a "strong" definition if we have no other choice.
-ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory;
-#endif
-
-} // namespace cctz_extension
-} // namespace time_internal
+#else
+#error Unsupported MSVC platform
+#endif // _M_<PLATFORM>
+#else
+// Make it a "strong" definition if we have no other choice.
+ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory;
+#endif
+
+} // namespace cctz_extension
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_chrono.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_chrono.inc
index 746fe23532..ef28e97e5a 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_chrono.inc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_chrono.inc
@@ -1,31 +1,31 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <chrono>
-#include <cstdint>
-
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <chrono>
+#include <cstdint>
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-
-static int64_t GetCurrentTimeNanosFromSystem() {
- return std::chrono::duration_cast<std::chrono::nanoseconds>(
- std::chrono::system_clock::now() -
- std::chrono::system_clock::from_time_t(0))
- .count();
-}
-
-} // namespace time_internal
+namespace time_internal {
+
+static int64_t GetCurrentTimeNanosFromSystem() {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now() -
+ std::chrono::system_clock::from_time_t(0))
+ .count();
+}
+
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_posix.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_posix.inc
index 2f6ae9af03..1068fea026 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_posix.inc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/get_current_time_posix.inc
@@ -1,24 +1,24 @@
#include "y_absl/time/clock.h"
-
-#include <sys/time.h>
-#include <ctime>
-#include <cstdint>
-
+
+#include <sys/time.h>
+#include <ctime>
+#include <cstdint>
+
#include "y_absl/base/internal/raw_logging.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-
-static int64_t GetCurrentTimeNanosFromSystem() {
- const int64_t kNanosPerSecond = 1000 * 1000 * 1000;
- struct timespec ts;
- ABSL_RAW_CHECK(clock_gettime(CLOCK_REALTIME, &ts) == 0,
- "Failed to read real-time clock.");
- return (int64_t{ts.tv_sec} * kNanosPerSecond +
- int64_t{ts.tv_nsec});
-}
-
-} // namespace time_internal
+namespace time_internal {
+
+static int64_t GetCurrentTimeNanosFromSystem() {
+ const int64_t kNanosPerSecond = 1000 * 1000 * 1000;
+ struct timespec ts;
+ ABSL_RAW_CHECK(clock_gettime(CLOCK_REALTIME, &ts) == 0,
+ "Failed to read real-time clock.");
+ return (int64_t{ts.tv_sec} * kNanosPerSecond +
+ int64_t{ts.tv_nsec});
+}
+
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/test_util.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/test_util.h
index 7432c67347..22b991b836 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/test_util.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/test_util.h
@@ -1,33 +1,33 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_TIME_INTERNAL_TEST_UTIL_H_
-#define ABSL_TIME_INTERNAL_TEST_UTIL_H_
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_TEST_UTIL_H_
+#define ABSL_TIME_INTERNAL_TEST_UTIL_H_
+
#include <util/generic/string.h>
-
+
#include "y_absl/time/time.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-namespace time_internal {
-
-// Loads the named timezone, but dies on any failure.
+namespace time_internal {
+
+// Loads the named timezone, but dies on any failure.
y_absl::TimeZone LoadTimeZone(const TString& name);
-
-} // namespace time_internal
+
+} // namespace time_internal
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_
+
+#endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/zoneinfo.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/zoneinfo.inc
index e453bb8356..bfed82990d 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/zoneinfo.inc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/zoneinfo.inc
@@ -1,729 +1,729 @@
-unsigned char America_Los_Angeles[] = {
- 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
- 0x9e, 0xa6, 0x48, 0xa0, 0x9f, 0xbb, 0x15, 0x90, 0xa0, 0x86, 0x2a, 0xa0,
- 0xa1, 0x9a, 0xf7, 0x90, 0xcb, 0x89, 0x1a, 0xa0, 0xd2, 0x23, 0xf4, 0x70,
- 0xd2, 0x61, 0x26, 0x10, 0xd6, 0xfe, 0x74, 0x5c, 0xd8, 0x80, 0xad, 0x90,
- 0xda, 0xfe, 0xc3, 0x90, 0xdb, 0xc0, 0x90, 0x10, 0xdc, 0xde, 0xa5, 0x90,
- 0xdd, 0xa9, 0xac, 0x90, 0xde, 0xbe, 0x87, 0x90, 0xdf, 0x89, 0x8e, 0x90,
- 0xe0, 0x9e, 0x69, 0x90, 0xe1, 0x69, 0x70, 0x90, 0xe2, 0x7e, 0x4b, 0x90,
- 0xe3, 0x49, 0x52, 0x90, 0xe4, 0x5e, 0x2d, 0x90, 0xe5, 0x29, 0x34, 0x90,
- 0xe6, 0x47, 0x4a, 0x10, 0xe7, 0x12, 0x51, 0x10, 0xe8, 0x27, 0x2c, 0x10,
- 0xe8, 0xf2, 0x33, 0x10, 0xea, 0x07, 0x0e, 0x10, 0xea, 0xd2, 0x15, 0x10,
- 0xeb, 0xe6, 0xf0, 0x10, 0xec, 0xb1, 0xf7, 0x10, 0xed, 0xc6, 0xd2, 0x10,
- 0xee, 0x91, 0xd9, 0x10, 0xef, 0xaf, 0xee, 0x90, 0xf0, 0x71, 0xbb, 0x10,
- 0xf1, 0x8f, 0xd0, 0x90, 0xf2, 0x7f, 0xc1, 0x90, 0xf3, 0x6f, 0xb2, 0x90,
- 0xf4, 0x5f, 0xa3, 0x90, 0xf5, 0x4f, 0x94, 0x90, 0xf6, 0x3f, 0x85, 0x90,
- 0xf7, 0x2f, 0x76, 0x90, 0xf8, 0x28, 0xa2, 0x10, 0xf9, 0x0f, 0x58, 0x90,
- 0xfa, 0x08, 0x84, 0x10, 0xfa, 0xf8, 0x83, 0x20, 0xfb, 0xe8, 0x66, 0x10,
- 0xfc, 0xd8, 0x65, 0x20, 0xfd, 0xc8, 0x48, 0x10, 0xfe, 0xb8, 0x47, 0x20,
- 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x98, 0x29, 0x20, 0x01, 0x88, 0x0c, 0x10,
- 0x02, 0x78, 0x0b, 0x20, 0x03, 0x71, 0x28, 0x90, 0x04, 0x61, 0x27, 0xa0,
- 0x05, 0x51, 0x0a, 0x90, 0x06, 0x41, 0x09, 0xa0, 0x07, 0x30, 0xec, 0x90,
- 0x07, 0x8d, 0x43, 0xa0, 0x09, 0x10, 0xce, 0x90, 0x09, 0xad, 0xbf, 0x20,
- 0x0a, 0xf0, 0xb0, 0x90, 0x0b, 0xe0, 0xaf, 0xa0, 0x0c, 0xd9, 0xcd, 0x10,
- 0x0d, 0xc0, 0x91, 0xa0, 0x0e, 0xb9, 0xaf, 0x10, 0x0f, 0xa9, 0xae, 0x20,
- 0x10, 0x99, 0x91, 0x10, 0x11, 0x89, 0x90, 0x20, 0x12, 0x79, 0x73, 0x10,
- 0x13, 0x69, 0x72, 0x20, 0x14, 0x59, 0x55, 0x10, 0x15, 0x49, 0x54, 0x20,
- 0x16, 0x39, 0x37, 0x10, 0x17, 0x29, 0x36, 0x20, 0x18, 0x22, 0x53, 0x90,
- 0x19, 0x09, 0x18, 0x20, 0x1a, 0x02, 0x35, 0x90, 0x1a, 0xf2, 0x34, 0xa0,
- 0x1b, 0xe2, 0x17, 0x90, 0x1c, 0xd2, 0x16, 0xa0, 0x1d, 0xc1, 0xf9, 0x90,
- 0x1e, 0xb1, 0xf8, 0xa0, 0x1f, 0xa1, 0xdb, 0x90, 0x20, 0x76, 0x2b, 0x20,
- 0x21, 0x81, 0xbd, 0x90, 0x22, 0x56, 0x0d, 0x20, 0x23, 0x6a, 0xda, 0x10,
- 0x24, 0x35, 0xef, 0x20, 0x25, 0x4a, 0xbc, 0x10, 0x26, 0x15, 0xd1, 0x20,
- 0x27, 0x2a, 0x9e, 0x10, 0x27, 0xfe, 0xed, 0xa0, 0x29, 0x0a, 0x80, 0x10,
- 0x29, 0xde, 0xcf, 0xa0, 0x2a, 0xea, 0x62, 0x10, 0x2b, 0xbe, 0xb1, 0xa0,
- 0x2c, 0xd3, 0x7e, 0x90, 0x2d, 0x9e, 0x93, 0xa0, 0x2e, 0xb3, 0x60, 0x90,
- 0x2f, 0x7e, 0x75, 0xa0, 0x30, 0x93, 0x42, 0x90, 0x31, 0x67, 0x92, 0x20,
- 0x32, 0x73, 0x24, 0x90, 0x33, 0x47, 0x74, 0x20, 0x34, 0x53, 0x06, 0x90,
- 0x35, 0x27, 0x56, 0x20, 0x36, 0x32, 0xe8, 0x90, 0x37, 0x07, 0x38, 0x20,
- 0x38, 0x1c, 0x05, 0x10, 0x38, 0xe7, 0x1a, 0x20, 0x39, 0xfb, 0xe7, 0x10,
- 0x3a, 0xc6, 0xfc, 0x20, 0x3b, 0xdb, 0xc9, 0x10, 0x3c, 0xb0, 0x18, 0xa0,
- 0x3d, 0xbb, 0xab, 0x10, 0x3e, 0x8f, 0xfa, 0xa0, 0x3f, 0x9b, 0x8d, 0x10,
- 0x40, 0x6f, 0xdc, 0xa0, 0x41, 0x84, 0xa9, 0x90, 0x42, 0x4f, 0xbe, 0xa0,
- 0x43, 0x64, 0x8b, 0x90, 0x44, 0x2f, 0xa0, 0xa0, 0x45, 0x44, 0x6d, 0x90,
- 0x45, 0xf3, 0xd3, 0x20, 0x47, 0x2d, 0x8a, 0x10, 0x47, 0xd3, 0xb5, 0x20,
- 0x49, 0x0d, 0x6c, 0x10, 0x49, 0xb3, 0x97, 0x20, 0x4a, 0xed, 0x4e, 0x10,
- 0x4b, 0x9c, 0xb3, 0xa0, 0x4c, 0xd6, 0x6a, 0x90, 0x4d, 0x7c, 0x95, 0xa0,
- 0x4e, 0xb6, 0x4c, 0x90, 0x4f, 0x5c, 0x77, 0xa0, 0x50, 0x96, 0x2e, 0x90,
- 0x51, 0x3c, 0x59, 0xa0, 0x52, 0x76, 0x10, 0x90, 0x53, 0x1c, 0x3b, 0xa0,
- 0x54, 0x55, 0xf2, 0x90, 0x54, 0xfc, 0x1d, 0xa0, 0x56, 0x35, 0xd4, 0x90,
- 0x56, 0xe5, 0x3a, 0x20, 0x58, 0x1e, 0xf1, 0x10, 0x58, 0xc5, 0x1c, 0x20,
- 0x59, 0xfe, 0xd3, 0x10, 0x5a, 0xa4, 0xfe, 0x20, 0x5b, 0xde, 0xb5, 0x10,
- 0x5c, 0x84, 0xe0, 0x20, 0x5d, 0xbe, 0x97, 0x10, 0x5e, 0x64, 0xc2, 0x20,
- 0x5f, 0x9e, 0x79, 0x10, 0x60, 0x4d, 0xde, 0xa0, 0x61, 0x87, 0x95, 0x90,
- 0x62, 0x2d, 0xc0, 0xa0, 0x63, 0x67, 0x77, 0x90, 0x64, 0x0d, 0xa2, 0xa0,
- 0x65, 0x47, 0x59, 0x90, 0x65, 0xed, 0x84, 0xa0, 0x67, 0x27, 0x3b, 0x90,
- 0x67, 0xcd, 0x66, 0xa0, 0x69, 0x07, 0x1d, 0x90, 0x69, 0xad, 0x48, 0xa0,
- 0x6a, 0xe6, 0xff, 0x90, 0x6b, 0x96, 0x65, 0x20, 0x6c, 0xd0, 0x1c, 0x10,
- 0x6d, 0x76, 0x47, 0x20, 0x6e, 0xaf, 0xfe, 0x10, 0x6f, 0x56, 0x29, 0x20,
- 0x70, 0x8f, 0xe0, 0x10, 0x71, 0x36, 0x0b, 0x20, 0x72, 0x6f, 0xc2, 0x10,
- 0x73, 0x15, 0xed, 0x20, 0x74, 0x4f, 0xa4, 0x10, 0x74, 0xff, 0x09, 0xa0,
- 0x76, 0x38, 0xc0, 0x90, 0x76, 0xde, 0xeb, 0xa0, 0x78, 0x18, 0xa2, 0x90,
- 0x78, 0xbe, 0xcd, 0xa0, 0x79, 0xf8, 0x84, 0x90, 0x7a, 0x9e, 0xaf, 0xa0,
- 0x7b, 0xd8, 0x66, 0x90, 0x7c, 0x7e, 0x91, 0xa0, 0x7d, 0xb8, 0x48, 0x90,
- 0x7e, 0x5e, 0x73, 0xa0, 0x7f, 0x98, 0x2a, 0x90, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90,
- 0x01, 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90,
- 0x01, 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00,
- 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00,
- 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xbb, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x04,
- 0x1a, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x48, 0xa0, 0xff, 0xff,
- 0xff, 0xff, 0x9f, 0xbb, 0x15, 0x90, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86,
- 0x2a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xf7, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xcb, 0x89, 0x1a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x23,
- 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x61, 0x26, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xd6, 0xfe, 0x74, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x80,
- 0xad, 0x90, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xc3, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xdb, 0xc0, 0x90, 0x10, 0xff, 0xff, 0xff, 0xff, 0xdc, 0xde,
- 0xa5, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0xac, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xde, 0xbe, 0x87, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x89,
- 0x8e, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x69, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xe1, 0x69, 0x70, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe2, 0x7e,
- 0x4b, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x52, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xe4, 0x5e, 0x2d, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x29,
- 0x34, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x4a, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xe7, 0x12, 0x51, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0x27,
- 0x2c, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0xf2, 0x33, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xea, 0x07, 0x0e, 0x10, 0xff, 0xff, 0xff, 0xff, 0xea, 0xd2,
- 0x15, 0x10, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xf0, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xec, 0xb1, 0xf7, 0x10, 0xff, 0xff, 0xff, 0xff, 0xed, 0xc6,
- 0xd2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xee, 0x91, 0xd9, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xef, 0xaf, 0xee, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x71,
- 0xbb, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xd0, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xf2, 0x7f, 0xc1, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x6f,
- 0xb2, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0xa3, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xf5, 0x4f, 0x94, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x3f,
- 0x85, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x76, 0x90, 0xff, 0xff,
- 0xff, 0xff, 0xf8, 0x28, 0xa2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0f,
- 0x58, 0x90, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x84, 0x10, 0xff, 0xff,
- 0xff, 0xff, 0xfa, 0xf8, 0x83, 0x20, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xe8,
- 0x66, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x65, 0x20, 0xff, 0xff,
- 0xff, 0xff, 0xfd, 0xc8, 0x48, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xb8,
- 0x47, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x98, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88,
- 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x0b, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61,
- 0x27, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0a, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x41, 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30,
- 0xec, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x43, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x09, 0x10, 0xce, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0xad,
- 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0xb0, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x0b, 0xe0, 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd9,
- 0xcd, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x91, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0xb9, 0xaf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa9,
- 0xae, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x89, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79,
- 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x72, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49,
- 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x17, 0x29, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22,
- 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x18, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x1a, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xf2,
- 0x34, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe2, 0x17, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0xd2, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1,
- 0xf9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xf8, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x1f, 0xa1, 0xdb, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76,
- 0x2b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xbd, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x22, 0x56, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6a,
- 0xda, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xef, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x4a, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15,
- 0xd1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x9e, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x27, 0xfe, 0xed, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0a,
- 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xcf, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x2a, 0xea, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xbe,
- 0xb1, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x7e, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x9e, 0x93, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb3,
- 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x75, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67,
- 0x92, 0x20, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x33, 0x47, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x34, 0x53,
- 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x56, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x36, 0x32, 0xe8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07,
- 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x05, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0xe7, 0x1a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x39, 0xfb,
- 0xe7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xfc, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x3b, 0xdb, 0xc9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb0,
- 0x18, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0xab, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x3e, 0x8f, 0xfa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9b,
- 0x8d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xdc, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x41, 0x84, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4f,
- 0xbe, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8b, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x44, 0x2f, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44,
- 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xd3, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x47, 0x2d, 0x8a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xd3,
- 0xb5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x6c, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x49, 0xb3, 0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xed,
- 0x4e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0xb3, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x4c, 0xd6, 0x6a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x7c,
- 0x95, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x4c, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x4f, 0x5c, 0x77, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96,
- 0x2e, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x59, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1c,
- 0x3b, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xf2, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x54, 0xfc, 0x1d, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35,
- 0xd4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x3a, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x58, 0x1e, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xc5,
- 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xd3, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x5a, 0xa4, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xde,
- 0xb5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xe0, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x5d, 0xbe, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x64,
- 0xc2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x79, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x4d, 0xde, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87,
- 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0xc0, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0d,
- 0xa2, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x65, 0xed, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27,
- 0x3b, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x66, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x69, 0x07, 0x1d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xad,
- 0x48, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xff, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x6b, 0x96, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd0,
- 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x47, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x6e, 0xaf, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x56,
- 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xe0, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x71, 0x36, 0x0b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6f,
- 0xc2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xed, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x74, 0x4f, 0xa4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0xff,
- 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0xc0, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xde, 0xeb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18,
- 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xcd, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x79, 0xf8, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x9e,
- 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x66, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0x7e, 0x91, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xb8,
- 0x48, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x73, 0xa0, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0x98, 0x2a, 0x90, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90, 0x01,
- 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90, 0x01,
- 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x50,
- 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50,
- 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x0a, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2c, 0x4d, 0x33,
- 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31, 0x2e, 0x31, 0x2e, 0x30,
- 0x0a
-};
-unsigned int America_Los_Angeles_len = 2845;
-unsigned char America_New_York[] = {
- 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
- 0x9e, 0xa6, 0x1e, 0x70, 0x9f, 0xba, 0xeb, 0x60, 0xa0, 0x86, 0x00, 0x70,
- 0xa1, 0x9a, 0xcd, 0x60, 0xa2, 0x65, 0xe2, 0x70, 0xa3, 0x83, 0xe9, 0xe0,
- 0xa4, 0x6a, 0xae, 0x70, 0xa5, 0x35, 0xa7, 0x60, 0xa6, 0x53, 0xca, 0xf0,
- 0xa7, 0x15, 0x89, 0x60, 0xa8, 0x33, 0xac, 0xf0, 0xa8, 0xfe, 0xa5, 0xe0,
- 0xaa, 0x13, 0x8e, 0xf0, 0xaa, 0xde, 0x87, 0xe0, 0xab, 0xf3, 0x70, 0xf0,
- 0xac, 0xbe, 0x69, 0xe0, 0xad, 0xd3, 0x52, 0xf0, 0xae, 0x9e, 0x4b, 0xe0,
- 0xaf, 0xb3, 0x34, 0xf0, 0xb0, 0x7e, 0x2d, 0xe0, 0xb1, 0x9c, 0x51, 0x70,
- 0xb2, 0x67, 0x4a, 0x60, 0xb3, 0x7c, 0x33, 0x70, 0xb4, 0x47, 0x2c, 0x60,
- 0xb5, 0x5c, 0x15, 0x70, 0xb6, 0x27, 0x0e, 0x60, 0xb7, 0x3b, 0xf7, 0x70,
- 0xb8, 0x06, 0xf0, 0x60, 0xb9, 0x1b, 0xd9, 0x70, 0xb9, 0xe6, 0xd2, 0x60,
- 0xbb, 0x04, 0xf5, 0xf0, 0xbb, 0xc6, 0xb4, 0x60, 0xbc, 0xe4, 0xd7, 0xf0,
- 0xbd, 0xaf, 0xd0, 0xe0, 0xbe, 0xc4, 0xb9, 0xf0, 0xbf, 0x8f, 0xb2, 0xe0,
- 0xc0, 0xa4, 0x9b, 0xf0, 0xc1, 0x6f, 0x94, 0xe0, 0xc2, 0x84, 0x7d, 0xf0,
- 0xc3, 0x4f, 0x76, 0xe0, 0xc4, 0x64, 0x5f, 0xf0, 0xc5, 0x2f, 0x58, 0xe0,
- 0xc6, 0x4d, 0x7c, 0x70, 0xc7, 0x0f, 0x3a, 0xe0, 0xc8, 0x2d, 0x5e, 0x70,
- 0xc8, 0xf8, 0x57, 0x60, 0xca, 0x0d, 0x40, 0x70, 0xca, 0xd8, 0x39, 0x60,
- 0xcb, 0x88, 0xf0, 0x70, 0xd2, 0x23, 0xf4, 0x70, 0xd2, 0x60, 0xfb, 0xe0,
- 0xd3, 0x75, 0xe4, 0xf0, 0xd4, 0x40, 0xdd, 0xe0, 0xd5, 0x55, 0xc6, 0xf0,
- 0xd6, 0x20, 0xbf, 0xe0, 0xd7, 0x35, 0xa8, 0xf0, 0xd8, 0x00, 0xa1, 0xe0,
- 0xd9, 0x15, 0x8a, 0xf0, 0xd9, 0xe0, 0x83, 0xe0, 0xda, 0xfe, 0xa7, 0x70,
- 0xdb, 0xc0, 0x65, 0xe0, 0xdc, 0xde, 0x89, 0x70, 0xdd, 0xa9, 0x82, 0x60,
- 0xde, 0xbe, 0x6b, 0x70, 0xdf, 0x89, 0x64, 0x60, 0xe0, 0x9e, 0x4d, 0x70,
- 0xe1, 0x69, 0x46, 0x60, 0xe2, 0x7e, 0x2f, 0x70, 0xe3, 0x49, 0x28, 0x60,
- 0xe4, 0x5e, 0x11, 0x70, 0xe5, 0x57, 0x2e, 0xe0, 0xe6, 0x47, 0x2d, 0xf0,
- 0xe7, 0x37, 0x10, 0xe0, 0xe8, 0x27, 0x0f, 0xf0, 0xe9, 0x16, 0xf2, 0xe0,
- 0xea, 0x06, 0xf1, 0xf0, 0xea, 0xf6, 0xd4, 0xe0, 0xeb, 0xe6, 0xd3, 0xf0,
- 0xec, 0xd6, 0xb6, 0xe0, 0xed, 0xc6, 0xb5, 0xf0, 0xee, 0xbf, 0xd3, 0x60,
- 0xef, 0xaf, 0xd2, 0x70, 0xf0, 0x9f, 0xb5, 0x60, 0xf1, 0x8f, 0xb4, 0x70,
- 0xf2, 0x7f, 0x97, 0x60, 0xf3, 0x6f, 0x96, 0x70, 0xf4, 0x5f, 0x79, 0x60,
- 0xf5, 0x4f, 0x78, 0x70, 0xf6, 0x3f, 0x5b, 0x60, 0xf7, 0x2f, 0x5a, 0x70,
- 0xf8, 0x28, 0x77, 0xe0, 0xf9, 0x0f, 0x3c, 0x70, 0xfa, 0x08, 0x59, 0xe0,
- 0xfa, 0xf8, 0x58, 0xf0, 0xfb, 0xe8, 0x3b, 0xe0, 0xfc, 0xd8, 0x3a, 0xf0,
- 0xfd, 0xc8, 0x1d, 0xe0, 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xa7, 0xff, 0xe0,
- 0x00, 0x97, 0xfe, 0xf0, 0x01, 0x87, 0xe1, 0xe0, 0x02, 0x77, 0xe0, 0xf0,
- 0x03, 0x70, 0xfe, 0x60, 0x04, 0x60, 0xfd, 0x70, 0x05, 0x50, 0xe0, 0x60,
- 0x06, 0x40, 0xdf, 0x70, 0x07, 0x30, 0xc2, 0x60, 0x07, 0x8d, 0x19, 0x70,
- 0x09, 0x10, 0xa4, 0x60, 0x09, 0xad, 0x94, 0xf0, 0x0a, 0xf0, 0x86, 0x60,
- 0x0b, 0xe0, 0x85, 0x70, 0x0c, 0xd9, 0xa2, 0xe0, 0x0d, 0xc0, 0x67, 0x70,
- 0x0e, 0xb9, 0x84, 0xe0, 0x0f, 0xa9, 0x83, 0xf0, 0x10, 0x99, 0x66, 0xe0,
- 0x11, 0x89, 0x65, 0xf0, 0x12, 0x79, 0x48, 0xe0, 0x13, 0x69, 0x47, 0xf0,
- 0x14, 0x59, 0x2a, 0xe0, 0x15, 0x49, 0x29, 0xf0, 0x16, 0x39, 0x0c, 0xe0,
- 0x17, 0x29, 0x0b, 0xf0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xed, 0xf0,
- 0x1a, 0x02, 0x0b, 0x60, 0x1a, 0xf2, 0x0a, 0x70, 0x1b, 0xe1, 0xed, 0x60,
- 0x1c, 0xd1, 0xec, 0x70, 0x1d, 0xc1, 0xcf, 0x60, 0x1e, 0xb1, 0xce, 0x70,
- 0x1f, 0xa1, 0xb1, 0x60, 0x20, 0x76, 0x00, 0xf0, 0x21, 0x81, 0x93, 0x60,
- 0x22, 0x55, 0xe2, 0xf0, 0x23, 0x6a, 0xaf, 0xe0, 0x24, 0x35, 0xc4, 0xf0,
- 0x25, 0x4a, 0x91, 0xe0, 0x26, 0x15, 0xa6, 0xf0, 0x27, 0x2a, 0x73, 0xe0,
- 0x27, 0xfe, 0xc3, 0x70, 0x29, 0x0a, 0x55, 0xe0, 0x29, 0xde, 0xa5, 0x70,
- 0x2a, 0xea, 0x37, 0xe0, 0x2b, 0xbe, 0x87, 0x70, 0x2c, 0xd3, 0x54, 0x60,
- 0x2d, 0x9e, 0x69, 0x70, 0x2e, 0xb3, 0x36, 0x60, 0x2f, 0x7e, 0x4b, 0x70,
- 0x30, 0x93, 0x18, 0x60, 0x31, 0x67, 0x67, 0xf0, 0x32, 0x72, 0xfa, 0x60,
- 0x33, 0x47, 0x49, 0xf0, 0x34, 0x52, 0xdc, 0x60, 0x35, 0x27, 0x2b, 0xf0,
- 0x36, 0x32, 0xbe, 0x60, 0x37, 0x07, 0x0d, 0xf0, 0x38, 0x1b, 0xda, 0xe0,
- 0x38, 0xe6, 0xef, 0xf0, 0x39, 0xfb, 0xbc, 0xe0, 0x3a, 0xc6, 0xd1, 0xf0,
- 0x3b, 0xdb, 0x9e, 0xe0, 0x3c, 0xaf, 0xee, 0x70, 0x3d, 0xbb, 0x80, 0xe0,
- 0x3e, 0x8f, 0xd0, 0x70, 0x3f, 0x9b, 0x62, 0xe0, 0x40, 0x6f, 0xb2, 0x70,
- 0x41, 0x84, 0x7f, 0x60, 0x42, 0x4f, 0x94, 0x70, 0x43, 0x64, 0x61, 0x60,
- 0x44, 0x2f, 0x76, 0x70, 0x45, 0x44, 0x43, 0x60, 0x45, 0xf3, 0xa8, 0xf0,
- 0x47, 0x2d, 0x5f, 0xe0, 0x47, 0xd3, 0x8a, 0xf0, 0x49, 0x0d, 0x41, 0xe0,
- 0x49, 0xb3, 0x6c, 0xf0, 0x4a, 0xed, 0x23, 0xe0, 0x4b, 0x9c, 0x89, 0x70,
- 0x4c, 0xd6, 0x40, 0x60, 0x4d, 0x7c, 0x6b, 0x70, 0x4e, 0xb6, 0x22, 0x60,
- 0x4f, 0x5c, 0x4d, 0x70, 0x50, 0x96, 0x04, 0x60, 0x51, 0x3c, 0x2f, 0x70,
- 0x52, 0x75, 0xe6, 0x60, 0x53, 0x1c, 0x11, 0x70, 0x54, 0x55, 0xc8, 0x60,
- 0x54, 0xfb, 0xf3, 0x70, 0x56, 0x35, 0xaa, 0x60, 0x56, 0xe5, 0x0f, 0xf0,
- 0x58, 0x1e, 0xc6, 0xe0, 0x58, 0xc4, 0xf1, 0xf0, 0x59, 0xfe, 0xa8, 0xe0,
- 0x5a, 0xa4, 0xd3, 0xf0, 0x5b, 0xde, 0x8a, 0xe0, 0x5c, 0x84, 0xb5, 0xf0,
- 0x5d, 0xbe, 0x6c, 0xe0, 0x5e, 0x64, 0x97, 0xf0, 0x5f, 0x9e, 0x4e, 0xe0,
- 0x60, 0x4d, 0xb4, 0x70, 0x61, 0x87, 0x6b, 0x60, 0x62, 0x2d, 0x96, 0x70,
- 0x63, 0x67, 0x4d, 0x60, 0x64, 0x0d, 0x78, 0x70, 0x65, 0x47, 0x2f, 0x60,
- 0x65, 0xed, 0x5a, 0x70, 0x67, 0x27, 0x11, 0x60, 0x67, 0xcd, 0x3c, 0x70,
- 0x69, 0x06, 0xf3, 0x60, 0x69, 0xad, 0x1e, 0x70, 0x6a, 0xe6, 0xd5, 0x60,
- 0x6b, 0x96, 0x3a, 0xf0, 0x6c, 0xcf, 0xf1, 0xe0, 0x6d, 0x76, 0x1c, 0xf0,
- 0x6e, 0xaf, 0xd3, 0xe0, 0x6f, 0x55, 0xfe, 0xf0, 0x70, 0x8f, 0xb5, 0xe0,
- 0x71, 0x35, 0xe0, 0xf0, 0x72, 0x6f, 0x97, 0xe0, 0x73, 0x15, 0xc2, 0xf0,
- 0x74, 0x4f, 0x79, 0xe0, 0x74, 0xfe, 0xdf, 0x70, 0x76, 0x38, 0x96, 0x60,
- 0x76, 0xde, 0xc1, 0x70, 0x78, 0x18, 0x78, 0x60, 0x78, 0xbe, 0xa3, 0x70,
- 0x79, 0xf8, 0x5a, 0x60, 0x7a, 0x9e, 0x85, 0x70, 0x7b, 0xd8, 0x3c, 0x60,
- 0x7c, 0x7e, 0x67, 0x70, 0x7d, 0xb8, 0x1e, 0x60, 0x7e, 0x5e, 0x49, 0x70,
- 0x7f, 0x98, 0x00, 0x60, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x04,
- 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x0c,
- 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x45, 0x44,
- 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50,
- 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x03, 0xf0, 0x90,
- 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x1e, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0x9f, 0xba, 0xeb, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86, 0x00, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xcd, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xa2, 0x65, 0xe2, 0x70, 0xff, 0xff, 0xff, 0xff, 0xa3, 0x83, 0xe9, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xa4, 0x6a, 0xae, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xa5, 0x35, 0xa7, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x53, 0xca, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xa7, 0x15, 0x89, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xa8, 0x33, 0xac, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xa8, 0xfe, 0xa5, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xaa, 0x13, 0x8e, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xaa, 0xde, 0x87, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xab, 0xf3, 0x70, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xac, 0xbe, 0x69, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xad, 0xd3, 0x52, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xae, 0x9e, 0x4b, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xaf, 0xb3, 0x34, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xb0, 0x7e, 0x2d, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x9c, 0x51, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xb2, 0x67, 0x4a, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xb3, 0x7c, 0x33, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb4, 0x47, 0x2c, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xb5, 0x5c, 0x15, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xb6, 0x27, 0x0e, 0x60, 0xff, 0xff, 0xff, 0xff, 0xb7, 0x3b, 0xf7, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xb8, 0x06, 0xf0, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xb9, 0x1b, 0xd9, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb9, 0xe6, 0xd2, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xbb, 0x04, 0xf5, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xbb, 0xc6, 0xb4, 0x60, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe4, 0xd7, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xbd, 0xaf, 0xd0, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xbe, 0xc4, 0xb9, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x8f, 0xb2, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa4, 0x9b, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xc1, 0x6f, 0x94, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x84, 0x7d, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xc3, 0x4f, 0x76, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xc4, 0x64, 0x5f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xc5, 0x2f, 0x58, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xc6, 0x4d, 0x7c, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xc7, 0x0f, 0x3a, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x2d, 0x5e, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xc8, 0xf8, 0x57, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xca, 0x0d, 0x40, 0x70, 0xff, 0xff, 0xff, 0xff, 0xca, 0xd8, 0x39, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xcb, 0x88, 0xf0, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xd2, 0x23, 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x60, 0xfb, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xd3, 0x75, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xd4, 0x40, 0xdd, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0xc6, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xd6, 0x20, 0xbf, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xd7, 0x35, 0xa8, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0xa1, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xd9, 0x15, 0x8a, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xd9, 0xe0, 0x83, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xa7, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xdb, 0xc0, 0x65, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xdc, 0xde, 0x89, 0x70, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0x82, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xde, 0xbe, 0x6b, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xdf, 0x89, 0x64, 0x60, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x4d, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xe1, 0x69, 0x46, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xe2, 0x7e, 0x2f, 0x70, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x28, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5e, 0x11, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xe5, 0x57, 0x2e, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x2d, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xe7, 0x37, 0x10, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xe8, 0x27, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x16, 0xf2, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xea, 0x06, 0xf1, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xea, 0xf6, 0xd4, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xd3, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xec, 0xd6, 0xb6, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xed, 0xc6, 0xb5, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xee, 0xbf, 0xd3, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xef, 0xaf, 0xd2, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xf0, 0x9f, 0xb5, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xb4, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xf2, 0x7f, 0x97, 0x60, 0xff, 0xff, 0xff, 0xff,
- 0xf3, 0x6f, 0x96, 0x70, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0x79, 0x60,
- 0xff, 0xff, 0xff, 0xff, 0xf5, 0x4f, 0x78, 0x70, 0xff, 0xff, 0xff, 0xff,
- 0xf6, 0x3f, 0x5b, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x5a, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xf8, 0x28, 0x77, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xf9, 0x0f, 0x3c, 0x70, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x59, 0xe0,
- 0xff, 0xff, 0xff, 0xff, 0xfa, 0xf8, 0x58, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xfb, 0xe8, 0x3b, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x3a, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xfd, 0xc8, 0x1d, 0xe0, 0xff, 0xff, 0xff, 0xff,
- 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0xff, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x87, 0xe1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0xe0, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x70, 0xfe, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x60, 0xfd, 0x70, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xe0, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x07, 0x30, 0xc2, 0x60, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x19, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xa4, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0xad, 0x94, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0x86, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe0, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0xd9, 0xa2, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x67, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb9, 0x84, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x0f, 0xa9, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x66, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x65, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x12, 0x79, 0x48, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x47, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x2a, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x15, 0x49, 0x29, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x0c, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x0b, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x22, 0x29, 0x60, 0x00, 0x00, 0x00, 0x00, 0x19, 0x08, 0xed, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x1a, 0xf2, 0x0a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0xed, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd1, 0xec, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x1d, 0xc1, 0xcf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xce, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x1f, 0xa1, 0xb1, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x76, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x93, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xe2, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x6a, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xc4, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x4a, 0x91, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x26, 0x15, 0xa6, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x73, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x27, 0xfe, 0xc3, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x29, 0x0a, 0x55, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xa5, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0xea, 0x37, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0xbe, 0x87, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x54, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x2d, 0x9e, 0x69, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x2e, 0xb3, 0x36, 0x60, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x4b, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x31, 0x67, 0x67, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0xfa, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x49, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x52, 0xdc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x2b, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xbe, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x37, 0x07, 0x0d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0xda, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x38, 0xe6, 0xef, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x39, 0xfb, 0xbc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xd1, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x3b, 0xdb, 0x9e, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x3c, 0xaf, 0xee, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0x80, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x3e, 0x8f, 0xd0, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x3f, 0x9b, 0x62, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb2, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x7f, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x42, 0x4f, 0x94, 0x70, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x61, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x45, 0x44, 0x43, 0x60, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xa8, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x47, 0x2d, 0x5f, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x47, 0xd3, 0x8a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x41, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0xb3, 0x6c, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x4a, 0xed, 0x23, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0x89, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x4c, 0xd6, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x4d, 0x7c, 0x6b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x22, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x4f, 0x5c, 0x4d, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x96, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x2f, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x52, 0x75, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x53, 0x1c, 0x11, 0x70, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xc8, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0xfb, 0xf3, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x56, 0x35, 0xaa, 0x60, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x0f, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0x1e, 0xc6, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x58, 0xc4, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xa8, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x5a, 0xa4, 0xd3, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x5b, 0xde, 0x8a, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xb5, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbe, 0x6c, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x5e, 0x64, 0x97, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x4e, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x4d, 0xb4, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x61, 0x87, 0x6b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0x96, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x4d, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x64, 0x0d, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x2f, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x65, 0xed, 0x5a, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x67, 0x27, 0x11, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x3c, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x69, 0x06, 0xf3, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x69, 0xad, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xd5, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x6b, 0x96, 0x3a, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x6c, 0xcf, 0xf1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x1c, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x6e, 0xaf, 0xd3, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x6f, 0x55, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xb5, 0xe0,
- 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x72, 0x6f, 0x97, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xc2, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x74, 0x4f, 0x79, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x74, 0xfe, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0x96, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0xde, 0xc1, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x78, 0x18, 0x78, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xa3, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x79, 0xf8, 0x5a, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x7a, 0x9e, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x3c, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7e, 0x67, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x7d, 0xb8, 0x1e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x49, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x7f, 0x98, 0x00, 0x60, 0x00, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff,
- 0xff, 0xc7, 0xc0, 0x01, 0x04, 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff,
- 0xff, 0xc7, 0xc0, 0x01, 0x0c, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c,
- 0x4d, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45,
- 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x45, 0x53, 0x54, 0x35, 0x45, 0x44,
- 0x54, 0x2c, 0x4d, 0x33, 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31,
- 0x2e, 0x31, 0x2e, 0x30, 0x0a
-};
-unsigned int America_New_York_len = 3545;
-unsigned char Australia_Sydney[] = {
- 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x00, 0x00, 0x00,
- 0x9c, 0x4e, 0xa6, 0x9c, 0x9c, 0xbc, 0x20, 0xf0, 0xcb, 0x54, 0xb3, 0x00,
- 0xcb, 0xc7, 0x57, 0x70, 0xcc, 0xb7, 0x56, 0x80, 0xcd, 0xa7, 0x39, 0x70,
- 0xce, 0xa0, 0x73, 0x00, 0xcf, 0x87, 0x1b, 0x70, 0x03, 0x70, 0x39, 0x80,
- 0x04, 0x0d, 0x1c, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x05, 0xf6, 0x38, 0x80,
- 0x07, 0x2f, 0xfd, 0x80, 0x07, 0xd6, 0x1a, 0x80, 0x09, 0x0f, 0xdf, 0x80,
- 0x09, 0xb5, 0xfc, 0x80, 0x0a, 0xef, 0xc1, 0x80, 0x0b, 0x9f, 0x19, 0x00,
- 0x0c, 0xd8, 0xde, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x0e, 0xb8, 0xc0, 0x00,
- 0x0f, 0x5e, 0xdd, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x11, 0x3e, 0xbf, 0x00,
- 0x12, 0x78, 0x84, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x14, 0x58, 0x66, 0x00,
- 0x14, 0xfe, 0x83, 0x00, 0x16, 0x38, 0x48, 0x00, 0x17, 0x0c, 0x89, 0x80,
- 0x18, 0x21, 0x64, 0x80, 0x18, 0xc7, 0x81, 0x80, 0x1a, 0x01, 0x46, 0x80,
- 0x1a, 0xa7, 0x63, 0x80, 0x1b, 0xe1, 0x28, 0x80, 0x1c, 0x87, 0x45, 0x80,
- 0x1d, 0xc1, 0x0a, 0x80, 0x1e, 0x79, 0x9c, 0x80, 0x1f, 0x97, 0xb2, 0x00,
- 0x20, 0x59, 0x7e, 0x80, 0x21, 0x80, 0xce, 0x80, 0x22, 0x42, 0x9b, 0x00,
- 0x23, 0x69, 0xeb, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x25, 0x49, 0xcd, 0x00,
- 0x25, 0xef, 0xea, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x27, 0xcf, 0xcc, 0x00,
- 0x29, 0x09, 0x91, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x2a, 0xe9, 0x73, 0x00,
- 0x2b, 0x98, 0xca, 0x80, 0x2c, 0xd2, 0x8f, 0x80, 0x2d, 0x78, 0xac, 0x80,
- 0x2e, 0xb2, 0x71, 0x80, 0x2f, 0x58, 0x8e, 0x80, 0x30, 0x92, 0x53, 0x80,
- 0x31, 0x5d, 0x5a, 0x80, 0x32, 0x72, 0x35, 0x80, 0x33, 0x3d, 0x3c, 0x80,
- 0x34, 0x52, 0x17, 0x80, 0x35, 0x1d, 0x1e, 0x80, 0x36, 0x31, 0xf9, 0x80,
- 0x36, 0xfd, 0x00, 0x80, 0x38, 0x1b, 0x16, 0x00, 0x38, 0xdc, 0xe2, 0x80,
- 0x39, 0xa7, 0xe9, 0x80, 0x3a, 0xbc, 0xc4, 0x80, 0x3b, 0xda, 0xda, 0x00,
- 0x3c, 0xa5, 0xe1, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x3e, 0x85, 0xc3, 0x00,
- 0x3f, 0x9a, 0x9e, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x41, 0x83, 0xba, 0x80,
- 0x42, 0x45, 0x87, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x44, 0x2e, 0xa3, 0x80,
- 0x45, 0x43, 0x7e, 0x80, 0x46, 0x05, 0x4b, 0x00, 0x47, 0x23, 0x60, 0x80,
- 0x47, 0xf7, 0xa2, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x49, 0xd7, 0x84, 0x00,
- 0x4a, 0xc7, 0x75, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x4c, 0xa7, 0x57, 0x00,
- 0x4d, 0x97, 0x48, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x4f, 0x77, 0x2a, 0x00,
- 0x50, 0x70, 0x55, 0x80, 0x51, 0x60, 0x46, 0x80, 0x52, 0x50, 0x37, 0x80,
- 0x53, 0x40, 0x28, 0x80, 0x54, 0x30, 0x19, 0x80, 0x55, 0x20, 0x0a, 0x80,
- 0x56, 0x0f, 0xfb, 0x80, 0x56, 0xff, 0xec, 0x80, 0x57, 0xef, 0xdd, 0x80,
- 0x58, 0xdf, 0xce, 0x80, 0x59, 0xcf, 0xbf, 0x80, 0x5a, 0xbf, 0xb0, 0x80,
- 0x5b, 0xb8, 0xdc, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x5d, 0x98, 0xbe, 0x00,
- 0x5e, 0x88, 0xaf, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x60, 0x68, 0x91, 0x00,
- 0x61, 0x58, 0x82, 0x00, 0x62, 0x48, 0x73, 0x00, 0x63, 0x38, 0x64, 0x00,
- 0x64, 0x28, 0x55, 0x00, 0x65, 0x18, 0x46, 0x00, 0x66, 0x11, 0x71, 0x80,
- 0x67, 0x01, 0x62, 0x80, 0x67, 0xf1, 0x53, 0x80, 0x68, 0xe1, 0x44, 0x80,
- 0x69, 0xd1, 0x35, 0x80, 0x6a, 0xc1, 0x26, 0x80, 0x6b, 0xb1, 0x17, 0x80,
- 0x6c, 0xa1, 0x08, 0x80, 0x6d, 0x90, 0xf9, 0x80, 0x6e, 0x80, 0xea, 0x80,
- 0x6f, 0x70, 0xdb, 0x80, 0x70, 0x6a, 0x07, 0x00, 0x71, 0x59, 0xf8, 0x00,
- 0x72, 0x49, 0xe9, 0x00, 0x73, 0x39, 0xda, 0x00, 0x74, 0x29, 0xcb, 0x00,
- 0x75, 0x19, 0xbc, 0x00, 0x76, 0x09, 0xad, 0x00, 0x76, 0xf9, 0x9e, 0x00,
- 0x77, 0xe9, 0x8f, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x79, 0xc9, 0x71, 0x00,
- 0x7a, 0xb9, 0x62, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x7c, 0xa2, 0x7e, 0x80,
- 0x7d, 0x92, 0x6f, 0x80, 0x7e, 0x82, 0x60, 0x80, 0x7f, 0x72, 0x51, 0x80,
- 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
- 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x00, 0x00,
- 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00,
- 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00,
- 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54, 0x00, 0x41, 0x45, 0x44, 0x54,
- 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e,
- 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x73, 0x16, 0x7f, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x4e, 0xa6, 0x9c,
- 0xff, 0xff, 0xff, 0xff, 0x9c, 0xbc, 0x20, 0xf0, 0xff, 0xff, 0xff, 0xff,
- 0xcb, 0x54, 0xb3, 0x00, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xc7, 0x57, 0x70,
- 0xff, 0xff, 0xff, 0xff, 0xcc, 0xb7, 0x56, 0x80, 0xff, 0xff, 0xff, 0xff,
- 0xcd, 0xa7, 0x39, 0x70, 0xff, 0xff, 0xff, 0xff, 0xce, 0xa0, 0x73, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xcf, 0x87, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x70, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0d, 0x1c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x05, 0xf6, 0x38, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x2f, 0xfd, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x07, 0xd6, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x0f, 0xdf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xb5, 0xfc, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0xef, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x0b, 0x9f, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd8, 0xde, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0e, 0xb8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5e, 0xdd, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x3e, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x78, 0x84, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x14, 0x58, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xfe, 0x83, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x16, 0x38, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x17, 0x0c, 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x21, 0x64, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0xc7, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x1a, 0x01, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xa7, 0x63, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0x28, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x1c, 0x87, 0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1, 0x0a, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x1e, 0x79, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x97, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x59, 0x7e, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0xce, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x22, 0x42, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x69, 0xeb, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x49, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xef, 0xea, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x27, 0xcf, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x09, 0x91, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0xe9, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x98, 0xca, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd2, 0x8f, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x2d, 0x78, 0xac, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb2, 0x71, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x2f, 0x58, 0x8e, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x92, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5d, 0x5a, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0x35, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x33, 0x3d, 0x3c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0x17, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x35, 0x1d, 0x1e, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x31, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x36, 0xfd, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x38, 0xdc, 0xe2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0xa7, 0xe9, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x3a, 0xbc, 0xc4, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x3b, 0xda, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xa5, 0xe1, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x3e, 0x85, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9a, 0x9e, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x41, 0x83, 0xba, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0x87, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x44, 0x2e, 0xa3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0x43, 0x7e, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x47, 0x23, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x47, 0xf7, 0xa2, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x49, 0xd7, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xc7, 0x75, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x4c, 0xa7, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x97, 0x48, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x4f, 0x77, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x70, 0x55, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x60, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x52, 0x50, 0x37, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x40, 0x28, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x30, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x55, 0x20, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0x0f, 0xfb, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x56, 0xff, 0xec, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x57, 0xef, 0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x58, 0xdf, 0xce, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x59, 0xcf, 0xbf, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x5a, 0xbf, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xb8, 0xdc, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5d, 0x98, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x88, 0xaf, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x60, 0x68, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x58, 0x82, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x62, 0x48, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x63, 0x38, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x55, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x65, 0x18, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x11, 0x71, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x62, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x67, 0xf1, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xe1, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xd1, 0x35, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x6a, 0xc1, 0x26, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x6b, 0xb1, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xa1, 0x08, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x6d, 0x90, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x6e, 0x80, 0xea, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x70, 0xdb, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x70, 0x6a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x71, 0x59, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x49, 0xe9, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x73, 0x39, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x74, 0x29, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x19, 0xbc, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x09, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x76, 0xf9, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xe9, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x79, 0xc9, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xb9, 0x62, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x7c, 0xa2, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x92, 0x6f, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x7f, 0x72, 0x51, 0x80, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
- 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
- 0x03, 0x04, 0x03, 0x00, 0x00, 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a,
- 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a,
- 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54,
- 0x00, 0x41, 0x45, 0x44, 0x54, 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x45,
- 0x53, 0x54, 0x2d, 0x31, 0x30, 0x41, 0x45, 0x44, 0x54, 0x2c, 0x4d, 0x31,
- 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x4d, 0x34, 0x2e, 0x31, 0x2e, 0x30,
- 0x2f, 0x33, 0x0a
-};
-unsigned int Australia_Sydney_len = 2223;
+unsigned char America_Los_Angeles[] = {
+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
+ 0x9e, 0xa6, 0x48, 0xa0, 0x9f, 0xbb, 0x15, 0x90, 0xa0, 0x86, 0x2a, 0xa0,
+ 0xa1, 0x9a, 0xf7, 0x90, 0xcb, 0x89, 0x1a, 0xa0, 0xd2, 0x23, 0xf4, 0x70,
+ 0xd2, 0x61, 0x26, 0x10, 0xd6, 0xfe, 0x74, 0x5c, 0xd8, 0x80, 0xad, 0x90,
+ 0xda, 0xfe, 0xc3, 0x90, 0xdb, 0xc0, 0x90, 0x10, 0xdc, 0xde, 0xa5, 0x90,
+ 0xdd, 0xa9, 0xac, 0x90, 0xde, 0xbe, 0x87, 0x90, 0xdf, 0x89, 0x8e, 0x90,
+ 0xe0, 0x9e, 0x69, 0x90, 0xe1, 0x69, 0x70, 0x90, 0xe2, 0x7e, 0x4b, 0x90,
+ 0xe3, 0x49, 0x52, 0x90, 0xe4, 0x5e, 0x2d, 0x90, 0xe5, 0x29, 0x34, 0x90,
+ 0xe6, 0x47, 0x4a, 0x10, 0xe7, 0x12, 0x51, 0x10, 0xe8, 0x27, 0x2c, 0x10,
+ 0xe8, 0xf2, 0x33, 0x10, 0xea, 0x07, 0x0e, 0x10, 0xea, 0xd2, 0x15, 0x10,
+ 0xeb, 0xe6, 0xf0, 0x10, 0xec, 0xb1, 0xf7, 0x10, 0xed, 0xc6, 0xd2, 0x10,
+ 0xee, 0x91, 0xd9, 0x10, 0xef, 0xaf, 0xee, 0x90, 0xf0, 0x71, 0xbb, 0x10,
+ 0xf1, 0x8f, 0xd0, 0x90, 0xf2, 0x7f, 0xc1, 0x90, 0xf3, 0x6f, 0xb2, 0x90,
+ 0xf4, 0x5f, 0xa3, 0x90, 0xf5, 0x4f, 0x94, 0x90, 0xf6, 0x3f, 0x85, 0x90,
+ 0xf7, 0x2f, 0x76, 0x90, 0xf8, 0x28, 0xa2, 0x10, 0xf9, 0x0f, 0x58, 0x90,
+ 0xfa, 0x08, 0x84, 0x10, 0xfa, 0xf8, 0x83, 0x20, 0xfb, 0xe8, 0x66, 0x10,
+ 0xfc, 0xd8, 0x65, 0x20, 0xfd, 0xc8, 0x48, 0x10, 0xfe, 0xb8, 0x47, 0x20,
+ 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x98, 0x29, 0x20, 0x01, 0x88, 0x0c, 0x10,
+ 0x02, 0x78, 0x0b, 0x20, 0x03, 0x71, 0x28, 0x90, 0x04, 0x61, 0x27, 0xa0,
+ 0x05, 0x51, 0x0a, 0x90, 0x06, 0x41, 0x09, 0xa0, 0x07, 0x30, 0xec, 0x90,
+ 0x07, 0x8d, 0x43, 0xa0, 0x09, 0x10, 0xce, 0x90, 0x09, 0xad, 0xbf, 0x20,
+ 0x0a, 0xf0, 0xb0, 0x90, 0x0b, 0xe0, 0xaf, 0xa0, 0x0c, 0xd9, 0xcd, 0x10,
+ 0x0d, 0xc0, 0x91, 0xa0, 0x0e, 0xb9, 0xaf, 0x10, 0x0f, 0xa9, 0xae, 0x20,
+ 0x10, 0x99, 0x91, 0x10, 0x11, 0x89, 0x90, 0x20, 0x12, 0x79, 0x73, 0x10,
+ 0x13, 0x69, 0x72, 0x20, 0x14, 0x59, 0x55, 0x10, 0x15, 0x49, 0x54, 0x20,
+ 0x16, 0x39, 0x37, 0x10, 0x17, 0x29, 0x36, 0x20, 0x18, 0x22, 0x53, 0x90,
+ 0x19, 0x09, 0x18, 0x20, 0x1a, 0x02, 0x35, 0x90, 0x1a, 0xf2, 0x34, 0xa0,
+ 0x1b, 0xe2, 0x17, 0x90, 0x1c, 0xd2, 0x16, 0xa0, 0x1d, 0xc1, 0xf9, 0x90,
+ 0x1e, 0xb1, 0xf8, 0xa0, 0x1f, 0xa1, 0xdb, 0x90, 0x20, 0x76, 0x2b, 0x20,
+ 0x21, 0x81, 0xbd, 0x90, 0x22, 0x56, 0x0d, 0x20, 0x23, 0x6a, 0xda, 0x10,
+ 0x24, 0x35, 0xef, 0x20, 0x25, 0x4a, 0xbc, 0x10, 0x26, 0x15, 0xd1, 0x20,
+ 0x27, 0x2a, 0x9e, 0x10, 0x27, 0xfe, 0xed, 0xa0, 0x29, 0x0a, 0x80, 0x10,
+ 0x29, 0xde, 0xcf, 0xa0, 0x2a, 0xea, 0x62, 0x10, 0x2b, 0xbe, 0xb1, 0xa0,
+ 0x2c, 0xd3, 0x7e, 0x90, 0x2d, 0x9e, 0x93, 0xa0, 0x2e, 0xb3, 0x60, 0x90,
+ 0x2f, 0x7e, 0x75, 0xa0, 0x30, 0x93, 0x42, 0x90, 0x31, 0x67, 0x92, 0x20,
+ 0x32, 0x73, 0x24, 0x90, 0x33, 0x47, 0x74, 0x20, 0x34, 0x53, 0x06, 0x90,
+ 0x35, 0x27, 0x56, 0x20, 0x36, 0x32, 0xe8, 0x90, 0x37, 0x07, 0x38, 0x20,
+ 0x38, 0x1c, 0x05, 0x10, 0x38, 0xe7, 0x1a, 0x20, 0x39, 0xfb, 0xe7, 0x10,
+ 0x3a, 0xc6, 0xfc, 0x20, 0x3b, 0xdb, 0xc9, 0x10, 0x3c, 0xb0, 0x18, 0xa0,
+ 0x3d, 0xbb, 0xab, 0x10, 0x3e, 0x8f, 0xfa, 0xa0, 0x3f, 0x9b, 0x8d, 0x10,
+ 0x40, 0x6f, 0xdc, 0xa0, 0x41, 0x84, 0xa9, 0x90, 0x42, 0x4f, 0xbe, 0xa0,
+ 0x43, 0x64, 0x8b, 0x90, 0x44, 0x2f, 0xa0, 0xa0, 0x45, 0x44, 0x6d, 0x90,
+ 0x45, 0xf3, 0xd3, 0x20, 0x47, 0x2d, 0x8a, 0x10, 0x47, 0xd3, 0xb5, 0x20,
+ 0x49, 0x0d, 0x6c, 0x10, 0x49, 0xb3, 0x97, 0x20, 0x4a, 0xed, 0x4e, 0x10,
+ 0x4b, 0x9c, 0xb3, 0xa0, 0x4c, 0xd6, 0x6a, 0x90, 0x4d, 0x7c, 0x95, 0xa0,
+ 0x4e, 0xb6, 0x4c, 0x90, 0x4f, 0x5c, 0x77, 0xa0, 0x50, 0x96, 0x2e, 0x90,
+ 0x51, 0x3c, 0x59, 0xa0, 0x52, 0x76, 0x10, 0x90, 0x53, 0x1c, 0x3b, 0xa0,
+ 0x54, 0x55, 0xf2, 0x90, 0x54, 0xfc, 0x1d, 0xa0, 0x56, 0x35, 0xd4, 0x90,
+ 0x56, 0xe5, 0x3a, 0x20, 0x58, 0x1e, 0xf1, 0x10, 0x58, 0xc5, 0x1c, 0x20,
+ 0x59, 0xfe, 0xd3, 0x10, 0x5a, 0xa4, 0xfe, 0x20, 0x5b, 0xde, 0xb5, 0x10,
+ 0x5c, 0x84, 0xe0, 0x20, 0x5d, 0xbe, 0x97, 0x10, 0x5e, 0x64, 0xc2, 0x20,
+ 0x5f, 0x9e, 0x79, 0x10, 0x60, 0x4d, 0xde, 0xa0, 0x61, 0x87, 0x95, 0x90,
+ 0x62, 0x2d, 0xc0, 0xa0, 0x63, 0x67, 0x77, 0x90, 0x64, 0x0d, 0xa2, 0xa0,
+ 0x65, 0x47, 0x59, 0x90, 0x65, 0xed, 0x84, 0xa0, 0x67, 0x27, 0x3b, 0x90,
+ 0x67, 0xcd, 0x66, 0xa0, 0x69, 0x07, 0x1d, 0x90, 0x69, 0xad, 0x48, 0xa0,
+ 0x6a, 0xe6, 0xff, 0x90, 0x6b, 0x96, 0x65, 0x20, 0x6c, 0xd0, 0x1c, 0x10,
+ 0x6d, 0x76, 0x47, 0x20, 0x6e, 0xaf, 0xfe, 0x10, 0x6f, 0x56, 0x29, 0x20,
+ 0x70, 0x8f, 0xe0, 0x10, 0x71, 0x36, 0x0b, 0x20, 0x72, 0x6f, 0xc2, 0x10,
+ 0x73, 0x15, 0xed, 0x20, 0x74, 0x4f, 0xa4, 0x10, 0x74, 0xff, 0x09, 0xa0,
+ 0x76, 0x38, 0xc0, 0x90, 0x76, 0xde, 0xeb, 0xa0, 0x78, 0x18, 0xa2, 0x90,
+ 0x78, 0xbe, 0xcd, 0xa0, 0x79, 0xf8, 0x84, 0x90, 0x7a, 0x9e, 0xaf, 0xa0,
+ 0x7b, 0xd8, 0x66, 0x90, 0x7c, 0x7e, 0x91, 0xa0, 0x7d, 0xb8, 0x48, 0x90,
+ 0x7e, 0x5e, 0x73, 0xa0, 0x7f, 0x98, 0x2a, 0x90, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90,
+ 0x01, 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90,
+ 0x01, 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00,
+ 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00,
+ 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xbb, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x04,
+ 0x1a, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x48, 0xa0, 0xff, 0xff,
+ 0xff, 0xff, 0x9f, 0xbb, 0x15, 0x90, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86,
+ 0x2a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xf7, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xcb, 0x89, 0x1a, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x23,
+ 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x61, 0x26, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xd6, 0xfe, 0x74, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x80,
+ 0xad, 0x90, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xc3, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xdb, 0xc0, 0x90, 0x10, 0xff, 0xff, 0xff, 0xff, 0xdc, 0xde,
+ 0xa5, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0xac, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xde, 0xbe, 0x87, 0x90, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x89,
+ 0x8e, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x69, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xe1, 0x69, 0x70, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe2, 0x7e,
+ 0x4b, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x52, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xe4, 0x5e, 0x2d, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x29,
+ 0x34, 0x90, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x4a, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xe7, 0x12, 0x51, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0x27,
+ 0x2c, 0x10, 0xff, 0xff, 0xff, 0xff, 0xe8, 0xf2, 0x33, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xea, 0x07, 0x0e, 0x10, 0xff, 0xff, 0xff, 0xff, 0xea, 0xd2,
+ 0x15, 0x10, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xf0, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xec, 0xb1, 0xf7, 0x10, 0xff, 0xff, 0xff, 0xff, 0xed, 0xc6,
+ 0xd2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xee, 0x91, 0xd9, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xef, 0xaf, 0xee, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x71,
+ 0xbb, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xd0, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xf2, 0x7f, 0xc1, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x6f,
+ 0xb2, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0xa3, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xf5, 0x4f, 0x94, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x3f,
+ 0x85, 0x90, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x76, 0x90, 0xff, 0xff,
+ 0xff, 0xff, 0xf8, 0x28, 0xa2, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0f,
+ 0x58, 0x90, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x84, 0x10, 0xff, 0xff,
+ 0xff, 0xff, 0xfa, 0xf8, 0x83, 0x20, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xe8,
+ 0x66, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x65, 0x20, 0xff, 0xff,
+ 0xff, 0xff, 0xfd, 0xc8, 0x48, 0x10, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xb8,
+ 0x47, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa8, 0x2a, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x98, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88,
+ 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x0b, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61,
+ 0x27, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0a, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x41, 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30,
+ 0xec, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x43, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x09, 0x10, 0xce, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0xad,
+ 0xbf, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0xb0, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x0b, 0xe0, 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd9,
+ 0xcd, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x91, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0xb9, 0xaf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa9,
+ 0xae, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x89, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79,
+ 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x72, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49,
+ 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x17, 0x29, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22,
+ 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x18, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x1a, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xf2,
+ 0x34, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe2, 0x17, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0xd2, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1,
+ 0xf9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xf8, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0xa1, 0xdb, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76,
+ 0x2b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xbd, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x22, 0x56, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6a,
+ 0xda, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xef, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x25, 0x4a, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15,
+ 0xd1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x9e, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x27, 0xfe, 0xed, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0a,
+ 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xcf, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x2a, 0xea, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xbe,
+ 0xb1, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x7e, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x9e, 0x93, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb3,
+ 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x75, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67,
+ 0x92, 0x20, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x33, 0x47, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x34, 0x53,
+ 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x56, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x36, 0x32, 0xe8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07,
+ 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x05, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0xe7, 0x1a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x39, 0xfb,
+ 0xe7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xfc, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x3b, 0xdb, 0xc9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb0,
+ 0x18, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0xab, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x8f, 0xfa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9b,
+ 0x8d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xdc, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x41, 0x84, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4f,
+ 0xbe, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8b, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x44, 0x2f, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44,
+ 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xd3, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x47, 0x2d, 0x8a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xd3,
+ 0xb5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x6c, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x49, 0xb3, 0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xed,
+ 0x4e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0xb3, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x4c, 0xd6, 0x6a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x7c,
+ 0x95, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x4c, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x4f, 0x5c, 0x77, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96,
+ 0x2e, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x59, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1c,
+ 0x3b, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xf2, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x54, 0xfc, 0x1d, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35,
+ 0xd4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x3a, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x58, 0x1e, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xc5,
+ 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xd3, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x5a, 0xa4, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xde,
+ 0xb5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xe0, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x5d, 0xbe, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x64,
+ 0xc2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x79, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x4d, 0xde, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87,
+ 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0xc0, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0d,
+ 0xa2, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x65, 0xed, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27,
+ 0x3b, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x66, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x69, 0x07, 0x1d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xad,
+ 0x48, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xff, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x6b, 0x96, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd0,
+ 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x47, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x6e, 0xaf, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x56,
+ 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xe0, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x71, 0x36, 0x0b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6f,
+ 0xc2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xed, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x74, 0x4f, 0xa4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0xff,
+ 0x09, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0xc0, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xde, 0xeb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18,
+ 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xcd, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x79, 0xf8, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x9e,
+ 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x66, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x7e, 0x91, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xb8,
+ 0x48, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x73, 0xa0, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x98, 0x2a, 0x90, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0xff, 0xff, 0x91, 0x26, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x90, 0x01,
+ 0x04, 0xff, 0xff, 0x8f, 0x80, 0x00, 0x08, 0xff, 0xff, 0x9d, 0x90, 0x01,
+ 0x0c, 0xff, 0xff, 0x9d, 0x90, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x50,
+ 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50,
+ 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x0a, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2c, 0x4d, 0x33,
+ 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31, 0x2e, 0x31, 0x2e, 0x30,
+ 0x0a
+};
+unsigned int America_Los_Angeles_len = 2845;
+unsigned char America_New_York[] = {
+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
+ 0x9e, 0xa6, 0x1e, 0x70, 0x9f, 0xba, 0xeb, 0x60, 0xa0, 0x86, 0x00, 0x70,
+ 0xa1, 0x9a, 0xcd, 0x60, 0xa2, 0x65, 0xe2, 0x70, 0xa3, 0x83, 0xe9, 0xe0,
+ 0xa4, 0x6a, 0xae, 0x70, 0xa5, 0x35, 0xa7, 0x60, 0xa6, 0x53, 0xca, 0xf0,
+ 0xa7, 0x15, 0x89, 0x60, 0xa8, 0x33, 0xac, 0xf0, 0xa8, 0xfe, 0xa5, 0xe0,
+ 0xaa, 0x13, 0x8e, 0xf0, 0xaa, 0xde, 0x87, 0xe0, 0xab, 0xf3, 0x70, 0xf0,
+ 0xac, 0xbe, 0x69, 0xe0, 0xad, 0xd3, 0x52, 0xf0, 0xae, 0x9e, 0x4b, 0xe0,
+ 0xaf, 0xb3, 0x34, 0xf0, 0xb0, 0x7e, 0x2d, 0xe0, 0xb1, 0x9c, 0x51, 0x70,
+ 0xb2, 0x67, 0x4a, 0x60, 0xb3, 0x7c, 0x33, 0x70, 0xb4, 0x47, 0x2c, 0x60,
+ 0xb5, 0x5c, 0x15, 0x70, 0xb6, 0x27, 0x0e, 0x60, 0xb7, 0x3b, 0xf7, 0x70,
+ 0xb8, 0x06, 0xf0, 0x60, 0xb9, 0x1b, 0xd9, 0x70, 0xb9, 0xe6, 0xd2, 0x60,
+ 0xbb, 0x04, 0xf5, 0xf0, 0xbb, 0xc6, 0xb4, 0x60, 0xbc, 0xe4, 0xd7, 0xf0,
+ 0xbd, 0xaf, 0xd0, 0xe0, 0xbe, 0xc4, 0xb9, 0xf0, 0xbf, 0x8f, 0xb2, 0xe0,
+ 0xc0, 0xa4, 0x9b, 0xf0, 0xc1, 0x6f, 0x94, 0xe0, 0xc2, 0x84, 0x7d, 0xf0,
+ 0xc3, 0x4f, 0x76, 0xe0, 0xc4, 0x64, 0x5f, 0xf0, 0xc5, 0x2f, 0x58, 0xe0,
+ 0xc6, 0x4d, 0x7c, 0x70, 0xc7, 0x0f, 0x3a, 0xe0, 0xc8, 0x2d, 0x5e, 0x70,
+ 0xc8, 0xf8, 0x57, 0x60, 0xca, 0x0d, 0x40, 0x70, 0xca, 0xd8, 0x39, 0x60,
+ 0xcb, 0x88, 0xf0, 0x70, 0xd2, 0x23, 0xf4, 0x70, 0xd2, 0x60, 0xfb, 0xe0,
+ 0xd3, 0x75, 0xe4, 0xf0, 0xd4, 0x40, 0xdd, 0xe0, 0xd5, 0x55, 0xc6, 0xf0,
+ 0xd6, 0x20, 0xbf, 0xe0, 0xd7, 0x35, 0xa8, 0xf0, 0xd8, 0x00, 0xa1, 0xe0,
+ 0xd9, 0x15, 0x8a, 0xf0, 0xd9, 0xe0, 0x83, 0xe0, 0xda, 0xfe, 0xa7, 0x70,
+ 0xdb, 0xc0, 0x65, 0xe0, 0xdc, 0xde, 0x89, 0x70, 0xdd, 0xa9, 0x82, 0x60,
+ 0xde, 0xbe, 0x6b, 0x70, 0xdf, 0x89, 0x64, 0x60, 0xe0, 0x9e, 0x4d, 0x70,
+ 0xe1, 0x69, 0x46, 0x60, 0xe2, 0x7e, 0x2f, 0x70, 0xe3, 0x49, 0x28, 0x60,
+ 0xe4, 0x5e, 0x11, 0x70, 0xe5, 0x57, 0x2e, 0xe0, 0xe6, 0x47, 0x2d, 0xf0,
+ 0xe7, 0x37, 0x10, 0xe0, 0xe8, 0x27, 0x0f, 0xf0, 0xe9, 0x16, 0xf2, 0xe0,
+ 0xea, 0x06, 0xf1, 0xf0, 0xea, 0xf6, 0xd4, 0xe0, 0xeb, 0xe6, 0xd3, 0xf0,
+ 0xec, 0xd6, 0xb6, 0xe0, 0xed, 0xc6, 0xb5, 0xf0, 0xee, 0xbf, 0xd3, 0x60,
+ 0xef, 0xaf, 0xd2, 0x70, 0xf0, 0x9f, 0xb5, 0x60, 0xf1, 0x8f, 0xb4, 0x70,
+ 0xf2, 0x7f, 0x97, 0x60, 0xf3, 0x6f, 0x96, 0x70, 0xf4, 0x5f, 0x79, 0x60,
+ 0xf5, 0x4f, 0x78, 0x70, 0xf6, 0x3f, 0x5b, 0x60, 0xf7, 0x2f, 0x5a, 0x70,
+ 0xf8, 0x28, 0x77, 0xe0, 0xf9, 0x0f, 0x3c, 0x70, 0xfa, 0x08, 0x59, 0xe0,
+ 0xfa, 0xf8, 0x58, 0xf0, 0xfb, 0xe8, 0x3b, 0xe0, 0xfc, 0xd8, 0x3a, 0xf0,
+ 0xfd, 0xc8, 0x1d, 0xe0, 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xa7, 0xff, 0xe0,
+ 0x00, 0x97, 0xfe, 0xf0, 0x01, 0x87, 0xe1, 0xe0, 0x02, 0x77, 0xe0, 0xf0,
+ 0x03, 0x70, 0xfe, 0x60, 0x04, 0x60, 0xfd, 0x70, 0x05, 0x50, 0xe0, 0x60,
+ 0x06, 0x40, 0xdf, 0x70, 0x07, 0x30, 0xc2, 0x60, 0x07, 0x8d, 0x19, 0x70,
+ 0x09, 0x10, 0xa4, 0x60, 0x09, 0xad, 0x94, 0xf0, 0x0a, 0xf0, 0x86, 0x60,
+ 0x0b, 0xe0, 0x85, 0x70, 0x0c, 0xd9, 0xa2, 0xe0, 0x0d, 0xc0, 0x67, 0x70,
+ 0x0e, 0xb9, 0x84, 0xe0, 0x0f, 0xa9, 0x83, 0xf0, 0x10, 0x99, 0x66, 0xe0,
+ 0x11, 0x89, 0x65, 0xf0, 0x12, 0x79, 0x48, 0xe0, 0x13, 0x69, 0x47, 0xf0,
+ 0x14, 0x59, 0x2a, 0xe0, 0x15, 0x49, 0x29, 0xf0, 0x16, 0x39, 0x0c, 0xe0,
+ 0x17, 0x29, 0x0b, 0xf0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xed, 0xf0,
+ 0x1a, 0x02, 0x0b, 0x60, 0x1a, 0xf2, 0x0a, 0x70, 0x1b, 0xe1, 0xed, 0x60,
+ 0x1c, 0xd1, 0xec, 0x70, 0x1d, 0xc1, 0xcf, 0x60, 0x1e, 0xb1, 0xce, 0x70,
+ 0x1f, 0xa1, 0xb1, 0x60, 0x20, 0x76, 0x00, 0xf0, 0x21, 0x81, 0x93, 0x60,
+ 0x22, 0x55, 0xe2, 0xf0, 0x23, 0x6a, 0xaf, 0xe0, 0x24, 0x35, 0xc4, 0xf0,
+ 0x25, 0x4a, 0x91, 0xe0, 0x26, 0x15, 0xa6, 0xf0, 0x27, 0x2a, 0x73, 0xe0,
+ 0x27, 0xfe, 0xc3, 0x70, 0x29, 0x0a, 0x55, 0xe0, 0x29, 0xde, 0xa5, 0x70,
+ 0x2a, 0xea, 0x37, 0xe0, 0x2b, 0xbe, 0x87, 0x70, 0x2c, 0xd3, 0x54, 0x60,
+ 0x2d, 0x9e, 0x69, 0x70, 0x2e, 0xb3, 0x36, 0x60, 0x2f, 0x7e, 0x4b, 0x70,
+ 0x30, 0x93, 0x18, 0x60, 0x31, 0x67, 0x67, 0xf0, 0x32, 0x72, 0xfa, 0x60,
+ 0x33, 0x47, 0x49, 0xf0, 0x34, 0x52, 0xdc, 0x60, 0x35, 0x27, 0x2b, 0xf0,
+ 0x36, 0x32, 0xbe, 0x60, 0x37, 0x07, 0x0d, 0xf0, 0x38, 0x1b, 0xda, 0xe0,
+ 0x38, 0xe6, 0xef, 0xf0, 0x39, 0xfb, 0xbc, 0xe0, 0x3a, 0xc6, 0xd1, 0xf0,
+ 0x3b, 0xdb, 0x9e, 0xe0, 0x3c, 0xaf, 0xee, 0x70, 0x3d, 0xbb, 0x80, 0xe0,
+ 0x3e, 0x8f, 0xd0, 0x70, 0x3f, 0x9b, 0x62, 0xe0, 0x40, 0x6f, 0xb2, 0x70,
+ 0x41, 0x84, 0x7f, 0x60, 0x42, 0x4f, 0x94, 0x70, 0x43, 0x64, 0x61, 0x60,
+ 0x44, 0x2f, 0x76, 0x70, 0x45, 0x44, 0x43, 0x60, 0x45, 0xf3, 0xa8, 0xf0,
+ 0x47, 0x2d, 0x5f, 0xe0, 0x47, 0xd3, 0x8a, 0xf0, 0x49, 0x0d, 0x41, 0xe0,
+ 0x49, 0xb3, 0x6c, 0xf0, 0x4a, 0xed, 0x23, 0xe0, 0x4b, 0x9c, 0x89, 0x70,
+ 0x4c, 0xd6, 0x40, 0x60, 0x4d, 0x7c, 0x6b, 0x70, 0x4e, 0xb6, 0x22, 0x60,
+ 0x4f, 0x5c, 0x4d, 0x70, 0x50, 0x96, 0x04, 0x60, 0x51, 0x3c, 0x2f, 0x70,
+ 0x52, 0x75, 0xe6, 0x60, 0x53, 0x1c, 0x11, 0x70, 0x54, 0x55, 0xc8, 0x60,
+ 0x54, 0xfb, 0xf3, 0x70, 0x56, 0x35, 0xaa, 0x60, 0x56, 0xe5, 0x0f, 0xf0,
+ 0x58, 0x1e, 0xc6, 0xe0, 0x58, 0xc4, 0xf1, 0xf0, 0x59, 0xfe, 0xa8, 0xe0,
+ 0x5a, 0xa4, 0xd3, 0xf0, 0x5b, 0xde, 0x8a, 0xe0, 0x5c, 0x84, 0xb5, 0xf0,
+ 0x5d, 0xbe, 0x6c, 0xe0, 0x5e, 0x64, 0x97, 0xf0, 0x5f, 0x9e, 0x4e, 0xe0,
+ 0x60, 0x4d, 0xb4, 0x70, 0x61, 0x87, 0x6b, 0x60, 0x62, 0x2d, 0x96, 0x70,
+ 0x63, 0x67, 0x4d, 0x60, 0x64, 0x0d, 0x78, 0x70, 0x65, 0x47, 0x2f, 0x60,
+ 0x65, 0xed, 0x5a, 0x70, 0x67, 0x27, 0x11, 0x60, 0x67, 0xcd, 0x3c, 0x70,
+ 0x69, 0x06, 0xf3, 0x60, 0x69, 0xad, 0x1e, 0x70, 0x6a, 0xe6, 0xd5, 0x60,
+ 0x6b, 0x96, 0x3a, 0xf0, 0x6c, 0xcf, 0xf1, 0xe0, 0x6d, 0x76, 0x1c, 0xf0,
+ 0x6e, 0xaf, 0xd3, 0xe0, 0x6f, 0x55, 0xfe, 0xf0, 0x70, 0x8f, 0xb5, 0xe0,
+ 0x71, 0x35, 0xe0, 0xf0, 0x72, 0x6f, 0x97, 0xe0, 0x73, 0x15, 0xc2, 0xf0,
+ 0x74, 0x4f, 0x79, 0xe0, 0x74, 0xfe, 0xdf, 0x70, 0x76, 0x38, 0x96, 0x60,
+ 0x76, 0xde, 0xc1, 0x70, 0x78, 0x18, 0x78, 0x60, 0x78, 0xbe, 0xa3, 0x70,
+ 0x79, 0xf8, 0x5a, 0x60, 0x7a, 0x9e, 0x85, 0x70, 0x7b, 0xd8, 0x3c, 0x60,
+ 0x7c, 0x7e, 0x67, 0x70, 0x7d, 0xb8, 0x1e, 0x60, 0x7e, 0x5e, 0x49, 0x70,
+ 0x7f, 0x98, 0x00, 0x60, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x04,
+ 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x0c,
+ 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c, 0x4d, 0x54, 0x00, 0x45, 0x44,
+ 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50,
+ 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x03, 0xf0, 0x90,
+ 0xff, 0xff, 0xff, 0xff, 0x9e, 0xa6, 0x1e, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0x9f, 0xba, 0xeb, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x86, 0x00, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xa1, 0x9a, 0xcd, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xa2, 0x65, 0xe2, 0x70, 0xff, 0xff, 0xff, 0xff, 0xa3, 0x83, 0xe9, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xa4, 0x6a, 0xae, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xa5, 0x35, 0xa7, 0x60, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x53, 0xca, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xa7, 0x15, 0x89, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xa8, 0x33, 0xac, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xa8, 0xfe, 0xa5, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xaa, 0x13, 0x8e, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xaa, 0xde, 0x87, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xab, 0xf3, 0x70, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xac, 0xbe, 0x69, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xad, 0xd3, 0x52, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xae, 0x9e, 0x4b, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xaf, 0xb3, 0x34, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xb0, 0x7e, 0x2d, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x9c, 0x51, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xb2, 0x67, 0x4a, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xb3, 0x7c, 0x33, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb4, 0x47, 0x2c, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xb5, 0x5c, 0x15, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xb6, 0x27, 0x0e, 0x60, 0xff, 0xff, 0xff, 0xff, 0xb7, 0x3b, 0xf7, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xb8, 0x06, 0xf0, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xb9, 0x1b, 0xd9, 0x70, 0xff, 0xff, 0xff, 0xff, 0xb9, 0xe6, 0xd2, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xbb, 0x04, 0xf5, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xbb, 0xc6, 0xb4, 0x60, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe4, 0xd7, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xbd, 0xaf, 0xd0, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xbe, 0xc4, 0xb9, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x8f, 0xb2, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa4, 0x9b, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xc1, 0x6f, 0x94, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x84, 0x7d, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xc3, 0x4f, 0x76, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xc4, 0x64, 0x5f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xc5, 0x2f, 0x58, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xc6, 0x4d, 0x7c, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xc7, 0x0f, 0x3a, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x2d, 0x5e, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xc8, 0xf8, 0x57, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xca, 0x0d, 0x40, 0x70, 0xff, 0xff, 0xff, 0xff, 0xca, 0xd8, 0x39, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xcb, 0x88, 0xf0, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xd2, 0x23, 0xf4, 0x70, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x60, 0xfb, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xd3, 0x75, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xd4, 0x40, 0xdd, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0xc6, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xd6, 0x20, 0xbf, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xd7, 0x35, 0xa8, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0xa1, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xd9, 0x15, 0x8a, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xd9, 0xe0, 0x83, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfe, 0xa7, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xdb, 0xc0, 0x65, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xdc, 0xde, 0x89, 0x70, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xa9, 0x82, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xde, 0xbe, 0x6b, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xdf, 0x89, 0x64, 0x60, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x9e, 0x4d, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xe1, 0x69, 0x46, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xe2, 0x7e, 0x2f, 0x70, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x49, 0x28, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5e, 0x11, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xe5, 0x57, 0x2e, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x47, 0x2d, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xe7, 0x37, 0x10, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xe8, 0x27, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x16, 0xf2, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xea, 0x06, 0xf1, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xea, 0xf6, 0xd4, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xe6, 0xd3, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xec, 0xd6, 0xb6, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xed, 0xc6, 0xb5, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xee, 0xbf, 0xd3, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xef, 0xaf, 0xd2, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0x9f, 0xb5, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xb4, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xf2, 0x7f, 0x97, 0x60, 0xff, 0xff, 0xff, 0xff,
+ 0xf3, 0x6f, 0x96, 0x70, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x5f, 0x79, 0x60,
+ 0xff, 0xff, 0xff, 0xff, 0xf5, 0x4f, 0x78, 0x70, 0xff, 0xff, 0xff, 0xff,
+ 0xf6, 0x3f, 0x5b, 0x60, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2f, 0x5a, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xf8, 0x28, 0x77, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xf9, 0x0f, 0x3c, 0x70, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x08, 0x59, 0xe0,
+ 0xff, 0xff, 0xff, 0xff, 0xfa, 0xf8, 0x58, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xfb, 0xe8, 0x3b, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd8, 0x3a, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xfd, 0xc8, 0x1d, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xfe, 0xb8, 0x1c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0xff, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x87, 0xe1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x77, 0xe0, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x70, 0xfe, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x60, 0xfd, 0x70, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xe0, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x30, 0xc2, 0x60, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8d, 0x19, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xa4, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0xad, 0x94, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0x86, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe0, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x0c, 0xd9, 0xa2, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x67, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb9, 0x84, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0xa9, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x66, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x65, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 0x79, 0x48, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x47, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x2a, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x49, 0x29, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x0c, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x0b, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x22, 0x29, 0x60, 0x00, 0x00, 0x00, 0x00, 0x19, 0x08, 0xed, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x1a, 0xf2, 0x0a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0xed, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd1, 0xec, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x1d, 0xc1, 0xcf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0xce, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0xa1, 0xb1, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x76, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x93, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xe2, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x23, 0x6a, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xc4, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x25, 0x4a, 0x91, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x26, 0x15, 0xa6, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2a, 0x73, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x27, 0xfe, 0xc3, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x29, 0x0a, 0x55, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x29, 0xde, 0xa5, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0xea, 0x37, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x2b, 0xbe, 0x87, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd3, 0x54, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 0x9e, 0x69, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x2e, 0xb3, 0x36, 0x60, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x7e, 0x4b, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x31, 0x67, 0x67, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0xfa, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x49, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x52, 0xdc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x2b, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xbe, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x37, 0x07, 0x0d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0xda, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x38, 0xe6, 0xef, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x39, 0xfb, 0xbc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xc6, 0xd1, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x3b, 0xdb, 0x9e, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0xaf, 0xee, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xbb, 0x80, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x8f, 0xd0, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x3f, 0x9b, 0x62, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb2, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x7f, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x42, 0x4f, 0x94, 0x70, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x61, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x44, 0x2f, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x44, 0x43, 0x60, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf3, 0xa8, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x47, 0x2d, 0x5f, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x47, 0xd3, 0x8a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0d, 0x41, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0xb3, 0x6c, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x4a, 0xed, 0x23, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x9c, 0x89, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x4c, 0xd6, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x4d, 0x7c, 0x6b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xb6, 0x22, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x4f, 0x5c, 0x4d, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x96, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3c, 0x2f, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x75, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x1c, 0x11, 0x70, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xc8, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0xfb, 0xf3, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x35, 0xaa, 0x60, 0x00, 0x00, 0x00, 0x00, 0x56, 0xe5, 0x0f, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x1e, 0xc6, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0xc4, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x59, 0xfe, 0xa8, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x5a, 0xa4, 0xd3, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x5b, 0xde, 0x8a, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x84, 0xb5, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbe, 0x6c, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x5e, 0x64, 0x97, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9e, 0x4e, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x4d, 0xb4, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x61, 0x87, 0x6b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2d, 0x96, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x4d, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x64, 0x0d, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x2f, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x65, 0xed, 0x5a, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x67, 0x27, 0x11, 0x60, 0x00, 0x00, 0x00, 0x00, 0x67, 0xcd, 0x3c, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x69, 0x06, 0xf3, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x69, 0xad, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xe6, 0xd5, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x6b, 0x96, 0x3a, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0xcf, 0xf1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x76, 0x1c, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x6e, 0xaf, 0xd3, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x6f, 0x55, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0xb5, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x6f, 0x97, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xc2, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x74, 0x4f, 0x79, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0xfe, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0x96, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xde, 0xc1, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x78, 0x18, 0x78, 0x60, 0x00, 0x00, 0x00, 0x00, 0x78, 0xbe, 0xa3, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x79, 0xf8, 0x5a, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x7a, 0x9e, 0x85, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7b, 0xd8, 0x3c, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7e, 0x67, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x7d, 0xb8, 0x1e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5e, 0x49, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x98, 0x00, 0x60, 0x00, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0xff, 0xff, 0xba, 0x9e, 0x00, 0x00, 0xff,
+ 0xff, 0xc7, 0xc0, 0x01, 0x04, 0xff, 0xff, 0xb9, 0xb0, 0x00, 0x08, 0xff,
+ 0xff, 0xc7, 0xc0, 0x01, 0x0c, 0xff, 0xff, 0xc7, 0xc0, 0x01, 0x10, 0x4c,
+ 0x4d, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45,
+ 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x45, 0x53, 0x54, 0x35, 0x45, 0x44,
+ 0x54, 0x2c, 0x4d, 0x33, 0x2e, 0x32, 0x2e, 0x30, 0x2c, 0x4d, 0x31, 0x31,
+ 0x2e, 0x31, 0x2e, 0x30, 0x0a
+};
+unsigned int America_New_York_len = 3545;
+unsigned char Australia_Sydney[] = {
+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x00, 0x00, 0x00,
+ 0x9c, 0x4e, 0xa6, 0x9c, 0x9c, 0xbc, 0x20, 0xf0, 0xcb, 0x54, 0xb3, 0x00,
+ 0xcb, 0xc7, 0x57, 0x70, 0xcc, 0xb7, 0x56, 0x80, 0xcd, 0xa7, 0x39, 0x70,
+ 0xce, 0xa0, 0x73, 0x00, 0xcf, 0x87, 0x1b, 0x70, 0x03, 0x70, 0x39, 0x80,
+ 0x04, 0x0d, 0x1c, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x05, 0xf6, 0x38, 0x80,
+ 0x07, 0x2f, 0xfd, 0x80, 0x07, 0xd6, 0x1a, 0x80, 0x09, 0x0f, 0xdf, 0x80,
+ 0x09, 0xb5, 0xfc, 0x80, 0x0a, 0xef, 0xc1, 0x80, 0x0b, 0x9f, 0x19, 0x00,
+ 0x0c, 0xd8, 0xde, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x0e, 0xb8, 0xc0, 0x00,
+ 0x0f, 0x5e, 0xdd, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x11, 0x3e, 0xbf, 0x00,
+ 0x12, 0x78, 0x84, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x14, 0x58, 0x66, 0x00,
+ 0x14, 0xfe, 0x83, 0x00, 0x16, 0x38, 0x48, 0x00, 0x17, 0x0c, 0x89, 0x80,
+ 0x18, 0x21, 0x64, 0x80, 0x18, 0xc7, 0x81, 0x80, 0x1a, 0x01, 0x46, 0x80,
+ 0x1a, 0xa7, 0x63, 0x80, 0x1b, 0xe1, 0x28, 0x80, 0x1c, 0x87, 0x45, 0x80,
+ 0x1d, 0xc1, 0x0a, 0x80, 0x1e, 0x79, 0x9c, 0x80, 0x1f, 0x97, 0xb2, 0x00,
+ 0x20, 0x59, 0x7e, 0x80, 0x21, 0x80, 0xce, 0x80, 0x22, 0x42, 0x9b, 0x00,
+ 0x23, 0x69, 0xeb, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x25, 0x49, 0xcd, 0x00,
+ 0x25, 0xef, 0xea, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x27, 0xcf, 0xcc, 0x00,
+ 0x29, 0x09, 0x91, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x2a, 0xe9, 0x73, 0x00,
+ 0x2b, 0x98, 0xca, 0x80, 0x2c, 0xd2, 0x8f, 0x80, 0x2d, 0x78, 0xac, 0x80,
+ 0x2e, 0xb2, 0x71, 0x80, 0x2f, 0x58, 0x8e, 0x80, 0x30, 0x92, 0x53, 0x80,
+ 0x31, 0x5d, 0x5a, 0x80, 0x32, 0x72, 0x35, 0x80, 0x33, 0x3d, 0x3c, 0x80,
+ 0x34, 0x52, 0x17, 0x80, 0x35, 0x1d, 0x1e, 0x80, 0x36, 0x31, 0xf9, 0x80,
+ 0x36, 0xfd, 0x00, 0x80, 0x38, 0x1b, 0x16, 0x00, 0x38, 0xdc, 0xe2, 0x80,
+ 0x39, 0xa7, 0xe9, 0x80, 0x3a, 0xbc, 0xc4, 0x80, 0x3b, 0xda, 0xda, 0x00,
+ 0x3c, 0xa5, 0xe1, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x3e, 0x85, 0xc3, 0x00,
+ 0x3f, 0x9a, 0x9e, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x41, 0x83, 0xba, 0x80,
+ 0x42, 0x45, 0x87, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x44, 0x2e, 0xa3, 0x80,
+ 0x45, 0x43, 0x7e, 0x80, 0x46, 0x05, 0x4b, 0x00, 0x47, 0x23, 0x60, 0x80,
+ 0x47, 0xf7, 0xa2, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x49, 0xd7, 0x84, 0x00,
+ 0x4a, 0xc7, 0x75, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x4c, 0xa7, 0x57, 0x00,
+ 0x4d, 0x97, 0x48, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x4f, 0x77, 0x2a, 0x00,
+ 0x50, 0x70, 0x55, 0x80, 0x51, 0x60, 0x46, 0x80, 0x52, 0x50, 0x37, 0x80,
+ 0x53, 0x40, 0x28, 0x80, 0x54, 0x30, 0x19, 0x80, 0x55, 0x20, 0x0a, 0x80,
+ 0x56, 0x0f, 0xfb, 0x80, 0x56, 0xff, 0xec, 0x80, 0x57, 0xef, 0xdd, 0x80,
+ 0x58, 0xdf, 0xce, 0x80, 0x59, 0xcf, 0xbf, 0x80, 0x5a, 0xbf, 0xb0, 0x80,
+ 0x5b, 0xb8, 0xdc, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x5d, 0x98, 0xbe, 0x00,
+ 0x5e, 0x88, 0xaf, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x60, 0x68, 0x91, 0x00,
+ 0x61, 0x58, 0x82, 0x00, 0x62, 0x48, 0x73, 0x00, 0x63, 0x38, 0x64, 0x00,
+ 0x64, 0x28, 0x55, 0x00, 0x65, 0x18, 0x46, 0x00, 0x66, 0x11, 0x71, 0x80,
+ 0x67, 0x01, 0x62, 0x80, 0x67, 0xf1, 0x53, 0x80, 0x68, 0xe1, 0x44, 0x80,
+ 0x69, 0xd1, 0x35, 0x80, 0x6a, 0xc1, 0x26, 0x80, 0x6b, 0xb1, 0x17, 0x80,
+ 0x6c, 0xa1, 0x08, 0x80, 0x6d, 0x90, 0xf9, 0x80, 0x6e, 0x80, 0xea, 0x80,
+ 0x6f, 0x70, 0xdb, 0x80, 0x70, 0x6a, 0x07, 0x00, 0x71, 0x59, 0xf8, 0x00,
+ 0x72, 0x49, 0xe9, 0x00, 0x73, 0x39, 0xda, 0x00, 0x74, 0x29, 0xcb, 0x00,
+ 0x75, 0x19, 0xbc, 0x00, 0x76, 0x09, 0xad, 0x00, 0x76, 0xf9, 0x9e, 0x00,
+ 0x77, 0xe9, 0x8f, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x79, 0xc9, 0x71, 0x00,
+ 0x7a, 0xb9, 0x62, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x7c, 0xa2, 0x7e, 0x80,
+ 0x7d, 0x92, 0x6f, 0x80, 0x7e, 0x82, 0x60, 0x80, 0x7f, 0x72, 0x51, 0x80,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+ 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x00, 0x00,
+ 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00,
+ 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a, 0xb0, 0x01, 0x04, 0x00, 0x00,
+ 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54, 0x00, 0x41, 0x45, 0x44, 0x54,
+ 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e,
+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x73, 0x16, 0x7f, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x4e, 0xa6, 0x9c,
+ 0xff, 0xff, 0xff, 0xff, 0x9c, 0xbc, 0x20, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0xcb, 0x54, 0xb3, 0x00, 0xff, 0xff, 0xff, 0xff, 0xcb, 0xc7, 0x57, 0x70,
+ 0xff, 0xff, 0xff, 0xff, 0xcc, 0xb7, 0x56, 0x80, 0xff, 0xff, 0xff, 0xff,
+ 0xcd, 0xa7, 0x39, 0x70, 0xff, 0xff, 0xff, 0xff, 0xce, 0xa0, 0x73, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xcf, 0x87, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x70, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0d, 0x1c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xf6, 0x38, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x2f, 0xfd, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xd6, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x0f, 0xdf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xb5, 0xfc, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xef, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x0b, 0x9f, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd8, 0xde, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7e, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0xb8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5e, 0xdd, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x98, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x3e, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x78, 0x84, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x13, 0x1e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x58, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xfe, 0x83, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x38, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x17, 0x0c, 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x21, 0x64, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0xc7, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x1a, 0x01, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xa7, 0x63, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe1, 0x28, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x1c, 0x87, 0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xc1, 0x0a, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x79, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x97, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x59, 0x7e, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0xce, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x42, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x69, 0xeb, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x22, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x25, 0x49, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xef, 0xea, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x27, 0x29, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x27, 0xcf, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x09, 0x91, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x29, 0xaf, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0xe9, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x98, 0xca, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd2, 0x8f, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 0x78, 0xac, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xb2, 0x71, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x2f, 0x58, 0x8e, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x92, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x5d, 0x5a, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x32, 0x72, 0x35, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x33, 0x3d, 0x3c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0x17, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x35, 0x1d, 0x1e, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x31, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x36, 0xfd, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0xdc, 0xe2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0xa7, 0xe9, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x3a, 0xbc, 0xc4, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x3b, 0xda, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xa5, 0xe1, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3d, 0xba, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0x85, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9a, 0x9e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x83, 0xba, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0x87, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x43, 0x63, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x2e, 0xa3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0x43, 0x7e, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x05, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x47, 0x23, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x47, 0xf7, 0xa2, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x48, 0xe7, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0xd7, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xc7, 0x75, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x4b, 0xb7, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4c, 0xa7, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x97, 0x48, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x4e, 0x87, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x77, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x70, 0x55, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x60, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x50, 0x37, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x40, 0x28, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x30, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x20, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0x0f, 0xfb, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x56, 0xff, 0xec, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x57, 0xef, 0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x58, 0xdf, 0xce, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x59, 0xcf, 0xbf, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x5a, 0xbf, 0xb0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x5b, 0xb8, 0xdc, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5c, 0xa8, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5d, 0x98, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x88, 0xaf, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5f, 0x78, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x68, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x58, 0x82, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0x48, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x63, 0x38, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x55, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x65, 0x18, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x66, 0x11, 0x71, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x62, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x67, 0xf1, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xe1, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xd1, 0x35, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x6a, 0xc1, 0x26, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x6b, 0xb1, 0x17, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xa1, 0x08, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x6d, 0x90, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x6e, 0x80, 0xea, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x70, 0xdb, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x6a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x71, 0x59, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x49, 0xe9, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x73, 0x39, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x29, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x19, 0xbc, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x09, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x76, 0xf9, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xe9, 0x8f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x78, 0xd9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x79, 0xc9, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xb9, 0x62, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7b, 0xb2, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x7c, 0xa2, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x92, 0x6f, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x7f, 0x72, 0x51, 0x80, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+ 0x03, 0x04, 0x03, 0x00, 0x00, 0x8d, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x9a,
+ 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x00, 0x00, 0x9a,
+ 0xb0, 0x01, 0x04, 0x00, 0x00, 0x8c, 0xa0, 0x00, 0x09, 0x4c, 0x4d, 0x54,
+ 0x00, 0x41, 0x45, 0x44, 0x54, 0x00, 0x41, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x45,
+ 0x53, 0x54, 0x2d, 0x31, 0x30, 0x41, 0x45, 0x44, 0x54, 0x2c, 0x4d, 0x31,
+ 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x4d, 0x34, 0x2e, 0x31, 0x2e, 0x30,
+ 0x2f, 0x33, 0x0a
+};
+unsigned int Australia_Sydney_len = 2223;
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.cc
index 21e5625759..441638b256 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.cc
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.cc
@@ -1,62 +1,62 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// The implementation of the y_absl::Time class, which is declared in
// //y_absl/time.h.
-//
+//
// The representation for an y_absl::Time is an y_absl::Duration offset from the
-// epoch. We use the traditional Unix epoch (1970-01-01 00:00:00 +0000)
-// for convenience, but this is not exposed in the API and could be changed.
-//
-// NOTE: To keep type verbosity to a minimum, the following variable naming
-// conventions are used throughout this file.
-//
+// epoch. We use the traditional Unix epoch (1970-01-01 00:00:00 +0000)
+// for convenience, but this is not exposed in the API and could be changed.
+//
+// NOTE: To keep type verbosity to a minimum, the following variable naming
+// conventions are used throughout this file.
+//
// tz: An y_absl::TimeZone
// ci: An y_absl::TimeZone::CivilInfo
// ti: An y_absl::TimeZone::TimeInfo
// cd: An y_absl::CivilDay or a cctz::civil_day
// cs: An y_absl::CivilSecond or a cctz::civil_second
// bd: An y_absl::Time::Breakdown
-// cl: A cctz::time_zone::civil_lookup
-// al: A cctz::time_zone::absolute_lookup
-
+// cl: A cctz::time_zone::civil_lookup
+// al: A cctz::time_zone::absolute_lookup
+
#include "y_absl/time/time.h"
-
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
-#include <cstring>
-#include <ctime>
-#include <limits>
-
+
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
+#include <cstring>
+#include <ctime>
+#include <limits>
+
#include "y_absl/time/internal/cctz/include/cctz/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
+
namespace cctz = y_absl::time_internal::cctz;
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-namespace {
-
-inline cctz::time_point<cctz::seconds> unix_epoch() {
- return std::chrono::time_point_cast<cctz::seconds>(
- std::chrono::system_clock::from_time_t(0));
-}
-
-// Floors d to the next unit boundary closer to negative infinity.
+
+namespace {
+
+inline cctz::time_point<cctz::seconds> unix_epoch() {
+ return std::chrono::time_point_cast<cctz::seconds>(
+ std::chrono::system_clock::from_time_t(0));
+}
+
+// Floors d to the next unit boundary closer to negative infinity.
inline int64_t FloorToUnit(y_absl::Duration d, y_absl::Duration unit) {
y_absl::Duration rem;
int64_t q = y_absl::IDivDuration(d, unit, &rem);
@@ -64,437 +64,437 @@ inline int64_t FloorToUnit(y_absl::Duration d, y_absl::Duration unit) {
q == std::numeric_limits<int64_t>::min())
? q
: q - 1;
-}
-
+}
+
inline y_absl::Time::Breakdown InfiniteFutureBreakdown() {
y_absl::Time::Breakdown bd;
- bd.year = std::numeric_limits<int64_t>::max();
- bd.month = 12;
- bd.day = 31;
- bd.hour = 23;
- bd.minute = 59;
- bd.second = 59;
+ bd.year = std::numeric_limits<int64_t>::max();
+ bd.month = 12;
+ bd.day = 31;
+ bd.hour = 23;
+ bd.minute = 59;
+ bd.second = 59;
bd.subsecond = y_absl::InfiniteDuration();
- bd.weekday = 4;
- bd.yearday = 365;
- bd.offset = 0;
- bd.is_dst = false;
- bd.zone_abbr = "-00";
- return bd;
-}
-
+ bd.weekday = 4;
+ bd.yearday = 365;
+ bd.offset = 0;
+ bd.is_dst = false;
+ bd.zone_abbr = "-00";
+ return bd;
+}
+
inline y_absl::Time::Breakdown InfinitePastBreakdown() {
- Time::Breakdown bd;
- bd.year = std::numeric_limits<int64_t>::min();
- bd.month = 1;
- bd.day = 1;
- bd.hour = 0;
- bd.minute = 0;
- bd.second = 0;
+ Time::Breakdown bd;
+ bd.year = std::numeric_limits<int64_t>::min();
+ bd.month = 1;
+ bd.day = 1;
+ bd.hour = 0;
+ bd.minute = 0;
+ bd.second = 0;
bd.subsecond = -y_absl::InfiniteDuration();
- bd.weekday = 7;
- bd.yearday = 1;
- bd.offset = 0;
- bd.is_dst = false;
- bd.zone_abbr = "-00";
- return bd;
-}
-
+ bd.weekday = 7;
+ bd.yearday = 1;
+ bd.offset = 0;
+ bd.is_dst = false;
+ bd.zone_abbr = "-00";
+ return bd;
+}
+
inline y_absl::TimeZone::CivilInfo InfiniteFutureCivilInfo() {
- TimeZone::CivilInfo ci;
- ci.cs = CivilSecond::max();
- ci.subsecond = InfiniteDuration();
- ci.offset = 0;
- ci.is_dst = false;
- ci.zone_abbr = "-00";
- return ci;
-}
-
+ TimeZone::CivilInfo ci;
+ ci.cs = CivilSecond::max();
+ ci.subsecond = InfiniteDuration();
+ ci.offset = 0;
+ ci.is_dst = false;
+ ci.zone_abbr = "-00";
+ return ci;
+}
+
inline y_absl::TimeZone::CivilInfo InfinitePastCivilInfo() {
- TimeZone::CivilInfo ci;
- ci.cs = CivilSecond::min();
- ci.subsecond = -InfiniteDuration();
- ci.offset = 0;
- ci.is_dst = false;
- ci.zone_abbr = "-00";
- return ci;
-}
-
+ TimeZone::CivilInfo ci;
+ ci.cs = CivilSecond::min();
+ ci.subsecond = -InfiniteDuration();
+ ci.offset = 0;
+ ci.is_dst = false;
+ ci.zone_abbr = "-00";
+ return ci;
+}
+
inline y_absl::TimeConversion InfiniteFutureTimeConversion() {
y_absl::TimeConversion tc;
tc.pre = tc.trans = tc.post = y_absl::InfiniteFuture();
tc.kind = y_absl::TimeConversion::UNIQUE;
- tc.normalized = true;
- return tc;
-}
-
-inline TimeConversion InfinitePastTimeConversion() {
+ tc.normalized = true;
+ return tc;
+}
+
+inline TimeConversion InfinitePastTimeConversion() {
y_absl::TimeConversion tc;
tc.pre = tc.trans = tc.post = y_absl::InfinitePast();
tc.kind = y_absl::TimeConversion::UNIQUE;
- tc.normalized = true;
- return tc;
-}
-
-// Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as
-// necessary. If sec is min/max, then consult cs+tz to check for overlow.
-Time MakeTimeWithOverflow(const cctz::time_point<cctz::seconds>& sec,
- const cctz::civil_second& cs,
- const cctz::time_zone& tz,
- bool* normalized = nullptr) {
- const auto max = cctz::time_point<cctz::seconds>::max();
- const auto min = cctz::time_point<cctz::seconds>::min();
- if (sec == max) {
- const auto al = tz.lookup(max);
- if (cs > al.cs) {
- if (normalized) *normalized = true;
+ tc.normalized = true;
+ return tc;
+}
+
+// Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as
+// necessary. If sec is min/max, then consult cs+tz to check for overlow.
+Time MakeTimeWithOverflow(const cctz::time_point<cctz::seconds>& sec,
+ const cctz::civil_second& cs,
+ const cctz::time_zone& tz,
+ bool* normalized = nullptr) {
+ const auto max = cctz::time_point<cctz::seconds>::max();
+ const auto min = cctz::time_point<cctz::seconds>::min();
+ if (sec == max) {
+ const auto al = tz.lookup(max);
+ if (cs > al.cs) {
+ if (normalized) *normalized = true;
return y_absl::InfiniteFuture();
- }
- }
- if (sec == min) {
- const auto al = tz.lookup(min);
- if (cs < al.cs) {
- if (normalized) *normalized = true;
+ }
+ }
+ if (sec == min) {
+ const auto al = tz.lookup(min);
+ if (cs < al.cs) {
+ if (normalized) *normalized = true;
return y_absl::InfinitePast();
- }
- }
- const auto hi = (sec - unix_epoch()).count();
- return time_internal::FromUnixDuration(time_internal::MakeDuration(hi));
-}
-
-// Returns Mon=1..Sun=7.
-inline int MapWeekday(const cctz::weekday& wd) {
- switch (wd) {
- case cctz::weekday::monday:
- return 1;
- case cctz::weekday::tuesday:
- return 2;
- case cctz::weekday::wednesday:
- return 3;
- case cctz::weekday::thursday:
- return 4;
- case cctz::weekday::friday:
- return 5;
- case cctz::weekday::saturday:
- return 6;
- case cctz::weekday::sunday:
- return 7;
- }
- return 1;
-}
-
-bool FindTransition(const cctz::time_zone& tz,
- bool (cctz::time_zone::*find_transition)(
- const cctz::time_point<cctz::seconds>& tp,
- cctz::time_zone::civil_transition* trans) const,
- Time t, TimeZone::CivilTransition* trans) {
- // Transitions are second-aligned, so we can discard any fractional part.
- const auto tp = unix_epoch() + cctz::seconds(ToUnixSeconds(t));
- cctz::time_zone::civil_transition tr;
- if (!(tz.*find_transition)(tp, &tr)) return false;
- trans->from = CivilSecond(tr.from);
- trans->to = CivilSecond(tr.to);
- return true;
-}
-
-} // namespace
-
-//
-// Time
-//
-
+ }
+ }
+ const auto hi = (sec - unix_epoch()).count();
+ return time_internal::FromUnixDuration(time_internal::MakeDuration(hi));
+}
+
+// Returns Mon=1..Sun=7.
+inline int MapWeekday(const cctz::weekday& wd) {
+ switch (wd) {
+ case cctz::weekday::monday:
+ return 1;
+ case cctz::weekday::tuesday:
+ return 2;
+ case cctz::weekday::wednesday:
+ return 3;
+ case cctz::weekday::thursday:
+ return 4;
+ case cctz::weekday::friday:
+ return 5;
+ case cctz::weekday::saturday:
+ return 6;
+ case cctz::weekday::sunday:
+ return 7;
+ }
+ return 1;
+}
+
+bool FindTransition(const cctz::time_zone& tz,
+ bool (cctz::time_zone::*find_transition)(
+ const cctz::time_point<cctz::seconds>& tp,
+ cctz::time_zone::civil_transition* trans) const,
+ Time t, TimeZone::CivilTransition* trans) {
+ // Transitions are second-aligned, so we can discard any fractional part.
+ const auto tp = unix_epoch() + cctz::seconds(ToUnixSeconds(t));
+ cctz::time_zone::civil_transition tr;
+ if (!(tz.*find_transition)(tp, &tr)) return false;
+ trans->from = CivilSecond(tr.from);
+ trans->to = CivilSecond(tr.to);
+ return true;
+}
+
+} // namespace
+
+//
+// Time
+//
+
y_absl::Time::Breakdown Time::In(y_absl::TimeZone tz) const {
if (*this == y_absl::InfiniteFuture()) return InfiniteFutureBreakdown();
if (*this == y_absl::InfinitePast()) return InfinitePastBreakdown();
-
- const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(rep_));
- const auto al = cctz::time_zone(tz).lookup(tp);
- const auto cs = al.cs;
- const auto cd = cctz::civil_day(cs);
-
+
+ const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(rep_));
+ const auto al = cctz::time_zone(tz).lookup(tp);
+ const auto cs = al.cs;
+ const auto cd = cctz::civil_day(cs);
+
y_absl::Time::Breakdown bd;
- bd.year = cs.year();
- bd.month = cs.month();
- bd.day = cs.day();
- bd.hour = cs.hour();
- bd.minute = cs.minute();
- bd.second = cs.second();
- bd.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(rep_));
- bd.weekday = MapWeekday(cctz::get_weekday(cd));
- bd.yearday = cctz::get_yearday(cd);
- bd.offset = al.offset;
- bd.is_dst = al.is_dst;
- bd.zone_abbr = al.abbr;
- return bd;
-}
-
-//
-// Conversions from/to other time types.
-//
-
+ bd.year = cs.year();
+ bd.month = cs.month();
+ bd.day = cs.day();
+ bd.hour = cs.hour();
+ bd.minute = cs.minute();
+ bd.second = cs.second();
+ bd.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(rep_));
+ bd.weekday = MapWeekday(cctz::get_weekday(cd));
+ bd.yearday = cctz::get_yearday(cd);
+ bd.offset = al.offset;
+ bd.is_dst = al.is_dst;
+ bd.zone_abbr = al.abbr;
+ return bd;
+}
+
+//
+// Conversions from/to other time types.
+//
+
y_absl::Time FromUDate(double udate) {
return time_internal::FromUnixDuration(y_absl::Milliseconds(udate));
-}
-
+}
+
y_absl::Time FromUniversal(int64_t universal) {
return y_absl::UniversalEpoch() + 100 * y_absl::Nanoseconds(universal);
-}
-
-int64_t ToUnixNanos(Time t) {
- if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
- time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) {
- return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) *
- 1000 * 1000 * 1000) +
- (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4);
- }
+}
+
+int64_t ToUnixNanos(Time t) {
+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) {
+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) *
+ 1000 * 1000 * 1000) +
+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4);
+ }
return FloorToUnit(time_internal::ToUnixDuration(t), y_absl::Nanoseconds(1));
-}
-
-int64_t ToUnixMicros(Time t) {
- if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
- time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 43 == 0) {
- return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) *
- 1000 * 1000) +
- (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4000);
- }
+}
+
+int64_t ToUnixMicros(Time t) {
+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 43 == 0) {
+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) *
+ 1000 * 1000) +
+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4000);
+ }
return FloorToUnit(time_internal::ToUnixDuration(t), y_absl::Microseconds(1));
-}
-
-int64_t ToUnixMillis(Time t) {
- if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
- time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 53 == 0) {
- return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * 1000) +
- (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) /
- (4000 * 1000));
- }
+}
+
+int64_t ToUnixMillis(Time t) {
+ if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 &&
+ time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 53 == 0) {
+ return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * 1000) +
+ (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) /
+ (4000 * 1000));
+ }
return FloorToUnit(time_internal::ToUnixDuration(t), y_absl::Milliseconds(1));
-}
-
-int64_t ToUnixSeconds(Time t) {
- return time_internal::GetRepHi(time_internal::ToUnixDuration(t));
-}
-
+}
+
+int64_t ToUnixSeconds(Time t) {
+ return time_internal::GetRepHi(time_internal::ToUnixDuration(t));
+}
+
time_t ToTimeT(Time t) { return y_absl::ToTimespec(t).tv_sec; }
-
-double ToUDate(Time t) {
+
+double ToUDate(Time t) {
return y_absl::FDivDuration(time_internal::ToUnixDuration(t),
y_absl::Milliseconds(1));
-}
-
+}
+
int64_t ToUniversal(y_absl::Time t) {
return y_absl::FloorToUnit(t - y_absl::UniversalEpoch(), y_absl::Nanoseconds(100));
-}
-
+}
+
y_absl::Time TimeFromTimespec(timespec ts) {
return time_internal::FromUnixDuration(y_absl::DurationFromTimespec(ts));
-}
-
+}
+
y_absl::Time TimeFromTimeval(timeval tv) {
return time_internal::FromUnixDuration(y_absl::DurationFromTimeval(tv));
-}
-
-timespec ToTimespec(Time t) {
- timespec ts;
+}
+
+timespec ToTimespec(Time t) {
+ timespec ts;
y_absl::Duration d = time_internal::ToUnixDuration(t);
- if (!time_internal::IsInfiniteDuration(d)) {
- ts.tv_sec = time_internal::GetRepHi(d);
- if (ts.tv_sec == time_internal::GetRepHi(d)) { // no time_t narrowing
- ts.tv_nsec = time_internal::GetRepLo(d) / 4; // floor
- return ts;
- }
- }
+ if (!time_internal::IsInfiniteDuration(d)) {
+ ts.tv_sec = time_internal::GetRepHi(d);
+ if (ts.tv_sec == time_internal::GetRepHi(d)) { // no time_t narrowing
+ ts.tv_nsec = time_internal::GetRepLo(d) / 4; // floor
+ return ts;
+ }
+ }
if (d >= y_absl::ZeroDuration()) {
- ts.tv_sec = std::numeric_limits<time_t>::max();
- ts.tv_nsec = 1000 * 1000 * 1000 - 1;
- } else {
- ts.tv_sec = std::numeric_limits<time_t>::min();
- ts.tv_nsec = 0;
- }
- return ts;
-}
-
-timeval ToTimeval(Time t) {
- timeval tv;
+ ts.tv_sec = std::numeric_limits<time_t>::max();
+ ts.tv_nsec = 1000 * 1000 * 1000 - 1;
+ } else {
+ ts.tv_sec = std::numeric_limits<time_t>::min();
+ ts.tv_nsec = 0;
+ }
+ return ts;
+}
+
+timeval ToTimeval(Time t) {
+ timeval tv;
timespec ts = y_absl::ToTimespec(t);
- tv.tv_sec = ts.tv_sec;
- if (tv.tv_sec != ts.tv_sec) { // narrowing
- if (ts.tv_sec < 0) {
- tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
- tv.tv_usec = 0;
- } else {
- tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
- tv.tv_usec = 1000 * 1000 - 1;
- }
- return tv;
- }
- tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t
- return tv;
-}
-
-Time FromChrono(const std::chrono::system_clock::time_point& tp) {
- return time_internal::FromUnixDuration(time_internal::FromChrono(
- tp - std::chrono::system_clock::from_time_t(0)));
-}
-
+ tv.tv_sec = ts.tv_sec;
+ if (tv.tv_sec != ts.tv_sec) { // narrowing
+ if (ts.tv_sec < 0) {
+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
+ tv.tv_usec = 1000 * 1000 - 1;
+ }
+ return tv;
+ }
+ tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t
+ return tv;
+}
+
+Time FromChrono(const std::chrono::system_clock::time_point& tp) {
+ return time_internal::FromUnixDuration(time_internal::FromChrono(
+ tp - std::chrono::system_clock::from_time_t(0)));
+}
+
std::chrono::system_clock::time_point ToChronoTime(y_absl::Time t) {
- using D = std::chrono::system_clock::duration;
- auto d = time_internal::ToUnixDuration(t);
- if (d < ZeroDuration()) d = Floor(d, FromChrono(D{1}));
- return std::chrono::system_clock::from_time_t(0) +
- time_internal::ToChronoDuration<D>(d);
-}
-
-//
-// TimeZone
-//
-
+ using D = std::chrono::system_clock::duration;
+ auto d = time_internal::ToUnixDuration(t);
+ if (d < ZeroDuration()) d = Floor(d, FromChrono(D{1}));
+ return std::chrono::system_clock::from_time_t(0) +
+ time_internal::ToChronoDuration<D>(d);
+}
+
+//
+// TimeZone
+//
+
y_absl::TimeZone::CivilInfo TimeZone::At(Time t) const {
if (t == y_absl::InfiniteFuture()) return InfiniteFutureCivilInfo();
if (t == y_absl::InfinitePast()) return InfinitePastCivilInfo();
-
- const auto ud = time_internal::ToUnixDuration(t);
- const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(ud));
- const auto al = cz_.lookup(tp);
-
- TimeZone::CivilInfo ci;
- ci.cs = CivilSecond(al.cs);
- ci.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(ud));
- ci.offset = al.offset;
- ci.is_dst = al.is_dst;
- ci.zone_abbr = al.abbr;
- return ci;
-}
-
+
+ const auto ud = time_internal::ToUnixDuration(t);
+ const auto tp = unix_epoch() + cctz::seconds(time_internal::GetRepHi(ud));
+ const auto al = cz_.lookup(tp);
+
+ TimeZone::CivilInfo ci;
+ ci.cs = CivilSecond(al.cs);
+ ci.subsecond = time_internal::MakeDuration(0, time_internal::GetRepLo(ud));
+ ci.offset = al.offset;
+ ci.is_dst = al.is_dst;
+ ci.zone_abbr = al.abbr;
+ return ci;
+}
+
y_absl::TimeZone::TimeInfo TimeZone::At(CivilSecond ct) const {
- const cctz::civil_second cs(ct);
- const auto cl = cz_.lookup(cs);
-
- TimeZone::TimeInfo ti;
- switch (cl.kind) {
- case cctz::time_zone::civil_lookup::UNIQUE:
- ti.kind = TimeZone::TimeInfo::UNIQUE;
- break;
- case cctz::time_zone::civil_lookup::SKIPPED:
- ti.kind = TimeZone::TimeInfo::SKIPPED;
- break;
- case cctz::time_zone::civil_lookup::REPEATED:
- ti.kind = TimeZone::TimeInfo::REPEATED;
- break;
- }
- ti.pre = MakeTimeWithOverflow(cl.pre, cs, cz_);
- ti.trans = MakeTimeWithOverflow(cl.trans, cs, cz_);
- ti.post = MakeTimeWithOverflow(cl.post, cs, cz_);
- return ti;
-}
-
-bool TimeZone::NextTransition(Time t, CivilTransition* trans) const {
- return FindTransition(cz_, &cctz::time_zone::next_transition, t, trans);
-}
-
-bool TimeZone::PrevTransition(Time t, CivilTransition* trans) const {
- return FindTransition(cz_, &cctz::time_zone::prev_transition, t, trans);
-}
-
-//
-// Conversions involving time zones.
-//
-
+ const cctz::civil_second cs(ct);
+ const auto cl = cz_.lookup(cs);
+
+ TimeZone::TimeInfo ti;
+ switch (cl.kind) {
+ case cctz::time_zone::civil_lookup::UNIQUE:
+ ti.kind = TimeZone::TimeInfo::UNIQUE;
+ break;
+ case cctz::time_zone::civil_lookup::SKIPPED:
+ ti.kind = TimeZone::TimeInfo::SKIPPED;
+ break;
+ case cctz::time_zone::civil_lookup::REPEATED:
+ ti.kind = TimeZone::TimeInfo::REPEATED;
+ break;
+ }
+ ti.pre = MakeTimeWithOverflow(cl.pre, cs, cz_);
+ ti.trans = MakeTimeWithOverflow(cl.trans, cs, cz_);
+ ti.post = MakeTimeWithOverflow(cl.post, cs, cz_);
+ return ti;
+}
+
+bool TimeZone::NextTransition(Time t, CivilTransition* trans) const {
+ return FindTransition(cz_, &cctz::time_zone::next_transition, t, trans);
+}
+
+bool TimeZone::PrevTransition(Time t, CivilTransition* trans) const {
+ return FindTransition(cz_, &cctz::time_zone::prev_transition, t, trans);
+}
+
+//
+// Conversions involving time zones.
+//
+
y_absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
- int min, int sec, TimeZone tz) {
- // Avoids years that are too extreme for CivilSecond to normalize.
- if (year > 300000000000) return InfiniteFutureTimeConversion();
- if (year < -300000000000) return InfinitePastTimeConversion();
-
- const CivilSecond cs(year, mon, day, hour, min, sec);
- const auto ti = tz.At(cs);
-
- TimeConversion tc;
- tc.pre = ti.pre;
- tc.trans = ti.trans;
- tc.post = ti.post;
- switch (ti.kind) {
- case TimeZone::TimeInfo::UNIQUE:
- tc.kind = TimeConversion::UNIQUE;
- break;
- case TimeZone::TimeInfo::SKIPPED:
- tc.kind = TimeConversion::SKIPPED;
- break;
- case TimeZone::TimeInfo::REPEATED:
- tc.kind = TimeConversion::REPEATED;
- break;
- }
- tc.normalized = false;
- if (year != cs.year() || mon != cs.month() || day != cs.day() ||
- hour != cs.hour() || min != cs.minute() || sec != cs.second()) {
- tc.normalized = true;
- }
- return tc;
-}
-
+ int min, int sec, TimeZone tz) {
+ // Avoids years that are too extreme for CivilSecond to normalize.
+ if (year > 300000000000) return InfiniteFutureTimeConversion();
+ if (year < -300000000000) return InfinitePastTimeConversion();
+
+ const CivilSecond cs(year, mon, day, hour, min, sec);
+ const auto ti = tz.At(cs);
+
+ TimeConversion tc;
+ tc.pre = ti.pre;
+ tc.trans = ti.trans;
+ tc.post = ti.post;
+ switch (ti.kind) {
+ case TimeZone::TimeInfo::UNIQUE:
+ tc.kind = TimeConversion::UNIQUE;
+ break;
+ case TimeZone::TimeInfo::SKIPPED:
+ tc.kind = TimeConversion::SKIPPED;
+ break;
+ case TimeZone::TimeInfo::REPEATED:
+ tc.kind = TimeConversion::REPEATED;
+ break;
+ }
+ tc.normalized = false;
+ if (year != cs.year() || mon != cs.month() || day != cs.day() ||
+ hour != cs.hour() || min != cs.minute() || sec != cs.second()) {
+ tc.normalized = true;
+ }
+ return tc;
+}
+
y_absl::Time FromTM(const struct tm& tm, y_absl::TimeZone tz) {
- civil_year_t tm_year = tm.tm_year;
- // Avoids years that are too extreme for CivilSecond to normalize.
- if (tm_year > 300000000000ll) return InfiniteFuture();
- if (tm_year < -300000000000ll) return InfinitePast();
- int tm_mon = tm.tm_mon;
- if (tm_mon == std::numeric_limits<int>::max()) {
- tm_mon -= 12;
- tm_year += 1;
- }
- const auto ti = tz.At(CivilSecond(tm_year + 1900, tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec));
- return tm.tm_isdst == 0 ? ti.post : ti.pre;
-}
-
+ civil_year_t tm_year = tm.tm_year;
+ // Avoids years that are too extreme for CivilSecond to normalize.
+ if (tm_year > 300000000000ll) return InfiniteFuture();
+ if (tm_year < -300000000000ll) return InfinitePast();
+ int tm_mon = tm.tm_mon;
+ if (tm_mon == std::numeric_limits<int>::max()) {
+ tm_mon -= 12;
+ tm_year += 1;
+ }
+ const auto ti = tz.At(CivilSecond(tm_year + 1900, tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec));
+ return tm.tm_isdst == 0 ? ti.post : ti.pre;
+}
+
struct tm ToTM(y_absl::Time t, y_absl::TimeZone tz) {
- struct tm tm = {};
-
- const auto ci = tz.At(t);
- const auto& cs = ci.cs;
- tm.tm_sec = cs.second();
- tm.tm_min = cs.minute();
- tm.tm_hour = cs.hour();
- tm.tm_mday = cs.day();
- tm.tm_mon = cs.month() - 1;
-
- // Saturates tm.tm_year in cases of over/underflow, accounting for the fact
- // that tm.tm_year is years since 1900.
- if (cs.year() < std::numeric_limits<int>::min() + 1900) {
- tm.tm_year = std::numeric_limits<int>::min();
- } else if (cs.year() > std::numeric_limits<int>::max()) {
- tm.tm_year = std::numeric_limits<int>::max() - 1900;
- } else {
- tm.tm_year = static_cast<int>(cs.year() - 1900);
- }
-
- switch (GetWeekday(cs)) {
- case Weekday::sunday:
- tm.tm_wday = 0;
- break;
- case Weekday::monday:
- tm.tm_wday = 1;
- break;
- case Weekday::tuesday:
- tm.tm_wday = 2;
- break;
- case Weekday::wednesday:
- tm.tm_wday = 3;
- break;
- case Weekday::thursday:
- tm.tm_wday = 4;
- break;
- case Weekday::friday:
- tm.tm_wday = 5;
- break;
- case Weekday::saturday:
- tm.tm_wday = 6;
- break;
- }
- tm.tm_yday = GetYearDay(cs) - 1;
- tm.tm_isdst = ci.is_dst ? 1 : 0;
-
- return tm;
-}
-
+ struct tm tm = {};
+
+ const auto ci = tz.At(t);
+ const auto& cs = ci.cs;
+ tm.tm_sec = cs.second();
+ tm.tm_min = cs.minute();
+ tm.tm_hour = cs.hour();
+ tm.tm_mday = cs.day();
+ tm.tm_mon = cs.month() - 1;
+
+ // Saturates tm.tm_year in cases of over/underflow, accounting for the fact
+ // that tm.tm_year is years since 1900.
+ if (cs.year() < std::numeric_limits<int>::min() + 1900) {
+ tm.tm_year = std::numeric_limits<int>::min();
+ } else if (cs.year() > std::numeric_limits<int>::max()) {
+ tm.tm_year = std::numeric_limits<int>::max() - 1900;
+ } else {
+ tm.tm_year = static_cast<int>(cs.year() - 1900);
+ }
+
+ switch (GetWeekday(cs)) {
+ case Weekday::sunday:
+ tm.tm_wday = 0;
+ break;
+ case Weekday::monday:
+ tm.tm_wday = 1;
+ break;
+ case Weekday::tuesday:
+ tm.tm_wday = 2;
+ break;
+ case Weekday::wednesday:
+ tm.tm_wday = 3;
+ break;
+ case Weekday::thursday:
+ tm.tm_wday = 4;
+ break;
+ case Weekday::friday:
+ tm.tm_wday = 5;
+ break;
+ case Weekday::saturday:
+ tm.tm_wday = 6;
+ break;
+ }
+ tm.tm_yday = GetYearDay(cs) - 1;
+ tm.tm_isdst = ci.is_dst ? 1 : 0;
+
+ return tm;
+}
+
ABSL_NAMESPACE_END
} // namespace y_absl
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h
index 70980887b1..16150ad3b6 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h
@@ -1,199 +1,199 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: time.h
-// -----------------------------------------------------------------------------
-//
-// This header file defines abstractions for computing with absolute points
-// in time, durations of time, and formatting and parsing time within a given
-// time zone. The following abstractions are defined:
-//
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: time.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines abstractions for computing with absolute points
+// in time, durations of time, and formatting and parsing time within a given
+// time zone. The following abstractions are defined:
+//
// * `y_absl::Time` defines an absolute, specific instance in time
// * `y_absl::Duration` defines a signed, fixed-length span of time
// * `y_absl::TimeZone` defines geopolitical time zone regions (as collected
-// within the IANA Time Zone database (https://www.iana.org/time-zones)).
-//
-// Note: Absolute times are distinct from civil times, which refer to the
-// human-scale time commonly represented by `YYYY-MM-DD hh:mm:ss`. The mapping
-// between absolute and civil times can be specified by use of time zones
+// within the IANA Time Zone database (https://www.iana.org/time-zones)).
+//
+// Note: Absolute times are distinct from civil times, which refer to the
+// human-scale time commonly represented by `YYYY-MM-DD hh:mm:ss`. The mapping
+// between absolute and civil times can be specified by use of time zones
// (`y_absl::TimeZone` within this API). That is:
-//
-// Civil Time = F(Absolute Time, Time Zone)
-// Absolute Time = G(Civil Time, Time Zone)
-//
-// See civil_time.h for abstractions related to constructing and manipulating
-// civil time.
-//
-// Example:
-//
+//
+// Civil Time = F(Absolute Time, Time Zone)
+// Absolute Time = G(Civil Time, Time Zone)
+//
+// See civil_time.h for abstractions related to constructing and manipulating
+// civil time.
+//
+// Example:
+//
// y_absl::TimeZone nyc;
-// // LoadTimeZone() may fail so it's always better to check for success.
+// // LoadTimeZone() may fail so it's always better to check for success.
// if (!y_absl::LoadTimeZone("America/New_York", &nyc)) {
-// // handle error case
-// }
-//
-// // My flight leaves NYC on Jan 2, 2017 at 03:04:05
+// // handle error case
+// }
+//
+// // My flight leaves NYC on Jan 2, 2017 at 03:04:05
// y_absl::CivilSecond cs(2017, 1, 2, 3, 4, 5);
// y_absl::Time takeoff = y_absl::FromCivil(cs, nyc);
-//
+//
// y_absl::Duration flight_duration = y_absl::Hours(21) + y_absl::Minutes(35);
// y_absl::Time landing = takeoff + flight_duration;
-//
+//
// y_absl::TimeZone syd;
// if (!y_absl::LoadTimeZone("Australia/Sydney", &syd)) {
-// // handle error case
-// }
+// // handle error case
+// }
// TString s = y_absl::FormatTime(
-// "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S",
-// landing, syd);
-
-#ifndef ABSL_TIME_TIME_H_
-#define ABSL_TIME_TIME_H_
-
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#else
-// We don't include `winsock2.h` because it drags in `windows.h` and friends,
-// and they define conflicting macros like OPAQUE, ERROR, and more. This has the
-// potential to break Abseil users.
-//
-// Instead we only forward declare `timeval` and require Windows users include
-// `winsock2.h` themselves. This is both inconsistent and troublesome, but so is
-// including 'windows.h' so we are picking the lesser of two evils here.
-struct timeval;
-#endif
-#include <chrono> // NOLINT(build/c++11)
-#include <cmath>
-#include <cstdint>
-#include <ctime>
-#include <ostream>
+// "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S",
+// landing, syd);
+
+#ifndef ABSL_TIME_TIME_H_
+#define ABSL_TIME_TIME_H_
+
+#if !defined(_MSC_VER)
+#include <sys/time.h>
+#else
+// We don't include `winsock2.h` because it drags in `windows.h` and friends,
+// and they define conflicting macros like OPAQUE, ERROR, and more. This has the
+// potential to break Abseil users.
+//
+// Instead we only forward declare `timeval` and require Windows users include
+// `winsock2.h` themselves. This is both inconsistent and troublesome, but so is
+// including 'windows.h' so we are picking the lesser of two evils here.
+struct timeval;
+#endif
+#include <chrono> // NOLINT(build/c++11)
+#include <cmath>
+#include <cstdint>
+#include <ctime>
+#include <ostream>
#include <util/generic/string.h>
-#include <type_traits>
-#include <utility>
-
+#include <type_traits>
+#include <utility>
+
#include "y_absl/base/macros.h"
#include "y_absl/strings/string_view.h"
#include "y_absl/time/civil_time.h"
#include "y_absl/time/internal/cctz/include/cctz/time_zone.h"
-
+
namespace y_absl {
ABSL_NAMESPACE_BEGIN
-
-class Duration; // Defined below
-class Time; // Defined below
-class TimeZone; // Defined below
-
-namespace time_internal {
-int64_t IDivDuration(bool satq, Duration num, Duration den, Duration* rem);
-constexpr Time FromUnixDuration(Duration d);
-constexpr Duration ToUnixDuration(Time t);
-constexpr int64_t GetRepHi(Duration d);
-constexpr uint32_t GetRepLo(Duration d);
-constexpr Duration MakeDuration(int64_t hi, uint32_t lo);
-constexpr Duration MakeDuration(int64_t hi, int64_t lo);
-inline Duration MakePosDoubleDuration(double n);
-constexpr int64_t kTicksPerNanosecond = 4;
-constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond;
-template <std::intmax_t N>
-constexpr Duration FromInt64(int64_t v, std::ratio<1, N>);
-constexpr Duration FromInt64(int64_t v, std::ratio<60>);
-constexpr Duration FromInt64(int64_t v, std::ratio<3600>);
-template <typename T>
-using EnableIfIntegral = typename std::enable_if<
- std::is_integral<T>::value || std::is_enum<T>::value, int>::type;
-template <typename T>
-using EnableIfFloat =
- typename std::enable_if<std::is_floating_point<T>::value, int>::type;
-} // namespace time_internal
-
-// Duration
-//
+
+class Duration; // Defined below
+class Time; // Defined below
+class TimeZone; // Defined below
+
+namespace time_internal {
+int64_t IDivDuration(bool satq, Duration num, Duration den, Duration* rem);
+constexpr Time FromUnixDuration(Duration d);
+constexpr Duration ToUnixDuration(Time t);
+constexpr int64_t GetRepHi(Duration d);
+constexpr uint32_t GetRepLo(Duration d);
+constexpr Duration MakeDuration(int64_t hi, uint32_t lo);
+constexpr Duration MakeDuration(int64_t hi, int64_t lo);
+inline Duration MakePosDoubleDuration(double n);
+constexpr int64_t kTicksPerNanosecond = 4;
+constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond;
+template <std::intmax_t N>
+constexpr Duration FromInt64(int64_t v, std::ratio<1, N>);
+constexpr Duration FromInt64(int64_t v, std::ratio<60>);
+constexpr Duration FromInt64(int64_t v, std::ratio<3600>);
+template <typename T>
+using EnableIfIntegral = typename std::enable_if<
+ std::is_integral<T>::value || std::is_enum<T>::value, int>::type;
+template <typename T>
+using EnableIfFloat =
+ typename std::enable_if<std::is_floating_point<T>::value, int>::type;
+} // namespace time_internal
+
+// Duration
+//
// The `y_absl::Duration` class represents a signed, fixed-length span of time.
-// A `Duration` is generated using a unit-specific factory function, or is
+// A `Duration` is generated using a unit-specific factory function, or is
// the result of subtracting one `y_absl::Time` from another. Durations behave
-// like unit-safe integers and they support all the natural integer-like
-// arithmetic operations. Arithmetic overflows and saturates at +/- infinity.
-// `Duration` should be passed by value rather than const reference.
-//
-// Factory functions `Nanoseconds()`, `Microseconds()`, `Milliseconds()`,
-// `Seconds()`, `Minutes()`, `Hours()` and `InfiniteDuration()` allow for
-// creation of constexpr `Duration` values
-//
-// Examples:
-//
+// like unit-safe integers and they support all the natural integer-like
+// arithmetic operations. Arithmetic overflows and saturates at +/- infinity.
+// `Duration` should be passed by value rather than const reference.
+//
+// Factory functions `Nanoseconds()`, `Microseconds()`, `Milliseconds()`,
+// `Seconds()`, `Minutes()`, `Hours()` and `InfiniteDuration()` allow for
+// creation of constexpr `Duration` values
+//
+// Examples:
+//
// constexpr y_absl::Duration ten_ns = y_absl::Nanoseconds(10);
// constexpr y_absl::Duration min = y_absl::Minutes(1);
// constexpr y_absl::Duration hour = y_absl::Hours(1);
// y_absl::Duration dur = 60 * min; // dur == hour
// y_absl::Duration half_sec = y_absl::Milliseconds(500);
// y_absl::Duration quarter_sec = 0.25 * y_absl::Seconds(1);
-//
-// `Duration` values can be easily converted to an integral number of units
-// using the division operator.
-//
-// Example:
-//
+//
+// `Duration` values can be easily converted to an integral number of units
+// using the division operator.
+//
+// Example:
+//
// constexpr y_absl::Duration dur = y_absl::Milliseconds(1500);
// int64_t ns = dur / y_absl::Nanoseconds(1); // ns == 1500000000
// int64_t ms = dur / y_absl::Milliseconds(1); // ms == 1500
// int64_t sec = dur / y_absl::Seconds(1); // sec == 1 (subseconds truncated)
// int64_t min = dur / y_absl::Minutes(1); // min == 0
-//
-// See the `IDivDuration()` and `FDivDuration()` functions below for details on
-// how to access the fractional parts of the quotient.
-//
-// Alternatively, conversions can be performed using helpers such as
-// `ToInt64Microseconds()` and `ToDoubleSeconds()`.
-class Duration {
- public:
- // Value semantics.
- constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration
-
- // Copyable.
-#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910
- // Explicitly defining the constexpr copy constructor avoids an MSVC bug.
- constexpr Duration(const Duration& d)
- : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {}
-#else
- constexpr Duration(const Duration& d) = default;
-#endif
- Duration& operator=(const Duration& d) = default;
-
- // Compound assignment operators.
- Duration& operator+=(Duration d);
- Duration& operator-=(Duration d);
- Duration& operator*=(int64_t r);
- Duration& operator*=(double r);
- Duration& operator/=(int64_t r);
- Duration& operator/=(double r);
- Duration& operator%=(Duration rhs);
-
- // Overloads that forward to either the int64_t or double overloads above.
- // Integer operands must be representable as int64_t.
+//
+// See the `IDivDuration()` and `FDivDuration()` functions below for details on
+// how to access the fractional parts of the quotient.
+//
+// Alternatively, conversions can be performed using helpers such as
+// `ToInt64Microseconds()` and `ToDoubleSeconds()`.
+class Duration {
+ public:
+ // Value semantics.
+ constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration
+
+ // Copyable.
+#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910
+ // Explicitly defining the constexpr copy constructor avoids an MSVC bug.
+ constexpr Duration(const Duration& d)
+ : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {}
+#else
+ constexpr Duration(const Duration& d) = default;
+#endif
+ Duration& operator=(const Duration& d) = default;
+
+ // Compound assignment operators.
+ Duration& operator+=(Duration d);
+ Duration& operator-=(Duration d);
+ Duration& operator*=(int64_t r);
+ Duration& operator*=(double r);
+ Duration& operator/=(int64_t r);
+ Duration& operator/=(double r);
+ Duration& operator%=(Duration rhs);
+
+ // Overloads that forward to either the int64_t or double overloads above.
+ // Integer operands must be representable as int64_t.
template <typename T, time_internal::EnableIfIntegral<T> = 0>
- Duration& operator*=(T r) {
- int64_t x = r;
- return *this *= x;
- }
+ Duration& operator*=(T r) {
+ int64_t x = r;
+ return *this *= x;
+ }
template <typename T, time_internal::EnableIfIntegral<T> = 0>
- Duration& operator/=(T r) {
- int64_t x = r;
- return *this /= x;
- }
-
+ Duration& operator/=(T r) {
+ int64_t x = r;
+ return *this /= x;
+ }
+
template <typename T, time_internal::EnableIfFloat<T> = 0>
Duration& operator*=(T r) {
double x = r;
@@ -206,201 +206,201 @@ class Duration {
return *this /= x;
}
- template <typename H>
- friend H AbslHashValue(H h, Duration d) {
- return H::combine(std::move(h), d.rep_hi_, d.rep_lo_);
- }
-
- private:
- friend constexpr int64_t time_internal::GetRepHi(Duration d);
- friend constexpr uint32_t time_internal::GetRepLo(Duration d);
- friend constexpr Duration time_internal::MakeDuration(int64_t hi,
- uint32_t lo);
- constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {}
- int64_t rep_hi_;
- uint32_t rep_lo_;
-};
-
-// Relational Operators
-constexpr bool operator<(Duration lhs, Duration rhs);
-constexpr bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; }
-constexpr bool operator>=(Duration lhs, Duration rhs) { return !(lhs < rhs); }
-constexpr bool operator<=(Duration lhs, Duration rhs) { return !(rhs < lhs); }
-constexpr bool operator==(Duration lhs, Duration rhs);
-constexpr bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); }
-
-// Additive Operators
-constexpr Duration operator-(Duration d);
-inline Duration operator+(Duration lhs, Duration rhs) { return lhs += rhs; }
-inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; }
-
-// Multiplicative Operators
-// Integer operands must be representable as int64_t.
-template <typename T>
-Duration operator*(Duration lhs, T rhs) {
- return lhs *= rhs;
-}
-template <typename T>
-Duration operator*(T lhs, Duration rhs) {
- return rhs *= lhs;
-}
-template <typename T>
-Duration operator/(Duration lhs, T rhs) {
- return lhs /= rhs;
-}
-inline int64_t operator/(Duration lhs, Duration rhs) {
- return time_internal::IDivDuration(true, lhs, rhs,
- &lhs); // trunc towards zero
-}
-inline Duration operator%(Duration lhs, Duration rhs) { return lhs %= rhs; }
-
-// IDivDuration()
-//
-// Divides a numerator `Duration` by a denominator `Duration`, returning the
-// quotient and remainder. The remainder always has the same sign as the
-// numerator. The returned quotient and remainder respect the identity:
-//
-// numerator = denominator * quotient + remainder
-//
-// Returned quotients are capped to the range of `int64_t`, with the difference
-// spilling into the remainder to uphold the above identity. This means that the
-// remainder returned could differ from the remainder returned by
-// `Duration::operator%` for huge quotients.
-//
-// See also the notes on `InfiniteDuration()` below regarding the behavior of
-// division involving zero and infinite durations.
-//
-// Example:
-//
+ template <typename H>
+ friend H AbslHashValue(H h, Duration d) {
+ return H::combine(std::move(h), d.rep_hi_, d.rep_lo_);
+ }
+
+ private:
+ friend constexpr int64_t time_internal::GetRepHi(Duration d);
+ friend constexpr uint32_t time_internal::GetRepLo(Duration d);
+ friend constexpr Duration time_internal::MakeDuration(int64_t hi,
+ uint32_t lo);
+ constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {}
+ int64_t rep_hi_;
+ uint32_t rep_lo_;
+};
+
+// Relational Operators
+constexpr bool operator<(Duration lhs, Duration rhs);
+constexpr bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; }
+constexpr bool operator>=(Duration lhs, Duration rhs) { return !(lhs < rhs); }
+constexpr bool operator<=(Duration lhs, Duration rhs) { return !(rhs < lhs); }
+constexpr bool operator==(Duration lhs, Duration rhs);
+constexpr bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); }
+
+// Additive Operators
+constexpr Duration operator-(Duration d);
+inline Duration operator+(Duration lhs, Duration rhs) { return lhs += rhs; }
+inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; }
+
+// Multiplicative Operators
+// Integer operands must be representable as int64_t.
+template <typename T>
+Duration operator*(Duration lhs, T rhs) {
+ return lhs *= rhs;
+}
+template <typename T>
+Duration operator*(T lhs, Duration rhs) {
+ return rhs *= lhs;
+}
+template <typename T>
+Duration operator/(Duration lhs, T rhs) {
+ return lhs /= rhs;
+}
+inline int64_t operator/(Duration lhs, Duration rhs) {
+ return time_internal::IDivDuration(true, lhs, rhs,
+ &lhs); // trunc towards zero
+}
+inline Duration operator%(Duration lhs, Duration rhs) { return lhs %= rhs; }
+
+// IDivDuration()
+//
+// Divides a numerator `Duration` by a denominator `Duration`, returning the
+// quotient and remainder. The remainder always has the same sign as the
+// numerator. The returned quotient and remainder respect the identity:
+//
+// numerator = denominator * quotient + remainder
+//
+// Returned quotients are capped to the range of `int64_t`, with the difference
+// spilling into the remainder to uphold the above identity. This means that the
+// remainder returned could differ from the remainder returned by
+// `Duration::operator%` for huge quotients.
+//
+// See also the notes on `InfiniteDuration()` below regarding the behavior of
+// division involving zero and infinite durations.
+//
+// Example:
+//
// constexpr y_absl::Duration a =
// y_absl::Seconds(std::numeric_limits<int64_t>::max()); // big
// constexpr y_absl::Duration b = y_absl::Nanoseconds(1); // small
-//
+//
// y_absl::Duration rem = a % b;
// // rem == y_absl::ZeroDuration()
-//
-// // Here, q would overflow int64_t, so rem accounts for the difference.
+//
+// // Here, q would overflow int64_t, so rem accounts for the difference.
// int64_t q = y_absl::IDivDuration(a, b, &rem);
-// // q == std::numeric_limits<int64_t>::max(), rem == a - b * q
-inline int64_t IDivDuration(Duration num, Duration den, Duration* rem) {
- return time_internal::IDivDuration(true, num, den,
- rem); // trunc towards zero
-}
-
-// FDivDuration()
-//
-// Divides a `Duration` numerator into a fractional number of units of a
-// `Duration` denominator.
-//
-// See also the notes on `InfiniteDuration()` below regarding the behavior of
-// division involving zero and infinite durations.
-//
-// Example:
-//
+// // q == std::numeric_limits<int64_t>::max(), rem == a - b * q
+inline int64_t IDivDuration(Duration num, Duration den, Duration* rem) {
+ return time_internal::IDivDuration(true, num, den,
+ rem); // trunc towards zero
+}
+
+// FDivDuration()
+//
+// Divides a `Duration` numerator into a fractional number of units of a
+// `Duration` denominator.
+//
+// See also the notes on `InfiniteDuration()` below regarding the behavior of
+// division involving zero and infinite durations.
+//
+// Example:
+//
// double d = y_absl::FDivDuration(y_absl::Milliseconds(1500), y_absl::Seconds(1));
-// // d == 1.5
-double FDivDuration(Duration num, Duration den);
-
-// ZeroDuration()
-//
-// Returns a zero-length duration. This function behaves just like the default
-// constructor, but the name helps make the semantics clear at call sites.
-constexpr Duration ZeroDuration() { return Duration(); }
-
-// AbsDuration()
-//
-// Returns the absolute value of a duration.
-inline Duration AbsDuration(Duration d) {
- return (d < ZeroDuration()) ? -d : d;
-}
-
-// Trunc()
-//
-// Truncates a duration (toward zero) to a multiple of a non-zero unit.
-//
-// Example:
-//
+// // d == 1.5
+double FDivDuration(Duration num, Duration den);
+
+// ZeroDuration()
+//
+// Returns a zero-length duration. This function behaves just like the default
+// constructor, but the name helps make the semantics clear at call sites.
+constexpr Duration ZeroDuration() { return Duration(); }
+
+// AbsDuration()
+//
+// Returns the absolute value of a duration.
+inline Duration AbsDuration(Duration d) {
+ return (d < ZeroDuration()) ? -d : d;
+}
+
+// Trunc()
+//
+// Truncates a duration (toward zero) to a multiple of a non-zero unit.
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Nanoseconds(123456789);
// y_absl::Duration a = y_absl::Trunc(d, y_absl::Microseconds(1)); // 123456us
-Duration Trunc(Duration d, Duration unit);
-
-// Floor()
-//
-// Floors a duration using the passed duration unit to its largest value not
-// greater than the duration.
-//
-// Example:
-//
+Duration Trunc(Duration d, Duration unit);
+
+// Floor()
+//
+// Floors a duration using the passed duration unit to its largest value not
+// greater than the duration.
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Nanoseconds(123456789);
// y_absl::Duration b = y_absl::Floor(d, y_absl::Microseconds(1)); // 123456us
-Duration Floor(Duration d, Duration unit);
-
-// Ceil()
-//
-// Returns the ceiling of a duration using the passed duration unit to its
-// smallest value not less than the duration.
-//
-// Example:
-//
+Duration Floor(Duration d, Duration unit);
+
+// Ceil()
+//
+// Returns the ceiling of a duration using the passed duration unit to its
+// smallest value not less than the duration.
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Nanoseconds(123456789);
// y_absl::Duration c = y_absl::Ceil(d, y_absl::Microseconds(1)); // 123457us
-Duration Ceil(Duration d, Duration unit);
-
-// InfiniteDuration()
-//
-// Returns an infinite `Duration`. To get a `Duration` representing negative
-// infinity, use `-InfiniteDuration()`.
-//
-// Duration arithmetic overflows to +/- infinity and saturates. In general,
-// arithmetic with `Duration` infinities is similar to IEEE 754 infinities
-// except where IEEE 754 NaN would be involved, in which case +/-
-// `InfiniteDuration()` is used in place of a "nan" Duration.
-//
-// Examples:
-//
+Duration Ceil(Duration d, Duration unit);
+
+// InfiniteDuration()
+//
+// Returns an infinite `Duration`. To get a `Duration` representing negative
+// infinity, use `-InfiniteDuration()`.
+//
+// Duration arithmetic overflows to +/- infinity and saturates. In general,
+// arithmetic with `Duration` infinities is similar to IEEE 754 infinities
+// except where IEEE 754 NaN would be involved, in which case +/-
+// `InfiniteDuration()` is used in place of a "nan" Duration.
+//
+// Examples:
+//
// constexpr y_absl::Duration inf = y_absl::InfiniteDuration();
// const y_absl::Duration d = ... any finite duration ...
-//
-// inf == inf + inf
-// inf == inf + d
-// inf == inf - inf
-// -inf == d - inf
-//
-// inf == d * 1e100
-// inf == inf / 2
-// 0 == d / inf
-// INT64_MAX == inf / d
-//
-// d < inf
-// -inf < d
-//
-// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate.
-// inf == d / 0
+//
+// inf == inf + inf
+// inf == inf + d
+// inf == inf - inf
+// -inf == d - inf
+//
+// inf == d * 1e100
+// inf == inf / 2
+// 0 == d / inf
+// INT64_MAX == inf / d
+//
+// d < inf
+// -inf < d
+//
+// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate.
+// inf == d / 0
// INT64_MAX == d / y_absl::ZeroDuration()
-//
-// The examples involving the `/` operator above also apply to `IDivDuration()`
-// and `FDivDuration()`.
-constexpr Duration InfiniteDuration();
-
-// Nanoseconds()
-// Microseconds()
-// Milliseconds()
-// Seconds()
-// Minutes()
-// Hours()
-//
-// Factory functions for constructing `Duration` values from an integral number
-// of the unit indicated by the factory function's name. The number must be
-// representable as int64_t.
-//
-// NOTE: no "Days()" factory function exists because "a day" is ambiguous.
-// Civil days are not always 24 hours long, and a 24-hour duration often does
-// not correspond with a civil day. If a 24-hour duration is needed, use
+//
+// The examples involving the `/` operator above also apply to `IDivDuration()`
+// and `FDivDuration()`.
+constexpr Duration InfiniteDuration();
+
+// Nanoseconds()
+// Microseconds()
+// Milliseconds()
+// Seconds()
+// Minutes()
+// Hours()
+//
+// Factory functions for constructing `Duration` values from an integral number
+// of the unit indicated by the factory function's name. The number must be
+// representable as int64_t.
+//
+// NOTE: no "Days()" factory function exists because "a day" is ambiguous.
+// Civil days are not always 24 hours long, and a 24-hour duration often does
+// not correspond with a civil day. If a 24-hour duration is needed, use
// `y_absl::Hours(24)`. If you actually want a civil day, use y_absl::CivilDay
-// from civil_time.h.
-//
-// Example:
-//
+// from civil_time.h.
+//
+// Example:
+//
// y_absl::Duration a = y_absl::Seconds(60);
// y_absl::Duration b = y_absl::Minutes(1); // b == a
template <typename T, time_internal::EnableIfIntegral<T> = 0>
@@ -427,65 +427,65 @@ template <typename T, time_internal::EnableIfIntegral<T> = 0>
constexpr Duration Hours(T n) {
return time_internal::FromInt64(n, std::ratio<3600>{});
}
-
-// Factory overloads for constructing `Duration` values from a floating-point
-// number of the unit indicated by the factory function's name. These functions
-// exist for convenience, but they are not as efficient as the integral
-// factories, which should be preferred.
-//
-// Example:
-//
+
+// Factory overloads for constructing `Duration` values from a floating-point
+// number of the unit indicated by the factory function's name. These functions
+// exist for convenience, but they are not as efficient as the integral
+// factories, which should be preferred.
+//
+// Example:
+//
// auto a = y_absl::Seconds(1.5); // OK
// auto b = y_absl::Milliseconds(1500); // BETTER
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Nanoseconds(T n) {
- return n * Nanoseconds(1);
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Microseconds(T n) {
- return n * Microseconds(1);
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Milliseconds(T n) {
- return n * Milliseconds(1);
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Seconds(T n) {
- if (n >= 0) { // Note: `NaN >= 0` is false.
- if (n >= static_cast<T>((std::numeric_limits<int64_t>::max)())) {
- return InfiniteDuration();
- }
- return time_internal::MakePosDoubleDuration(n);
- } else {
- if (std::isnan(n))
- return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration();
- if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration();
- return -time_internal::MakePosDoubleDuration(-n);
- }
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Minutes(T n) {
- return n * Minutes(1);
-}
-template <typename T, time_internal::EnableIfFloat<T> = 0>
-Duration Hours(T n) {
- return n * Hours(1);
-}
-
-// ToInt64Nanoseconds()
-// ToInt64Microseconds()
-// ToInt64Milliseconds()
-// ToInt64Seconds()
-// ToInt64Minutes()
-// ToInt64Hours()
-//
-// Helper functions that convert a Duration to an integral count of the
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Nanoseconds(T n) {
+ return n * Nanoseconds(1);
+}
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Microseconds(T n) {
+ return n * Microseconds(1);
+}
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Milliseconds(T n) {
+ return n * Milliseconds(1);
+}
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Seconds(T n) {
+ if (n >= 0) { // Note: `NaN >= 0` is false.
+ if (n >= static_cast<T>((std::numeric_limits<int64_t>::max)())) {
+ return InfiniteDuration();
+ }
+ return time_internal::MakePosDoubleDuration(n);
+ } else {
+ if (std::isnan(n))
+ return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration();
+ if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration();
+ return -time_internal::MakePosDoubleDuration(-n);
+ }
+}
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Minutes(T n) {
+ return n * Minutes(1);
+}
+template <typename T, time_internal::EnableIfFloat<T> = 0>
+Duration Hours(T n) {
+ return n * Hours(1);
+}
+
+// ToInt64Nanoseconds()
+// ToInt64Microseconds()
+// ToInt64Milliseconds()
+// ToInt64Seconds()
+// ToInt64Minutes()
+// ToInt64Hours()
+//
+// Helper functions that convert a Duration to an integral count of the
// indicated unit. These return the same results as the `IDivDuration()`
// function, though they usually do so more efficiently; see the
// documentation of `IDivDuration()` for details about overflow, etc.
-//
-// Example:
-//
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Milliseconds(1500);
// int64_t isec = y_absl::ToInt64Seconds(d); // isec == 1
ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Nanoseconds(Duration d);
@@ -494,20 +494,20 @@ ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Milliseconds(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Seconds(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Minutes(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Hours(Duration d);
-
-// ToDoubleNanoSeconds()
-// ToDoubleMicroseconds()
-// ToDoubleMilliseconds()
-// ToDoubleSeconds()
-// ToDoubleMinutes()
-// ToDoubleHours()
-//
-// Helper functions that convert a Duration to a floating point count of the
-// indicated unit. These functions are shorthand for the `FDivDuration()`
-// function above; see its documentation for details about overflow, etc.
-//
-// Example:
-//
+
+// ToDoubleNanoSeconds()
+// ToDoubleMicroseconds()
+// ToDoubleMilliseconds()
+// ToDoubleSeconds()
+// ToDoubleMinutes()
+// ToDoubleHours()
+//
+// Helper functions that convert a Duration to a floating point count of the
+// indicated unit. These functions are shorthand for the `FDivDuration()`
+// function above; see its documentation for details about overflow, etc.
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Milliseconds(1500);
// double dsec = y_absl::ToDoubleSeconds(d); // dsec == 1.5
ABSL_ATTRIBUTE_PURE_FUNCTION double ToDoubleNanoseconds(Duration d);
@@ -516,67 +516,67 @@ ABSL_ATTRIBUTE_PURE_FUNCTION double ToDoubleMilliseconds(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION double ToDoubleSeconds(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION double ToDoubleMinutes(Duration d);
ABSL_ATTRIBUTE_PURE_FUNCTION double ToDoubleHours(Duration d);
-
-// FromChrono()
-//
+
+// FromChrono()
+//
// Converts any of the pre-defined std::chrono durations to an y_absl::Duration.
-//
-// Example:
-//
-// std::chrono::milliseconds ms(123);
+//
+// Example:
+//
+// std::chrono::milliseconds ms(123);
// y_absl::Duration d = y_absl::FromChrono(ms);
-constexpr Duration FromChrono(const std::chrono::nanoseconds& d);
-constexpr Duration FromChrono(const std::chrono::microseconds& d);
-constexpr Duration FromChrono(const std::chrono::milliseconds& d);
-constexpr Duration FromChrono(const std::chrono::seconds& d);
-constexpr Duration FromChrono(const std::chrono::minutes& d);
-constexpr Duration FromChrono(const std::chrono::hours& d);
-
-// ToChronoNanoseconds()
-// ToChronoMicroseconds()
-// ToChronoMilliseconds()
-// ToChronoSeconds()
-// ToChronoMinutes()
-// ToChronoHours()
-//
+constexpr Duration FromChrono(const std::chrono::nanoseconds& d);
+constexpr Duration FromChrono(const std::chrono::microseconds& d);
+constexpr Duration FromChrono(const std::chrono::milliseconds& d);
+constexpr Duration FromChrono(const std::chrono::seconds& d);
+constexpr Duration FromChrono(const std::chrono::minutes& d);
+constexpr Duration FromChrono(const std::chrono::hours& d);
+
+// ToChronoNanoseconds()
+// ToChronoMicroseconds()
+// ToChronoMilliseconds()
+// ToChronoSeconds()
+// ToChronoMinutes()
+// ToChronoHours()
+//
// Converts an y_absl::Duration to any of the pre-defined std::chrono durations.
-// If overflow would occur, the returned value will saturate at the min/max
-// chrono duration value instead.
-//
-// Example:
-//
+// If overflow would occur, the returned value will saturate at the min/max
+// chrono duration value instead.
+//
+// Example:
+//
// y_absl::Duration d = y_absl::Microseconds(123);
// auto x = y_absl::ToChronoMicroseconds(d);
// auto y = y_absl::ToChronoNanoseconds(d); // x == y
// auto z = y_absl::ToChronoSeconds(y_absl::InfiniteDuration());
-// // z == std::chrono::seconds::max()
-std::chrono::nanoseconds ToChronoNanoseconds(Duration d);
-std::chrono::microseconds ToChronoMicroseconds(Duration d);
-std::chrono::milliseconds ToChronoMilliseconds(Duration d);
-std::chrono::seconds ToChronoSeconds(Duration d);
-std::chrono::minutes ToChronoMinutes(Duration d);
-std::chrono::hours ToChronoHours(Duration d);
-
-// FormatDuration()
-//
-// Returns a string representing the duration in the form "72h3m0.5s".
-// Returns "inf" or "-inf" for +/- `InfiniteDuration()`.
+// // z == std::chrono::seconds::max()
+std::chrono::nanoseconds ToChronoNanoseconds(Duration d);
+std::chrono::microseconds ToChronoMicroseconds(Duration d);
+std::chrono::milliseconds ToChronoMilliseconds(Duration d);
+std::chrono::seconds ToChronoSeconds(Duration d);
+std::chrono::minutes ToChronoMinutes(Duration d);
+std::chrono::hours ToChronoHours(Duration d);
+
+// FormatDuration()
+//
+// Returns a string representing the duration in the form "72h3m0.5s".
+// Returns "inf" or "-inf" for +/- `InfiniteDuration()`.
TString FormatDuration(Duration d);
-
-// Output stream operator.
-inline std::ostream& operator<<(std::ostream& os, Duration d) {
- return os << FormatDuration(d);
-}
-
-// ParseDuration()
-//
-// Parses a duration string consisting of a possibly signed sequence of
-// decimal numbers, each with an optional fractional part and a unit
-// suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h".
-// Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as
-// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
+
+// Output stream operator.
+inline std::ostream& operator<<(std::ostream& os, Duration d) {
+ return os << FormatDuration(d);
+}
+
+// ParseDuration()
+//
+// Parses a duration string consisting of a possibly signed sequence of
+// decimal numbers, each with an optional fractional part and a unit
+// suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h".
+// Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as
+// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
bool ParseDuration(y_absl::string_view dur_string, Duration* d);
-
+
// AbslParseFlag()
//
// Parses a command-line flag string representation `text` into a a Duration
@@ -591,280 +591,280 @@ bool AbslParseFlag(y_absl::string_view text, Duration* dst, TString* error);
// the format specified by `y_absl::ParseDuration()`.
TString AbslUnparseFlag(Duration d);
-ABSL_DEPRECATED("Use AbslParseFlag() instead.")
+ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const TString& text, Duration* dst, TString* error);
-ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
+ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
TString UnparseFlag(Duration d);
-
-// Time
-//
+
+// Time
+//
// An `y_absl::Time` represents a specific instant in time. Arithmetic operators
-// are provided for naturally expressing time calculations. Instances are
+// are provided for naturally expressing time calculations. Instances are
// created using `y_absl::Now()` and the `y_absl::From*()` factory functions that
-// accept the gamut of other time representations. Formatting and parsing
+// accept the gamut of other time representations. Formatting and parsing
// functions are provided for conversion to and from strings. `y_absl::Time`
-// should be passed by value rather than const reference.
-//
+// should be passed by value rather than const reference.
+//
// `y_absl::Time` assumes there are 60 seconds in a minute, which means the
-// underlying time scales must be "smeared" to eliminate leap seconds.
-// See https://developers.google.com/time/smear.
-//
+// underlying time scales must be "smeared" to eliminate leap seconds.
+// See https://developers.google.com/time/smear.
+//
// Even though `y_absl::Time` supports a wide range of timestamps, exercise
// caution when using values in the distant past. `y_absl::Time` uses the
-// Proleptic Gregorian calendar, which extends the Gregorian calendar backward
-// to dates before its introduction in 1582.
-// See https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
-// for more information. Use the ICU calendar classes to convert a date in
-// some other calendar (http://userguide.icu-project.org/datetime/calendar).
-//
-// Similarly, standardized time zones are a reasonably recent innovation, with
-// the Greenwich prime meridian being established in 1884. The TZ database
-// itself does not profess accurate offsets for timestamps prior to 1970. The
-// breakdown of future timestamps is subject to the whim of regional
-// governments.
-//
+// Proleptic Gregorian calendar, which extends the Gregorian calendar backward
+// to dates before its introduction in 1582.
+// See https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
+// for more information. Use the ICU calendar classes to convert a date in
+// some other calendar (http://userguide.icu-project.org/datetime/calendar).
+//
+// Similarly, standardized time zones are a reasonably recent innovation, with
+// the Greenwich prime meridian being established in 1884. The TZ database
+// itself does not profess accurate offsets for timestamps prior to 1970. The
+// breakdown of future timestamps is subject to the whim of regional
+// governments.
+//
// The `y_absl::Time` class represents an instant in time as a count of clock
-// ticks of some granularity (resolution) from some starting point (epoch).
-//
+// ticks of some granularity (resolution) from some starting point (epoch).
+//
// `y_absl::Time` uses a resolution that is high enough to avoid loss in
-// precision, and a range that is wide enough to avoid overflow, when
-// converting between tick counts in most Google time scales (i.e., resolution
-// of at least one nanosecond, and range +/-100 billion years). Conversions
-// between the time scales are performed by truncating (towards negative
-// infinity) to the nearest representable point.
-//
-// Examples:
-//
+// precision, and a range that is wide enough to avoid overflow, when
+// converting between tick counts in most Google time scales (i.e., resolution
+// of at least one nanosecond, and range +/-100 billion years). Conversions
+// between the time scales are performed by truncating (towards negative
+// infinity) to the nearest representable point.
+//
+// Examples:
+//
// y_absl::Time t1 = ...;
// y_absl::Time t2 = t1 + y_absl::Minutes(2);
// y_absl::Duration d = t2 - t1; // == y_absl::Minutes(2)
-//
-class Time {
- public:
- // Value semantics.
-
- // Returns the Unix epoch. However, those reading your code may not know
- // or expect the Unix epoch as the default value, so make your code more
- // readable by explicitly initializing all instances before use.
- //
- // Example:
+//
+class Time {
+ public:
+ // Value semantics.
+
+ // Returns the Unix epoch. However, those reading your code may not know
+ // or expect the Unix epoch as the default value, so make your code more
+ // readable by explicitly initializing all instances before use.
+ //
+ // Example:
// y_absl::Time t = y_absl::UnixEpoch();
// y_absl::Time t = y_absl::Now();
// y_absl::Time t = y_absl::TimeFromTimeval(tv);
// y_absl::Time t = y_absl::InfinitePast();
- constexpr Time() = default;
-
- // Copyable.
- constexpr Time(const Time& t) = default;
- Time& operator=(const Time& t) = default;
-
- // Assignment operators.
- Time& operator+=(Duration d) {
- rep_ += d;
- return *this;
- }
- Time& operator-=(Duration d) {
- rep_ -= d;
- return *this;
- }
-
- // Time::Breakdown
- //
- // The calendar and wall-clock (aka "civil time") components of an
+ constexpr Time() = default;
+
+ // Copyable.
+ constexpr Time(const Time& t) = default;
+ Time& operator=(const Time& t) = default;
+
+ // Assignment operators.
+ Time& operator+=(Duration d) {
+ rep_ += d;
+ return *this;
+ }
+ Time& operator-=(Duration d) {
+ rep_ -= d;
+ return *this;
+ }
+
+ // Time::Breakdown
+ //
+ // The calendar and wall-clock (aka "civil time") components of an
// `y_absl::Time` in a certain `y_absl::TimeZone`. This struct is not
- // intended to represent an instant in time. So, rather than passing
+ // intended to represent an instant in time. So, rather than passing
// a `Time::Breakdown` to a function, pass an `y_absl::Time` and an
// `y_absl::TimeZone`.
- //
+ //
// Deprecated. Use `y_absl::TimeZone::CivilInfo`.
- struct
- Breakdown {
+ struct
+ Breakdown {
int64_t year; // year (e.g., 2013)
- int month; // month of year [1:12]
- int day; // day of month [1:31]
- int hour; // hour of day [0:23]
- int minute; // minute of hour [0:59]
- int second; // second of minute [0:59]
- Duration subsecond; // [Seconds(0):Seconds(1)) if finite
- int weekday; // 1==Mon, ..., 7=Sun
- int yearday; // day of year [1:366]
-
- // Note: The following fields exist for backward compatibility
- // with older APIs. Accessing these fields directly is a sign of
- // imprudent logic in the calling code. Modern time-related code
- // should only access this data indirectly by way of FormatTime().
- // These fields are undefined for InfiniteFuture() and InfinitePast().
- int offset; // seconds east of UTC
- bool is_dst; // is offset non-standard?
- const char* zone_abbr; // time-zone abbreviation (e.g., "PST")
- };
-
- // Time::In()
- //
- // Returns the breakdown of this instant in the given TimeZone.
- //
+ int month; // month of year [1:12]
+ int day; // day of month [1:31]
+ int hour; // hour of day [0:23]
+ int minute; // minute of hour [0:59]
+ int second; // second of minute [0:59]
+ Duration subsecond; // [Seconds(0):Seconds(1)) if finite
+ int weekday; // 1==Mon, ..., 7=Sun
+ int yearday; // day of year [1:366]
+
+ // Note: The following fields exist for backward compatibility
+ // with older APIs. Accessing these fields directly is a sign of
+ // imprudent logic in the calling code. Modern time-related code
+ // should only access this data indirectly by way of FormatTime().
+ // These fields are undefined for InfiniteFuture() and InfinitePast().
+ int offset; // seconds east of UTC
+ bool is_dst; // is offset non-standard?
+ const char* zone_abbr; // time-zone abbreviation (e.g., "PST")
+ };
+
+ // Time::In()
+ //
+ // Returns the breakdown of this instant in the given TimeZone.
+ //
// Deprecated. Use `y_absl::TimeZone::At(Time)`.
- Breakdown In(TimeZone tz) const;
-
- template <typename H>
- friend H AbslHashValue(H h, Time t) {
- return H::combine(std::move(h), t.rep_);
- }
-
- private:
- friend constexpr Time time_internal::FromUnixDuration(Duration d);
- friend constexpr Duration time_internal::ToUnixDuration(Time t);
- friend constexpr bool operator<(Time lhs, Time rhs);
- friend constexpr bool operator==(Time lhs, Time rhs);
- friend Duration operator-(Time lhs, Time rhs);
- friend constexpr Time UniversalEpoch();
- friend constexpr Time InfiniteFuture();
- friend constexpr Time InfinitePast();
- constexpr explicit Time(Duration rep) : rep_(rep) {}
- Duration rep_;
-};
-
-// Relational Operators
-constexpr bool operator<(Time lhs, Time rhs) { return lhs.rep_ < rhs.rep_; }
-constexpr bool operator>(Time lhs, Time rhs) { return rhs < lhs; }
-constexpr bool operator>=(Time lhs, Time rhs) { return !(lhs < rhs); }
-constexpr bool operator<=(Time lhs, Time rhs) { return !(rhs < lhs); }
-constexpr bool operator==(Time lhs, Time rhs) { return lhs.rep_ == rhs.rep_; }
-constexpr bool operator!=(Time lhs, Time rhs) { return !(lhs == rhs); }
-
-// Additive Operators
-inline Time operator+(Time lhs, Duration rhs) { return lhs += rhs; }
-inline Time operator+(Duration lhs, Time rhs) { return rhs += lhs; }
-inline Time operator-(Time lhs, Duration rhs) { return lhs -= rhs; }
-inline Duration operator-(Time lhs, Time rhs) { return lhs.rep_ - rhs.rep_; }
-
-// UnixEpoch()
-//
+ Breakdown In(TimeZone tz) const;
+
+ template <typename H>
+ friend H AbslHashValue(H h, Time t) {
+ return H::combine(std::move(h), t.rep_);
+ }
+
+ private:
+ friend constexpr Time time_internal::FromUnixDuration(Duration d);
+ friend constexpr Duration time_internal::ToUnixDuration(Time t);
+ friend constexpr bool operator<(Time lhs, Time rhs);
+ friend constexpr bool operator==(Time lhs, Time rhs);
+ friend Duration operator-(Time lhs, Time rhs);
+ friend constexpr Time UniversalEpoch();
+ friend constexpr Time InfiniteFuture();
+ friend constexpr Time InfinitePast();
+ constexpr explicit Time(Duration rep) : rep_(rep) {}
+ Duration rep_;
+};
+
+// Relational Operators
+constexpr bool operator<(Time lhs, Time rhs) { return lhs.rep_ < rhs.rep_; }
+constexpr bool operator>(Time lhs, Time rhs) { return rhs < lhs; }
+constexpr bool operator>=(Time lhs, Time rhs) { return !(lhs < rhs); }
+constexpr bool operator<=(Time lhs, Time rhs) { return !(rhs < lhs); }
+constexpr bool operator==(Time lhs, Time rhs) { return lhs.rep_ == rhs.rep_; }
+constexpr bool operator!=(Time lhs, Time rhs) { return !(lhs == rhs); }
+
+// Additive Operators
+inline Time operator+(Time lhs, Duration rhs) { return lhs += rhs; }
+inline Time operator+(Duration lhs, Time rhs) { return rhs += lhs; }
+inline Time operator-(Time lhs, Duration rhs) { return lhs -= rhs; }
+inline Duration operator-(Time lhs, Time rhs) { return lhs.rep_ - rhs.rep_; }
+
+// UnixEpoch()
+//
// Returns the `y_absl::Time` representing "1970-01-01 00:00:00.0 +0000".
-constexpr Time UnixEpoch() { return Time(); }
-
-// UniversalEpoch()
-//
+constexpr Time UnixEpoch() { return Time(); }
+
+// UniversalEpoch()
+//
// Returns the `y_absl::Time` representing "0001-01-01 00:00:00.0 +0000", the
-// epoch of the ICU Universal Time Scale.
-constexpr Time UniversalEpoch() {
- // 719162 is the number of days from 0001-01-01 to 1970-01-01,
- // assuming the Gregorian calendar.
- return Time(time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, 0U));
-}
-
-// InfiniteFuture()
-//
+// epoch of the ICU Universal Time Scale.
+constexpr Time UniversalEpoch() {
+ // 719162 is the number of days from 0001-01-01 to 1970-01-01,
+ // assuming the Gregorian calendar.
+ return Time(time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, 0U));
+}
+
+// InfiniteFuture()
+//
// Returns an `y_absl::Time` that is infinitely far in the future.
-constexpr Time InfiniteFuture() {
- return Time(
- time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U));
-}
-
-// InfinitePast()
-//
+constexpr Time InfiniteFuture() {
+ return Time(
+ time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U));
+}
+
+// InfinitePast()
+//
// Returns an `y_absl::Time` that is infinitely far in the past.
-constexpr Time InfinitePast() {
- return Time(
- time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U));
-}
-
-// FromUnixNanos()
-// FromUnixMicros()
-// FromUnixMillis()
-// FromUnixSeconds()
-// FromTimeT()
-// FromUDate()
-// FromUniversal()
-//
+constexpr Time InfinitePast() {
+ return Time(
+ time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U));
+}
+
+// FromUnixNanos()
+// FromUnixMicros()
+// FromUnixMillis()
+// FromUnixSeconds()
+// FromTimeT()
+// FromUDate()
+// FromUniversal()
+//
// Creates an `y_absl::Time` from a variety of other representations.
-constexpr Time FromUnixNanos(int64_t ns);
-constexpr Time FromUnixMicros(int64_t us);
-constexpr Time FromUnixMillis(int64_t ms);
-constexpr Time FromUnixSeconds(int64_t s);
-constexpr Time FromTimeT(time_t t);
-Time FromUDate(double udate);
-Time FromUniversal(int64_t universal);
-
-// ToUnixNanos()
-// ToUnixMicros()
-// ToUnixMillis()
-// ToUnixSeconds()
-// ToTimeT()
-// ToUDate()
-// ToUniversal()
-//
+constexpr Time FromUnixNanos(int64_t ns);
+constexpr Time FromUnixMicros(int64_t us);
+constexpr Time FromUnixMillis(int64_t ms);
+constexpr Time FromUnixSeconds(int64_t s);
+constexpr Time FromTimeT(time_t t);
+Time FromUDate(double udate);
+Time FromUniversal(int64_t universal);
+
+// ToUnixNanos()
+// ToUnixMicros()
+// ToUnixMillis()
+// ToUnixSeconds()
+// ToTimeT()
+// ToUDate()
+// ToUniversal()
+//
// Converts an `y_absl::Time` to a variety of other representations. Note that
-// these operations round down toward negative infinity where necessary to
-// adjust to the resolution of the result type. Beware of possible time_t
-// over/underflow in ToTime{T,val,spec}() on 32-bit platforms.
-int64_t ToUnixNanos(Time t);
-int64_t ToUnixMicros(Time t);
-int64_t ToUnixMillis(Time t);
-int64_t ToUnixSeconds(Time t);
-time_t ToTimeT(Time t);
-double ToUDate(Time t);
-int64_t ToUniversal(Time t);
-
-// DurationFromTimespec()
-// DurationFromTimeval()
-// ToTimespec()
-// ToTimeval()
-// TimeFromTimespec()
-// TimeFromTimeval()
-// ToTimespec()
-// ToTimeval()
-//
-// Some APIs use a timespec or a timeval as a Duration (e.g., nanosleep(2)
-// and select(2)), while others use them as a Time (e.g. clock_gettime(2)
-// and gettimeofday(2)), so conversion functions are provided for both cases.
-// The "to timespec/val" direction is easily handled via overloading, but
-// for "from timespec/val" the desired type is part of the function name.
-Duration DurationFromTimespec(timespec ts);
-Duration DurationFromTimeval(timeval tv);
-timespec ToTimespec(Duration d);
-timeval ToTimeval(Duration d);
-Time TimeFromTimespec(timespec ts);
-Time TimeFromTimeval(timeval tv);
-timespec ToTimespec(Time t);
-timeval ToTimeval(Time t);
-
-// FromChrono()
-//
+// these operations round down toward negative infinity where necessary to
+// adjust to the resolution of the result type. Beware of possible time_t
+// over/underflow in ToTime{T,val,spec}() on 32-bit platforms.
+int64_t ToUnixNanos(Time t);
+int64_t ToUnixMicros(Time t);
+int64_t ToUnixMillis(Time t);
+int64_t ToUnixSeconds(Time t);
+time_t ToTimeT(Time t);
+double ToUDate(Time t);
+int64_t ToUniversal(Time t);
+
+// DurationFromTimespec()
+// DurationFromTimeval()
+// ToTimespec()
+// ToTimeval()
+// TimeFromTimespec()
+// TimeFromTimeval()
+// ToTimespec()
+// ToTimeval()
+//
+// Some APIs use a timespec or a timeval as a Duration (e.g., nanosleep(2)
+// and select(2)), while others use them as a Time (e.g. clock_gettime(2)
+// and gettimeofday(2)), so conversion functions are provided for both cases.
+// The "to timespec/val" direction is easily handled via overloading, but
+// for "from timespec/val" the desired type is part of the function name.
+Duration DurationFromTimespec(timespec ts);
+Duration DurationFromTimeval(timeval tv);
+timespec ToTimespec(Duration d);
+timeval ToTimeval(Duration d);
+Time TimeFromTimespec(timespec ts);
+Time TimeFromTimeval(timeval tv);
+timespec ToTimespec(Time t);
+timeval ToTimeval(Time t);
+
+// FromChrono()
+//
// Converts a std::chrono::system_clock::time_point to an y_absl::Time.
-//
-// Example:
-//
-// auto tp = std::chrono::system_clock::from_time_t(123);
+//
+// Example:
+//
+// auto tp = std::chrono::system_clock::from_time_t(123);
// y_absl::Time t = y_absl::FromChrono(tp);
// // t == y_absl::FromTimeT(123)
-Time FromChrono(const std::chrono::system_clock::time_point& tp);
-
-// ToChronoTime()
-//
+Time FromChrono(const std::chrono::system_clock::time_point& tp);
+
+// ToChronoTime()
+//
// Converts an y_absl::Time to a std::chrono::system_clock::time_point. If
-// overflow would occur, the returned value will saturate at the min/max time
-// point value instead.
-//
-// Example:
-//
+// overflow would occur, the returned value will saturate at the min/max time
+// point value instead.
+//
+// Example:
+//
// y_absl::Time t = y_absl::FromTimeT(123);
// auto tp = y_absl::ToChronoTime(t);
-// // tp == std::chrono::system_clock::from_time_t(123);
-std::chrono::system_clock::time_point ToChronoTime(Time);
-
+// // tp == std::chrono::system_clock::from_time_t(123);
+std::chrono::system_clock::time_point ToChronoTime(Time);
+
// AbslParseFlag()
-//
+//
// Parses the command-line flag string representation `text` into a Time value.
// Time flags must be specified in a format that matches y_absl::RFC3339_full.
//
// For example:
//
-// --start_time=2016-01-02T03:04:05.678+08:00
-//
-// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required.
-//
-// Additionally, if you'd like to specify a time as a count of
+// --start_time=2016-01-02T03:04:05.678+08:00
+//
+// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required.
+//
+// Additionally, if you'd like to specify a time as a count of
// seconds/milliseconds/etc from the Unix epoch, use an y_absl::Duration flag
// and add that duration to y_absl::UnixEpoch() to get an y_absl::Time.
bool AbslParseFlag(y_absl::string_view text, Time* t, TString* error);
@@ -875,360 +875,360 @@ bool AbslParseFlag(y_absl::string_view text, Time* t, TString* error);
// the format specified by `y_absl::ParseTime()`.
TString AbslUnparseFlag(Time t);
-ABSL_DEPRECATED("Use AbslParseFlag() instead.")
+ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const TString& text, Time* t, TString* error);
-ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
+ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
TString UnparseFlag(Time t);
-
-// TimeZone
-//
+
+// TimeZone
+//
// The `y_absl::TimeZone` is an opaque, small, value-type class representing a
-// geo-political region within which particular rules are used for converting
+// geo-political region within which particular rules are used for converting
// between absolute and civil times (see https://git.io/v59Ly). `y_absl::TimeZone`
-// values are named using the TZ identifiers from the IANA Time Zone Database,
+// values are named using the TZ identifiers from the IANA Time Zone Database,
// such as "America/Los_Angeles" or "Australia/Sydney". `y_absl::TimeZone` values
// are created from factory functions such as `y_absl::LoadTimeZone()`. Note:
-// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by
-// value rather than const reference.
-//
-// For more on the fundamental concepts of time zones, absolute times, and civil
-// times, see https://github.com/google/cctz#fundamental-concepts
-//
-// Examples:
-//
+// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by
+// value rather than const reference.
+//
+// For more on the fundamental concepts of time zones, absolute times, and civil
+// times, see https://github.com/google/cctz#fundamental-concepts
+//
+// Examples:
+//
// y_absl::TimeZone utc = y_absl::UTCTimeZone();
// y_absl::TimeZone pst = y_absl::FixedTimeZone(-8 * 60 * 60);
// y_absl::TimeZone loc = y_absl::LocalTimeZone();
// y_absl::TimeZone lax;
// if (!y_absl::LoadTimeZone("America/Los_Angeles", &lax)) {
-// // handle error case
-// }
-//
-// See also:
-// - https://github.com/google/cctz
-// - https://www.iana.org/time-zones
-// - https://en.wikipedia.org/wiki/Zoneinfo
-class TimeZone {
- public:
- explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {}
- TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit.
-
- // Copyable.
- TimeZone(const TimeZone&) = default;
- TimeZone& operator=(const TimeZone&) = default;
-
- explicit operator time_internal::cctz::time_zone() const { return cz_; }
-
+// // handle error case
+// }
+//
+// See also:
+// - https://github.com/google/cctz
+// - https://www.iana.org/time-zones
+// - https://en.wikipedia.org/wiki/Zoneinfo
+class TimeZone {
+ public:
+ explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {}
+ TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit.
+
+ // Copyable.
+ TimeZone(const TimeZone&) = default;
+ TimeZone& operator=(const TimeZone&) = default;
+
+ explicit operator time_internal::cctz::time_zone() const { return cz_; }
+
TString name() const { return cz_.name(); }
-
- // TimeZone::CivilInfo
- //
- // Information about the civil time corresponding to an absolute time.
- // This struct is not intended to represent an instant in time. So, rather
+
+ // TimeZone::CivilInfo
+ //
+ // Information about the civil time corresponding to an absolute time.
+ // This struct is not intended to represent an instant in time. So, rather
// than passing a `TimeZone::CivilInfo` to a function, pass an `y_absl::Time`
// and an `y_absl::TimeZone`.
- struct CivilInfo {
- CivilSecond cs;
- Duration subsecond;
-
- // Note: The following fields exist for backward compatibility
- // with older APIs. Accessing these fields directly is a sign of
- // imprudent logic in the calling code. Modern time-related code
- // should only access this data indirectly by way of FormatTime().
- // These fields are undefined for InfiniteFuture() and InfinitePast().
- int offset; // seconds east of UTC
- bool is_dst; // is offset non-standard?
- const char* zone_abbr; // time-zone abbreviation (e.g., "PST")
- };
-
- // TimeZone::At(Time)
- //
+ struct CivilInfo {
+ CivilSecond cs;
+ Duration subsecond;
+
+ // Note: The following fields exist for backward compatibility
+ // with older APIs. Accessing these fields directly is a sign of
+ // imprudent logic in the calling code. Modern time-related code
+ // should only access this data indirectly by way of FormatTime().
+ // These fields are undefined for InfiniteFuture() and InfinitePast().
+ int offset; // seconds east of UTC
+ bool is_dst; // is offset non-standard?
+ const char* zone_abbr; // time-zone abbreviation (e.g., "PST")
+ };
+
+ // TimeZone::At(Time)
+ //
// Returns the civil time for this TimeZone at a certain `y_absl::Time`.
- // If the input time is infinite, the output civil second will be set to
- // CivilSecond::max() or min(), and the subsecond will be infinite.
- //
- // Example:
- //
+ // If the input time is infinite, the output civil second will be set to
+ // CivilSecond::max() or min(), and the subsecond will be infinite.
+ //
+ // Example:
+ //
// const auto epoch = lax.At(y_absl::UnixEpoch());
- // // epoch.cs == 1969-12-31 16:00:00
+ // // epoch.cs == 1969-12-31 16:00:00
// // epoch.subsecond == y_absl::ZeroDuration()
- // // epoch.offset == -28800
- // // epoch.is_dst == false
- // // epoch.abbr == "PST"
- CivilInfo At(Time t) const;
-
- // TimeZone::TimeInfo
- //
- // Information about the absolute times corresponding to a civil time.
- // (Subseconds must be handled separately.)
- //
- // It is possible for a caller to pass a civil-time value that does
- // not represent an actual or unique instant in time (due to a shift
- // in UTC offset in the TimeZone, which results in a discontinuity in
- // the civil-time components). For example, a daylight-saving-time
- // transition skips or repeats civil times---in the United States,
- // March 13, 2011 02:15 never occurred, while November 6, 2011 01:15
- // occurred twice---so requests for such times are not well-defined.
+ // // epoch.offset == -28800
+ // // epoch.is_dst == false
+ // // epoch.abbr == "PST"
+ CivilInfo At(Time t) const;
+
+ // TimeZone::TimeInfo
+ //
+ // Information about the absolute times corresponding to a civil time.
+ // (Subseconds must be handled separately.)
+ //
+ // It is possible for a caller to pass a civil-time value that does
+ // not represent an actual or unique instant in time (due to a shift
+ // in UTC offset in the TimeZone, which results in a discontinuity in
+ // the civil-time components). For example, a daylight-saving-time
+ // transition skips or repeats civil times---in the United States,
+ // March 13, 2011 02:15 never occurred, while November 6, 2011 01:15
+ // occurred twice---so requests for such times are not well-defined.
// To account for these possibilities, `y_absl::TimeZone::TimeInfo` is
// richer than just a single `y_absl::Time`.
- struct TimeInfo {
- enum CivilKind {
- UNIQUE, // the civil time was singular (pre == trans == post)
- SKIPPED, // the civil time did not exist (pre >= trans > post)
- REPEATED, // the civil time was ambiguous (pre < trans <= post)
- } kind;
- Time pre; // time calculated using the pre-transition offset
- Time trans; // when the civil-time discontinuity occurred
- Time post; // time calculated using the post-transition offset
- };
-
- // TimeZone::At(CivilSecond)
- //
+ struct TimeInfo {
+ enum CivilKind {
+ UNIQUE, // the civil time was singular (pre == trans == post)
+ SKIPPED, // the civil time did not exist (pre >= trans > post)
+ REPEATED, // the civil time was ambiguous (pre < trans <= post)
+ } kind;
+ Time pre; // time calculated using the pre-transition offset
+ Time trans; // when the civil-time discontinuity occurred
+ Time post; // time calculated using the post-transition offset
+ };
+
+ // TimeZone::At(CivilSecond)
+ //
// Returns an `y_absl::TimeInfo` containing the absolute time(s) for this
// TimeZone at an `y_absl::CivilSecond`. When the civil time is skipped or
- // repeated, returns times calculated using the pre-transition and post-
- // transition UTC offsets, plus the transition time itself.
- //
- // Examples:
- //
- // // A unique civil time
+ // repeated, returns times calculated using the pre-transition and post-
+ // transition UTC offsets, plus the transition time itself.
+ //
+ // Examples:
+ //
+ // // A unique civil time
// const auto jan01 = lax.At(y_absl::CivilSecond(2011, 1, 1, 0, 0, 0));
- // // jan01.kind == TimeZone::TimeInfo::UNIQUE
- // // jan01.pre is 2011-01-01 00:00:00 -0800
- // // jan01.trans is 2011-01-01 00:00:00 -0800
- // // jan01.post is 2011-01-01 00:00:00 -0800
- //
- // // A Spring DST transition, when there is a gap in civil time
+ // // jan01.kind == TimeZone::TimeInfo::UNIQUE
+ // // jan01.pre is 2011-01-01 00:00:00 -0800
+ // // jan01.trans is 2011-01-01 00:00:00 -0800
+ // // jan01.post is 2011-01-01 00:00:00 -0800
+ //
+ // // A Spring DST transition, when there is a gap in civil time
// const auto mar13 = lax.At(y_absl::CivilSecond(2011, 3, 13, 2, 15, 0));
- // // mar13.kind == TimeZone::TimeInfo::SKIPPED
- // // mar13.pre is 2011-03-13 03:15:00 -0700
- // // mar13.trans is 2011-03-13 03:00:00 -0700
- // // mar13.post is 2011-03-13 01:15:00 -0800
- //
- // // A Fall DST transition, when civil times are repeated
+ // // mar13.kind == TimeZone::TimeInfo::SKIPPED
+ // // mar13.pre is 2011-03-13 03:15:00 -0700
+ // // mar13.trans is 2011-03-13 03:00:00 -0700
+ // // mar13.post is 2011-03-13 01:15:00 -0800
+ //
+ // // A Fall DST transition, when civil times are repeated
// const auto nov06 = lax.At(y_absl::CivilSecond(2011, 11, 6, 1, 15, 0));
- // // nov06.kind == TimeZone::TimeInfo::REPEATED
- // // nov06.pre is 2011-11-06 01:15:00 -0700
- // // nov06.trans is 2011-11-06 01:00:00 -0800
- // // nov06.post is 2011-11-06 01:15:00 -0800
- TimeInfo At(CivilSecond ct) const;
-
- // TimeZone::NextTransition()
- // TimeZone::PrevTransition()
- //
- // Finds the time of the next/previous offset change in this time zone.
- //
- // By definition, `NextTransition(t, &trans)` returns false when `t` is
- // `InfiniteFuture()`, and `PrevTransition(t, &trans)` returns false
- // when `t` is `InfinitePast()`. If the zone has no transitions, the
- // result will also be false no matter what the argument.
- //
- // Otherwise, when `t` is `InfinitePast()`, `NextTransition(t, &trans)`
- // returns true and sets `trans` to the first recorded transition. Chains
- // of calls to `NextTransition()/PrevTransition()` will eventually return
- // false, but it is unspecified exactly when `NextTransition(t, &trans)`
- // jumps to false, or what time is set by `PrevTransition(t, &trans)` for
- // a very distant `t`.
- //
- // Note: Enumeration of time-zone transitions is for informational purposes
- // only. Modern time-related code should not care about when offset changes
- // occur.
- //
- // Example:
+ // // nov06.kind == TimeZone::TimeInfo::REPEATED
+ // // nov06.pre is 2011-11-06 01:15:00 -0700
+ // // nov06.trans is 2011-11-06 01:00:00 -0800
+ // // nov06.post is 2011-11-06 01:15:00 -0800
+ TimeInfo At(CivilSecond ct) const;
+
+ // TimeZone::NextTransition()
+ // TimeZone::PrevTransition()
+ //
+ // Finds the time of the next/previous offset change in this time zone.
+ //
+ // By definition, `NextTransition(t, &trans)` returns false when `t` is
+ // `InfiniteFuture()`, and `PrevTransition(t, &trans)` returns false
+ // when `t` is `InfinitePast()`. If the zone has no transitions, the
+ // result will also be false no matter what the argument.
+ //
+ // Otherwise, when `t` is `InfinitePast()`, `NextTransition(t, &trans)`
+ // returns true and sets `trans` to the first recorded transition. Chains
+ // of calls to `NextTransition()/PrevTransition()` will eventually return
+ // false, but it is unspecified exactly when `NextTransition(t, &trans)`
+ // jumps to false, or what time is set by `PrevTransition(t, &trans)` for
+ // a very distant `t`.
+ //
+ // Note: Enumeration of time-zone transitions is for informational purposes
+ // only. Modern time-related code should not care about when offset changes
+ // occur.
+ //
+ // Example:
// y_absl::TimeZone nyc;
// if (!y_absl::LoadTimeZone("America/New_York", &nyc)) { ... }
// const auto now = y_absl::Now();
// auto t = y_absl::InfinitePast();
// y_absl::TimeZone::CivilTransition trans;
- // while (t <= now && nyc.NextTransition(t, &trans)) {
- // // transition: trans.from -> trans.to
- // t = nyc.At(trans.to).trans;
- // }
- struct CivilTransition {
- CivilSecond from; // the civil time we jump from
- CivilSecond to; // the civil time we jump to
- };
- bool NextTransition(Time t, CivilTransition* trans) const;
- bool PrevTransition(Time t, CivilTransition* trans) const;
-
- template <typename H>
- friend H AbslHashValue(H h, TimeZone tz) {
- return H::combine(std::move(h), tz.cz_);
- }
-
- private:
- friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; }
- friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; }
- friend std::ostream& operator<<(std::ostream& os, TimeZone tz) {
- return os << tz.name();
- }
-
- time_internal::cctz::time_zone cz_;
-};
-
-// LoadTimeZone()
-//
-// Loads the named zone. May perform I/O on the initial load of the named
-// zone. If the name is invalid, or some other kind of error occurs, returns
-// `false` and `*tz` is set to the UTC time zone.
+ // while (t <= now && nyc.NextTransition(t, &trans)) {
+ // // transition: trans.from -> trans.to
+ // t = nyc.At(trans.to).trans;
+ // }
+ struct CivilTransition {
+ CivilSecond from; // the civil time we jump from
+ CivilSecond to; // the civil time we jump to
+ };
+ bool NextTransition(Time t, CivilTransition* trans) const;
+ bool PrevTransition(Time t, CivilTransition* trans) const;
+
+ template <typename H>
+ friend H AbslHashValue(H h, TimeZone tz) {
+ return H::combine(std::move(h), tz.cz_);
+ }
+
+ private:
+ friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; }
+ friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; }
+ friend std::ostream& operator<<(std::ostream& os, TimeZone tz) {
+ return os << tz.name();
+ }
+
+ time_internal::cctz::time_zone cz_;
+};
+
+// LoadTimeZone()
+//
+// Loads the named zone. May perform I/O on the initial load of the named
+// zone. If the name is invalid, or some other kind of error occurs, returns
+// `false` and `*tz` is set to the UTC time zone.
inline bool LoadTimeZone(y_absl::string_view name, TimeZone* tz) {
- if (name == "localtime") {
- *tz = TimeZone(time_internal::cctz::local_time_zone());
- return true;
- }
- time_internal::cctz::time_zone cz;
+ if (name == "localtime") {
+ *tz = TimeZone(time_internal::cctz::local_time_zone());
+ return true;
+ }
+ time_internal::cctz::time_zone cz;
const bool b = time_internal::cctz::load_time_zone(TString(name), &cz);
- *tz = TimeZone(cz);
- return b;
-}
-
-// FixedTimeZone()
-//
-// Returns a TimeZone that is a fixed offset (seconds east) from UTC.
-// Note: If the absolute value of the offset is greater than 24 hours
-// you'll get UTC (i.e., no offset) instead.
-inline TimeZone FixedTimeZone(int seconds) {
- return TimeZone(
- time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds)));
-}
-
-// UTCTimeZone()
-//
-// Convenience method returning the UTC time zone.
-inline TimeZone UTCTimeZone() {
- return TimeZone(time_internal::cctz::utc_time_zone());
-}
-
-// LocalTimeZone()
-//
-// Convenience method returning the local time zone, or UTC if there is
-// no configured local zone. Warning: Be wary of using LocalTimeZone(),
-// and particularly so in a server process, as the zone configured for the
-// local machine should be irrelevant. Prefer an explicit zone name.
-inline TimeZone LocalTimeZone() {
- return TimeZone(time_internal::cctz::local_time_zone());
-}
-
-// ToCivilSecond()
-// ToCivilMinute()
-// ToCivilHour()
-// ToCivilDay()
-// ToCivilMonth()
-// ToCivilYear()
-//
-// Helpers for TimeZone::At(Time) to return particularly aligned civil times.
-//
-// Example:
-//
+ *tz = TimeZone(cz);
+ return b;
+}
+
+// FixedTimeZone()
+//
+// Returns a TimeZone that is a fixed offset (seconds east) from UTC.
+// Note: If the absolute value of the offset is greater than 24 hours
+// you'll get UTC (i.e., no offset) instead.
+inline TimeZone FixedTimeZone(int seconds) {
+ return TimeZone(
+ time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds)));
+}
+
+// UTCTimeZone()
+//
+// Convenience method returning the UTC time zone.
+inline TimeZone UTCTimeZone() {
+ return TimeZone(time_internal::cctz::utc_time_zone());
+}
+
+// LocalTimeZone()
+//
+// Convenience method returning the local time zone, or UTC if there is
+// no configured local zone. Warning: Be wary of using LocalTimeZone(),
+// and particularly so in a server process, as the zone configured for the
+// local machine should be irrelevant. Prefer an explicit zone name.
+inline TimeZone LocalTimeZone() {
+ return TimeZone(time_internal::cctz::local_time_zone());
+}
+
+// ToCivilSecond()
+// ToCivilMinute()
+// ToCivilHour()
+// ToCivilDay()
+// ToCivilMonth()
+// ToCivilYear()
+//
+// Helpers for TimeZone::At(Time) to return particularly aligned civil times.
+//
+// Example:
+//
// y_absl::Time t = ...;
// y_absl::TimeZone tz = ...;
// const auto cd = y_absl::ToCivilDay(t, tz);
-inline CivilSecond ToCivilSecond(Time t, TimeZone tz) {
- return tz.At(t).cs; // already a CivilSecond
-}
-inline CivilMinute ToCivilMinute(Time t, TimeZone tz) {
- return CivilMinute(tz.At(t).cs);
-}
-inline CivilHour ToCivilHour(Time t, TimeZone tz) {
- return CivilHour(tz.At(t).cs);
-}
-inline CivilDay ToCivilDay(Time t, TimeZone tz) {
- return CivilDay(tz.At(t).cs);
-}
-inline CivilMonth ToCivilMonth(Time t, TimeZone tz) {
- return CivilMonth(tz.At(t).cs);
-}
-inline CivilYear ToCivilYear(Time t, TimeZone tz) {
- return CivilYear(tz.At(t).cs);
-}
-
-// FromCivil()
-//
-// Helper for TimeZone::At(CivilSecond) that provides "order-preserving
-// semantics." If the civil time maps to a unique time, that time is
-// returned. If the civil time is repeated in the given time zone, the
-// time using the pre-transition offset is returned. Otherwise, the
-// civil time is skipped in the given time zone, and the transition time
-// is returned. This means that for any two civil times, ct1 and ct2,
-// (ct1 < ct2) => (FromCivil(ct1) <= FromCivil(ct2)), the equal case
-// being when two non-existent civil times map to the same transition time.
-//
-// Note: Accepts civil times of any alignment.
-inline Time FromCivil(CivilSecond ct, TimeZone tz) {
- const auto ti = tz.At(ct);
- if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans;
- return ti.pre;
-}
-
-// TimeConversion
-//
+inline CivilSecond ToCivilSecond(Time t, TimeZone tz) {
+ return tz.At(t).cs; // already a CivilSecond
+}
+inline CivilMinute ToCivilMinute(Time t, TimeZone tz) {
+ return CivilMinute(tz.At(t).cs);
+}
+inline CivilHour ToCivilHour(Time t, TimeZone tz) {
+ return CivilHour(tz.At(t).cs);
+}
+inline CivilDay ToCivilDay(Time t, TimeZone tz) {
+ return CivilDay(tz.At(t).cs);
+}
+inline CivilMonth ToCivilMonth(Time t, TimeZone tz) {
+ return CivilMonth(tz.At(t).cs);
+}
+inline CivilYear ToCivilYear(Time t, TimeZone tz) {
+ return CivilYear(tz.At(t).cs);
+}
+
+// FromCivil()
+//
+// Helper for TimeZone::At(CivilSecond) that provides "order-preserving
+// semantics." If the civil time maps to a unique time, that time is
+// returned. If the civil time is repeated in the given time zone, the
+// time using the pre-transition offset is returned. Otherwise, the
+// civil time is skipped in the given time zone, and the transition time
+// is returned. This means that for any two civil times, ct1 and ct2,
+// (ct1 < ct2) => (FromCivil(ct1) <= FromCivil(ct2)), the equal case
+// being when two non-existent civil times map to the same transition time.
+//
+// Note: Accepts civil times of any alignment.
+inline Time FromCivil(CivilSecond ct, TimeZone tz) {
+ const auto ti = tz.At(ct);
+ if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans;
+ return ti.pre;
+}
+
+// TimeConversion
+//
// An `y_absl::TimeConversion` represents the conversion of year, month, day,
-// hour, minute, and second values (i.e., a civil time), in a particular
+// hour, minute, and second values (i.e., a civil time), in a particular
// `y_absl::TimeZone`, to a time instant (an absolute time), as returned by
// `y_absl::ConvertDateTime()`. Legacy version of `y_absl::TimeZone::TimeInfo`.
-//
+//
// Deprecated. Use `y_absl::TimeZone::TimeInfo`.
-struct
- TimeConversion {
- Time pre; // time calculated using the pre-transition offset
- Time trans; // when the civil-time discontinuity occurred
- Time post; // time calculated using the post-transition offset
-
- enum Kind {
- UNIQUE, // the civil time was singular (pre == trans == post)
- SKIPPED, // the civil time did not exist
- REPEATED, // the civil time was ambiguous
- };
- Kind kind;
-
- bool normalized; // input values were outside their valid ranges
-};
-
-// ConvertDateTime()
-//
+struct
+ TimeConversion {
+ Time pre; // time calculated using the pre-transition offset
+ Time trans; // when the civil-time discontinuity occurred
+ Time post; // time calculated using the post-transition offset
+
+ enum Kind {
+ UNIQUE, // the civil time was singular (pre == trans == post)
+ SKIPPED, // the civil time did not exist
+ REPEATED, // the civil time was ambiguous
+ };
+ Kind kind;
+
+ bool normalized; // input values were outside their valid ranges
+};
+
+// ConvertDateTime()
+//
// Legacy version of `y_absl::TimeZone::At(y_absl::CivilSecond)` that takes
-// the civil time as six, separate values (YMDHMS).
-//
-// The input month, day, hour, minute, and second values can be outside
-// of their valid ranges, in which case they will be "normalized" during
-// the conversion.
-//
-// Example:
-//
-// // "October 32" normalizes to "November 1".
+// the civil time as six, separate values (YMDHMS).
+//
+// The input month, day, hour, minute, and second values can be outside
+// of their valid ranges, in which case they will be "normalized" during
+// the conversion.
+//
+// Example:
+//
+// // "October 32" normalizes to "November 1".
// y_absl::TimeConversion tc =
// y_absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, lax);
-// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true
+// // tc.kind == TimeConversion::UNIQUE && tc.normalized == true
// // y_absl::ToCivilDay(tc.pre, tz).month() == 11
// // y_absl::ToCivilDay(tc.pre, tz).day() == 1
-//
+//
// Deprecated. Use `y_absl::TimeZone::At(CivilSecond)`.
-TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
- int min, int sec, TimeZone tz);
-
-// FromDateTime()
-//
+TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
+ int min, int sec, TimeZone tz);
+
+// FromDateTime()
+//
// A convenience wrapper for `y_absl::ConvertDateTime()` that simply returns
// the "pre" `y_absl::Time`. That is, the unique result, or the instant that
-// is correct using the pre-transition offset (as if the transition never
-// happened).
-//
-// Example:
-//
+// is correct using the pre-transition offset (as if the transition never
+// happened).
+//
+// Example:
+//
// y_absl::Time t = y_absl::FromDateTime(2017, 9, 26, 9, 30, 0, lax);
-// // t = 2017-09-26 09:30:00 -0700
-//
+// // t = 2017-09-26 09:30:00 -0700
+//
// Deprecated. Use `y_absl::FromCivil(CivilSecond, TimeZone)`. Note that the
-// behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil
+// behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil
// times. If you care about that see `y_absl::TimeZone::At(y_absl::CivilSecond)`.
-inline Time FromDateTime(int64_t year, int mon, int day, int hour,
- int min, int sec, TimeZone tz) {
- return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre;
-}
-
-// FromTM()
-//
-// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and
+inline Time FromDateTime(int64_t year, int mon, int day, int hour,
+ int min, int sec, TimeZone tz) {
+ return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre;
+}
+
+// FromTM()
+//
+// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and
// `tm_sec` fields to an `y_absl::Time` using the given time zone. See ctime(3)
// for a description of the expected values of the tm fields. If the civil time
// is unique (see `y_absl::TimeZone::At(y_absl::CivilSecond)` above), the matching
@@ -1239,378 +1239,378 @@ inline Time FromDateTime(int64_t year, int mon, int day, int hour,
// instant, so `tm_isdst != 0` returns the DST instant, and `tm_isdst == 0`
// returns the non-DST instant, that would have matched if the transition never
// happened.
-Time FromTM(const struct tm& tm, TimeZone tz);
-
-// ToTM()
-//
+Time FromTM(const struct tm& tm, TimeZone tz);
+
+// ToTM()
+//
// Converts the given `y_absl::Time` to a struct tm using the given time zone.
-// See ctime(3) for a description of the values of the tm fields.
-struct tm ToTM(Time t, TimeZone tz);
-
-// RFC3339_full
-// RFC3339_sec
-//
-// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings,
-// with trailing zeros trimmed or with fractional seconds omitted altogether.
-//
-// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and
-// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that
-// years have exactly four digits, but we allow them to take their natural
-// width.
+// See ctime(3) for a description of the values of the tm fields.
+struct tm ToTM(Time t, TimeZone tz);
+
+// RFC3339_full
+// RFC3339_sec
+//
+// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings,
+// with trailing zeros trimmed or with fractional seconds omitted altogether.
+//
+// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and
+// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that
+// years have exactly four digits, but we allow them to take their natural
+// width.
ABSL_DLL extern const char RFC3339_full[]; // %Y-%m-%d%ET%H:%M:%E*S%Ez
ABSL_DLL extern const char RFC3339_sec[]; // %Y-%m-%d%ET%H:%M:%S%Ez
-
-// RFC1123_full
-// RFC1123_no_wday
-//
-// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
+
+// RFC1123_full
+// RFC1123_no_wday
+//
+// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
ABSL_DLL extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z
ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z
-
-// FormatTime()
-//
+
+// FormatTime()
+//
// Formats the given `y_absl::Time` in the `y_absl::TimeZone` according to the
-// provided format string. Uses strftime()-like formatting options, with
-// the following extensions:
-//
-// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
-// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
-// - %E#S - Seconds with # digits of fractional precision
-// - %E*S - Seconds with full fractional precision (a literal '*')
-// - %E#f - Fractional seconds with # digits of precision
-// - %E*f - Fractional seconds with full precision (a literal '*')
-// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+// provided format string. Uses strftime()-like formatting options, with
+// the following extensions:
+//
+// - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
+// - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
+// - %E#S - Seconds with # digits of fractional precision
+// - %E*S - Seconds with full fractional precision (a literal '*')
+// - %E#f - Fractional seconds with # digits of precision
+// - %E*f - Fractional seconds with full precision (a literal '*')
+// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
// - %ET - The RFC3339 "date-time" separator "T"
-//
-// Note that %E0S behaves like %S, and %E0f produces no characters. In
-// contrast %E*f always produces at least one digit, which may be '0'.
-//
-// Note that %Y produces as many characters as it takes to fully render the
-// year. A year outside of [-999:9999] when formatted with %E4Y will produce
-// more than four characters, just like %Y.
-//
-// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z)
-// so that the result uniquely identifies a time instant.
-//
-// Example:
-//
+//
+// Note that %E0S behaves like %S, and %E0f produces no characters. In
+// contrast %E*f always produces at least one digit, which may be '0'.
+//
+// Note that %Y produces as many characters as it takes to fully render the
+// year. A year outside of [-999:9999] when formatted with %E4Y will produce
+// more than four characters, just like %Y.
+//
+// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z)
+// so that the result uniquely identifies a time instant.
+//
+// Example:
+//
// y_absl::CivilSecond cs(2013, 1, 2, 3, 4, 5);
// y_absl::Time t = y_absl::FromCivil(cs, lax);
// TString f = y_absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05"
// f = y_absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000"
-//
+//
// Note: If the given `y_absl::Time` is `y_absl::InfiniteFuture()`, the returned
// string will be exactly "infinite-future". If the given `y_absl::Time` is
// `y_absl::InfinitePast()`, the returned string will be exactly "infinite-past".
// In both cases the given format string and `y_absl::TimeZone` are ignored.
-//
+//
TString FormatTime(y_absl::string_view format, Time t, TimeZone tz);
-
-// Convenience functions that format the given time using the RFC3339_full
-// format. The first overload uses the provided TimeZone, while the second
-// uses LocalTimeZone().
+
+// Convenience functions that format the given time using the RFC3339_full
+// format. The first overload uses the provided TimeZone, while the second
+// uses LocalTimeZone().
TString FormatTime(Time t, TimeZone tz);
TString FormatTime(Time t);
-
-// Output stream operator.
-inline std::ostream& operator<<(std::ostream& os, Time t) {
- return os << FormatTime(t);
-}
-
-// ParseTime()
-//
-// Parses an input string according to the provided format string and
+
+// Output stream operator.
+inline std::ostream& operator<<(std::ostream& os, Time t) {
+ return os << FormatTime(t);
+}
+
+// ParseTime()
+//
+// Parses an input string according to the provided format string and
// returns the corresponding `y_absl::Time`. Uses strftime()-like formatting
-// options, with the same extensions as FormatTime(), but with the
-// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
+// options, with the same extensions as FormatTime(), but with the
+// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
// and %E*z also accept the same inputs, which (along with %z) includes
// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'.
-//
-// %Y consumes as many numeric characters as it can, so the matching data
-// should always be terminated with a non-numeric. %E4Y always consumes
-// exactly four characters, including any sign.
-//
-// Unspecified fields are taken from the default date and time of ...
-//
-// "1970-01-01 00:00:00.0 +0000"
-//
+//
+// %Y consumes as many numeric characters as it can, so the matching data
+// should always be terminated with a non-numeric. %E4Y always consumes
+// exactly four characters, including any sign.
+//
+// Unspecified fields are taken from the default date and time of ...
+//
+// "1970-01-01 00:00:00.0 +0000"
+//
// For example, parsing a string of "15:45" (%H:%M) will return an y_absl::Time
-// that represents "1970-01-01 15:45:00.0 +0000".
-//
-// Note that since ParseTime() returns time instants, it makes the most sense
-// to parse fully-specified date/time strings that include a UTC offset (%z,
-// %Ez, or %E*z).
-//
+// that represents "1970-01-01 15:45:00.0 +0000".
+//
+// Note that since ParseTime() returns time instants, it makes the most sense
+// to parse fully-specified date/time strings that include a UTC offset (%z,
+// %Ez, or %E*z).
+//
// Note also that `y_absl::ParseTime()` only heeds the fields year, month, day,
-// hour, minute, (fractional) second, and UTC offset. Other fields, like
-// weekday (%a or %A), while parsed for syntactic validity, are ignored
-// in the conversion.
-//
-// Date and time fields that are out-of-range will be treated as errors
+// hour, minute, (fractional) second, and UTC offset. Other fields, like
+// weekday (%a or %A), while parsed for syntactic validity, are ignored
+// in the conversion.
+//
+// Date and time fields that are out-of-range will be treated as errors
// rather than normalizing them like `y_absl::CivilSecond` does. For example,
-// it is an error to parse the date "Oct 32, 2013" because 32 is out of range.
-//
-// A leap second of ":60" is normalized to ":00" of the following minute
-// with fractional seconds discarded. The following table shows how the
-// given seconds and subseconds will be parsed:
-//
-// "59.x" -> 59.x // exact
-// "60.x" -> 00.0 // normalized
-// "00.x" -> 00.x // exact
-//
-// Errors are indicated by returning false and assigning an error message
-// to the "err" out param if it is non-null.
-//
-// Note: If the input string is exactly "infinite-future", the returned
+// it is an error to parse the date "Oct 32, 2013" because 32 is out of range.
+//
+// A leap second of ":60" is normalized to ":00" of the following minute
+// with fractional seconds discarded. The following table shows how the
+// given seconds and subseconds will be parsed:
+//
+// "59.x" -> 59.x // exact
+// "60.x" -> 00.0 // normalized
+// "00.x" -> 00.x // exact
+//
+// Errors are indicated by returning false and assigning an error message
+// to the "err" out param if it is non-null.
+//
+// Note: If the input string is exactly "infinite-future", the returned
// `y_absl::Time` will be `y_absl::InfiniteFuture()` and `true` will be returned.
// If the input string is "infinite-past", the returned `y_absl::Time` will be
// `y_absl::InfinitePast()` and `true` will be returned.
-//
+//
bool ParseTime(y_absl::string_view format, y_absl::string_view input, Time* time,
TString* err);
-
-// Like ParseTime() above, but if the format string does not contain a UTC
-// offset specification (%z/%Ez/%E*z) then the input is interpreted in the
-// given TimeZone. This means that the input, by itself, does not identify a
-// unique instant. Being time-zone dependent, it also admits the possibility
-// of ambiguity or non-existence, in which case the "pre" time (as defined
-// by TimeZone::TimeInfo) is returned. For these reasons we recommend that
-// all date/time strings include a UTC offset so they're context independent.
+
+// Like ParseTime() above, but if the format string does not contain a UTC
+// offset specification (%z/%Ez/%E*z) then the input is interpreted in the
+// given TimeZone. This means that the input, by itself, does not identify a
+// unique instant. Being time-zone dependent, it also admits the possibility
+// of ambiguity or non-existence, in which case the "pre" time (as defined
+// by TimeZone::TimeInfo) is returned. For these reasons we recommend that
+// all date/time strings include a UTC offset so they're context independent.
bool ParseTime(y_absl::string_view format, y_absl::string_view input, TimeZone tz,
Time* time, TString* err);
-
-// ============================================================================
-// Implementation Details Follow
-// ============================================================================
-
-namespace time_internal {
-
-// Creates a Duration with a given representation.
-// REQUIRES: hi,lo is a valid representation of a Duration as specified
-// in time/duration.cc.
-constexpr Duration MakeDuration(int64_t hi, uint32_t lo = 0) {
- return Duration(hi, lo);
-}
-
-constexpr Duration MakeDuration(int64_t hi, int64_t lo) {
- return MakeDuration(hi, static_cast<uint32_t>(lo));
-}
-
-// Make a Duration value from a floating-point number, as long as that number
-// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as
-// it's positive and can be converted to int64_t without risk of UB.
-inline Duration MakePosDoubleDuration(double n) {
- const int64_t int_secs = static_cast<int64_t>(n);
+
+// ============================================================================
+// Implementation Details Follow
+// ============================================================================
+
+namespace time_internal {
+
+// Creates a Duration with a given representation.
+// REQUIRES: hi,lo is a valid representation of a Duration as specified
+// in time/duration.cc.
+constexpr Duration MakeDuration(int64_t hi, uint32_t lo = 0) {
+ return Duration(hi, lo);
+}
+
+constexpr Duration MakeDuration(int64_t hi, int64_t lo) {
+ return MakeDuration(hi, static_cast<uint32_t>(lo));
+}
+
+// Make a Duration value from a floating-point number, as long as that number
+// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as
+// it's positive and can be converted to int64_t without risk of UB.
+inline Duration MakePosDoubleDuration(double n) {
+ const int64_t int_secs = static_cast<int64_t>(n);
const uint32_t ticks = static_cast<uint32_t>(
std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond));
- return ticks < kTicksPerSecond
- ? MakeDuration(int_secs, ticks)
- : MakeDuration(int_secs + 1, ticks - kTicksPerSecond);
-}
-
-// Creates a normalized Duration from an almost-normalized (sec,ticks)
-// pair. sec may be positive or negative. ticks must be in the range
-// -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it
-// will be normalized to a positive value in the resulting Duration.
-constexpr Duration MakeNormalizedDuration(int64_t sec, int64_t ticks) {
- return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond)
- : MakeDuration(sec, ticks);
-}
-
-// Provide access to the Duration representation.
-constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; }
-constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; }
-
-// Returns true iff d is positive or negative infinity.
-constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; }
-
-// Returns an infinite Duration with the opposite sign.
-// REQUIRES: IsInfiniteDuration(d)
-constexpr Duration OppositeInfinity(Duration d) {
- return GetRepHi(d) < 0
- ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)
- : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U);
-}
-
-// Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow.
-constexpr int64_t NegateAndSubtractOne(int64_t n) {
- // Note: Good compilers will optimize this expression to ~n when using
- // a two's-complement representation (which is required for int64_t).
- return (n < 0) ? -(n + 1) : (-n) - 1;
-}
-
-// Map between a Time and a Duration since the Unix epoch. Note that these
-// functions depend on the above mentioned choice of the Unix epoch for the
-// Time representation (and both need to be Time friends). Without this
-// knowledge, we would need to add-in/subtract-out UnixEpoch() respectively.
-constexpr Time FromUnixDuration(Duration d) { return Time(d); }
-constexpr Duration ToUnixDuration(Time t) { return t.rep_; }
-
-template <std::intmax_t N>
-constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) {
- static_assert(0 < N && N <= 1000 * 1000 * 1000, "Unsupported ratio");
- // Subsecond ratios cannot overflow.
- return MakeNormalizedDuration(
- v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N);
-}
-constexpr Duration FromInt64(int64_t v, std::ratio<60>) {
- return (v <= (std::numeric_limits<int64_t>::max)() / 60 &&
- v >= (std::numeric_limits<int64_t>::min)() / 60)
- ? MakeDuration(v * 60)
- : v > 0 ? InfiniteDuration() : -InfiniteDuration();
-}
-constexpr Duration FromInt64(int64_t v, std::ratio<3600>) {
- return (v <= (std::numeric_limits<int64_t>::max)() / 3600 &&
- v >= (std::numeric_limits<int64_t>::min)() / 3600)
- ? MakeDuration(v * 3600)
- : v > 0 ? InfiniteDuration() : -InfiniteDuration();
-}
-
-// IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is
-// valid. That is, if a T can be assigned to an int64_t without narrowing.
-template <typename T>
-constexpr auto IsValidRep64(int) -> decltype(int64_t{std::declval<T>()} == 0) {
- return true;
-}
-template <typename T>
-constexpr auto IsValidRep64(char) -> bool {
- return false;
-}
-
+ return ticks < kTicksPerSecond
+ ? MakeDuration(int_secs, ticks)
+ : MakeDuration(int_secs + 1, ticks - kTicksPerSecond);
+}
+
+// Creates a normalized Duration from an almost-normalized (sec,ticks)
+// pair. sec may be positive or negative. ticks must be in the range
+// -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it
+// will be normalized to a positive value in the resulting Duration.
+constexpr Duration MakeNormalizedDuration(int64_t sec, int64_t ticks) {
+ return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond)
+ : MakeDuration(sec, ticks);
+}
+
+// Provide access to the Duration representation.
+constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; }
+constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; }
+
+// Returns true iff d is positive or negative infinity.
+constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; }
+
+// Returns an infinite Duration with the opposite sign.
+// REQUIRES: IsInfiniteDuration(d)
+constexpr Duration OppositeInfinity(Duration d) {
+ return GetRepHi(d) < 0
+ ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)
+ : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U);
+}
+
+// Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow.
+constexpr int64_t NegateAndSubtractOne(int64_t n) {
+ // Note: Good compilers will optimize this expression to ~n when using
+ // a two's-complement representation (which is required for int64_t).
+ return (n < 0) ? -(n + 1) : (-n) - 1;
+}
+
+// Map between a Time and a Duration since the Unix epoch. Note that these
+// functions depend on the above mentioned choice of the Unix epoch for the
+// Time representation (and both need to be Time friends). Without this
+// knowledge, we would need to add-in/subtract-out UnixEpoch() respectively.
+constexpr Time FromUnixDuration(Duration d) { return Time(d); }
+constexpr Duration ToUnixDuration(Time t) { return t.rep_; }
+
+template <std::intmax_t N>
+constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) {
+ static_assert(0 < N && N <= 1000 * 1000 * 1000, "Unsupported ratio");
+ // Subsecond ratios cannot overflow.
+ return MakeNormalizedDuration(
+ v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N);
+}
+constexpr Duration FromInt64(int64_t v, std::ratio<60>) {
+ return (v <= (std::numeric_limits<int64_t>::max)() / 60 &&
+ v >= (std::numeric_limits<int64_t>::min)() / 60)
+ ? MakeDuration(v * 60)
+ : v > 0 ? InfiniteDuration() : -InfiniteDuration();
+}
+constexpr Duration FromInt64(int64_t v, std::ratio<3600>) {
+ return (v <= (std::numeric_limits<int64_t>::max)() / 3600 &&
+ v >= (std::numeric_limits<int64_t>::min)() / 3600)
+ ? MakeDuration(v * 3600)
+ : v > 0 ? InfiniteDuration() : -InfiniteDuration();
+}
+
+// IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is
+// valid. That is, if a T can be assigned to an int64_t without narrowing.
+template <typename T>
+constexpr auto IsValidRep64(int) -> decltype(int64_t{std::declval<T>()} == 0) {
+ return true;
+}
+template <typename T>
+constexpr auto IsValidRep64(char) -> bool {
+ return false;
+}
+
// Converts a std::chrono::duration to an y_absl::Duration.
-template <typename Rep, typename Period>
-constexpr Duration FromChrono(const std::chrono::duration<Rep, Period>& d) {
- static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
- return FromInt64(int64_t{d.count()}, Period{});
-}
-
-template <typename Ratio>
-int64_t ToInt64(Duration d, Ratio) {
- // Note: This may be used on MSVC, which may have a system_clock period of
- // std::ratio<1, 10 * 1000 * 1000>
- return ToInt64Seconds(d * Ratio::den / Ratio::num);
-}
-// Fastpath implementations for the 6 common duration units.
-inline int64_t ToInt64(Duration d, std::nano) {
- return ToInt64Nanoseconds(d);
-}
-inline int64_t ToInt64(Duration d, std::micro) {
- return ToInt64Microseconds(d);
-}
-inline int64_t ToInt64(Duration d, std::milli) {
- return ToInt64Milliseconds(d);
-}
-inline int64_t ToInt64(Duration d, std::ratio<1>) {
- return ToInt64Seconds(d);
-}
-inline int64_t ToInt64(Duration d, std::ratio<60>) {
- return ToInt64Minutes(d);
-}
-inline int64_t ToInt64(Duration d, std::ratio<3600>) {
- return ToInt64Hours(d);
-}
-
+template <typename Rep, typename Period>
+constexpr Duration FromChrono(const std::chrono::duration<Rep, Period>& d) {
+ static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
+ return FromInt64(int64_t{d.count()}, Period{});
+}
+
+template <typename Ratio>
+int64_t ToInt64(Duration d, Ratio) {
+ // Note: This may be used on MSVC, which may have a system_clock period of
+ // std::ratio<1, 10 * 1000 * 1000>
+ return ToInt64Seconds(d * Ratio::den / Ratio::num);
+}
+// Fastpath implementations for the 6 common duration units.
+inline int64_t ToInt64(Duration d, std::nano) {
+ return ToInt64Nanoseconds(d);
+}
+inline int64_t ToInt64(Duration d, std::micro) {
+ return ToInt64Microseconds(d);
+}
+inline int64_t ToInt64(Duration d, std::milli) {
+ return ToInt64Milliseconds(d);
+}
+inline int64_t ToInt64(Duration d, std::ratio<1>) {
+ return ToInt64Seconds(d);
+}
+inline int64_t ToInt64(Duration d, std::ratio<60>) {
+ return ToInt64Minutes(d);
+}
+inline int64_t ToInt64(Duration d, std::ratio<3600>) {
+ return ToInt64Hours(d);
+}
+
// Converts an y_absl::Duration to a chrono duration of type T.
-template <typename T>
-T ToChronoDuration(Duration d) {
- using Rep = typename T::rep;
- using Period = typename T::period;
- static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
- if (time_internal::IsInfiniteDuration(d))
- return d < ZeroDuration() ? (T::min)() : (T::max)();
- const auto v = ToInt64(d, Period{});
- if (v > (std::numeric_limits<Rep>::max)()) return (T::max)();
- if (v < (std::numeric_limits<Rep>::min)()) return (T::min)();
- return T{v};
-}
-
-} // namespace time_internal
-
-constexpr bool operator<(Duration lhs, Duration rhs) {
- return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs)
- ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs)
+template <typename T>
+T ToChronoDuration(Duration d) {
+ using Rep = typename T::rep;
+ using Period = typename T::period;
+ static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
+ if (time_internal::IsInfiniteDuration(d))
+ return d < ZeroDuration() ? (T::min)() : (T::max)();
+ const auto v = ToInt64(d, Period{});
+ if (v > (std::numeric_limits<Rep>::max)()) return (T::max)();
+ if (v < (std::numeric_limits<Rep>::min)()) return (T::min)();
+ return T{v};
+}
+
+} // namespace time_internal
+
+constexpr bool operator<(Duration lhs, Duration rhs) {
+ return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs)
+ ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs)
: time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)()
? time_internal::GetRepLo(lhs) + 1 <
time_internal::GetRepLo(rhs) + 1
: time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs);
-}
-
-constexpr bool operator==(Duration lhs, Duration rhs) {
- return time_internal::GetRepHi(lhs) == time_internal::GetRepHi(rhs) &&
- time_internal::GetRepLo(lhs) == time_internal::GetRepLo(rhs);
-}
-
-constexpr Duration operator-(Duration d) {
- // This is a little interesting because of the special cases.
- //
- // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're
- // dealing with an integral number of seconds, and the only special case is
- // the maximum negative finite duration, which can't be negated.
- //
- // Infinities stay infinite, and just change direction.
- //
- // Finally we're in the case where rep_lo_ is non-zero, and we can borrow
- // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1
- // is safe).
- return time_internal::GetRepLo(d) == 0
- ? time_internal::GetRepHi(d) ==
- (std::numeric_limits<int64_t>::min)()
- ? InfiniteDuration()
- : time_internal::MakeDuration(-time_internal::GetRepHi(d))
- : time_internal::IsInfiniteDuration(d)
- ? time_internal::OppositeInfinity(d)
- : time_internal::MakeDuration(
- time_internal::NegateAndSubtractOne(
- time_internal::GetRepHi(d)),
- time_internal::kTicksPerSecond -
- time_internal::GetRepLo(d));
-}
-
-constexpr Duration InfiniteDuration() {
- return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
- ~0U);
-}
-
-constexpr Duration FromChrono(const std::chrono::nanoseconds& d) {
- return time_internal::FromChrono(d);
-}
-constexpr Duration FromChrono(const std::chrono::microseconds& d) {
- return time_internal::FromChrono(d);
-}
-constexpr Duration FromChrono(const std::chrono::milliseconds& d) {
- return time_internal::FromChrono(d);
-}
-constexpr Duration FromChrono(const std::chrono::seconds& d) {
- return time_internal::FromChrono(d);
-}
-constexpr Duration FromChrono(const std::chrono::minutes& d) {
- return time_internal::FromChrono(d);
-}
-constexpr Duration FromChrono(const std::chrono::hours& d) {
- return time_internal::FromChrono(d);
-}
-
-constexpr Time FromUnixNanos(int64_t ns) {
- return time_internal::FromUnixDuration(Nanoseconds(ns));
-}
-
-constexpr Time FromUnixMicros(int64_t us) {
- return time_internal::FromUnixDuration(Microseconds(us));
-}
-
-constexpr Time FromUnixMillis(int64_t ms) {
- return time_internal::FromUnixDuration(Milliseconds(ms));
-}
-
-constexpr Time FromUnixSeconds(int64_t s) {
- return time_internal::FromUnixDuration(Seconds(s));
-}
-
-constexpr Time FromTimeT(time_t t) {
- return time_internal::FromUnixDuration(Seconds(t));
-}
-
+}
+
+constexpr bool operator==(Duration lhs, Duration rhs) {
+ return time_internal::GetRepHi(lhs) == time_internal::GetRepHi(rhs) &&
+ time_internal::GetRepLo(lhs) == time_internal::GetRepLo(rhs);
+}
+
+constexpr Duration operator-(Duration d) {
+ // This is a little interesting because of the special cases.
+ //
+ // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're
+ // dealing with an integral number of seconds, and the only special case is
+ // the maximum negative finite duration, which can't be negated.
+ //
+ // Infinities stay infinite, and just change direction.
+ //
+ // Finally we're in the case where rep_lo_ is non-zero, and we can borrow
+ // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1
+ // is safe).
+ return time_internal::GetRepLo(d) == 0
+ ? time_internal::GetRepHi(d) ==
+ (std::numeric_limits<int64_t>::min)()
+ ? InfiniteDuration()
+ : time_internal::MakeDuration(-time_internal::GetRepHi(d))
+ : time_internal::IsInfiniteDuration(d)
+ ? time_internal::OppositeInfinity(d)
+ : time_internal::MakeDuration(
+ time_internal::NegateAndSubtractOne(
+ time_internal::GetRepHi(d)),
+ time_internal::kTicksPerSecond -
+ time_internal::GetRepLo(d));
+}
+
+constexpr Duration InfiniteDuration() {
+ return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
+ ~0U);
+}
+
+constexpr Duration FromChrono(const std::chrono::nanoseconds& d) {
+ return time_internal::FromChrono(d);
+}
+constexpr Duration FromChrono(const std::chrono::microseconds& d) {
+ return time_internal::FromChrono(d);
+}
+constexpr Duration FromChrono(const std::chrono::milliseconds& d) {
+ return time_internal::FromChrono(d);
+}
+constexpr Duration FromChrono(const std::chrono::seconds& d) {
+ return time_internal::FromChrono(d);
+}
+constexpr Duration FromChrono(const std::chrono::minutes& d) {
+ return time_internal::FromChrono(d);
+}
+constexpr Duration FromChrono(const std::chrono::hours& d) {
+ return time_internal::FromChrono(d);
+}
+
+constexpr Time FromUnixNanos(int64_t ns) {
+ return time_internal::FromUnixDuration(Nanoseconds(ns));
+}
+
+constexpr Time FromUnixMicros(int64_t us) {
+ return time_internal::FromUnixDuration(Microseconds(us));
+}
+
+constexpr Time FromUnixMillis(int64_t ms) {
+ return time_internal::FromUnixDuration(Milliseconds(ms));
+}
+
+constexpr Time FromUnixSeconds(int64_t s) {
+ return time_internal::FromUnixDuration(Seconds(s));
+}
+
+constexpr Time FromTimeT(time_t t) {
+ return time_internal::FromUnixDuration(Seconds(t));
+}
+
ABSL_NAMESPACE_END
} // namespace y_absl
-
-#endif // ABSL_TIME_TIME_H_
+
+#endif // ABSL_TIME_TIME_H_
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone/ya.make
index d2930432bd..d7e1dc0c26 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone/ya.make
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone/ya.make
@@ -1,38 +1,38 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-
+
OWNER(
somov
g:cpp-contrib
)
-LICENSE(Apache-2.0)
-
+LICENSE(Apache-2.0)
+
ADDINCL(
GLOBAL contrib/restricted/abseil-cpp-tstring
)
-
+
IF (OS_DARWIN)
EXTRALIBS("-framework CoreFoundation")
ENDIF()
-NO_COMPILER_WARNINGS()
-
+NO_COMPILER_WARNINGS()
+
SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src)
-
-SRCS(
- time_zone_fixed.cc
- time_zone_format.cc
- time_zone_if.cc
- time_zone_impl.cc
- time_zone_info.cc
- time_zone_libc.cc
- time_zone_lookup.cc
- time_zone_posix.cc
- zone_info_source.cc
-)
-
-END()
+
+SRCS(
+ time_zone_fixed.cc
+ time_zone_format.cc
+ time_zone_if.cc
+ time_zone_impl.cc
+ time_zone_info.cc
+ time_zone_libc.cc
+ time_zone_lookup.cc
+ time_zone_posix.cc
+ zone_info_source.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make
index 95bd98470b..37cc779265 100644
--- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make
+++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make
@@ -1,20 +1,20 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
somov
g:cpp-contrib
)
-
+
LICENSE(
Apache-2.0 AND
Public-Domain
)
-
+
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/restricted/abseil-cpp-tstring/y_absl/base
contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging
contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait
@@ -25,20 +25,20 @@ PEERDIR(
contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal
contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time
contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone
-)
-
+)
+
ADDINCL(
GLOBAL contrib/restricted/abseil-cpp-tstring
)
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- civil_time.cc
- clock.cc
- duration.cc
- format.cc
- time.cc
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+SRCS(
+ civil_time.cc
+ clock.cc
+ duration.cc
+ format.cc
+ time.cc
+)
+
+END()