You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ja...@apache.org on 2018/06/18 18:35:26 UTC
[07/62] [abbrv] [partial] marmotta git commit: * Replace gtest with
upstream version,
including LICENSE header. * Include absl library for faster and safer string
operations. * Update license headers where needed. * Removed custom code
replaced by absl.
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_test.cc
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_test.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_test.cc
new file mode 100644
index 0000000..6408388
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_test.cc
@@ -0,0 +1,1088 @@
+// 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
+//
+// http://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 "absl/time/time.h"
+
+#include <chrono> // NOLINT(build/c++11)
+#include <cstring>
+#include <ctime>
+#include <iomanip>
+#include <limits>
+#include <string>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/time/clock.h"
+#include "absl/time/internal/test_util.h"
+
+namespace {
+
+// A gMock matcher to match timespec values. Use this matcher like:
+// timespec ts1, ts2;
+// EXPECT_THAT(ts1, TimespecMatcher(ts2));
+MATCHER_P(TimespecMatcher, ts, "") {
+ if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec)
+ return true;
+ *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} ";
+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}";
+ return false;
+}
+
+// A gMock matcher to match timeval values. Use this matcher like:
+// timeval tv1, tv2;
+// EXPECT_THAT(tv1, TimevalMatcher(tv2));
+MATCHER_P(TimevalMatcher, tv, "") {
+ if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec)
+ return true;
+ *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} ";
+ *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}";
+ return false;
+}
+
+TEST(Time, ConstExpr) {
+ constexpr absl::Time t0 = absl::UnixEpoch();
+ static_assert(t0 == absl::Time(), "UnixEpoch");
+ constexpr absl::Time t1 = absl::InfiniteFuture();
+ static_assert(t1 != absl::Time(), "InfiniteFuture");
+ constexpr absl::Time t2 = absl::InfinitePast();
+ static_assert(t2 != absl::Time(), "InfinitePast");
+ constexpr absl::Time t3 = absl::FromUnixNanos(0);
+ static_assert(t3 == absl::Time(), "FromUnixNanos");
+ constexpr absl::Time t4 = absl::FromUnixMicros(0);
+ static_assert(t4 == absl::Time(), "FromUnixMicros");
+ constexpr absl::Time t5 = absl::FromUnixMillis(0);
+ static_assert(t5 == absl::Time(), "FromUnixMillis");
+ constexpr absl::Time t6 = absl::FromUnixSeconds(0);
+ static_assert(t6 == absl::Time(), "FromUnixSeconds");
+ constexpr absl::Time t7 = absl::FromTimeT(0);
+ static_assert(t7 == absl::Time(), "FromTimeT");
+}
+
+TEST(Time, ValueSemantics) {
+ absl::Time a; // Default construction
+ absl::Time b = a; // Copy construction
+ EXPECT_EQ(a, b);
+ absl::Time c(a); // Copy construction (again)
+ EXPECT_EQ(a, b);
+ EXPECT_EQ(a, c);
+ EXPECT_EQ(b, c);
+ b = c; // Assignment
+ EXPECT_EQ(a, b);
+ EXPECT_EQ(a, c);
+ EXPECT_EQ(b, c);
+}
+
+TEST(Time, UnixEpoch) {
+ absl::Time::Breakdown bd = absl::UnixEpoch().In(absl::UTCTimeZone());
+ ABSL_INTERNAL_EXPECT_TIME(bd, 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond);
+ EXPECT_EQ(4, bd.weekday); // Thursday
+}
+
+TEST(Time, Breakdown) {
+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/New_York");
+ absl::Time t = absl::UnixEpoch();
+
+ // The Unix epoch as seen in NYC.
+ absl::Time::Breakdown bd = t.In(tz);
+ ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 19, 0, 0, -18000, false, "EST");
+ EXPECT_EQ(absl::ZeroDuration(), bd.subsecond);
+ EXPECT_EQ(3, bd.weekday); // Wednesday
+
+ // Just before the epoch.
+ t -= absl::Nanoseconds(1);
+ bd = t.In(tz);
+ ABSL_INTERNAL_EXPECT_TIME(bd, 1969, 12, 31, 18, 59, 59, -18000, false, "EST");
+ EXPECT_EQ(absl::Nanoseconds(999999999), bd.subsecond);
+ EXPECT_EQ(3, bd.weekday); // Wednesday
+
+ // Some time later.
+ t += absl::Hours(24) * 2735;
+ t += absl::Hours(18) + absl::Minutes(30) + absl::Seconds(15) +
+ absl::Nanoseconds(9);
+ bd = t.In(tz);
+ ABSL_INTERNAL_EXPECT_TIME(bd, 1977, 6, 28, 14, 30, 15, -14400, true, "EDT");
+ EXPECT_EQ(8, bd.subsecond / absl::Nanoseconds(1));
+ EXPECT_EQ(2, bd.weekday); // Tuesday
+}
+
+TEST(Time, AdditiveOperators) {
+ const absl::Duration d = absl::Nanoseconds(1);
+ const absl::Time t0;
+ const absl::Time t1 = t0 + d;
+
+ EXPECT_EQ(d, t1 - t0);
+ EXPECT_EQ(-d, t0 - t1);
+ EXPECT_EQ(t0, t1 - d);
+
+ absl::Time t(t0);
+ EXPECT_EQ(t0, t);
+ t += d;
+ EXPECT_EQ(t0 + d, t);
+ EXPECT_EQ(d, t - t0);
+ t -= d;
+ EXPECT_EQ(t0, t);
+
+ // Tests overflow between subseconds and seconds.
+ t = absl::UnixEpoch();
+ t += absl::Milliseconds(500);
+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t);
+ t += absl::Milliseconds(600);
+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(1100), t);
+ t -= absl::Milliseconds(600);
+ EXPECT_EQ(absl::UnixEpoch() + absl::Milliseconds(500), t);
+ t -= absl::Milliseconds(500);
+ EXPECT_EQ(absl::UnixEpoch(), t);
+}
+
+TEST(Time, RelationalOperators) {
+ constexpr absl::Time t1 = absl::FromUnixNanos(0);
+ constexpr absl::Time t2 = absl::FromUnixNanos(1);
+ constexpr absl::Time t3 = absl::FromUnixNanos(2);
+
+ static_assert(absl::Time() == t1, "");
+ static_assert(t1 == t1, "");
+ static_assert(t2 == t2, "");
+ static_assert(t3 == t3, "");
+
+ static_assert(t1 < t2, "");
+ static_assert(t2 < t3, "");
+ static_assert(t1 < t3, "");
+
+ static_assert(t1 <= t1, "");
+ static_assert(t1 <= t2, "");
+ static_assert(t2 <= t2, "");
+ static_assert(t2 <= t3, "");
+ static_assert(t3 <= t3, "");
+ static_assert(t1 <= t3, "");
+
+ static_assert(t2 > t1, "");
+ static_assert(t3 > t2, "");
+ static_assert(t3 > t1, "");
+
+ static_assert(t2 >= t2, "");
+ static_assert(t2 >= t1, "");
+ static_assert(t3 >= t3, "");
+ static_assert(t3 >= t2, "");
+ static_assert(t1 >= t1, "");
+ static_assert(t3 >= t1, "");
+}
+
+TEST(Time, Infinity) {
+ constexpr absl::Time ifuture = absl::InfiniteFuture();
+ constexpr absl::Time ipast = absl::InfinitePast();
+
+ static_assert(ifuture == ifuture, "");
+ static_assert(ipast == ipast, "");
+ static_assert(ipast < ifuture, "");
+ static_assert(ifuture > ipast, "");
+
+ // Arithmetic saturates
+ EXPECT_EQ(ifuture, ifuture + absl::Seconds(1));
+ EXPECT_EQ(ifuture, ifuture - absl::Seconds(1));
+ EXPECT_EQ(ipast, ipast + absl::Seconds(1));
+ EXPECT_EQ(ipast, ipast - absl::Seconds(1));
+
+ EXPECT_EQ(absl::InfiniteDuration(), ifuture - ifuture);
+ EXPECT_EQ(absl::InfiniteDuration(), ifuture - ipast);
+ EXPECT_EQ(-absl::InfiniteDuration(), ipast - ifuture);
+ EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast);
+
+ constexpr absl::Time t = absl::UnixEpoch(); // Any finite time.
+ static_assert(t < ifuture, "");
+ static_assert(t > ipast, "");
+}
+
+TEST(Time, FloorConversion) {
+#define TEST_FLOOR_CONVERSION(TO, FROM) \
+ EXPECT_EQ(1, TO(FROM(1001))); \
+ EXPECT_EQ(1, TO(FROM(1000))); \
+ EXPECT_EQ(0, TO(FROM(999))); \
+ EXPECT_EQ(0, TO(FROM(1))); \
+ EXPECT_EQ(0, TO(FROM(0))); \
+ EXPECT_EQ(-1, TO(FROM(-1))); \
+ EXPECT_EQ(-1, TO(FROM(-999))); \
+ EXPECT_EQ(-1, TO(FROM(-1000))); \
+ EXPECT_EQ(-2, TO(FROM(-1001)));
+
+ TEST_FLOOR_CONVERSION(absl::ToUnixMicros, absl::FromUnixNanos);
+ TEST_FLOOR_CONVERSION(absl::ToUnixMillis, absl::FromUnixMicros);
+ TEST_FLOOR_CONVERSION(absl::ToUnixSeconds, absl::FromUnixMillis);
+ TEST_FLOOR_CONVERSION(absl::ToTimeT, absl::FromUnixMillis);
+
+#undef TEST_FLOOR_CONVERSION
+
+ // Tests ToUnixNanos.
+ EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(3) / 2));
+ EXPECT_EQ(1, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1)));
+ EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(1) / 2));
+ EXPECT_EQ(0, absl::ToUnixNanos(absl::UnixEpoch() + absl::Nanoseconds(0)));
+ EXPECT_EQ(-1,
+ absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1) / 2));
+ EXPECT_EQ(-1, absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(1)));
+ EXPECT_EQ(-2,
+ absl::ToUnixNanos(absl::UnixEpoch() - absl::Nanoseconds(3) / 2));
+
+ // Tests ToUniversal, which uses a different epoch than the tests above.
+ EXPECT_EQ(1,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(101)));
+ EXPECT_EQ(1,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(100)));
+ EXPECT_EQ(0,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(99)));
+ EXPECT_EQ(0,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(1)));
+ EXPECT_EQ(0,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(0)));
+ EXPECT_EQ(-1,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-1)));
+ EXPECT_EQ(-1,
+ absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-99)));
+ EXPECT_EQ(
+ -1, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-100)));
+ EXPECT_EQ(
+ -2, absl::ToUniversal(absl::UniversalEpoch() + absl::Nanoseconds(-101)));
+
+ // Tests ToTimespec()/TimeFromTimespec()
+ const struct {
+ absl::Time t;
+ timespec ts;
+ } to_ts[] = {
+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(1), {1, 1}},
+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(1) / 2, {1, 0}},
+ {absl::FromUnixSeconds(1) + absl::Nanoseconds(0), {1, 0}},
+ {absl::FromUnixSeconds(0) + absl::Nanoseconds(0), {0, 0}},
+ {absl::FromUnixSeconds(0) - absl::Nanoseconds(1) / 2, {-1, 999999999}},
+ {absl::FromUnixSeconds(0) - absl::Nanoseconds(1), {-1, 999999999}},
+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1), {-1, 1}},
+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(1) / 2, {-1, 0}},
+ {absl::FromUnixSeconds(-1) + absl::Nanoseconds(0), {-1, 0}},
+ {absl::FromUnixSeconds(-1) - absl::Nanoseconds(1) / 2, {-2, 999999999}},
+ };
+ for (const auto& test : to_ts) {
+ EXPECT_THAT(absl::ToTimespec(test.t), TimespecMatcher(test.ts));
+ }
+ const struct {
+ timespec ts;
+ absl::Time t;
+ } from_ts[] = {
+ {{1, 1}, absl::FromUnixSeconds(1) + absl::Nanoseconds(1)},
+ {{1, 0}, absl::FromUnixSeconds(1) + absl::Nanoseconds(0)},
+ {{0, 0}, absl::FromUnixSeconds(0) + absl::Nanoseconds(0)},
+ {{0, -1}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)},
+ {{-1, 999999999}, absl::FromUnixSeconds(0) - absl::Nanoseconds(1)},
+ {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(1)},
+ {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Nanoseconds(0)},
+ {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)},
+ {{-2, 999999999}, absl::FromUnixSeconds(-1) - absl::Nanoseconds(1)},
+ };
+ for (const auto& test : from_ts) {
+ EXPECT_EQ(test.t, absl::TimeFromTimespec(test.ts));
+ }
+
+ // Tests ToTimeval()/TimeFromTimeval() (same as timespec above)
+ const struct {
+ absl::Time t;
+ timeval tv;
+ } to_tv[] = {
+ {absl::FromUnixSeconds(1) + absl::Microseconds(1), {1, 1}},
+ {absl::FromUnixSeconds(1) + absl::Microseconds(1) / 2, {1, 0}},
+ {absl::FromUnixSeconds(1) + absl::Microseconds(0), {1, 0}},
+ {absl::FromUnixSeconds(0) + absl::Microseconds(0), {0, 0}},
+ {absl::FromUnixSeconds(0) - absl::Microseconds(1) / 2, {-1, 999999}},
+ {absl::FromUnixSeconds(0) - absl::Microseconds(1), {-1, 999999}},
+ {absl::FromUnixSeconds(-1) + absl::Microseconds(1), {-1, 1}},
+ {absl::FromUnixSeconds(-1) + absl::Microseconds(1) / 2, {-1, 0}},
+ {absl::FromUnixSeconds(-1) + absl::Microseconds(0), {-1, 0}},
+ {absl::FromUnixSeconds(-1) - absl::Microseconds(1) / 2, {-2, 999999}},
+ };
+ for (const auto& test : to_tv) {
+ EXPECT_THAT(ToTimeval(test.t), TimevalMatcher(test.tv));
+ }
+ const struct {
+ timeval tv;
+ absl::Time t;
+ } from_tv[] = {
+ {{1, 1}, absl::FromUnixSeconds(1) + absl::Microseconds(1)},
+ {{1, 0}, absl::FromUnixSeconds(1) + absl::Microseconds(0)},
+ {{0, 0}, absl::FromUnixSeconds(0) + absl::Microseconds(0)},
+ {{0, -1}, absl::FromUnixSeconds(0) - absl::Microseconds(1)},
+ {{-1, 999999}, absl::FromUnixSeconds(0) - absl::Microseconds(1)},
+ {{-1, 1}, absl::FromUnixSeconds(-1) + absl::Microseconds(1)},
+ {{-1, 0}, absl::FromUnixSeconds(-1) + absl::Microseconds(0)},
+ {{-1, -1}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)},
+ {{-2, 999999}, absl::FromUnixSeconds(-1) - absl::Microseconds(1)},
+ };
+ for (const auto& test : from_tv) {
+ EXPECT_EQ(test.t, absl::TimeFromTimeval(test.tv));
+ }
+
+ // Tests flooring near negative infinity.
+ const int64_t min_plus_1 = std::numeric_limits<int64_t>::min() + 1;
+ EXPECT_EQ(min_plus_1, absl::ToUnixSeconds(absl::FromUnixSeconds(min_plus_1)));
+ EXPECT_EQ(std::numeric_limits<int64_t>::min(),
+ absl::ToUnixSeconds(
+ absl::FromUnixSeconds(min_plus_1) - absl::Nanoseconds(1) / 2));
+
+ // Tests flooring near positive infinity.
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(),
+ absl::ToUnixSeconds(absl::FromUnixSeconds(
+ std::numeric_limits<int64_t>::max()) + absl::Nanoseconds(1) / 2));
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(),
+ absl::ToUnixSeconds(
+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max())));
+ EXPECT_EQ(std::numeric_limits<int64_t>::max() - 1,
+ absl::ToUnixSeconds(absl::FromUnixSeconds(
+ std::numeric_limits<int64_t>::max()) - absl::Nanoseconds(1) / 2));
+}
+
+TEST(Time, RoundtripConversion) {
+#define TEST_CONVERSION_ROUND_TRIP(SOURCE, FROM, TO, MATCHER) \
+ EXPECT_THAT(TO(FROM(SOURCE)), MATCHER(SOURCE))
+
+ // FromUnixNanos() and ToUnixNanos()
+ int64_t now_ns = absl::GetCurrentTimeNanos();
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixNanos, absl::ToUnixNanos,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixNanos, absl::ToUnixNanos,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixNanos, absl::ToUnixNanos,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_ns, absl::FromUnixNanos, absl::ToUnixNanos,
+ testing::Eq)
+ << now_ns;
+
+ // FromUnixMicros() and ToUnixMicros()
+ int64_t now_us = absl::GetCurrentTimeNanos() / 1000;
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMicros, absl::ToUnixMicros,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMicros, absl::ToUnixMicros,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMicros, absl::ToUnixMicros,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_us, absl::FromUnixMicros, absl::ToUnixMicros,
+ testing::Eq)
+ << now_us;
+
+ // FromUnixMillis() and ToUnixMillis()
+ int64_t now_ms = absl::GetCurrentTimeNanos() / 1000000;
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixMillis, absl::ToUnixMillis,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixMillis, absl::ToUnixMillis,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixMillis, absl::ToUnixMillis,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_ms, absl::FromUnixMillis, absl::ToUnixMillis,
+ testing::Eq)
+ << now_ms;
+
+ // FromUnixSeconds() and ToUnixSeconds()
+ int64_t now_s = std::time(nullptr);
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUnixSeconds, absl::ToUnixSeconds,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUnixSeconds, absl::ToUnixSeconds,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUnixSeconds, absl::ToUnixSeconds,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_s, absl::FromUnixSeconds, absl::ToUnixSeconds,
+ testing::Eq)
+ << now_s;
+
+ // FromTimeT() and ToTimeT()
+ time_t now_time_t = std::time(nullptr);
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromTimeT, absl::ToTimeT, testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromTimeT, absl::ToTimeT, testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromTimeT, absl::ToTimeT, testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_time_t, absl::FromTimeT, absl::ToTimeT,
+ testing::Eq)
+ << now_time_t;
+
+ // TimeFromTimeval() and ToTimeval()
+ timeval tv;
+ tv.tv_sec = -1;
+ tv.tv_usec = 0;
+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
+ TimevalMatcher);
+ tv.tv_sec = -1;
+ tv.tv_usec = 999999;
+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
+ TimevalMatcher);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
+ TimevalMatcher);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
+ TimevalMatcher);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ TEST_CONVERSION_ROUND_TRIP(tv, absl::TimeFromTimeval, absl::ToTimeval,
+ TimevalMatcher);
+
+ // TimeFromTimespec() and ToTimespec()
+ timespec ts;
+ ts.tv_sec = -1;
+ ts.tv_nsec = 0;
+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
+ TimespecMatcher);
+ ts.tv_sec = -1;
+ ts.tv_nsec = 999999999;
+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
+ TimespecMatcher);
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
+ TimespecMatcher);
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
+ TimespecMatcher);
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ TEST_CONVERSION_ROUND_TRIP(ts, absl::TimeFromTimespec, absl::ToTimespec,
+ TimespecMatcher);
+
+ // FromUDate() and ToUDate()
+ double now_ud = absl::GetCurrentTimeNanos() / 1000000;
+ TEST_CONVERSION_ROUND_TRIP(-1.5, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(-0.5, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(0.5, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(1.5, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq);
+ TEST_CONVERSION_ROUND_TRIP(now_ud, absl::FromUDate, absl::ToUDate,
+ testing::DoubleEq)
+ << std::fixed << std::setprecision(17) << now_ud;
+
+ // FromUniversal() and ToUniversal()
+ int64_t now_uni = ((719162LL * (24 * 60 * 60)) * (1000 * 1000 * 10)) +
+ (absl::GetCurrentTimeNanos() / 100);
+ TEST_CONVERSION_ROUND_TRIP(-1, absl::FromUniversal, absl::ToUniversal,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(0, absl::FromUniversal, absl::ToUniversal,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(1, absl::FromUniversal, absl::ToUniversal,
+ testing::Eq);
+ TEST_CONVERSION_ROUND_TRIP(now_uni, absl::FromUniversal, absl::ToUniversal,
+ testing::Eq)
+ << now_uni;
+
+#undef TEST_CONVERSION_ROUND_TRIP
+}
+
+template <typename Duration>
+std::chrono::system_clock::time_point MakeChronoUnixTime(const Duration& d) {
+ return std::chrono::system_clock::from_time_t(0) + d;
+}
+
+TEST(Time, FromChrono) {
+ EXPECT_EQ(absl::FromTimeT(-1),
+ absl::FromChrono(std::chrono::system_clock::from_time_t(-1)));
+ EXPECT_EQ(absl::FromTimeT(0),
+ absl::FromChrono(std::chrono::system_clock::from_time_t(0)));
+ EXPECT_EQ(absl::FromTimeT(1),
+ absl::FromChrono(std::chrono::system_clock::from_time_t(1)));
+
+ EXPECT_EQ(
+ absl::FromUnixMillis(-1),
+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(-1))));
+ EXPECT_EQ(absl::FromUnixMillis(0),
+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(0))));
+ EXPECT_EQ(absl::FromUnixMillis(1),
+ absl::FromChrono(MakeChronoUnixTime(std::chrono::milliseconds(1))));
+
+ // Chrono doesn't define exactly its range and precision (neither does
+ // absl::Time), so let's simply test +/- ~100 years to make sure things work.
+ const auto century_sec = 60 * 60 * 24 * 365 * int64_t{100};
+ const auto century = std::chrono::seconds(century_sec);
+ const auto chrono_future = MakeChronoUnixTime(century);
+ const auto chrono_past = MakeChronoUnixTime(-century);
+ EXPECT_EQ(absl::FromUnixSeconds(century_sec),
+ absl::FromChrono(chrono_future));
+ EXPECT_EQ(absl::FromUnixSeconds(-century_sec), absl::FromChrono(chrono_past));
+
+ // Roundtrip them both back to chrono.
+ EXPECT_EQ(chrono_future,
+ absl::ToChronoTime(absl::FromUnixSeconds(century_sec)));
+ EXPECT_EQ(chrono_past,
+ absl::ToChronoTime(absl::FromUnixSeconds(-century_sec)));
+}
+
+TEST(Time, ToChronoTime) {
+ EXPECT_EQ(std::chrono::system_clock::from_time_t(-1),
+ absl::ToChronoTime(absl::FromTimeT(-1)));
+ EXPECT_EQ(std::chrono::system_clock::from_time_t(0),
+ absl::ToChronoTime(absl::FromTimeT(0)));
+ EXPECT_EQ(std::chrono::system_clock::from_time_t(1),
+ absl::ToChronoTime(absl::FromTimeT(1)));
+
+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(-1)),
+ absl::ToChronoTime(absl::FromUnixMillis(-1)));
+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(0)),
+ absl::ToChronoTime(absl::FromUnixMillis(0)));
+ EXPECT_EQ(MakeChronoUnixTime(std::chrono::milliseconds(1)),
+ absl::ToChronoTime(absl::FromUnixMillis(1)));
+
+ // Time before the Unix epoch should floor, not trunc.
+ const auto tick = absl::Nanoseconds(1) / 4;
+ EXPECT_EQ(std::chrono::system_clock::from_time_t(0) -
+ std::chrono::system_clock::duration(1),
+ absl::ToChronoTime(absl::UnixEpoch() - tick));
+}
+
+TEST(Time, ConvertDateTime) {
+ const absl::TimeZone utc = absl::UTCTimeZone();
+ const absl::TimeZone goog =
+ absl::time_internal::LoadTimeZone("America/Los_Angeles");
+ const absl::TimeZone nyc =
+ absl::time_internal::LoadTimeZone("America/New_York");
+ const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)";
+
+ // A simple case of normalization.
+ absl::TimeConversion oct32 = ConvertDateTime(2013, 10, 32, 8, 30, 0, goog);
+ EXPECT_TRUE(oct32.normalized);
+ EXPECT_EQ(absl::TimeConversion::UNIQUE, oct32.kind);
+ absl::TimeConversion nov01 = ConvertDateTime(2013, 11, 1, 8, 30, 0, goog);
+ EXPECT_FALSE(nov01.normalized);
+ EXPECT_EQ(absl::TimeConversion::UNIQUE, nov01.kind);
+ EXPECT_EQ(oct32.pre, nov01.pre);
+ EXPECT_EQ("Fri, 1 Nov 2013 08:30:00 -0700 (PDT)",
+ absl::FormatTime(fmt, nov01.pre, goog));
+
+ // A Spring DST transition, when there is a gap in civil time
+ // and we prefer the later of the possible interpretations of a
+ // non-existent time.
+ absl::TimeConversion mar13 = ConvertDateTime(2011, 3, 13, 2, 15, 0, nyc);
+ EXPECT_FALSE(mar13.normalized);
+ EXPECT_EQ(absl::TimeConversion::SKIPPED, mar13.kind);
+ EXPECT_EQ("Sun, 13 Mar 2011 03:15:00 -0400 (EDT)",
+ absl::FormatTime(fmt, mar13.pre, nyc));
+ EXPECT_EQ("Sun, 13 Mar 2011 03:00:00 -0400 (EDT)",
+ absl::FormatTime(fmt, mar13.trans, nyc));
+ EXPECT_EQ("Sun, 13 Mar 2011 01:15:00 -0500 (EST)",
+ absl::FormatTime(fmt, mar13.post, nyc));
+ EXPECT_EQ(mar13.pre, absl::FromDateTime(2011, 3, 13, 2, 15, 0, nyc));
+
+ // A Fall DST transition, when civil times are repeated and
+ // we prefer the earlier of the possible interpretations of an
+ // ambiguous time.
+ absl::TimeConversion nov06 = ConvertDateTime(2011, 11, 6, 1, 15, 0, nyc);
+ EXPECT_FALSE(nov06.normalized);
+ EXPECT_EQ(absl::TimeConversion::REPEATED, nov06.kind);
+ EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0400 (EDT)",
+ absl::FormatTime(fmt, nov06.pre, nyc));
+ EXPECT_EQ("Sun, 6 Nov 2011 01:00:00 -0500 (EST)",
+ absl::FormatTime(fmt, nov06.trans, nyc));
+ EXPECT_EQ("Sun, 6 Nov 2011 01:15:00 -0500 (EST)",
+ absl::FormatTime(fmt, nov06.post, nyc));
+ EXPECT_EQ(nov06.pre, absl::FromDateTime(2011, 11, 6, 1, 15, 0, nyc));
+
+ // Check that (time_t) -1 is handled correctly.
+ absl::TimeConversion minus1 = ConvertDateTime(1969, 12, 31, 18, 59, 59, nyc);
+ EXPECT_FALSE(minus1.normalized);
+ EXPECT_EQ(absl::TimeConversion::UNIQUE, minus1.kind);
+ EXPECT_EQ(-1, absl::ToTimeT(minus1.pre));
+ EXPECT_EQ("Wed, 31 Dec 1969 18:59:59 -0500 (EST)",
+ absl::FormatTime(fmt, minus1.pre, nyc));
+ EXPECT_EQ("Wed, 31 Dec 1969 23:59:59 +0000 (UTC)",
+ absl::FormatTime(fmt, minus1.pre, utc));
+}
+
+// FromDateTime(year, mon, day, hour, min, sec, UTCTimeZone()) has
+// a specialized fastpath implementation which we exercise here.
+TEST(Time, FromDateTimeUTC) {
+ const absl::TimeZone utc = absl::UTCTimeZone();
+ const std::string fmt = "%a, %e %b %Y %H:%M:%S %z (%Z)";
+ const int kMax = std::numeric_limits<int>::max();
+ const int kMin = std::numeric_limits<int>::min();
+ absl::Time t;
+
+ // 292091940881 is the last positive year to use the fastpath.
+ t = absl::FromDateTime(292091940881, kMax, kMax, kMax, kMax, kMax, utc);
+ EXPECT_EQ("Fri, 25 Nov 292277026596 12:21:07 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+ t = absl::FromDateTime(292091940882, kMax, kMax, kMax, kMax, kMax, utc);
+ EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow
+ t = absl::FromDateTime(
+ std::numeric_limits<int64_t>::max(), kMax, kMax, kMax, kMax, kMax, utc);
+ EXPECT_EQ("infinite-future", absl::FormatTime(fmt, t, utc)); // no overflow
+
+ // -292091936940 is the last negative year to use the fastpath.
+ t = absl::FromDateTime(-292091936940, kMin, kMin, kMin, kMin, kMin, utc);
+ EXPECT_EQ("Fri, 1 Nov -292277022657 10:37:52 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+ t = absl::FromDateTime(-292091936941, kMin, kMin, kMin, kMin, kMin, utc);
+ EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no underflow
+ t = absl::FromDateTime(
+ std::numeric_limits<int64_t>::min(), kMin, kMin, kMin, kMin, kMin, utc);
+ EXPECT_EQ("infinite-past", absl::FormatTime(fmt, t, utc)); // no overflow
+
+ // Check that we're counting leap years correctly.
+ t = absl::FromDateTime(1900, 2, 28, 23, 59, 59, utc);
+ EXPECT_EQ("Wed, 28 Feb 1900 23:59:59 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+ t = absl::FromDateTime(1900, 3, 1, 0, 0, 0, utc);
+ EXPECT_EQ("Thu, 1 Mar 1900 00:00:00 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+ t = absl::FromDateTime(2000, 2, 29, 23, 59, 59, utc);
+ EXPECT_EQ("Tue, 29 Feb 2000 23:59:59 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+ t = absl::FromDateTime(2000, 3, 1, 0, 0, 0, utc);
+ EXPECT_EQ("Wed, 1 Mar 2000 00:00:00 +0000 (UTC)",
+ absl::FormatTime(fmt, t, utc));
+
+ // Check normalization.
+ const std::string ymdhms = "%Y-%m-%d %H:%M:%S";
+ t = absl::FromDateTime(2015, 1, 1, 0, 0, 60, utc);
+ EXPECT_EQ("2015-01-01 00:01:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 1, 0, 60, 0, utc);
+ EXPECT_EQ("2015-01-01 01:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 1, 24, 0, 0, utc);
+ EXPECT_EQ("2015-01-02 00:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 32, 0, 0, 0, utc);
+ EXPECT_EQ("2015-02-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 13, 1, 0, 0, 0, utc);
+ EXPECT_EQ("2016-01-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 13, 32, 60, 60, 60, utc);
+ EXPECT_EQ("2016-02-03 13:01:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 1, 0, 0, -1, utc);
+ EXPECT_EQ("2014-12-31 23:59:59", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 1, 0, -1, 0, utc);
+ EXPECT_EQ("2014-12-31 23:59:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, 1, -1, 0, 0, utc);
+ EXPECT_EQ("2014-12-31 23:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, 1, -1, 0, 0, 0, utc);
+ EXPECT_EQ("2014-12-30 00:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, -1, 1, 0, 0, 0, utc);
+ EXPECT_EQ("2014-11-01 00:00:00", absl::FormatTime(ymdhms, t, utc));
+ t = absl::FromDateTime(2015, -1, -1, -1, -1, -1, utc);
+ EXPECT_EQ("2014-10-29 22:58:59", absl::FormatTime(ymdhms, t, utc));
+}
+
+TEST(Time, ToTM) {
+ const absl::TimeZone utc = absl::UTCTimeZone();
+
+ // Compares the results of ToTM() to gmtime_r() for lots of times over the
+ // course of a few days.
+ const absl::Time start = absl::FromDateTime(2014, 1, 2, 3, 4, 5, utc);
+ const absl::Time end = absl::FromDateTime(2014, 1, 5, 3, 4, 5, utc);
+ for (absl::Time t = start; t < end; t += absl::Seconds(30)) {
+ const struct tm tm_bt = ToTM(t, utc);
+ const time_t tt = absl::ToTimeT(t);
+ struct tm tm_lc;
+#ifdef _WIN32
+ gmtime_s(&tm_lc, &tt);
+#else
+ gmtime_r(&tt, &tm_lc);
+#endif
+ EXPECT_EQ(tm_lc.tm_year, tm_bt.tm_year);
+ EXPECT_EQ(tm_lc.tm_mon, tm_bt.tm_mon);
+ EXPECT_EQ(tm_lc.tm_mday, tm_bt.tm_mday);
+ EXPECT_EQ(tm_lc.tm_hour, tm_bt.tm_hour);
+ EXPECT_EQ(tm_lc.tm_min, tm_bt.tm_min);
+ EXPECT_EQ(tm_lc.tm_sec, tm_bt.tm_sec);
+ EXPECT_EQ(tm_lc.tm_wday, tm_bt.tm_wday);
+ EXPECT_EQ(tm_lc.tm_yday, tm_bt.tm_yday);
+ EXPECT_EQ(tm_lc.tm_isdst, tm_bt.tm_isdst);
+
+ ASSERT_FALSE(HasFailure());
+ }
+
+ // Checks that the tm_isdst field is correct when in standard time.
+ const absl::TimeZone nyc =
+ absl::time_internal::LoadTimeZone("America/New_York");
+ absl::Time t = absl::FromDateTime(2014, 3, 1, 0, 0, 0, nyc);
+ struct tm tm = ToTM(t, nyc);
+ EXPECT_FALSE(tm.tm_isdst);
+
+ // Checks that the tm_isdst field is correct when in daylight time.
+ t = absl::FromDateTime(2014, 4, 1, 0, 0, 0, nyc);
+ tm = ToTM(t, nyc);
+ EXPECT_TRUE(tm.tm_isdst);
+
+ // Checks overflow.
+ tm = ToTM(absl::InfiniteFuture(), nyc);
+ EXPECT_EQ(std::numeric_limits<int>::max() - 1900, tm.tm_year);
+ EXPECT_EQ(11, tm.tm_mon);
+ EXPECT_EQ(31, tm.tm_mday);
+ EXPECT_EQ(23, tm.tm_hour);
+ EXPECT_EQ(59, tm.tm_min);
+ EXPECT_EQ(59, tm.tm_sec);
+ EXPECT_EQ(4, tm.tm_wday);
+ EXPECT_EQ(364, tm.tm_yday);
+ EXPECT_FALSE(tm.tm_isdst);
+
+ // Checks underflow.
+ tm = ToTM(absl::InfinitePast(), nyc);
+ EXPECT_EQ(std::numeric_limits<int>::min(), tm.tm_year);
+ EXPECT_EQ(0, tm.tm_mon);
+ EXPECT_EQ(1, tm.tm_mday);
+ EXPECT_EQ(0, tm.tm_hour);
+ EXPECT_EQ(0, tm.tm_min);
+ EXPECT_EQ(0, tm.tm_sec);
+ EXPECT_EQ(0, tm.tm_wday);
+ EXPECT_EQ(0, tm.tm_yday);
+ EXPECT_FALSE(tm.tm_isdst);
+}
+
+TEST(Time, FromTM) {
+ const absl::TimeZone nyc =
+ absl::time_internal::LoadTimeZone("America/New_York");
+
+ // Verifies that tm_isdst doesn't affect anything when the time is unique.
+ struct tm tm;
+ std::memset(&tm, 0, sizeof(tm));
+ tm.tm_year = 2014 - 1900;
+ tm.tm_mon = 6 - 1;
+ tm.tm_mday = 28;
+ tm.tm_hour = 1;
+ tm.tm_min = 2;
+ tm.tm_sec = 3;
+ tm.tm_isdst = -1;
+ absl::Time t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
+ tm.tm_isdst = 0;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
+ tm.tm_isdst = 1;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-06-28T01:02:03-04:00", absl::FormatTime(t, nyc)); // DST
+
+ // Adjusts tm to refer to an ambiguous time.
+ tm.tm_year = 2014 - 1900;
+ tm.tm_mon = 11 - 1;
+ tm.tm_mday = 2;
+ tm.tm_hour = 1;
+ tm.tm_min = 30;
+ tm.tm_sec = 42;
+ tm.tm_isdst = -1;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST
+ tm.tm_isdst = 0;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-11-02T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD
+ tm.tm_isdst = 1;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-11-02T01:30:42-04:00", absl::FormatTime(t, nyc)); // DST
+
+ // Adjusts tm to refer to a skipped time.
+ tm.tm_year = 2014 - 1900;
+ tm.tm_mon = 3 - 1;
+ tm.tm_mday = 9;
+ tm.tm_hour = 2;
+ tm.tm_min = 30;
+ tm.tm_sec = 42;
+ tm.tm_isdst = -1;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST
+ tm.tm_isdst = 0;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-03-09T01:30:42-05:00", absl::FormatTime(t, nyc)); // STD
+ tm.tm_isdst = 1;
+ t = FromTM(tm, nyc);
+ EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST
+}
+
+TEST(Time, TMRoundTrip) {
+ const absl::TimeZone nyc =
+ absl::time_internal::LoadTimeZone("America/New_York");
+
+ // Test round-tripping across a skipped transition
+ absl::Time start = absl::FromDateTime(2014, 3, 9, 0, 0, 0, nyc);
+ absl::Time end = absl::FromDateTime(2014, 3, 9, 4, 0, 0, nyc);
+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
+ struct tm tm = ToTM(t, nyc);
+ absl::Time rt = FromTM(tm, nyc);
+ EXPECT_EQ(rt, t);
+ }
+
+ // Test round-tripping across an ambiguous transition
+ start = absl::FromDateTime(2014, 11, 2, 0, 0, 0, nyc);
+ end = absl::FromDateTime(2014, 11, 2, 4, 0, 0, nyc);
+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
+ struct tm tm = ToTM(t, nyc);
+ absl::Time rt = FromTM(tm, nyc);
+ EXPECT_EQ(rt, t);
+ }
+
+ // Test round-tripping of unique instants crossing a day boundary
+ start = absl::FromDateTime(2014, 6, 27, 22, 0, 0, nyc);
+ end = absl::FromDateTime(2014, 6, 28, 4, 0, 0, nyc);
+ for (absl::Time t = start; t < end; t += absl::Minutes(1)) {
+ struct tm tm = ToTM(t, nyc);
+ absl::Time rt = FromTM(tm, nyc);
+ EXPECT_EQ(rt, t);
+ }
+}
+
+TEST(Time, Range) {
+ // The API's documented range is +/- 100 billion years.
+ const absl::Duration range = absl::Hours(24) * 365.2425 * 100000000000;
+
+ // Arithmetic and comparison still works at +/-range around base values.
+ absl::Time bases[2] = {absl::UnixEpoch(), absl::Now()};
+ for (const auto base : bases) {
+ absl::Time bottom = base - range;
+ EXPECT_GT(bottom, bottom - absl::Nanoseconds(1));
+ EXPECT_LT(bottom, bottom + absl::Nanoseconds(1));
+ absl::Time top = base + range;
+ EXPECT_GT(top, top - absl::Nanoseconds(1));
+ EXPECT_LT(top, top + absl::Nanoseconds(1));
+ absl::Duration full_range = 2 * range;
+ EXPECT_EQ(full_range, top - bottom);
+ EXPECT_EQ(-full_range, bottom - top);
+ }
+}
+
+TEST(Time, Limits) {
+ // It is an implementation detail that Time().rep_ == ZeroDuration(),
+ // and that the resolution of a Duration is 1/4 of a nanosecond.
+ const absl::Time zero;
+ const absl::Time max =
+ zero + absl::Seconds(std::numeric_limits<int64_t>::max()) +
+ absl::Nanoseconds(999999999) + absl::Nanoseconds(3) / 4;
+ const absl::Time min =
+ zero + absl::Seconds(std::numeric_limits<int64_t>::min());
+
+ // Some simple max/min bounds checks.
+ EXPECT_LT(max, absl::InfiniteFuture());
+ EXPECT_GT(min, absl::InfinitePast());
+ EXPECT_LT(zero, max);
+ EXPECT_GT(zero, min);
+ EXPECT_GE(absl::UnixEpoch(), min);
+ EXPECT_LT(absl::UnixEpoch(), max);
+
+ // Check sign of Time differences.
+ EXPECT_LT(absl::ZeroDuration(), max - zero);
+ EXPECT_LT(absl::ZeroDuration(),
+ zero - absl::Nanoseconds(1) / 4 - min); // avoid zero - min
+
+ // Arithmetic works at max - 0.25ns and min + 0.25ns.
+ EXPECT_GT(max, max - absl::Nanoseconds(1) / 4);
+ EXPECT_LT(min, min + absl::Nanoseconds(1) / 4);
+}
+
+TEST(Time, ConversionSaturation) {
+ const absl::TimeZone utc = absl::UTCTimeZone();
+ absl::Time t;
+
+ const auto max_time_t = std::numeric_limits<time_t>::max();
+ const auto min_time_t = std::numeric_limits<time_t>::min();
+ time_t tt = max_time_t - 1;
+ t = absl::FromTimeT(tt);
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(max_time_t - 1, tt);
+ t += absl::Seconds(1);
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(max_time_t, tt);
+ t += absl::Seconds(1); // no effect
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(max_time_t, tt);
+
+ tt = min_time_t + 1;
+ t = absl::FromTimeT(tt);
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(min_time_t + 1, tt);
+ t -= absl::Seconds(1);
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(min_time_t, tt);
+ t -= absl::Seconds(1); // no effect
+ tt = absl::ToTimeT(t);
+ EXPECT_EQ(min_time_t, tt);
+
+ const auto max_timeval_sec =
+ std::numeric_limits<decltype(timeval::tv_sec)>::max();
+ const auto min_timeval_sec =
+ std::numeric_limits<decltype(timeval::tv_sec)>::min();
+ timeval tv;
+ tv.tv_sec = max_timeval_sec;
+ tv.tv_usec = 999998;
+ t = absl::TimeFromTimeval(tv);
+ tv = ToTimeval(t);
+ EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(999998, tv.tv_usec);
+ t += absl::Microseconds(1);
+ tv = ToTimeval(t);
+ EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(999999, tv.tv_usec);
+ t += absl::Microseconds(1); // no effect
+ tv = ToTimeval(t);
+ EXPECT_EQ(max_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(999999, tv.tv_usec);
+
+ tv.tv_sec = min_timeval_sec;
+ tv.tv_usec = 1;
+ t = absl::TimeFromTimeval(tv);
+ tv = ToTimeval(t);
+ EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(1, tv.tv_usec);
+ t -= absl::Microseconds(1);
+ tv = ToTimeval(t);
+ EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(0, tv.tv_usec);
+ t -= absl::Microseconds(1); // no effect
+ tv = ToTimeval(t);
+ EXPECT_EQ(min_timeval_sec, tv.tv_sec);
+ EXPECT_EQ(0, tv.tv_usec);
+
+ const auto max_timespec_sec =
+ std::numeric_limits<decltype(timespec::tv_sec)>::max();
+ const auto min_timespec_sec =
+ std::numeric_limits<decltype(timespec::tv_sec)>::min();
+ timespec ts;
+ ts.tv_sec = max_timespec_sec;
+ ts.tv_nsec = 999999998;
+ t = absl::TimeFromTimespec(ts);
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(999999998, ts.tv_nsec);
+ t += absl::Nanoseconds(1);
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(999999999, ts.tv_nsec);
+ t += absl::Nanoseconds(1); // no effect
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(max_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(999999999, ts.tv_nsec);
+
+ ts.tv_sec = min_timespec_sec;
+ ts.tv_nsec = 1;
+ t = absl::TimeFromTimespec(ts);
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(1, ts.tv_nsec);
+ t -= absl::Nanoseconds(1);
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(0, ts.tv_nsec);
+ t -= absl::Nanoseconds(1); // no effect
+ ts = absl::ToTimespec(t);
+ EXPECT_EQ(min_timespec_sec, ts.tv_sec);
+ EXPECT_EQ(0, ts.tv_nsec);
+
+ // Checks how Time::In() saturates on infinities.
+ absl::Time::Breakdown bd = absl::InfiniteFuture().In(utc);
+ ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::max(), 12, 31, 23,
+ 59, 59, 0, false, "-0000");
+ EXPECT_EQ(absl::InfiniteDuration(), bd.subsecond);
+ EXPECT_EQ(4, bd.weekday); // Thursday
+ EXPECT_EQ(365, bd.yearday);
+ bd = absl::InfinitePast().In(utc);
+ ABSL_INTERNAL_EXPECT_TIME(bd, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0,
+ 0, 0, false, "-0000");
+ EXPECT_EQ(-absl::InfiniteDuration(), bd.subsecond);
+ EXPECT_EQ(7, bd.weekday); // Sunday
+ EXPECT_EQ(1, bd.yearday);
+
+ // Approach the maximal Time value from below.
+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 6, utc);
+ EXPECT_EQ("292277026596-12-04T15:30:06+00:00",
+ absl::FormatTime(absl::RFC3339_full, t, utc));
+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 7, utc);
+ EXPECT_EQ("292277026596-12-04T15:30:07+00:00",
+ absl::FormatTime(absl::RFC3339_full, t, utc));
+ EXPECT_EQ(
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
+
+ // Checks that we can also get the maximal Time value for a far-east zone.
+ const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60);
+ t = absl::FromDateTime(292277026596, 12, 5, 5, 30, 7, plus14);
+ EXPECT_EQ("292277026596-12-05T05:30:07+14:00",
+ absl::FormatTime(absl::RFC3339_full, t, plus14));
+ EXPECT_EQ(
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::max()), t);
+
+ // One second later should push us to infinity.
+ t = absl::FromDateTime(292277026596, 12, 4, 15, 30, 8, utc);
+ EXPECT_EQ("infinite-future", absl::FormatTime(absl::RFC3339_full, t, utc));
+
+ // Approach the minimal Time value from above.
+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 53, utc);
+ EXPECT_EQ("-292277022657-01-27T08:29:53+00:00",
+ absl::FormatTime(absl::RFC3339_full, t, utc));
+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 52, utc);
+ EXPECT_EQ("-292277022657-01-27T08:29:52+00:00",
+ absl::FormatTime(absl::RFC3339_full, t, utc));
+ EXPECT_EQ(
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
+
+ // Checks that we can also get the minimal Time value for a far-west zone.
+ const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60);
+ t = absl::FromDateTime(-292277022657, 1, 26, 20, 29, 52, minus12);
+ EXPECT_EQ("-292277022657-01-26T20:29:52-12:00",
+ absl::FormatTime(absl::RFC3339_full, t, minus12));
+ EXPECT_EQ(
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::min()), t);
+
+ // One second before should push us to -infinity.
+ t = absl::FromDateTime(-292277022657, 1, 27, 8, 29, 51, utc);
+ EXPECT_EQ("infinite-past", absl::FormatTime(absl::RFC3339_full, t, utc));
+}
+
+// In zones with POSIX-style recurring rules we use special logic to
+// handle conversions in the distant future. Here we check the limits
+// of those conversions, particularly with respect to integer overflow.
+TEST(Time, ExtendedConversionSaturation) {
+ const absl::TimeZone syd =
+ absl::time_internal::LoadTimeZone("Australia/Sydney");
+ const absl::TimeZone nyc =
+ absl::time_internal::LoadTimeZone("America/New_York");
+ const absl::Time max =
+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max());
+ absl::Time::Breakdown bd;
+ absl::Time t;
+
+ // The maximal time converted in each zone.
+ bd = max.In(syd);
+ ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 5, 2, 30, 7, 39600, true,
+ "AEDT");
+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 7, syd);
+ EXPECT_EQ(max, t);
+ bd = max.In(nyc);
+ ABSL_INTERNAL_EXPECT_TIME(bd, 292277026596, 12, 4, 10, 30, 7, -18000, false,
+ "EST");
+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 7, nyc);
+ EXPECT_EQ(max, t);
+
+ // One second later should push us to infinity.
+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 8, syd);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 8, nyc);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+
+ // And we should stick there.
+ t = absl::FromDateTime(292277026596, 12, 5, 2, 30, 9, syd);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+ t = absl::FromDateTime(292277026596, 12, 4, 10, 30, 9, nyc);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+
+ // All the way up to a saturated date/time, without overflow.
+ t = absl::FromDateTime(
+ std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, syd);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+ t = absl::FromDateTime(
+ std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59, nyc);
+ EXPECT_EQ(absl::InfiniteFuture(), t);
+}
+
+} // namespace
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_zone_test.cc
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_zone_test.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_zone_test.cc
new file mode 100644
index 0000000..7138560
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/time/time_zone_test.cc
@@ -0,0 +1,97 @@
+// 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
+//
+// http://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 "absl/time/internal/cctz/include/cctz/time_zone.h"
+
+#include "gtest/gtest.h"
+#include "absl/time/internal/test_util.h"
+#include "absl/time/time.h"
+
+namespace cctz = absl::time_internal::cctz;
+
+namespace {
+
+TEST(TimeZone, ValueSemantics) {
+ absl::TimeZone tz;
+ absl::TimeZone tz2 = tz; // Copy-construct
+ EXPECT_EQ(tz, tz2);
+ tz2 = tz; // Copy-assign
+ EXPECT_EQ(tz, tz2);
+}
+
+TEST(TimeZone, Equality) {
+ absl::TimeZone a, b;
+ EXPECT_EQ(a, b);
+ EXPECT_EQ(a.name(), b.name());
+
+ absl::TimeZone implicit_utc;
+ absl::TimeZone explicit_utc = absl::UTCTimeZone();
+ EXPECT_EQ(implicit_utc, explicit_utc);
+ EXPECT_EQ(implicit_utc.name(), explicit_utc.name());
+
+ absl::TimeZone la = absl::time_internal::LoadTimeZone("America/Los_Angeles");
+ absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York");
+ EXPECT_NE(la, nyc);
+}
+
+TEST(TimeZone, CCTZConversion) {
+ const cctz::time_zone cz = cctz::utc_time_zone();
+ const absl::TimeZone tz(cz);
+ EXPECT_EQ(cz, cctz::time_zone(tz));
+}
+
+TEST(TimeZone, DefaultTimeZones) {
+ absl::TimeZone tz;
+ EXPECT_EQ("UTC", absl::TimeZone().name());
+ EXPECT_EQ("UTC", absl::UTCTimeZone().name());
+}
+
+TEST(TimeZone, FixedTimeZone) {
+ const absl::TimeZone tz = absl::FixedTimeZone(123);
+ const cctz::time_zone cz = cctz::fixed_time_zone(cctz::sys_seconds(123));
+ EXPECT_EQ(tz, absl::TimeZone(cz));
+}
+
+TEST(TimeZone, LocalTimeZone) {
+ const absl::TimeZone local_tz = absl::LocalTimeZone();
+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("localtime");
+ EXPECT_EQ(tz, local_tz);
+}
+
+TEST(TimeZone, NamedTimeZones) {
+ absl::TimeZone nyc = absl::time_internal::LoadTimeZone("America/New_York");
+ EXPECT_EQ("America/New_York", nyc.name());
+ absl::TimeZone syd = absl::time_internal::LoadTimeZone("Australia/Sydney");
+ EXPECT_EQ("Australia/Sydney", syd.name());
+ absl::TimeZone fixed = absl::FixedTimeZone((((3 * 60) + 25) * 60) + 45);
+ EXPECT_EQ("Fixed/UTC+03:25:45", fixed.name());
+}
+
+TEST(TimeZone, Failures) {
+ absl::TimeZone tz = absl::time_internal::LoadTimeZone("America/Los_Angeles");
+ EXPECT_FALSE(LoadTimeZone("Invalid/TimeZone", &tz));
+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC
+
+ // Ensures that the load still fails on a subsequent attempt.
+ tz = absl::time_internal::LoadTimeZone("America/Los_Angeles");
+ EXPECT_FALSE(LoadTimeZone("Invalid/TimeZone", &tz));
+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC
+
+ // Loading an empty std::string timezone should fail.
+ tz = absl::time_internal::LoadTimeZone("America/Los_Angeles");
+ EXPECT_FALSE(LoadTimeZone("", &tz));
+ EXPECT_EQ(absl::UTCTimeZone(), tz); // guaranteed fallback to UTC
+}
+
+} // namespace
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/types/BUILD.bazel
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/BUILD.bazel b/libraries/ostrich/backend/3rdparty/abseil/absl/types/BUILD.bazel
new file mode 100644
index 0000000..0bdb2f7
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/BUILD.bazel
@@ -0,0 +1,225 @@
+#
+# 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
+#
+# http://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.
+#
+
+load(
+ "//absl:copts.bzl",
+ "ABSL_DEFAULT_COPTS",
+ "ABSL_TEST_COPTS",
+ "ABSL_EXCEPTIONS_FLAG",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"]) # Apache 2.0
+
+cc_library(
+ name = "any",
+ hdrs = ["any.h"],
+ copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":bad_any_cast",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/meta:type_traits",
+ "//absl/utility",
+ ],
+)
+
+cc_library(
+ name = "bad_any_cast",
+ srcs = ["bad_any_cast.cc"],
+ hdrs = ["bad_any_cast.h"],
+ copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/base",
+ "//absl/base:config",
+ ],
+)
+
+cc_test(
+ name = "any_test",
+ size = "small",
+ srcs = [
+ "any_test.cc",
+ ],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":any",
+ "//absl/base",
+ "//absl/base:config",
+ "//absl/base:exception_testing",
+ "//absl/container:test_instance_tracker",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "any_test_noexceptions",
+ size = "small",
+ srcs = [
+ "any_test.cc",
+ ],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":any",
+ "//absl/base",
+ "//absl/base:config",
+ "//absl/base:exception_testing",
+ "//absl/container:test_instance_tracker",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "any_exception_safety_test",
+ srcs = ["any_exception_safety_test.cc"],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":any",
+ "//absl/base:exception_safety_testing",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "span",
+ hdrs = ["span.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/algorithm",
+ "//absl/base:core_headers",
+ "//absl/base:throw_delegate",
+ "//absl/meta:type_traits",
+ ],
+)
+
+cc_test(
+ name = "span_test",
+ size = "small",
+ srcs = ["span_test.cc"],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":span",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/base:exception_testing",
+ "//absl/container:fixed_array",
+ "//absl/container:inlined_vector",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "span_test_noexceptions",
+ size = "small",
+ srcs = ["span_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":span",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/base:exception_testing",
+ "//absl/container:fixed_array",
+ "//absl/container:inlined_vector",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "optional",
+ srcs = ["optional.cc"],
+ hdrs = ["optional.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":bad_optional_access",
+ "//absl/base:config",
+ "//absl/memory",
+ "//absl/meta:type_traits",
+ "//absl/utility",
+ ],
+)
+
+cc_library(
+ name = "bad_optional_access",
+ srcs = ["bad_optional_access.cc"],
+ hdrs = ["bad_optional_access.h"],
+ copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ "//absl/base",
+ "//absl/base:config",
+ ],
+)
+
+cc_library(
+ name = "bad_variant_access",
+ srcs = ["bad_variant_access.cc"],
+ hdrs = ["bad_variant_access.h"],
+ copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/base",
+ "//absl/base:config",
+ ],
+)
+
+cc_test(
+ name = "optional_test",
+ size = "small",
+ srcs = [
+ "optional_test.cc",
+ ],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":optional",
+ "//absl/base",
+ "//absl/base:config",
+ "//absl/meta:type_traits",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
+ name = "variant",
+ srcs = ["internal/variant.h"],
+ hdrs = ["variant.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ ":bad_variant_access",
+ "//absl/base:base_internal",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/meta:type_traits",
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "variant_test",
+ size = "small",
+ srcs = ["variant_test.cc"],
+ copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ deps = [
+ ":variant",
+ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/memory",
+ "//absl/meta:type_traits",
+ "//absl/strings",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/CMakeLists.txt b/libraries/ostrich/backend/3rdparty/abseil/absl/types/CMakeLists.txt
new file mode 100644
index 0000000..f51d126
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/CMakeLists.txt
@@ -0,0 +1,201 @@
+#
+# 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
+#
+# http://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.
+#
+
+list(APPEND TYPES_PUBLIC_HEADERS
+ "any.h"
+ "bad_any_cast.h"
+ "bad_optional_access.h"
+ "optional.h"
+ "span.h"
+ "variant.h"
+)
+
+
+# any library
+absl_header_library(
+ TARGET
+ absl_any
+ PUBLIC_LIBRARIES
+ absl::utility
+ PRIVATE_COMPILE_FLAGS
+ ${ABSL_EXCEPTIONS_FLAG}
+ EXPORT_NAME
+ any
+)
+
+# span library
+absl_header_library(
+ TARGET
+ absl_span
+ PUBLIC_LIBRARIES
+ absl::utility
+ EXPORT_NAME
+ span
+)
+
+
+# bad_any_cast library
+list(APPEND BAD_ANY_CAST_SRC
+ "bad_any_cast.cc"
+ ${TYPES_PUBLIC_HEADERS}
+)
+
+absl_library(
+ TARGET
+ absl_bad_any_cast
+ SOURCES
+ ${BAD_ANY_CAST_SRC}
+ PUBLIC_LIBRARIES
+ absl::base absl::any
+ EXPORT_NAME
+ bad_any_cast
+)
+
+
+# optional library
+list(APPEND OPTIONAL_SRC
+ "optional.cc"
+)
+
+absl_library(
+ TARGET
+ absl_optional
+ SOURCES
+ ${OPTIONAL_SRC}
+ PUBLIC_LIBRARIES
+ absl::base
+ EXPORT_NAME
+ optional
+)
+
+
+set(BAD_OPTIONAL_ACCESS_SRC "bad_optional_access.cc")
+set(BAD_OPTIONAL_ACCESS_LIBRARIES absl::base)
+
+absl_library(
+ TARGET
+ absl_bad_optional_access
+ SOURCES
+ ${BAD_OPTIONAL_ACCESS_SRC}
+ PUBLIC_LIBRARIES
+ ${BAD_OPTIONAL_ACCESS_PUBLIC_LIBRARIES}
+ EXPORT_NAME
+ bad_optional_access
+)
+
+# variant library
+absl_library(
+ TARGET
+ absl_variant
+ SOURCES
+ "bad_variant_access.h" "bad_variant_access.cc" "variant.h" "internal/variant.h"
+ PUBLIC_LIBRARIES
+ absl::base absl::meta absl::utility
+ PRIVATE_COMPILE_FLAGS
+ ${ABSL_EXCEPTIONS_FLAG}
+ EXPORT_NAME
+ variant
+)
+
+#
+## TESTS
+#
+
+
+# test any_test
+set(ANY_TEST_SRC "any_test.cc")
+set(ANY_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::any absl::bad_any_cast test_instance_tracker_lib)
+
+absl_test(
+ TARGET
+ any_test
+ SOURCES
+ ${ANY_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${ANY_TEST_PUBLIC_LIBRARIES}
+ PRIVATE_COMPILE_FLAGS
+ ${ABSL_EXCEPTIONS_FLAG}
+)
+
+
+# test any_test_noexceptions
+absl_test(
+ TARGET
+ any_test_noexceptions
+ SOURCES
+ ${ANY_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${ANY_TEST_PUBLIC_LIBRARIES}
+)
+
+# test any_exception_safety_test
+set(ANY_EXCEPTION_SAFETY_TEST_SRC "any_exception_safety_test.cc")
+set(ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES absl::any absl::base absl::base_internal_exception_safety_testing)
+
+absl_test(
+ TARGET
+ any_exception_safety_test
+ SOURCES
+ ${ANY_EXCEPTION_SAFETY_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
+ PRIVATE_COMPILE_FLAGS
+ ${ABSL_EXCEPTIONS_FLAG}
+)
+
+
+# test span_test
+set(SPAN_TEST_SRC "span_test.cc")
+set(SPAN_TEST_PUBLIC_LIBRARIES absl::base absl::strings absl::throw_delegate absl::span test_instance_tracker_lib)
+
+absl_test(
+ TARGET
+ span_test
+ SOURCES
+ ${SPAN_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${SPAN_TEST_PUBLIC_LIBRARIES}
+ PRIVATE_COMPILE_FLAGS
+ ${ABSL_EXCEPTIONS_FLAG}
+)
+
+
+# test span_test_noexceptions
+absl_test(
+ TARGET
+ span_test_noexceptions
+ SOURCES
+ ${SPAN_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${SPAN_TEST_PUBLIC_LIBRARIES}
+)
+
+
+
+# test optional_test
+set(OPTIONAL_TEST_SRC "optional_test.cc")
+set(OPTIONAL_TEST_PUBLIC_LIBRARIES absl::base absl::throw_delegate absl::optional absl_bad_optional_access)
+
+absl_test(
+ TARGET
+ optional_test
+ SOURCES
+ ${OPTIONAL_TEST_SRC}
+ PUBLIC_LIBRARIES
+ ${OPTIONAL_TEST_PUBLIC_LIBRARIES}
+)
+
+
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/types/any.h
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/any.h b/libraries/ostrich/backend/3rdparty/abseil/absl/types/any.h
new file mode 100644
index 0000000..a973c6d
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/any.h
@@ -0,0 +1,539 @@
+//
+// 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
+//
+// http://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.
+//
+// -----------------------------------------------------------------------------
+// any.h
+// -----------------------------------------------------------------------------
+//
+// This header file define the `absl::any` type for holding a type-safe value
+// of any type. The 'absl::any` type is useful for providing a way to hold
+// something that is, as yet, unspecified. Such unspecified types
+// traditionally are passed between API boundaries until they are later cast to
+// their "destination" types. To cast to such a destination type, use
+// `absl::any_cast()`. Note that when casting an `absl::any`, you must cast it
+// to an explicit type; implicit conversions will throw.
+//
+// Example:
+//
+// auto a = absl::any(65);
+// absl::any_cast<int>(a); // 65
+// absl::any_cast<char>(a); // throws absl::bad_any_cast
+// absl::any_cast<std::string>(a); // throws absl::bad_any_cast
+//
+// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction
+// and is designed to be a drop-in replacement for code compliant with C++17.
+//
+// Traditionally, the behavior of casting to a temporary unspecified type has
+// been accomplished with the `void *` paradigm, where the pointer was to some
+// other unspecified type. `absl::any` provides an "owning" version of `void *`
+// that avoids issues of pointer management.
+//
+// Note: just as in the case of `void *`, use of `absl::any` (and its C++17
+// version `std::any`) is a code smell indicating that your API might not be
+// constructed correctly. We have seen that most uses of `any` are unwarranted,
+// and `absl::any`, like `std::any`, is difficult to use properly. Before using
+// this abstraction, make sure that you should not instead be rewriting your
+// code to be more specific.
+//
+// Abseil expects to release an `absl::variant` type shortly (a C++11 compatible
+// version of the C++17 `std::variant), which is generally preferred for use
+// over `absl::any`.
+#ifndef ABSL_TYPES_ANY_H_
+#define ABSL_TYPES_ANY_H_
+
+#include "absl/base/config.h"
+#include "absl/utility/utility.h"
+
+#ifdef ABSL_HAVE_STD_ANY
+
+#include <any>
+
+namespace absl {
+using std::any;
+using std::any_cast;
+using std::bad_any_cast;
+using std::make_any;
+} // namespace absl
+
+#else // ABSL_HAVE_STD_ANY
+
+#include <algorithm>
+#include <cstddef>
+#include <initializer_list>
+#include <memory>
+#include <stdexcept>
+#include <type_traits>
+#include <typeinfo>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/meta/type_traits.h"
+#include "absl/types/bad_any_cast.h"
+
+// NOTE: This macro is an implementation detail that is undefined at the bottom
+// of the file. It is not intended for expansion directly from user code.
+#ifdef ABSL_ANY_DETAIL_HAS_RTTI
+#error ABSL_ANY_DETAIL_HAS_RTTI cannot be directly set
+#elif !defined(__GNUC__) || defined(__GXX_RTTI)
+#define ABSL_ANY_DETAIL_HAS_RTTI 1
+#endif // !defined(__GNUC__) || defined(__GXX_RTTI)
+
+namespace absl {
+
+namespace any_internal {
+
+template <typename Type>
+struct TypeTag {
+ constexpr static char dummy_var = 0;
+};
+
+template <typename Type>
+constexpr char TypeTag<Type>::dummy_var;
+
+// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the
+// passed in type. These are meant to be good match for keys into maps or
+// straight up comparisons.
+template<typename Type>
+constexpr inline const void* FastTypeId() {
+ return &TypeTag<Type>::dummy_var;
+}
+
+} // namespace any_internal
+
+class any;
+
+// swap()
+//
+// Swaps two `absl::any` values. Equivalent to `x.swap(y) where `x` and `y` are
+// `absl::any` types.
+void swap(any& x, any& y) noexcept;
+
+// make_any()
+//
+// Constructs an `absl::any` of type `T` with the given arguments.
+template <typename T, typename... Args>
+any make_any(Args&&... args);
+
+// Overload of `absl::make_any()` for constructing an `absl::any` type from an
+// initializer list.
+template <typename T, typename U, typename... Args>
+any make_any(std::initializer_list<U> il, Args&&... args);
+
+// any_cast()
+//
+// Statically casts the value of a `const absl::any` type to the given type.
+// This function will throw `absl::bad_any_cast` if the stored value type of the
+// `absl::any` does not match the cast.
+//
+// `any_cast()` can also be used to get a reference to the internal storage iff
+// a reference type is passed as its `ValueType`:
+//
+// Example:
+//
+// absl::any my_any = std::vector<int>();
+// absl::any_cast<std::vector<int>&>(my_any).push_back(42);
+template <typename ValueType>
+ValueType any_cast(const any& operand);
+
+// Overload of `any_cast()` to statically cast the value of a non-const
+// `absl::any` type to the given type. This function will throw
+// `absl::bad_any_cast` if the stored value type of the `absl::any` does not
+// match the cast.
+template <typename ValueType>
+ValueType any_cast(any& operand); // NOLINT(runtime/references)
+
+// Overload of `any_cast()` to statically cast the rvalue of an `absl::any`
+// type. This function will throw `absl::bad_any_cast` if the stored value type
+// of the `absl::any` does not match the cast.
+template <typename ValueType>
+ValueType any_cast(any&& operand);
+
+// Overload of `any_cast()` to statically cast the value of a const pointer
+// `absl::any` type to the given pointer type, or `nullptr` if the stored value
+// type of the `absl::any` does not match the cast.
+template <typename ValueType>
+const ValueType* any_cast(const any* operand) noexcept;
+
+// Overload of `any_cast()` to statically cast the value of a pointer
+// `absl::any` type to the given pointer type, or `nullptr` if the stored value
+// type of the `absl::any` does not match the cast.
+template <typename ValueType>
+ValueType* any_cast(any* operand) noexcept;
+
+// -----------------------------------------------------------------------------
+// absl::any
+// -----------------------------------------------------------------------------
+//
+// An `absl::any` object provides the facility to either store an instance of a
+// type, known as the "contained object", or no value. An `absl::any` is used to
+// store values of types that are unknown at compile time. The `absl::any`
+// object, when containing a value, must contain a value type; storing a
+// reference type is neither desired nor supported.
+//
+// An `absl::any` can only store a type that is copy-constructable; move-only
+// types are not allowed within an `any` object.
+//
+// Example:
+//
+// auto a = absl::any(65); // Literal, copyable
+// auto b = absl::any(std::vector<int>()); // Default-initialized, copyable
+// std::unique_ptr<Foo> my_foo;
+// auto c = absl::any(std::move(my_foo)); // Error, not copy-constructable
+//
+// Note that `absl::any` makes use of decayed types (`absl::decay_t` in this
+// context) to remove const-volatile qualifiers (known as "cv qualifiers"),
+// decay functions to function pointers, etc. We essentially "decay" a given
+// type into its essential type.
+//
+// `absl::any` makes use of decayed types when determining the basic type `T` of
+// the value to store in the any's contained object. In the documentation below,
+// we explicitly denote this by using the phrase "a decayed type of `T`".
+//
+// Example:
+//
+// const int a = 4;
+// absl::any foo(a); // Decay ensures we store an "int", not a "const int&".
+//
+// void my_function() {}
+// absl::any bar(my_function); // Decay ensures we store a function pointer.
+//
+// `absl::any` is a C++11 compatible version of the C++17 `std::any` abstraction
+// and is designed to be a drop-in replacement for code compliant with C++17.
+class any {
+ private:
+ template <typename T>
+ struct IsInPlaceType;
+
+ public:
+ // Constructors
+
+ // Constructs an empty `absl::any` object (`any::has_value()` will return
+ // `false`).
+ constexpr any() noexcept;
+
+ // Copy constructs an `absl::any` object with a "contained object" of the
+ // passed type of `other` (or an empty `absl::any` if `other.has_value()` is
+ // `false`.
+ any(const any& other)
+ : obj_(other.has_value() ? other.obj_->Clone()
+ : std::unique_ptr<ObjInterface>()) {}
+
+ // Move constructs an `absl::any` object with a "contained object" of the
+ // passed type of `other` (or an empty `absl::any` if `other.has_value()` is
+ // `false`).
+ any(any&& other) noexcept = default;
+
+ // Constructs an `absl::any` object with a "contained object" of the decayed
+ // type of `T`, which is initialized via `std::forward<T>(value)`.
+ //
+ // This constructor will not participate in overload resolution if the
+ // decayed type of `T` is not copy-constructible.
+ template <
+ typename T, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<!absl::disjunction<
+ std::is_same<any, VT>, IsInPlaceType<VT>,
+ absl::negation<std::is_copy_constructible<VT> > >::value>* = nullptr>
+ any(T&& value) : obj_(new Obj<VT>(in_place, std::forward<T>(value))) {}
+
+ // Constructs an `absl::any` object with a "contained object" of the decayed
+ // type of `T`, which is initialized via `std::forward<T>(value)`.
+ template <typename T, typename... Args, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<absl::conjunction<
+ std::is_copy_constructible<VT>,
+ std::is_constructible<VT, Args...>>::value>* = nullptr>
+ explicit any(in_place_type_t<T> /*tag*/, Args&&... args)
+ : obj_(new Obj<VT>(in_place, std::forward<Args>(args)...)) {}
+
+ // Constructs an `absl::any` object with a "contained object" of the passed
+ // type `VT` as a decayed type of `T`. `VT` is initialized as if
+ // direct-non-list-initializing an object of type `VT` with the arguments
+ // `initializer_list, std::forward<Args>(args)...`.
+ template <
+ typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<
+ absl::conjunction<std::is_copy_constructible<VT>,
+ std::is_constructible<VT, std::initializer_list<U>&,
+ Args...>>::value>* = nullptr>
+ explicit any(in_place_type_t<T> /*tag*/, std::initializer_list<U> ilist,
+ Args&&... args)
+ : obj_(new Obj<VT>(in_place, ilist, std::forward<Args>(args)...)) {}
+
+ // Assignment operators
+
+ // Copy assigns an `absl::any` object with a "contained object" of the
+ // passed type.
+ any& operator=(const any& rhs) {
+ any(rhs).swap(*this);
+ return *this;
+ }
+
+ // Move assigns an `absl::any` object with a "contained object" of the
+ // passed type. `rhs` is left in a valid but otherwise unspecified state.
+ any& operator=(any&& rhs) noexcept {
+ any(std::move(rhs)).swap(*this);
+ return *this;
+ }
+
+ // Assigns an `absl::any` object with a "contained object" of the passed type.
+ template <typename T, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<absl::conjunction<
+ absl::negation<std::is_same<VT, any>>,
+ std::is_copy_constructible<VT>>::value>* = nullptr>
+ any& operator=(T&& rhs) {
+ any tmp(in_place_type_t<VT>(), std::forward<T>(rhs));
+ tmp.swap(*this);
+ return *this;
+ }
+
+ // Modifiers
+
+ // any::emplace()
+ //
+ // Emplaces a value within an `absl::any` object by calling `any::reset()`,
+ // initializing the contained value as if direct-non-list-initializing an
+ // object of type `VT` with the arguments `std::forward<Args>(args)...`, and
+ // returning a reference to the new contained value.
+ //
+ // Note: If an exception is thrown during the call to `VT`'s constructor,
+ // `*this` does not contain a value, and any previously contained value has
+ // been destroyed.
+ template <
+ typename T, typename... Args, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<std::is_copy_constructible<VT>::value &&
+ std::is_constructible<VT, Args...>::value>* = nullptr>
+ VT& emplace(Args&&... args) {
+ reset(); // NOTE: reset() is required here even in the world of exceptions.
+ Obj<VT>* const object_ptr =
+ new Obj<VT>(in_place, std::forward<Args>(args)...);
+ obj_ = std::unique_ptr<ObjInterface>(object_ptr);
+ return object_ptr->value;
+ }
+
+ // Overload of `any::emplace()` to emplace a value within an `absl::any`
+ // object by calling `any::reset()`, initializing the contained value as if
+ // direct-non-list-initializing an object of type `VT` with the arguments
+ // `initializer_list, std::forward<Args>(args)...`, and returning a reference
+ // to the new contained value.
+ //
+ // Note: If an exception is thrown during the call to `VT`'s constructor,
+ // `*this` does not contain a value, and any previously contained value has
+ // been destroyed. The function shall not participate in overload resolution
+ // unless `is_copy_constructible_v<VT>` is `true` and
+ // `is_constructible_v<VT, initializer_list<U>&, Args...>` is `true`.
+ template <
+ typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
+ absl::enable_if_t<std::is_copy_constructible<VT>::value &&
+ std::is_constructible<VT, std::initializer_list<U>&,
+ Args...>::value>* = nullptr>
+ VT& emplace(std::initializer_list<U> ilist, Args&&... args) {
+ reset(); // NOTE: reset() is required here even in the world of exceptions.
+ Obj<VT>* const object_ptr =
+ new Obj<VT>(in_place, ilist, std::forward<Args>(args)...);
+ obj_ = std::unique_ptr<ObjInterface>(object_ptr);
+ return object_ptr->value;
+ }
+
+ // any::reset()
+ //
+ // Resets the state of the `absl::any` object, destroying the contained object
+ // if present.
+ void reset() noexcept { obj_ = nullptr; }
+
+ // any::swap()
+ //
+ // Swaps the passed value and the value of this `absl::any` object.
+ void swap(any& other) noexcept { obj_.swap(other.obj_); }
+
+ // Observers
+
+ // any::has_value()
+ //
+ // Returns `true` if the `any` object has a contained value, otherwise
+ // returns `false`.
+ bool has_value() const noexcept { return obj_ != nullptr; }
+
+#if ABSL_ANY_DETAIL_HAS_RTTI
+ // Returns: typeid(T) if *this has a contained object of type T, otherwise
+ // typeid(void).
+ const std::type_info& type() const noexcept {
+ if (has_value()) {
+ return obj_->Type();
+ }
+
+ return typeid(void);
+ }
+#endif // ABSL_ANY_DETAIL_HAS_RTTI
+
+ private:
+ // Tagged type-erased abstraction for holding a cloneable object.
+ class ObjInterface {
+ public:
+ virtual ~ObjInterface() = default;
+ virtual std::unique_ptr<ObjInterface> Clone() const = 0;
+ virtual const void* ObjTypeId() const noexcept = 0;
+#if ABSL_ANY_DETAIL_HAS_RTTI
+ virtual const std::type_info& Type() const noexcept = 0;
+#endif // ABSL_ANY_DETAIL_HAS_RTTI
+ };
+
+ // Hold a value of some queryable type, with an ability to Clone it.
+ template <typename T>
+ class Obj : public ObjInterface {
+ public:
+ template <typename... Args>
+ explicit Obj(in_place_t /*tag*/, Args&&... args)
+ : value(std::forward<Args>(args)...) {}
+
+ std::unique_ptr<ObjInterface> Clone() const final {
+ return std::unique_ptr<ObjInterface>(new Obj(in_place, value));
+ }
+
+ const void* ObjTypeId() const noexcept final { return IdForType<T>(); }
+
+#if ABSL_ANY_DETAIL_HAS_RTTI
+ const std::type_info& Type() const noexcept final { return typeid(T); }
+#endif // ABSL_ANY_DETAIL_HAS_RTTI
+
+ T value;
+ };
+
+ std::unique_ptr<ObjInterface> CloneObj() const {
+ if (!obj_) return nullptr;
+ return obj_->Clone();
+ }
+
+ template <typename T>
+ constexpr static const void* IdForType() {
+ // Note: This type dance is to make the behavior consistent with typeid.
+ using NormalizedType =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+ return any_internal::FastTypeId<NormalizedType>();
+ }
+
+ const void* GetObjTypeId() const {
+ return obj_ ? obj_->ObjTypeId() : any_internal::FastTypeId<void>();
+ }
+
+ // `absl::any` nonmember functions //
+
+ // Description at the declaration site (top of file).
+ template <typename ValueType>
+ friend ValueType any_cast(const any& operand);
+
+ // Description at the declaration site (top of file).
+ template <typename ValueType>
+ friend ValueType any_cast(any& operand); // NOLINT(runtime/references)
+
+ // Description at the declaration site (top of file).
+ template <typename T>
+ friend const T* any_cast(const any* operand) noexcept;
+
+ // Description at the declaration site (top of file).
+ template <typename T>
+ friend T* any_cast(any* operand) noexcept;
+
+ std::unique_ptr<ObjInterface> obj_;
+};
+
+// -----------------------------------------------------------------------------
+// Implementation Details
+// -----------------------------------------------------------------------------
+
+constexpr any::any() noexcept = default;
+
+template <typename T>
+struct any::IsInPlaceType : std::false_type {};
+
+template <typename T>
+struct any::IsInPlaceType<in_place_type_t<T>> : std::true_type {};
+
+inline void swap(any& x, any& y) noexcept { x.swap(y); }
+
+// Description at the declaration site (top of file).
+template <typename T, typename... Args>
+any make_any(Args&&... args) {
+ return any(in_place_type_t<T>(), std::forward<Args>(args)...);
+}
+
+// Description at the declaration site (top of file).
+template <typename T, typename U, typename... Args>
+any make_any(std::initializer_list<U> il, Args&&... args) {
+ return any(in_place_type_t<T>(), il, std::forward<Args>(args)...);
+}
+
+// Description at the declaration site (top of file).
+template <typename ValueType>
+ValueType any_cast(const any& operand) {
+ using U = typename std::remove_cv<
+ typename std::remove_reference<ValueType>::type>::type;
+ static_assert(std::is_constructible<ValueType, const U&>::value,
+ "Invalid ValueType");
+ auto* const result = (any_cast<U>)(&operand);
+ if (result == nullptr) {
+ any_internal::ThrowBadAnyCast();
+ }
+ return static_cast<ValueType>(*result);
+}
+
+// Description at the declaration site (top of file).
+template <typename ValueType>
+ValueType any_cast(any& operand) { // NOLINT(runtime/references)
+ using U = typename std::remove_cv<
+ typename std::remove_reference<ValueType>::type>::type;
+ static_assert(std::is_constructible<ValueType, U&>::value,
+ "Invalid ValueType");
+ auto* result = (any_cast<U>)(&operand);
+ if (result == nullptr) {
+ any_internal::ThrowBadAnyCast();
+ }
+ return static_cast<ValueType>(*result);
+}
+
+// Description at the declaration site (top of file).
+template <typename ValueType>
+ValueType any_cast(any&& operand) {
+ using U = typename std::remove_cv<
+ typename std::remove_reference<ValueType>::type>::type;
+ static_assert(std::is_constructible<ValueType, U>::value,
+ "Invalid ValueType");
+ return static_cast<ValueType>(std::move((any_cast<U&>)(operand)));
+}
+
+// Description at the declaration site (top of file).
+template <typename T>
+const T* any_cast(const any* operand) noexcept {
+ return operand && operand->GetObjTypeId() == any::IdForType<T>()
+ ? std::addressof(
+ static_cast<const any::Obj<T>*>(operand->obj_.get())->value)
+ : nullptr;
+}
+
+// Description at the declaration site (top of file).
+template <typename T>
+T* any_cast(any* operand) noexcept {
+ return operand && operand->GetObjTypeId() == any::IdForType<T>()
+ ? std::addressof(
+ static_cast<any::Obj<T>*>(operand->obj_.get())->value)
+ : nullptr;
+}
+
+} // namespace absl
+
+#undef ABSL_ANY_DETAIL_HAS_RTTI
+
+#endif // ABSL_HAVE_STD_ANY
+
+#endif // ABSL_TYPES_ANY_H_
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/types/any_exception_safety_test.cc
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/any_exception_safety_test.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/types/any_exception_safety_test.cc
new file mode 100644
index 0000000..7a72e72
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/any_exception_safety_test.cc
@@ -0,0 +1,166 @@
+// 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
+//
+// http://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 "absl/types/any.h"
+
+#include <typeinfo>
+#include <vector>
+
+#include "gtest/gtest.h"
+#include "absl/base/internal/exception_safety_testing.h"
+
+using Thrower = absl::ThrowingValue<>;
+using NoThrowMoveThrower =
+ absl::ThrowingValue<absl::NoThrow::kMoveCtor | absl::NoThrow::kMoveAssign>;
+using ThrowerList = std::initializer_list<Thrower>;
+using ThrowerVec = std::vector<Thrower>;
+using ThrowingAlloc = absl::ThrowingAllocator<Thrower>;
+using ThrowingThrowerVec = std::vector<Thrower, ThrowingAlloc>;
+
+namespace {
+
+testing::AssertionResult AnyInvariants(absl::any* a) {
+ using testing::AssertionFailure;
+ using testing::AssertionSuccess;
+
+ if (a->has_value()) {
+ if (a->type() == typeid(void)) {
+ return AssertionFailure()
+ << "A non-empty any should not have type `void`";
+ }
+ } else {
+ if (a->type() != typeid(void)) {
+ return AssertionFailure()
+ << "An empty any should have type void, but has type "
+ << a->type().name();
+ }
+ }
+
+ // Make sure that reset() changes any to a valid state.
+ a->reset();
+ if (a->has_value()) {
+ return AssertionFailure() << "A reset `any` should be valueless";
+ }
+ if (a->type() != typeid(void)) {
+ return AssertionFailure() << "A reset `any` should have type() of `void`, "
+ "but instead has type "
+ << a->type().name();
+ }
+ try {
+ auto unused = absl::any_cast<Thrower>(*a);
+ static_cast<void>(unused);
+ return AssertionFailure()
+ << "A reset `any` should not be able to be any_cast";
+ } catch (absl::bad_any_cast) {
+ } catch (...) {
+ return AssertionFailure()
+ << "Unexpected exception thrown from absl::any_cast";
+ }
+ return AssertionSuccess();
+}
+
+testing::AssertionResult AnyIsEmpty(absl::any* a) {
+ if (!a->has_value()) {
+ return testing::AssertionSuccess();
+ }
+ return testing::AssertionFailure()
+ << "a should be empty, but instead has value "
+ << absl::any_cast<Thrower>(*a).Get();
+}
+
+TEST(AnyExceptionSafety, Ctors) {
+ Thrower val(1);
+ absl::TestThrowingCtor<absl::any>(val);
+
+ Thrower copy(val);
+ absl::TestThrowingCtor<absl::any>(copy);
+
+ absl::TestThrowingCtor<absl::any>(absl::in_place_type_t<Thrower>(), 1);
+
+ absl::TestThrowingCtor<absl::any>(absl::in_place_type_t<ThrowerVec>(),
+ ThrowerList{val});
+
+ absl::TestThrowingCtor<absl::any, absl::in_place_type_t<ThrowingThrowerVec>,
+ ThrowerList, ThrowingAlloc>(
+ absl::in_place_type_t<ThrowingThrowerVec>(), {val}, ThrowingAlloc());
+}
+
+TEST(AnyExceptionSafety, Assignment) {
+ auto original =
+ absl::any(absl::in_place_type_t<Thrower>(), 1, absl::no_throw_ctor);
+ auto any_is_strong = [original](absl::any* ap) {
+ return testing::AssertionResult(ap->has_value() &&
+ absl::any_cast<Thrower>(original) ==
+ absl::any_cast<Thrower>(*ap));
+ };
+ auto any_strong_tester = absl::MakeExceptionSafetyTester()
+ .WithInitialValue(original)
+ .WithInvariants(AnyInvariants, any_is_strong);
+
+ Thrower val(2);
+ absl::any any_val(val);
+ NoThrowMoveThrower mv_val(2);
+
+ auto assign_any = [&any_val](absl::any* ap) { *ap = any_val; };
+ auto assign_val = [&val](absl::any* ap) { *ap = val; };
+ auto move = [&val](absl::any* ap) { *ap = std::move(val); };
+ auto move_movable = [&mv_val](absl::any* ap) { *ap = std::move(mv_val); };
+
+ EXPECT_TRUE(any_strong_tester.Test(assign_any));
+ EXPECT_TRUE(any_strong_tester.Test(assign_val));
+ EXPECT_TRUE(any_strong_tester.Test(move));
+ EXPECT_TRUE(any_strong_tester.Test(move_movable));
+
+ auto empty_any_is_strong = [](absl::any* ap) {
+ return testing::AssertionResult{!ap->has_value()};
+ };
+ auto strong_empty_any_tester =
+ absl::MakeExceptionSafetyTester()
+ .WithInitialValue(absl::any{})
+ .WithInvariants(AnyInvariants, empty_any_is_strong);
+
+ EXPECT_TRUE(strong_empty_any_tester.Test(assign_any));
+ EXPECT_TRUE(strong_empty_any_tester.Test(assign_val));
+ EXPECT_TRUE(strong_empty_any_tester.Test(move));
+}
+// libstdc++ std::any fails this test
+#if !defined(ABSL_HAVE_STD_ANY)
+TEST(AnyExceptionSafety, Emplace) {
+ auto initial_val =
+ absl::any{absl::in_place_type_t<Thrower>(), 1, absl::no_throw_ctor};
+ auto one_tester = absl::MakeExceptionSafetyTester()
+ .WithInitialValue(initial_val)
+ .WithInvariants(AnyInvariants, AnyIsEmpty);
+
+ auto emp_thrower = [](absl::any* ap) { ap->emplace<Thrower>(2); };
+ auto emp_throwervec = [](absl::any* ap) {
+ std::initializer_list<Thrower> il{Thrower(2, absl::no_throw_ctor)};
+ ap->emplace<ThrowerVec>(il);
+ };
+ auto emp_movethrower = [](absl::any* ap) {
+ ap->emplace<NoThrowMoveThrower>(2);
+ };
+
+ EXPECT_TRUE(one_tester.Test(emp_thrower));
+ EXPECT_TRUE(one_tester.Test(emp_throwervec));
+ EXPECT_TRUE(one_tester.Test(emp_movethrower));
+
+ auto empty_tester = one_tester.WithInitialValue(absl::any{});
+
+ EXPECT_TRUE(empty_tester.Test(emp_thrower));
+ EXPECT_TRUE(empty_tester.Test(emp_throwervec));
+}
+#endif // ABSL_HAVE_STD_ANY
+
+} // namespace