tvl-depot/absl/time/format.cc

154 lines
4.9 KiB
C++
Raw Normal View History

2017-09-19 22:54:40 +02:00
// 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
2017-09-19 22:54:40 +02:00
//
// 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 "absl/time/internal/cctz/include/cctz/time_zone.h"
2017-09-19 22:54:40 +02:00
#include "absl/time/time.h"
namespace cctz = absl::time_internal::cctz;
2017-09-19 22:54:40 +02:00
namespace absl {
Export of internal Abseil changes -- c99f979ad34f155fbeeea69b88bdc7458d89a21c by Derek Mauro <dmauro@google.com>: Remove a floating point division by zero test. This isn't testing behavior related to the library, and MSVC warns about it in opt mode. PiperOrigin-RevId: 285220804 -- 68b015491f0dbf1ab547994673281abd1f34cd4b by Gennadiy Rozental <rogeeff@google.com>: This CL introduces following changes to the class FlagImpl: * We eliminate the CommandLineFlagLocks struct. Instead callback guard and callback function are combined into a single CallbackData struct, while primary data lock is stored separately. * CallbackData member of class FlagImpl is initially set to be nullptr and is only allocated and initialized when a flag's callback is being set. For most flags we do not pay for the extra space and extra absl::Mutex now. * Primary data guard is stored in data_guard_ data member. This is a properly aligned character buffer of necessary size. During initialization of the flag we construct absl::Mutex in this space using placement new call. * We now avoid extra value copy after successful attempt to parse value out of string. Instead we swap flag's current value with tentative value we just produced. PiperOrigin-RevId: 285132636 -- ed45d118fb818969eb13094cf7827c885dfc562c by Tom Manshreck <shreck@google.com>: Change null-term* (and nul-term*) to NUL-term* in comments PiperOrigin-RevId: 285036610 -- 729619017944db895ce8d6d29c1995aa2e5628a5 by Derek Mauro <dmauro@google.com>: Use the Posix implementation of thread identity on MinGW. Some versions of MinGW suffer from thread_local bugs. PiperOrigin-RevId: 285022920 -- 39a25493503c76885bc3254c28f66a251c5b5bb0 by Greg Falcon <gfalcon@google.com>: Implementation detail change. Add further ABSL_NAMESPACE_BEGIN and _END annotation macros to files in Abseil. PiperOrigin-RevId: 285012012 GitOrigin-RevId: c99f979ad34f155fbeeea69b88bdc7458d89a21c Change-Id: I4c85d3704e45d11a9ac50d562f39640a6adbedc1
2019-12-12 19:36:03 +01:00
ABSL_NAMESPACE_BEGIN
2017-09-19 22:54:40 +02:00
Export of internal Abseil changes -- 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 by Eric Fiselier <ericwf@google.com>: Workaround bug in GCC 9.2 and after. PiperOrigin-RevId: 291982551 -- 47ff4820e595f96c082a90d733725f6882d83e3b by Abseil Team <absl-team@google.com>: Improve ABSL_ATTRIBUTE_PACKED documentation Recommend to apply ABSL_ATTRIBUTE_PACKED to structure members instead of to an entire structure because applying this attribute to an entire structure may cause the compiler to generate suboptimal code. It reduces the alignment of the data structure from a value larger than one to one. When applied to a structure, ABSL_ATTRIBUTE_PACKED reduces the alignment of a structure (alignof()) to 1. As a result, the compiler can no longer assume that e.g. uint32 members are aligned on a four byte boundary and hence is forced to use single-byte load and store instructions on CPU architectures that do not support non-aligned loads or stores. PiperOrigin-RevId: 291977920 -- 902b7a86f860da699d3a2e5c738be5ef73ede3b4 by Mark Barolak <mbar@google.com>: Internal change PiperOrigin-RevId: 291963048 -- bb3bd3247e376d53a3080b105f13ec7566d3ae50 by Abseil Team <absl-team@google.com>: Support the C++17 insert_or_assign() API in btree_map. PiperOrigin-RevId: 291945474 -- ff3b3cfcbbc64f086f95501f48d49426bcde356f by Gennadiy Rozental <rogeeff@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 291861110 -- fd465cd9cbbacd3962f67a7346d6462edaddd809 by Derek Mauro <dmauro@google.com>: Add flaky=1 to beta_distribution_test. PiperOrigin-RevId: 291757364 -- 3603adfb59c4128c542b670952cce250d59e1f67 by Derek Mauro <dmauro@google.com>: Separate the initialization of NumCPUs() and NominalCPUFrequency() The OSS version of Abseil never needs to call NominalCPUFrequency(). In some configurations, initializing NominalCPUFrequency() requires spending at least 3ms measuring the CPU frequency. By separating the initialization from NumCPUs(), which is called in most configurations, we can save at least 3ms of program startup time. PiperOrigin-RevId: 291737273 -- bea9e4a6bff5a0351d340deab966641867e08c4d by Abseil Team <absl-team@google.com>: Change the cmake library names not to have a redundant `absl_` prefix. PiperOrigin-RevId: 291640501 -- 501b602ef260cd7c8c527342581ceffb3c5b6d4c by Gennadiy Rozental <rogeeff@google.com>: Introducing benchmark for absl::GetFlag. PiperOrigin-RevId: 291433394 -- 4eeaddc788da4b91c272a8adca77ca6dbbbc1d44 by Xiaoyi Zhang <zhangxy@google.com>: fix: Add support for more ARM processors detection Import of https://github.com/abseil/abseil-cpp/pull/608 PiperOrigin-RevId: 291420397 -- a3087a8e883c5d71de7d9bd4ec8f4db5142dfcf5 by Derek Mauro <dmauro@google.com>: Removes the flaky raw_hash_set prefetch test PiperOrigin-RevId: 291197079 -- aad6c2121c102ac36216e771c83227cf3e3bfd66 by Andy Soffer <asoffer@google.com>: Enable building Abseil as a DLL. This is currently experimental and unsupported. This CL does a few things: 1. Adds the ABSL_DLL macro to any class holding a static data member, or to global constants in headers. 2. Adds a whitelist of all files in the DLL and all the build targets that are conglomerated into the DLL. 3. When BUILD_SHARED_LIBS is specified, any build target that would be in the DLL still exists, but we swap out all of it's dependencies so it just depends on abseil_dll PiperOrigin-RevId: 291192055 -- 5e888cd6f2a7722805d41f872108a03a84e421c7 by Mark Barolak <mbar@google.com>: Move absl/strings/internal/escaping.{cc,h} into internal build targets. This puts absl/strings/internal/escaping.h behind a whitelist and it also resolves https://github.com/abseil/abseil-cpp/issues/604. PiperOrigin-RevId: 291173320 -- 166836d24970da87587c1728036f53f05a28f0af by Eric Fiselier <ericwf@google.com>: Internal Change. PiperOrigin-RevId: 291012718 -- 996ddb3dffda02440fa93f30ca5d71b14b688875 by Abseil Team <absl-team@google.com>: Fix shared libraries log spam for built-in types in absl::GetFlag PiperOrigin-RevId: 290772743 GitOrigin-RevId: 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 Change-Id: I8bf2265dd14ebbace220a1b6b982bb5040ad2a26
2020-01-28 20:50:11 +01:00
ABSL_DLL extern const char RFC3339_full[] =
"%Y-%m-%dT%H:%M:%E*S%Ez";
ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%dT%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";
2017-09-19 22:54:40 +02:00
namespace {
const char kInfiniteFutureStr[] = "infinite-future";
const char kInfinitePastStr[] = "infinite-past";
struct cctz_parts {
cctz::time_point<cctz::seconds> sec;
cctz::detail::femtoseconds fem;
2017-09-19 22:54:40 +02:00
};
inline cctz::time_point<cctz::seconds> unix_epoch() {
return std::chrono::time_point_cast<cctz::seconds>(
2017-09-19 22:54:40 +02:00
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(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));
2017-09-19 22:54:40 +02:00
return {sec, fem};
}
// Joins the given seconds and femtoseconds into a Time. See duration.cc for
// details about rep_hi and rep_lo.
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
std::string FormatTime(const std::string& format, absl::Time t,
absl::TimeZone tz) {
2017-09-19 22:54:40 +02:00
if (t == absl::InfiniteFuture()) return kInfiniteFutureStr;
if (t == absl::InfinitePast()) return kInfinitePastStr;
const auto parts = Split(t);
return cctz::detail::format(format, parts.sec, parts.fem,
cctz::time_zone(tz));
}
std::string FormatTime(absl::Time t, absl::TimeZone tz) {
return FormatTime(RFC3339_full, t, tz);
}
std::string FormatTime(absl::Time t) {
return absl::FormatTime(RFC3339_full, t, absl::LocalTimeZone());
}
bool ParseTime(const std::string& format, const std::string& input,
absl::Time* time, std::string* err) {
2017-09-19 22:54:40 +02:00
return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err);
}
// If the input string does not contain an explicit UTC offset, interpret
2017-09-19 22:54:40 +02:00
// the fields with respect to the given TimeZone.
bool ParseTime(const std::string& format, const std::string& input,
absl::TimeZone tz, absl::Time* time, std::string* err) {
2017-09-19 22:54:40 +02:00
const char* data = input.c_str();
while (std::isspace(*data)) ++data;
size_t inf_size = strlen(kInfiniteFutureStr);
if (strncmp(data, kInfiniteFutureStr, inf_size) == 0) {
const char* new_data = data + inf_size;
while (std::isspace(*new_data)) ++new_data;
if (*new_data == '\0') {
*time = InfiniteFuture();
return true;
}
}
inf_size = strlen(kInfinitePastStr);
if (strncmp(data, kInfinitePastStr, inf_size) == 0) {
const char* new_data = data + inf_size;
while (std::isspace(*new_data)) ++new_data;
if (*new_data == '\0') {
*time = InfinitePast();
return true;
}
}
std::string error;
cctz_parts parts;
const bool b = cctz::detail::parse(format, input, cctz::time_zone(tz),
&parts.sec, &parts.fem, &error);
if (b) {
*time = Join(parts);
} else if (err != nullptr) {
*err = error;
}
return b;
}
Changes imported from Abseil "staging" branch: - b527a3e4b36b644ac424e3c525b1cd393f6f6c40 Fix some typos in the usage examples by Jorg Brown <jorg@google.com> - 82be4a9adf3bb0ddafc0d46274969c99afffe870 Fix typo in optional.h comment. by Abseil Team <absl-team@google.com> - d6ee63bf8fc51fba074c23b33cebc28c808d7f07 Remove internal-only identifiers from code. by Daniel Katz <katzdm@google.com> - f9c3ad2f0d73f53b21603638af8b4bed636e79f4 Use easier understandable names for absl::StartsWith and ... by Abseil Team <absl-team@google.com> - 7c16c14fefee89c927b8789d6043c4691bcffc9b Add -Wno-missing-prototypes back to the LLVM copts. by Derek Mauro <dmauro@google.com> - 2f4b7d2e50c7023240242f1e15db60ccd7e8768d IWYU | absl/strings by Juemin Yang <jueminyang@google.com> - a99cbcc1daa34a2d6a2bb26de275e05173cc77e9 IWYU | absl/type by Juemin Yang <jueminyang@google.com> - 12e1146d0fc76c071d7e0ebaabb62f0a984fae66 Use LLVM_FLAGS and LLVM_TEST_FLAGS when --compiler=llvm. by Derek Mauro <dmauro@google.com> - cd6bea616abda558d0bace5bd77455662a233688 IWYU | absl/debugging by Juemin Yang <jueminyang@google.com> - d9a7382e59d46a8581b6b7a31cd5a48bb89326e9 IWYU | absl/synchronization by Juemin Yang <jueminyang@google.com> - 07ec7d6d5a4a666f4183c5d0ed9c342baa7b24bc IWYU | absl/numeric by Juemin Yang <jueminyang@google.com> - 12bfe40051f4270f8707e191af5652f83f2f750c Remove the RoundTrip{Float,Double}ToBuffer routines from ... by Jorg Brown <jorg@google.com> - eeb4fd67c9d97f66cb9475c3c5e51ab132f1c810 Adds conversion functions for converting between absl/tim... by Greg Miller <jgm@google.com> - 59a2108d05d4ea85dc5cc11e49b2cd2335d4295a Change Substitute to use %.6g formatting rather than 15/1... by Jorg Brown <jorg@google.com> - 394becb48e0fcd161642cdaac5120d32567e0ef8 IWYU | absl/meta by Juemin Yang <jueminyang@google.com> - 1e5da6e8da336699b2469dcf6dda025b9b0ec4c9 Rewrite atomic_hook.h to not use std::atomic<T*> under Wi... by Greg Falcon <gfalcon@google.com> GitOrigin-RevId: b527a3e4b36b644ac424e3c525b1cd393f6f6c40 Change-Id: I14e331d91c956ef045ac7927091a9f179716de0c
2017-09-24 17:20:48 +02:00
// Functions required to support absl::Time flags.
Export of internal Abseil changes -- f13697e3d33803f9667d124072da4f6dd8bfbf85 by Andy Soffer <asoffer@google.com>: Addressing https://github.com/abseil/abseil-cpp/issues/314, fixing CMakeLists.txt to reference ABSL_TEST_COPTS rather than ABSL_DEFAULT_COPTS. ABSL_TEST_COPTS should be preferred for all tests so that they are configured consistently (moreover, CMake should agree with Bazel). PiperOrigin-RevId: 274932312 -- c31c24a1fa6bb98136adf51ef37c0818ac366690 by Derek Mauro <dmauro@google.com>: Silence MSAN in the stack consumption test utility PiperOrigin-RevId: 274912950 -- 2412913c05a246cd527cd4c31452f126e9129f3a by CJ Johnson <johnsoncj@google.com>: Internal change PiperOrigin-RevId: 274847103 -- 75e984a93b5760873501b96ac3229ccfd955daf8 by Abseil Team <absl-team@google.com>: Reformat BUILD file to current standards. PiperOrigin-RevId: 274815392 -- a2780e085f1df1e4ca2c814a58c893d1b78a1d9c by Samuel Benzaquen <sbenza@google.com>: Fix invalid result regarding leading zeros in the exponent. PiperOrigin-RevId: 274808017 -- dd402e1cb5c4ebacb576372ae24bf289d729d323 by Samuel Benzaquen <sbenza@google.com>: Make string_view's relational operators constexpr when possible. PiperOrigin-RevId: 274807873 -- b4ef32565653a5da1cb8bb8d0351586d23519658 by Abseil Team <absl-team@google.com>: Internal rework. PiperOrigin-RevId: 274787159 -- 70d81971c5914e6785b8e8a9d4f6eb2655dd62c0 by Gennadiy Rozental <rogeeff@google.com>: Internal rework. PiperOrigin-RevId: 274715557 -- 14f5b0440e353b899cafaaa15b53e77f98f401af by Gennadiy Rozental <rogeeff@google.com>: Make deprecated statements about ParseFLag/UnparseFlag consistent in a file. PiperOrigin-RevId: 274668123 -- 2e85adbdbb92612e4d750bc34fbca3333128b42d by Abseil Team <absl-team@google.com>: Allow absl::c_equal to be used with arrays. This is achieved by allowing container size computation for arrays. PiperOrigin-RevId: 274426830 -- 219719f107226d328773e6cec99fb473f5d3119c by Gennadiy Rozental <rogeeff@google.com>: Release correct extension interfaces to support usage of absl::Time and absl::Duration as ABSL_FLAG PiperOrigin-RevId: 274273788 -- 47a77f93fda23b69b4a6bdbd506fe643c69a5579 by Gennadiy Rozental <rogeeff@google.com>: Rework of flags persistence/FlagSaver internals. PiperOrigin-RevId: 274225213 -- 7807be3fe757c19e3b0c487298387683d4c9f5b3 by Abseil Team <absl-team@google.com>: Switch reference to sdkddkver.h to lowercase, matching conventions used in the Windows SDK and other uses. This helps to avoid confusion on case-sensitive filesystems. PiperOrigin-RevId: 274061877 -- 561304090087a19f1d10f0475f564fe132ebf06e by Andy Getzendanner <durandal@google.com>: Fix ABSL_WAITER_MODE detection for mingw Import of https://github.com/abseil/abseil-cpp/pull/342 PiperOrigin-RevId: 274030071 -- 9b3caac2cf202b9d440dfa1b4ffd538ac4bf715b by Derek Mauro <dmauro@google.com>: Support using Abseil with the musl libc implementation. Only test changes were required: * Workaround for a bug in sigaltstack() on musl * printf-style pointer formatting (%p) is implementation defined, so verify StrFromat produces something compatible * Fix detection of feenableexcept() PiperOrigin-RevId: 274011666 -- 73e8a938fc139e1cc8670d4513a445bacc855539 by Abseil Team <absl-team@google.com>: nvcc workaround: explicitly specify the definition of node_handle::Base PiperOrigin-RevId: 274011392 -- ab9cc6d042aca7d48e16c504ab10eab39433f4b2 by Andy Soffer <asoffer@google.com>: Internal change PiperOrigin-RevId: 273996318 -- e567c4979ca99c7e71821ec1523b8f5edd2c76ac by Abseil Team <absl-team@google.com>: Introduce a type alias to work around an nvcc bug. On the previous code, nvcc gets confused thinking that T has to be a parameter pack, as IsDecomposable accepts one. PiperOrigin-RevId: 273980472 -- 105b6e6339b77a32f4432de05f44cd3f9c436751 by Eric Fiselier <ericwf@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 273955589 -- 8feb87ff1d7e721fe094855e67c19539d5e582b7 by Abseil Team <absl-team@google.com>: Avoid dual-exporting scheduling_mode.h PiperOrigin-RevId: 273825112 -- fbc37854776d295dae98fb9d06a541f296daab95 by Andy Getzendanner <durandal@google.com>: Fix ABSL_HAVE_ALARM check on mingw Import of https://github.com/abseil/abseil-cpp/pull/341 PiperOrigin-RevId: 273817839 -- 6aedcd63a735b9133e143b043744ba0a25407f6f by Andy Soffer <asoffer@google.com>: Remove bit_gen_view.h now that all callers have been migrated to bit_gen_ref.h Tested: TGP - https://test.corp.google.com/ui#id=OCL:273762409:BASE:273743370:1570639020744:3001bcb5 PiperOrigin-RevId: 273810331 -- 6573de24a66ba715c579f7f32b5c48a1d743c7f8 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 273589963 -- 91c8c28b6dca26d98b39e8e06a8ed17c701ff793 by Abseil Team <absl-team@google.com>: Update macro name for `ABSL_GUARDED_BY()` in the example section. PiperOrigin-RevId: 273286983 -- 0ff7d1a93d70f8ecd693f8dbb98b7a4a016ca2a4 by Abseil Team <absl-team@google.com>: Fix potential integer overflow in the absl time library. In absl::FromTM, the tm.tm_year is added by 1900 regarding that tm.tm_year represents the years since 1900. This change checks integer overflow before doing the arithmetic operation. PiperOrigin-RevId: 273092952 -- b41c2a1310086807be09a833099ae6d4009f037c by Gennadiy Rozental <rogeeff@google.com>: Correctly Unlock the global mutex in case of concurrent flag initialization. Fixes #386 PiperOrigin-RevId: 272979749 -- c53103e71b2a6063af3c6d4ff68aa2d8f9ae9e06 by Abseil Team <absl-team@google.com>: Try to become idle only when there is no wakeup. Immediately after waking up (when futex wait returns), the current thread tries to become idle doing bunch of memory loads and a branch. Problem is that there is a good chance that we woke up due to a wakeup, especially for actively used threads. For such wakeups, calling MaybeBecomeIdle() would be a waste of cycles. Instead, call MaybeBecomeIdle() only when we are sure there is no wakeup. For idle threads the net effect should be the same. For active, threads this will be more efficient. Moreover, since MaybeBecomeIdle() is called before waiting on the futex, the current thread will try to become idle before sleeping. This should result in more accurate idleness and more efficient release of thread resources. PiperOrigin-RevId: 272940381 GitOrigin-RevId: f13697e3d33803f9667d124072da4f6dd8bfbf85 Change-Id: I36de05aec12595183725652dd362dfa58fb095d0
2019-10-16 03:18:40 +02:00
bool AbslParseFlag(absl::string_view text, absl::Time* t, std::string* error) {
return absl::ParseTime(RFC3339_full, std::string(text), absl::UTCTimeZone(),
t, error);
}
std::string AbslUnparseFlag(absl::Time t) {
return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone());
}
2017-09-19 22:54:40 +02:00
bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) {
return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error);
}
std::string UnparseFlag(absl::Time t) {
return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone());
}
Export of internal Abseil changes -- c99f979ad34f155fbeeea69b88bdc7458d89a21c by Derek Mauro <dmauro@google.com>: Remove a floating point division by zero test. This isn't testing behavior related to the library, and MSVC warns about it in opt mode. PiperOrigin-RevId: 285220804 -- 68b015491f0dbf1ab547994673281abd1f34cd4b by Gennadiy Rozental <rogeeff@google.com>: This CL introduces following changes to the class FlagImpl: * We eliminate the CommandLineFlagLocks struct. Instead callback guard and callback function are combined into a single CallbackData struct, while primary data lock is stored separately. * CallbackData member of class FlagImpl is initially set to be nullptr and is only allocated and initialized when a flag's callback is being set. For most flags we do not pay for the extra space and extra absl::Mutex now. * Primary data guard is stored in data_guard_ data member. This is a properly aligned character buffer of necessary size. During initialization of the flag we construct absl::Mutex in this space using placement new call. * We now avoid extra value copy after successful attempt to parse value out of string. Instead we swap flag's current value with tentative value we just produced. PiperOrigin-RevId: 285132636 -- ed45d118fb818969eb13094cf7827c885dfc562c by Tom Manshreck <shreck@google.com>: Change null-term* (and nul-term*) to NUL-term* in comments PiperOrigin-RevId: 285036610 -- 729619017944db895ce8d6d29c1995aa2e5628a5 by Derek Mauro <dmauro@google.com>: Use the Posix implementation of thread identity on MinGW. Some versions of MinGW suffer from thread_local bugs. PiperOrigin-RevId: 285022920 -- 39a25493503c76885bc3254c28f66a251c5b5bb0 by Greg Falcon <gfalcon@google.com>: Implementation detail change. Add further ABSL_NAMESPACE_BEGIN and _END annotation macros to files in Abseil. PiperOrigin-RevId: 285012012 GitOrigin-RevId: c99f979ad34f155fbeeea69b88bdc7458d89a21c Change-Id: I4c85d3704e45d11a9ac50d562f39640a6adbedc1
2019-12-12 19:36:03 +01:00
ABSL_NAMESPACE_END
2017-09-19 22:54:40 +02:00
} // namespace absl