You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2018/04/29 19:35:32 UTC

[03/51] [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/types/span_test.cc
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/span_test.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/types/span_test.cc
new file mode 100644
index 0000000..5a4f001
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/span_test.cc
@@ -0,0 +1,781 @@
+// 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/span.h"
+
+#include <array>
+#include <initializer_list>
+#include <numeric>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/exception_testing.h"
+#include "absl/container/fixed_array.h"
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/str_cat.h"
+
+namespace {
+
+MATCHER_P(DataIs, data,
+          absl::StrCat("data() is ", negation ? "is " : "isn't ",
+                       testing::PrintToString(data))) {
+  return arg.data() == data;
+}
+
+template <typename T>
+auto SpanIs(T data, size_t size)
+    -> decltype(testing::AllOf(DataIs(data), testing::SizeIs(size))) {
+  return testing::AllOf(DataIs(data), testing::SizeIs(size));
+}
+
+template <typename Container>
+auto SpanIs(const Container& c) -> decltype(SpanIs(c.data(), c.size())) {
+  return SpanIs(c.data(), c.size());
+}
+
+std::vector<int> MakeRamp(int len, int offset = 0) {
+  std::vector<int> v(len);
+  std::iota(v.begin(), v.end(), offset);
+  return v;
+}
+
+TEST(IntSpan, EmptyCtors) {
+  absl::Span<int> s;
+  EXPECT_THAT(s, SpanIs(nullptr, 0));
+}
+
+TEST(IntSpan, PtrLenCtor) {
+  int a[] = {1, 2, 3};
+  absl::Span<int> s(&a[0], 2);
+  EXPECT_THAT(s, SpanIs(a, 2));
+}
+
+TEST(IntSpan, ArrayCtor) {
+  int a[] = {1, 2, 3};
+  absl::Span<int> s(a);
+  EXPECT_THAT(s, SpanIs(a, 3));
+
+  EXPECT_TRUE((std::is_constructible<absl::Span<const int>, int[3]>::value));
+  EXPECT_TRUE(
+      (std::is_constructible<absl::Span<const int>, const int[3]>::value));
+  EXPECT_FALSE((std::is_constructible<absl::Span<int>, const int[3]>::value));
+  EXPECT_TRUE((std::is_convertible<int[3], absl::Span<const int>>::value));
+  EXPECT_TRUE(
+      (std::is_convertible<const int[3], absl::Span<const int>>::value));
+}
+
+template <typename T>
+void TakesGenericSpan(absl::Span<T>) {}
+
+TEST(IntSpan, ContainerCtor) {
+  std::vector<int> empty;
+  absl::Span<int> s_empty(empty);
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::vector<int> filled{1, 2, 3};
+  absl::Span<int> s_filled(filled);
+  EXPECT_THAT(s_filled, SpanIs(filled));
+
+  absl::Span<int> s_from_span(filled);
+  EXPECT_THAT(s_from_span, SpanIs(s_filled));
+
+  absl::Span<const int> const_filled = filled;
+  EXPECT_THAT(const_filled, SpanIs(filled));
+
+  absl::Span<const int> const_from_span = s_filled;
+  EXPECT_THAT(const_from_span, SpanIs(s_filled));
+
+  EXPECT_TRUE(
+      (std::is_convertible<std::vector<int>&, absl::Span<const int>>::value));
+  EXPECT_TRUE(
+      (std::is_convertible<absl::Span<int>&, absl::Span<const int>>::value));
+
+  TakesGenericSpan(absl::Span<int>(filled));
+}
+
+// A struct supplying shallow data() const.
+struct ContainerWithShallowConstData {
+  std::vector<int> storage;
+  int* data() const { return const_cast<int*>(storage.data()); }
+  int size() const { return storage.size(); }
+};
+
+TEST(IntSpan, ShallowConstness) {
+  const ContainerWithShallowConstData c{MakeRamp(20)};
+  absl::Span<int> s(
+      c);  // We should be able to do this even though data() is const.
+  s[0] = -1;
+  EXPECT_EQ(c.storage[0], -1);
+}
+
+TEST(CharSpan, StringCtor) {
+  std::string empty = "";
+  absl::Span<char> s_empty(empty);
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::string abc = "abc";
+  absl::Span<char> s_abc(abc);
+  EXPECT_THAT(s_abc, SpanIs(abc));
+
+  absl::Span<const char> s_const_abc = abc;
+  EXPECT_THAT(s_const_abc, SpanIs(abc));
+
+  EXPECT_FALSE((std::is_constructible<absl::Span<int>, std::string>::value));
+  EXPECT_FALSE((std::is_constructible<absl::Span<const int>, std::string>::value));
+  EXPECT_TRUE((std::is_convertible<std::string, absl::Span<const char>>::value));
+}
+
+TEST(IntSpan, FromConstPointer) {
+  EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>,
+                                     std::vector<int*>>::value));
+  EXPECT_TRUE((std::is_constructible<absl::Span<const int* const>,
+                                     std::vector<const int*>>::value));
+  EXPECT_FALSE((
+      std::is_constructible<absl::Span<const int*>, std::vector<int*>>::value));
+  EXPECT_FALSE((
+      std::is_constructible<absl::Span<int*>, std::vector<const int*>>::value));
+}
+
+struct TypeWithMisleadingData {
+  int& data() { return i; }
+  int size() { return 1; }
+  int i;
+};
+
+struct TypeWithMisleadingSize {
+  int* data() { return &i; }
+  const char* size() { return "1"; }
+  int i;
+};
+
+TEST(IntSpan, EvilTypes) {
+  EXPECT_FALSE(
+      (std::is_constructible<absl::Span<int>, TypeWithMisleadingData&>::value));
+  EXPECT_FALSE(
+      (std::is_constructible<absl::Span<int>, TypeWithMisleadingSize&>::value));
+}
+
+struct Base {
+  int* data() { return &i; }
+  int size() { return 1; }
+  int i;
+};
+struct Derived : Base {};
+
+TEST(IntSpan, SpanOfDerived) {
+  EXPECT_TRUE((std::is_constructible<absl::Span<int>, Base&>::value));
+  EXPECT_TRUE((std::is_constructible<absl::Span<int>, Derived&>::value));
+  EXPECT_FALSE(
+      (std::is_constructible<absl::Span<Base>, std::vector<Derived>>::value));
+}
+
+void TestInitializerList(absl::Span<const int> s, const std::vector<int>& v) {
+  EXPECT_TRUE(absl::equal(s.begin(), s.end(), v.begin(), v.end()));
+}
+
+TEST(ConstIntSpan, InitializerListConversion) {
+  TestInitializerList({}, {});
+  TestInitializerList({1}, {1});
+  TestInitializerList({1, 2, 3}, {1, 2, 3});
+
+  EXPECT_FALSE((std::is_constructible<absl::Span<int>,
+                                      std::initializer_list<int>>::value));
+  EXPECT_FALSE((
+      std::is_convertible<absl::Span<int>, std::initializer_list<int>>::value));
+}
+
+TEST(IntSpan, Data) {
+  int i;
+  absl::Span<int> s(&i, 1);
+  EXPECT_EQ(&i, s.data());
+}
+
+TEST(IntSpan, SizeLengthEmpty) {
+  absl::Span<int> empty;
+  EXPECT_EQ(empty.size(), 0);
+  EXPECT_TRUE(empty.empty());
+  EXPECT_EQ(empty.size(), empty.length());
+
+  auto v = MakeRamp(10);
+  absl::Span<int> s(v);
+  EXPECT_EQ(s.size(), 10);
+  EXPECT_FALSE(s.empty());
+  EXPECT_EQ(s.size(), s.length());
+}
+
+TEST(IntSpan, ElementAccess) {
+  auto v = MakeRamp(10);
+  absl::Span<int> s(v);
+  for (int i = 0; i < s.size(); ++i) {
+    EXPECT_EQ(s[i], s.at(i));
+  }
+
+  EXPECT_EQ(s.front(), s[0]);
+  EXPECT_EQ(s.back(), s[9]);
+}
+
+TEST(IntSpan, AtThrows) {
+  auto v = MakeRamp(10);
+  absl::Span<int> s(v);
+
+  EXPECT_EQ(s.at(9), 9);
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(s.at(10), std::out_of_range,
+                                 "failed bounds check");
+}
+
+TEST(IntSpan, RemovePrefixAndSuffix) {
+  auto v = MakeRamp(20, 1);
+  absl::Span<int> s(v);
+  EXPECT_EQ(s.size(), 20);
+
+  s.remove_suffix(0);
+  s.remove_prefix(0);
+  EXPECT_EQ(s.size(), 20);
+
+  s.remove_prefix(1);
+  EXPECT_EQ(s.size(), 19);
+  EXPECT_EQ(s[0], 2);
+
+  s.remove_suffix(1);
+  EXPECT_EQ(s.size(), 18);
+  EXPECT_EQ(s.back(), 19);
+
+  s.remove_prefix(7);
+  EXPECT_EQ(s.size(), 11);
+  EXPECT_EQ(s[0], 9);
+
+  s.remove_suffix(11);
+  EXPECT_EQ(s.size(), 0);
+
+  EXPECT_EQ(v, MakeRamp(20, 1));
+}
+
+TEST(IntSpan, Subspan) {
+  std::vector<int> empty;
+  EXPECT_EQ(absl::MakeSpan(empty).subspan(), empty);
+  EXPECT_THAT(absl::MakeSpan(empty).subspan(0, 0), SpanIs(empty));
+  EXPECT_THAT(absl::MakeSpan(empty).subspan(0, absl::Span<const int>::npos),
+              SpanIs(empty));
+
+  auto ramp = MakeRamp(10);
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(), SpanIs(ramp));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, 10), SpanIs(ramp));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, absl::Span<const int>::npos),
+              SpanIs(ramp));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(0, 3), SpanIs(ramp.data(), 3));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(5, absl::Span<const int>::npos),
+              SpanIs(ramp.data() + 5, 5));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(3, 3), SpanIs(ramp.data() + 3, 3));
+  EXPECT_THAT(absl::MakeSpan(ramp).subspan(10, 5), SpanIs(ramp.data() + 10, 0));
+
+#ifdef ABSL_HAVE_EXCEPTIONS
+  EXPECT_THROW(absl::MakeSpan(ramp).subspan(11, 5), std::out_of_range);
+#else
+  EXPECT_DEATH(absl::MakeSpan(ramp).subspan(11, 5), "");
+#endif
+}
+
+TEST(IntSpan, MakeSpanPtrLength) {
+  std::vector<int> empty;
+  auto s_empty = absl::MakeSpan(empty.data(), empty.size());
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::array<int, 3> a{{1, 2, 3}};
+  auto s = absl::MakeSpan(a.data(), a.size());
+  EXPECT_THAT(s, SpanIs(a));
+
+  EXPECT_THAT(absl::MakeConstSpan(empty.data(), empty.size()), SpanIs(s_empty));
+  EXPECT_THAT(absl::MakeConstSpan(a.data(), a.size()), SpanIs(s));
+}
+
+TEST(IntSpan, MakeSpanTwoPtrs) {
+  std::vector<int> empty;
+  auto s_empty = absl::MakeSpan(empty.data(), empty.data());
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::vector<int> v{1, 2, 3};
+  auto s = absl::MakeSpan(v.data(), v.data() + 1);
+  EXPECT_THAT(s, SpanIs(v.data(), 1));
+
+  EXPECT_THAT(absl::MakeConstSpan(empty.data(), empty.data()), SpanIs(s_empty));
+  EXPECT_THAT(absl::MakeConstSpan(v.data(), v.data() + 1), SpanIs(s));
+}
+
+TEST(IntSpan, MakeSpanContainer) {
+  std::vector<int> empty;
+  auto s_empty = absl::MakeSpan(empty);
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::vector<int> v{1, 2, 3};
+  auto s = absl::MakeSpan(v);
+  EXPECT_THAT(s, SpanIs(v));
+
+  EXPECT_THAT(absl::MakeConstSpan(empty), SpanIs(s_empty));
+  EXPECT_THAT(absl::MakeConstSpan(v), SpanIs(s));
+
+  EXPECT_THAT(absl::MakeSpan(s), SpanIs(s));
+  EXPECT_THAT(absl::MakeConstSpan(s), SpanIs(s));
+}
+
+TEST(CharSpan, MakeSpanString) {
+  std::string empty = "";
+  auto s_empty = absl::MakeSpan(empty);
+  EXPECT_THAT(s_empty, SpanIs(empty));
+
+  std::string str = "abc";
+  auto s_str = absl::MakeSpan(str);
+  EXPECT_THAT(s_str, SpanIs(str));
+
+  EXPECT_THAT(absl::MakeConstSpan(empty), SpanIs(s_empty));
+  EXPECT_THAT(absl::MakeConstSpan(str), SpanIs(s_str));
+}
+
+TEST(IntSpan, MakeSpanArray) {
+  int a[] = {1, 2, 3};
+  auto s = absl::MakeSpan(a);
+  EXPECT_THAT(s, SpanIs(a, 3));
+
+  const int ca[] = {1, 2, 3};
+  auto s_ca = absl::MakeSpan(ca);
+  EXPECT_THAT(s_ca, SpanIs(ca, 3));
+
+  EXPECT_THAT(absl::MakeConstSpan(a), SpanIs(s));
+  EXPECT_THAT(absl::MakeConstSpan(ca), SpanIs(s_ca));
+}
+
+// Compile-asserts that the argument has the expected decayed type.
+template <typename Expected, typename T>
+void CheckType(const T& /* value */) {
+  testing::StaticAssertTypeEq<Expected, T>();
+}
+
+TEST(IntSpan, MakeSpanTypes) {
+  std::vector<int> vec;
+  const std::vector<int> cvec;
+  int a[1];
+  const int ca[] = {1};
+  int* ip = a;
+  const int* cip = ca;
+  std::string s = "";
+  const std::string cs = "";
+  CheckType<absl::Span<int>>(absl::MakeSpan(vec));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(cvec));
+  CheckType<absl::Span<int>>(absl::MakeSpan(ip, ip + 1));
+  CheckType<absl::Span<int>>(absl::MakeSpan(ip, 1));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(cip, cip + 1));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(cip, 1));
+  CheckType<absl::Span<int>>(absl::MakeSpan(a));
+  CheckType<absl::Span<int>>(absl::MakeSpan(a, a + 1));
+  CheckType<absl::Span<int>>(absl::MakeSpan(a, 1));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(ca));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(ca, ca + 1));
+  CheckType<absl::Span<const int>>(absl::MakeSpan(ca, 1));
+  CheckType<absl::Span<char>>(absl::MakeSpan(s));
+  CheckType<absl::Span<const char>>(absl::MakeSpan(cs));
+}
+
+TEST(ConstIntSpan, MakeConstSpanTypes) {
+  std::vector<int> vec;
+  const std::vector<int> cvec;
+  int array[1];
+  const int carray[] = {0};
+  int* ptr = array;
+  const int* cptr = carray;
+  std::string s = "";
+  std::string cs = "";
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(vec));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(cvec));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(ptr, ptr + 1));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(ptr, 1));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(cptr, cptr + 1));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(cptr, 1));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(array));
+  CheckType<absl::Span<const int>>(absl::MakeConstSpan(carray));
+  CheckType<absl::Span<const char>>(absl::MakeConstSpan(s));
+  CheckType<absl::Span<const char>>(absl::MakeConstSpan(cs));
+}
+
+TEST(IntSpan, Equality) {
+  const int arr1[] = {1, 2, 3, 4, 5};
+  int arr2[] = {1, 2, 3, 4, 5};
+  std::vector<int> vec1(std::begin(arr1), std::end(arr1));
+  std::vector<int> vec2 = vec1;
+  std::vector<int> other_vec = {2, 4, 6, 8, 10};
+  // These two slices are from different vectors, but have the same size and
+  // have the same elements (right now).  They should compare equal. Test both
+  // == and !=.
+  const absl::Span<const int> from1 = vec1;
+  const absl::Span<const int> from2 = vec2;
+  EXPECT_EQ(from1, from1);
+  EXPECT_FALSE(from1 != from1);
+  EXPECT_EQ(from1, from2);
+  EXPECT_FALSE(from1 != from2);
+
+  // These two slices have different underlying vector values. They should be
+  // considered not equal. Test both == and !=.
+  const absl::Span<const int> from_other = other_vec;
+  EXPECT_NE(from1, from_other);
+  EXPECT_FALSE(from1 == from_other);
+
+  // Comparison between a vector and its slice should be equal. And vice-versa.
+  // This ensures implicit conversion to Span works on both sides of ==.
+  EXPECT_EQ(vec1, from1);
+  EXPECT_FALSE(vec1 != from1);
+  EXPECT_EQ(from1, vec1);
+  EXPECT_FALSE(from1 != vec1);
+
+  // This verifies that absl::Span<T> can be compared freely with
+  // absl::Span<const T>.
+  const absl::Span<int> mutable_from1(vec1);
+  const absl::Span<int> mutable_from2(vec2);
+  EXPECT_EQ(from1, mutable_from1);
+  EXPECT_EQ(mutable_from1, from1);
+  EXPECT_EQ(mutable_from1, mutable_from2);
+  EXPECT_EQ(mutable_from2, mutable_from1);
+
+  // Comparison between a vector and its slice should be equal for mutable
+  // Spans as well.
+  EXPECT_EQ(vec1, mutable_from1);
+  EXPECT_FALSE(vec1 != mutable_from1);
+  EXPECT_EQ(mutable_from1, vec1);
+  EXPECT_FALSE(mutable_from1 != vec1);
+
+  // Comparison between convertible-to-Span-of-const and Span-of-mutable. Arrays
+  // are used because they're the only value type which converts to a
+  // Span-of-mutable. EXPECT_TRUE is used instead of EXPECT_EQ to avoid
+  // array-to-pointer decay.
+  EXPECT_TRUE(arr1 == mutable_from1);
+  EXPECT_FALSE(arr1 != mutable_from1);
+  EXPECT_TRUE(mutable_from1 == arr1);
+  EXPECT_FALSE(mutable_from1 != arr1);
+
+  // Comparison between convertible-to-Span-of-mutable and Span-of-const
+  EXPECT_TRUE(arr2 == from1);
+  EXPECT_FALSE(arr2 != from1);
+  EXPECT_TRUE(from1 == arr2);
+  EXPECT_FALSE(from1 != arr2);
+
+  // With a different size, the array slices should not be equal.
+  EXPECT_NE(from1, absl::Span<const int>(from1).subspan(0, from1.size() - 1));
+
+  // With different contents, the array slices should not be equal.
+  ++vec2.back();
+  EXPECT_NE(from1, from2);
+}
+
+class IntSpanOrderComparisonTest : public testing::Test {
+ public:
+  IntSpanOrderComparisonTest()
+      : arr_before_{1, 2, 3},
+        arr_after_{1, 2, 4},
+        carr_after_{1, 2, 4},
+        vec_before_(std::begin(arr_before_), std::end(arr_before_)),
+        vec_after_(std::begin(arr_after_), std::end(arr_after_)),
+        before_(vec_before_),
+        after_(vec_after_),
+        cbefore_(vec_before_),
+        cafter_(vec_after_) {}
+
+ protected:
+  int arr_before_[3], arr_after_[3];
+  const int carr_after_[3];
+  std::vector<int> vec_before_, vec_after_;
+  absl::Span<int> before_, after_;
+  absl::Span<const int> cbefore_, cafter_;
+};
+
+TEST_F(IntSpanOrderComparisonTest, CompareSpans) {
+  EXPECT_TRUE(cbefore_ < cafter_);
+  EXPECT_TRUE(cbefore_ <= cafter_);
+  EXPECT_TRUE(cafter_ > cbefore_);
+  EXPECT_TRUE(cafter_ >= cbefore_);
+
+  EXPECT_FALSE(cbefore_ > cafter_);
+  EXPECT_FALSE(cafter_ < cbefore_);
+
+  EXPECT_TRUE(before_ < after_);
+  EXPECT_TRUE(before_ <= after_);
+  EXPECT_TRUE(after_ > before_);
+  EXPECT_TRUE(after_ >= before_);
+
+  EXPECT_FALSE(before_ > after_);
+  EXPECT_FALSE(after_ < before_);
+
+  EXPECT_TRUE(cbefore_ < after_);
+  EXPECT_TRUE(cbefore_ <= after_);
+  EXPECT_TRUE(after_ > cbefore_);
+  EXPECT_TRUE(after_ >= cbefore_);
+
+  EXPECT_FALSE(cbefore_ > after_);
+  EXPECT_FALSE(after_ < cbefore_);
+}
+
+TEST_F(IntSpanOrderComparisonTest, SpanOfConstAndContainer) {
+  EXPECT_TRUE(cbefore_ < vec_after_);
+  EXPECT_TRUE(cbefore_ <= vec_after_);
+  EXPECT_TRUE(vec_after_ > cbefore_);
+  EXPECT_TRUE(vec_after_ >= cbefore_);
+
+  EXPECT_FALSE(cbefore_ > vec_after_);
+  EXPECT_FALSE(vec_after_ < cbefore_);
+
+  EXPECT_TRUE(arr_before_ < cafter_);
+  EXPECT_TRUE(arr_before_ <= cafter_);
+  EXPECT_TRUE(cafter_ > arr_before_);
+  EXPECT_TRUE(cafter_ >= arr_before_);
+
+  EXPECT_FALSE(arr_before_ > cafter_);
+  EXPECT_FALSE(cafter_ < arr_before_);
+}
+
+TEST_F(IntSpanOrderComparisonTest, SpanOfMutableAndContainer) {
+  EXPECT_TRUE(vec_before_ < after_);
+  EXPECT_TRUE(vec_before_ <= after_);
+  EXPECT_TRUE(after_ > vec_before_);
+  EXPECT_TRUE(after_ >= vec_before_);
+
+  EXPECT_FALSE(vec_before_ > after_);
+  EXPECT_FALSE(after_ < vec_before_);
+
+  EXPECT_TRUE(before_ < carr_after_);
+  EXPECT_TRUE(before_ <= carr_after_);
+  EXPECT_TRUE(carr_after_ > before_);
+  EXPECT_TRUE(carr_after_ >= before_);
+
+  EXPECT_FALSE(before_ > carr_after_);
+  EXPECT_FALSE(carr_after_ < before_);
+}
+
+TEST_F(IntSpanOrderComparisonTest, EqualSpans) {
+  EXPECT_FALSE(before_ < before_);
+  EXPECT_TRUE(before_ <= before_);
+  EXPECT_FALSE(before_ > before_);
+  EXPECT_TRUE(before_ >= before_);
+}
+
+TEST_F(IntSpanOrderComparisonTest, Subspans) {
+  auto subspan = before_.subspan(0, 1);
+  EXPECT_TRUE(subspan < before_);
+  EXPECT_TRUE(subspan <= before_);
+  EXPECT_TRUE(before_ > subspan);
+  EXPECT_TRUE(before_ >= subspan);
+
+  EXPECT_FALSE(subspan > before_);
+  EXPECT_FALSE(before_ < subspan);
+}
+
+TEST_F(IntSpanOrderComparisonTest, EmptySpans) {
+  absl::Span<int> empty;
+  EXPECT_FALSE(empty < empty);
+  EXPECT_TRUE(empty <= empty);
+  EXPECT_FALSE(empty > empty);
+  EXPECT_TRUE(empty >= empty);
+
+  EXPECT_TRUE(empty < before_);
+  EXPECT_TRUE(empty <= before_);
+  EXPECT_TRUE(before_ > empty);
+  EXPECT_TRUE(before_ >= empty);
+
+  EXPECT_FALSE(empty > before_);
+  EXPECT_FALSE(before_ < empty);
+}
+
+TEST(IntSpan, ExposesContainerTypesAndConsts) {
+  absl::Span<int> slice;
+  CheckType<absl::Span<int>::iterator>(slice.begin());
+  EXPECT_TRUE((std::is_convertible<decltype(slice.begin()),
+                                   absl::Span<int>::const_iterator>::value));
+  CheckType<absl::Span<int>::const_iterator>(slice.cbegin());
+  EXPECT_TRUE((std::is_convertible<decltype(slice.end()),
+                                   absl::Span<int>::const_iterator>::value));
+  CheckType<absl::Span<int>::const_iterator>(slice.cend());
+  CheckType<absl::Span<int>::reverse_iterator>(slice.rend());
+  EXPECT_TRUE(
+      (std::is_convertible<decltype(slice.rend()),
+                           absl::Span<int>::const_reverse_iterator>::value));
+  CheckType<absl::Span<int>::const_reverse_iterator>(slice.crend());
+  testing::StaticAssertTypeEq<int, absl::Span<int>::value_type>();
+  testing::StaticAssertTypeEq<int, absl::Span<const int>::value_type>();
+  testing::StaticAssertTypeEq<int*, absl::Span<int>::pointer>();
+  testing::StaticAssertTypeEq<const int*, absl::Span<const int>::pointer>();
+  testing::StaticAssertTypeEq<int&, absl::Span<int>::reference>();
+  testing::StaticAssertTypeEq<const int&, absl::Span<const int>::reference>();
+  testing::StaticAssertTypeEq<const int&, absl::Span<int>::const_reference>();
+  testing::StaticAssertTypeEq<const int&,
+                              absl::Span<const int>::const_reference>();
+  EXPECT_EQ(static_cast<absl::Span<int>::size_type>(-1), absl::Span<int>::npos);
+}
+
+TEST(IntSpan, IteratorsAndReferences) {
+  auto accept_pointer = [](int*) {};
+  auto accept_reference = [](int&) {};
+  auto accept_iterator = [](absl::Span<int>::iterator) {};
+  auto accept_const_iterator = [](absl::Span<int>::const_iterator) {};
+  auto accept_reverse_iterator = [](absl::Span<int>::reverse_iterator) {};
+  auto accept_const_reverse_iterator =
+      [](absl::Span<int>::const_reverse_iterator) {};
+
+  int a[1];
+  absl::Span<int> s = a;
+
+  accept_pointer(s.data());
+  accept_iterator(s.begin());
+  accept_const_iterator(s.begin());
+  accept_const_iterator(s.cbegin());
+  accept_iterator(s.end());
+  accept_const_iterator(s.end());
+  accept_const_iterator(s.cend());
+  accept_reverse_iterator(s.rbegin());
+  accept_const_reverse_iterator(s.rbegin());
+  accept_const_reverse_iterator(s.crbegin());
+  accept_reverse_iterator(s.rend());
+  accept_const_reverse_iterator(s.rend());
+  accept_const_reverse_iterator(s.crend());
+
+  accept_reference(s[0]);
+  accept_reference(s.at(0));
+  accept_reference(s.front());
+  accept_reference(s.back());
+}
+
+TEST(IntSpan, IteratorsAndReferences_Const) {
+  auto accept_pointer = [](int*) {};
+  auto accept_reference = [](int&) {};
+  auto accept_iterator = [](absl::Span<int>::iterator) {};
+  auto accept_const_iterator = [](absl::Span<int>::const_iterator) {};
+  auto accept_reverse_iterator = [](absl::Span<int>::reverse_iterator) {};
+  auto accept_const_reverse_iterator =
+      [](absl::Span<int>::const_reverse_iterator) {};
+
+  int a[1];
+  const absl::Span<int> s = a;
+
+  accept_pointer(s.data());
+  accept_iterator(s.begin());
+  accept_const_iterator(s.begin());
+  accept_const_iterator(s.cbegin());
+  accept_iterator(s.end());
+  accept_const_iterator(s.end());
+  accept_const_iterator(s.cend());
+  accept_reverse_iterator(s.rbegin());
+  accept_const_reverse_iterator(s.rbegin());
+  accept_const_reverse_iterator(s.crbegin());
+  accept_reverse_iterator(s.rend());
+  accept_const_reverse_iterator(s.rend());
+  accept_const_reverse_iterator(s.crend());
+
+  accept_reference(s[0]);
+  accept_reference(s.at(0));
+  accept_reference(s.front());
+  accept_reference(s.back());
+}
+
+TEST(IntSpan, NoexceptTest) {
+  int a[] = {1, 2, 3};
+  std::vector<int> v;
+  EXPECT_TRUE(noexcept(absl::Span<const int>()));
+  EXPECT_TRUE(noexcept(absl::Span<const int>(a, 2)));
+  EXPECT_TRUE(noexcept(absl::Span<const int>(a)));
+  EXPECT_TRUE(noexcept(absl::Span<const int>(v)));
+  EXPECT_TRUE(noexcept(absl::Span<int>(v)));
+  EXPECT_TRUE(noexcept(absl::Span<const int>({1, 2, 3})));
+  EXPECT_TRUE(noexcept(absl::MakeSpan(v)));
+  EXPECT_TRUE(noexcept(absl::MakeSpan(a)));
+  EXPECT_TRUE(noexcept(absl::MakeSpan(a, 2)));
+  EXPECT_TRUE(noexcept(absl::MakeSpan(a, a + 1)));
+  EXPECT_TRUE(noexcept(absl::MakeConstSpan(v)));
+  EXPECT_TRUE(noexcept(absl::MakeConstSpan(a)));
+  EXPECT_TRUE(noexcept(absl::MakeConstSpan(a, 2)));
+  EXPECT_TRUE(noexcept(absl::MakeConstSpan(a, a + 1)));
+
+  absl::Span<int> s(v);
+  EXPECT_TRUE(noexcept(s.data()));
+  EXPECT_TRUE(noexcept(s.size()));
+  EXPECT_TRUE(noexcept(s.length()));
+  EXPECT_TRUE(noexcept(s.empty()));
+  EXPECT_TRUE(noexcept(s[0]));
+  EXPECT_TRUE(noexcept(s.front()));
+  EXPECT_TRUE(noexcept(s.back()));
+  EXPECT_TRUE(noexcept(s.begin()));
+  EXPECT_TRUE(noexcept(s.cbegin()));
+  EXPECT_TRUE(noexcept(s.end()));
+  EXPECT_TRUE(noexcept(s.cend()));
+  EXPECT_TRUE(noexcept(s.rbegin()));
+  EXPECT_TRUE(noexcept(s.crbegin()));
+  EXPECT_TRUE(noexcept(s.rend()));
+  EXPECT_TRUE(noexcept(s.crend()));
+  EXPECT_TRUE(noexcept(s.remove_prefix(0)));
+  EXPECT_TRUE(noexcept(s.remove_suffix(0)));
+}
+
+// ConstexprTester exercises expressions in a constexpr context. Simply placing
+// the expression in a constexpr function is not enough, as some compilers will
+// simply compile the constexpr function as runtime code. Using template
+// parameters forces compile-time execution.
+template <int i>
+struct ConstexprTester {};
+
+#define ABSL_TEST_CONSTEXPR(expr)                       \
+  do {                                                  \
+    ABSL_ATTRIBUTE_UNUSED ConstexprTester<(expr, 1)> t; \
+  } while (0)
+
+struct ContainerWithConstexprMethods {
+  constexpr int size() const { return 1; }
+  constexpr const int* data() const { return &i; }
+  const int i;
+};
+
+TEST(ConstIntSpan, ConstexprTest) {
+  static constexpr int a[] = {1, 2, 3};
+  static constexpr int sized_arr[2] = {1, 2};
+  static constexpr ContainerWithConstexprMethods c{1};
+  ABSL_TEST_CONSTEXPR(absl::Span<const int>());
+  ABSL_TEST_CONSTEXPR(absl::Span<const int>(a, 2));
+  ABSL_TEST_CONSTEXPR(absl::Span<const int>(sized_arr));
+  ABSL_TEST_CONSTEXPR(absl::Span<const int>(c));
+  ABSL_TEST_CONSTEXPR(absl::MakeSpan(&a[0], 1));
+  ABSL_TEST_CONSTEXPR(absl::MakeSpan(c));
+  ABSL_TEST_CONSTEXPR(absl::MakeSpan(a));
+  ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(&a[0], 1));
+  ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(c));
+  ABSL_TEST_CONSTEXPR(absl::MakeConstSpan(a));
+
+  constexpr absl::Span<const int> span = c;
+  ABSL_TEST_CONSTEXPR(span.data());
+  ABSL_TEST_CONSTEXPR(span.size());
+  ABSL_TEST_CONSTEXPR(span.length());
+  ABSL_TEST_CONSTEXPR(span.empty());
+  ABSL_TEST_CONSTEXPR(span.begin());
+  ABSL_TEST_CONSTEXPR(span.cbegin());
+  ABSL_TEST_CONSTEXPR(span.subspan(0, 0));
+  ABSL_TEST_CONSTEXPR(span[0]);
+}
+
+struct BigStruct {
+  char bytes[10000];
+};
+
+TEST(Span, SpanSize) {
+  EXPECT_LE(sizeof(absl::Span<int>), 2 * sizeof(void*));
+  EXPECT_LE(sizeof(absl::Span<BigStruct>), 2 * sizeof(void*));
+}
+
+}  // namespace

http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/types/variant.h
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/types/variant.h b/libraries/ostrich/backend/3rdparty/abseil/absl/types/variant.h
new file mode 100644
index 0000000..52a311e
--- /dev/null
+++ b/libraries/ostrich/backend/3rdparty/abseil/absl/types/variant.h
@@ -0,0 +1,838 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      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.
+//
+// -----------------------------------------------------------------------------
+// variant.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines an `absl::variant` type for holding a type-safe
+// value of some prescribed set of types (noted as alternative types), and
+// associated functions for managing variants.
+//
+// The `absl::variant` type is a form of type-safe union. An `absl::variant`
+// should always hold a value of one of its alternative types (except in the
+// "valueless by exception state" -- see below). A default-constructed
+// `absl::variant` will hold the value of its first alternative type, provided
+// it is default-constructable.
+//
+// In exceptional cases due to error, an `absl::variant` can hold no
+// value (known as a "valueless by exception" state), though this is not the
+// norm.
+//
+// As with `absl::optional`, an `absl::variant` -- when it holds a value --
+// allocates a value of that type directly within the `variant` itself; it
+// cannot hold a reference, array, or the type `void`; it can, however, hold a
+// pointer to externally managed memory.
+//
+// `absl::variant` is a C++11 compatible version of the C++17 `std::variant`
+// abstraction and is designed to be a drop-in replacement for code compliant
+// with C++17.
+
+#ifndef ABSL_TYPES_VARIANT_H_
+#define ABSL_TYPES_VARIANT_H_
+
+#include "absl/base/config.h"
+#include "absl/utility/utility.h"
+
+#ifdef ABSL_HAVE_STD_VARIANT
+
+#include <variant>
+
+namespace absl {
+using std::bad_variant_access;
+using std::get;
+using std::get_if;
+using std::holds_alternative;
+using std::monostate;
+using std::variant;
+using std::variant_alternative;
+using std::variant_alternative_t;
+using std::variant_npos;
+using std::variant_size;
+using std::variant_size_v;
+using std::visit;
+}  // namespace absl
+
+#else  // ABSL_HAVE_STD_VARIANT
+
+#include <functional>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/base/port.h"
+#include "absl/meta/type_traits.h"
+#include "absl/types/internal/variant.h"
+
+namespace absl {
+
+// -----------------------------------------------------------------------------
+// absl::variant
+// -----------------------------------------------------------------------------
+//
+// An 'absl::variant` type is a form of type-safe union. An `absl::variant` --
+// except in exceptional cases -- always holds a value of one of its alternative
+// types.
+//
+// Example:
+//
+//   // Construct a variant that holds either an integer or a std::string and
+//   // assign it to a std::string.
+//   absl::variant<int, std::string> v = std::string("abc");
+//
+//   // A default-contructed variant will hold a value-initialized value of
+//   // the first alternative type.
+//   auto a = absl::variant<int, std::string>();   // Holds an int of value '0'.
+//
+//   // variants are assignable.
+//
+//   // copy assignment
+//   auto v1 = absl::variant<int, std::string>("abc");
+//   auto v2 = absl::variant<int, std::string>(10);
+//   v2 = v1;  // copy assign
+//
+//   // move assignment
+//   auto v1 = absl::variant<int, std::string>("abc");
+//   v1 = absl::variant<int, std::string>(10);
+//
+//   // assignment through type conversion
+//   a = 128;         // variant contains int
+//   a = "128";       // variant contains std::string
+//
+// An `absl::variant` holding a value of one of its alternative types `T` holds
+// an allocation of `T` directly within the variant itself. An `absl::variant`
+// is not allowed to allocate additional storage, such as dynamic memory, to
+// allocate the contained value. The contained value shall be allocated in a
+// region of the variant storage suitably aligned for all alternative types.
+template <typename... Ts>
+class variant;
+
+// swap()
+//
+// Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)`
+// where `v` and `w` are `absl::variant` types.
+//
+// Note that this function requires all alternative types to be both swappable
+// and move-constructible, because any two variants may refer to either the same
+// type (in which case, they will be swapped) or to two different types (in
+// which case the values will need to be moved).
+//
+template <typename... Ts>
+void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
+  v.swap(w);
+}
+
+// variant_size
+//
+// Returns the number of alterative types available for a given `absl::variant`
+// type as a compile-time constant expression. As this is a class template, it
+// is not generally useful for accessing the number of alternative types of
+// any given `absl::variant` instance.
+//
+// Example:
+//
+//   auto a = absl::variant<int, std::string>;
+//   constexpr int num_types =
+//       absl::variant_size<absl::variant<int, std::string>>();
+//
+//   // You can also use the member constant `value`.
+//   constexpr int num_types =
+//       absl::variant_size<absl::variant<int, std::string>>::value;
+//
+//   // `absl::variant_size` is more valuable for use in generic code:
+//   template <typename Variant>
+//   constexpr bool IsVariantMultivalue() {
+//       return absl::variant_size<Variant>() > 1;
+//   }
+//
+// Note that the set of cv-qualified specializations of `variant_size` are
+// provided to ensure that those specializations compile (especially when passed
+// within template logic).
+template <class T>
+struct variant_size;
+
+template <class... Ts>
+struct variant_size<variant<Ts...>>
+    : std::integral_constant<std::size_t, sizeof...(Ts)> {};
+
+// Specialization of `variant_size` for const qualified variants.
+template <class T>
+struct variant_size<const T> : variant_size<T>::type {};
+
+// Specialization of `variant_size` for volatile qualified variants.
+template <class T>
+struct variant_size<volatile T> : variant_size<T>::type {};
+
+// Specialization of `variant_size` for const volatile qualified variants.
+template <class T>
+struct variant_size<const volatile T> : variant_size<T>::type {};
+
+// variant_alternative
+//
+// Returns the alternative type for a given `absl::variant` at the passed
+// index value as a compile-time constant expression. As this is a class
+// template resulting in a type, it is not useful for access of the run-time
+// value of any given `absl::variant` variable.
+//
+// Example:
+//
+//   // The type of the 0th alternative is "int".
+//   using alternative_type_0
+//     = absl::variant_alternative<0, absl::variant<int, std::string>>::type;
+//
+//   static_assert(std::is_same<alternative_type_0, int>::value, "");
+//
+//   // `absl::variant_alternative` is more valuable for use in generic code:
+//   template <typename Variant>
+//   constexpr bool IsFirstElementTrivial() {
+//       return std::is_trivial_v<variant_alternative<0, Variant>::type>;
+//   }
+//
+// Note that the set of cv-qualified specializations of `variant_alternative`
+// are provided to ensure that those specializations compile (especially when
+// passed within template logic).
+template <std::size_t I, class T>
+struct variant_alternative;
+
+template <std::size_t I, class... Types>
+struct variant_alternative<I, variant<Types...>> {
+  using type =
+      variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
+};
+
+// Specialization of `variant_alternative` for const qualified variants.
+template <std::size_t I, class T>
+struct variant_alternative<I, const T> {
+  using type = const typename variant_alternative<I, T>::type;
+};
+
+// Specialization of `variant_alternative` for volatile qualified variants.
+template <std::size_t I, class T>
+struct variant_alternative<I, volatile T> {
+  using type = volatile typename variant_alternative<I, T>::type;
+};
+
+// Specialization of `variant_alternative` for const volatile qualified
+// variants.
+template <std::size_t I, class T>
+struct variant_alternative<I, const volatile T> {
+  using type = const volatile typename variant_alternative<I, T>::type;
+};
+
+// Template type alias for variant_alternative<I, T>::type.
+//
+// Example:
+//
+//   using alternative_type_0
+//     = absl::variant_alternative_t<0, absl::variant<int, std::string>>;
+//   static_assert(std::is_same<alternative_type_0, int>::value, "");
+template <std::size_t I, class T>
+using variant_alternative_t = typename variant_alternative<I, T>::type;
+
+// holds_alternative()
+//
+// Checks whether the given variant currently holds a given alternative type,
+// returning `true` if so.
+//
+// Example:
+//
+//   absl::variant<int, std::string> bar = 42;
+//   if (absl::holds_alternative<int>(foo)) {
+//       std::cout << "The variant holds an integer";
+//   }
+template <class T, class... Types>
+constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
+  static_assert(
+      variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
+                                               0>::value != sizeof...(Types),
+      "The type T must occur exactly once in Types...");
+  return v.index() ==
+         variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
+}
+
+// get()
+//
+// Returns a reference to the value currently within a given variant, using
+// either a unique alternative type amongst the variant's set of alternative
+// types, or the variant's index value. Attempting to get a variant's value
+// using a type that is not unique within the variant's set of alternative types
+// is a compile-time error. If the index of the alternative being specified is
+// different from the index of the alternative that is currently stored, throws
+// `absl::bad_variant_access`.
+//
+// Example:
+//
+//   auto a = absl::variant<int, std::string>;
+//
+//   // Get the value by type (if unique).
+//   int i = absl::get<int>(a);
+//
+//   auto b = absl::variant<int, int>;
+//
+//   // Getting the value by a type that is not unique is ill-formed.
+//   int j = absl::get<int>(b);     // Compile Error!
+//
+//   // Getting value by index not ambiguous and allowed.
+//   int k = absl::get<1>(b);
+
+// Overload for getting a variant's lvalue by type.
+template <class T, class... Types>
+constexpr T& get(variant<Types...>& v) {  // NOLINT
+  return variant_internal::VariantCoreAccess::Access<
+      variant_internal::IndexOf<T, Types...>::value>(v);
+}
+
+// Overload for getting a variant's rvalue by type.
+// Note: `absl::move()` is required to allow use of constexpr in C++11.
+template <class T, class... Types>
+constexpr T&& get(variant<Types...>&& v) {
+  return variant_internal::VariantCoreAccess::Access<
+      variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
+}
+
+// Overload for getting a variant's const lvalue by type.
+template <class T, class... Types>
+constexpr const T& get(const variant<Types...>& v) {
+  return variant_internal::VariantCoreAccess::Access<
+      variant_internal::IndexOf<T, Types...>::value>(v);
+}
+
+// Overload for getting a variant's const rvalue by type.
+// Note: `absl::move()` is required to allow use of constexpr in C++11.
+template <class T, class... Types>
+constexpr const T&& get(const variant<Types...>&& v) {
+  return variant_internal::VariantCoreAccess::Access<
+      variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
+}
+
+// Overload for getting a variant's lvalue by index.
+template <std::size_t I, class... Types>
+constexpr variant_alternative_t<I, variant<Types...>>& get(
+    variant<Types...>& v) {  // NOLINT
+  return variant_internal::VariantCoreAccess::Access<I>(v);
+}
+
+// Overload for getting a variant's rvalue by index.
+// Note: `absl::move()` is required to allow use of constexpr in C++11.
+template <std::size_t I, class... Types>
+constexpr variant_alternative_t<I, variant<Types...>>&& get(
+    variant<Types...>&& v) {
+  return variant_internal::VariantCoreAccess::Access<I>(absl::move(v));
+}
+
+// Overload for getting a variant's const lvalue by index.
+template <std::size_t I, class... Types>
+constexpr const variant_alternative_t<I, variant<Types...>>& get(
+    const variant<Types...>& v) {
+  return variant_internal::VariantCoreAccess::Access<I>(v);
+}
+
+// Overload for getting a variant's const rvalue by index.
+// Note: `absl::move()` is required to allow use of constexpr in C++11.
+template <std::size_t I, class... Types>
+constexpr const variant_alternative_t<I, variant<Types...>>&& get(
+    const variant<Types...>&& v) {
+  return variant_internal::VariantCoreAccess::Access<I>(absl::move(v));
+}
+
+// get_if()
+//
+// Returns a pointer to the value currently stored within a given variant, if
+// present, using either a unique alternative type amonst the variant's set of
+// alternative types, or the variant's index value. If such a value does not
+// exist, returns `nullptr`.
+//
+// As with `get`, attempting to get a variant's value using a type that is not
+// unique within the variant's set of alternative types is a compile-time error.
+
+// Overload for getting a pointer to the value stored in the given variant by
+// index.
+template <std::size_t I, class... Types>
+constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
+get_if(variant<Types...>* v) noexcept {
+  return (v != nullptr && v->index() == I) ? std::addressof(absl::get<I>(*v))
+                                           : nullptr;
+}
+
+// Overload for getting a pointer to the const value stored in the given
+// variant by index.
+template <std::size_t I, class... Types>
+constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
+get_if(const variant<Types...>* v) noexcept {
+  return (v != nullptr && v->index() == I) ? std::addressof(absl::get<I>(*v))
+                                           : nullptr;
+}
+
+// Overload for getting a pointer to the value stored in the given variant by
+// type.
+template <class T, class... Types>
+constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
+  return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
+}
+
+// Overload for getting a pointer to the const value stored in the given variant
+// by type.
+template <class T, class... Types>
+constexpr absl::add_pointer_t<const T> get_if(
+    const variant<Types...>* v) noexcept {
+  return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
+}
+
+// visit()
+//
+// Calls a provided functor on a given set of variants. `absl::visit()` is
+// commonly used to conditionally inspect the state of a given variant (or set
+// of variants).
+// Requires: The expression in the Effects: element shall be a valid expression
+// of the same type and value category, for all combinations of alternative
+// types of all variants. Otherwise, the program is ill-formed.
+//
+// Example:
+//
+//   // Define a visitor functor
+//   struct GetVariant {
+//       template<typename T>
+//       void operator()(const T& i) const {
+//         std::cout << "The variant's value is: " << i;
+//       }
+//   };
+//
+//   // Declare our variant, and call `absl::visit()` on it.
+//   std::variant<int, std::string> foo = std::string("foo");
+//   GetVariant visitor;
+//   std::visit(visitor, foo);  // Prints `The variant's value is: foo'
+template <typename Visitor, typename... Variants>
+variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
+                                                          Variants&&... vars) {
+  return variant_internal::visit_indices<
+      variant_size<absl::decay_t<Variants>>::value...>(
+      variant_internal::PerformVisitation<Visitor, Variants...>{
+          std::forward_as_tuple(absl::forward<Variants>(vars)...),
+          absl::forward<Visitor>(vis)},
+      vars.index()...);
+}
+
+// monostate
+//
+// The monostate class serves as a first alternative type for a variant for
+// which the first variant type is otherwise not default-constructible.
+struct monostate {};
+
+// `absl::monostate` Relational Operators
+
+constexpr bool operator<(monostate, monostate) noexcept { return false; }
+constexpr bool operator>(monostate, monostate) noexcept { return false; }
+constexpr bool operator<=(monostate, monostate) noexcept { return true; }
+constexpr bool operator>=(monostate, monostate) noexcept { return true; }
+constexpr bool operator==(monostate, monostate) noexcept { return true; }
+constexpr bool operator!=(monostate, monostate) noexcept { return false; }
+
+
+//------------------------------------------------------------------------------
+// `absl::variant` Template Definition
+//------------------------------------------------------------------------------
+template <typename T0, typename... Tn>
+class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
+  static_assert(absl::conjunction<std::is_object<T0>, std::is_object<Tn>...,
+                                  absl::negation<std::is_array<T0>>,
+                                  absl::negation<std::is_array<Tn>>...,
+                                  std::is_nothrow_destructible<T0>,
+                                  std::is_nothrow_destructible<Tn>...>::value,
+                "Attempted to instantiate a variant with an unsupported type.");
+
+  friend struct variant_internal::VariantCoreAccess;
+
+ private:
+  using Base = variant_internal::VariantBase<T0, Tn...>;
+
+ public:
+  // Constructors
+
+  // Constructs a variant holding a default-initialized value of the first
+  // alternative type.
+  constexpr variant() /*noexcept(see 111above)*/ = default;
+
+  // Copy constructor, standard semantics
+  variant(const variant& other) = default;
+
+  // Move constructor, standard semantics
+  variant(variant&& other) /*noexcept(see above)*/ = default;
+
+  // Constructs a variant of an alternative type specified by overload
+  // resolution of the provided forwarding arguments through
+  // direct-initialization.
+  //
+  // Note: If the selected constructor is a constexpr constructor, this
+  // constructor shall be a constexpr constructor.
+  //
+  // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
+  // has been voted passed the design phase in the C++ standard meeting in Mar
+  // 2018. It will be implemented and integrated into `absl::variant`.
+  template <
+      class T,
+      std::size_t I = std::enable_if<
+          variant_internal::IsNeitherSelfNorInPlace<variant,
+                                                    absl::decay_t<T>>::value,
+          variant_internal::IndexOfConstructedType<variant, T>>::type::value,
+      class Tj = absl::variant_alternative_t<I, variant>,
+      absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
+          nullptr>
+  constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
+      : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
+
+  // Constructs a variant of an alternative type from the arguments through
+  // direct-initialization.
+  //
+  // Note: If the selected constructor is a constexpr constructor, this
+  // constructor shall be a constexpr constructor.
+  template <class T, class... Args,
+            typename std::enable_if<std::is_constructible<
+                variant_internal::UnambiguousTypeOfT<variant, T>,
+                Args...>::value>::type* = nullptr>
+  constexpr explicit variant(in_place_type_t<T>, Args&&... args)
+      : Base(variant_internal::EmplaceTag<
+                 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
+             absl::forward<Args>(args)...) {}
+
+  // Constructs a variant of an alternative type from an initializer list
+  // and other arguments through direct-initialization.
+  //
+  // Note: If the selected constructor is a constexpr constructor, this
+  // constructor shall be a constexpr constructor.
+  template <class T, class U, class... Args,
+            typename std::enable_if<std::is_constructible<
+                variant_internal::UnambiguousTypeOfT<variant, T>,
+                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
+  constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
+                             Args&&... args)
+      : Base(variant_internal::EmplaceTag<
+                 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
+             il, absl::forward<Args>(args)...) {}
+
+  // Constructs a variant of an alternative type from a provided index,
+  // through value-initialization using the provided forwarded arguments.
+  template <std::size_t I, class... Args,
+            typename std::enable_if<std::is_constructible<
+                variant_internal::VariantAlternativeSfinaeT<I, variant>,
+                Args...>::value>::type* = nullptr>
+  constexpr explicit variant(in_place_index_t<I>, Args&&... args)
+      : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}
+
+  // Constructs a variant of an alternative type from a provided index,
+  // through value-initialization of an initializer list and the provided
+  // forwarded arguments.
+  template <std::size_t I, class U, class... Args,
+            typename std::enable_if<std::is_constructible<
+                variant_internal::VariantAlternativeSfinaeT<I, variant>,
+                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
+  constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
+                             Args&&... args)
+      : Base(variant_internal::EmplaceTag<I>(), il,
+             absl::forward<Args>(args)...) {}
+
+  // Destructors
+
+  // Destroys the variant's currently contained value, provided that
+  // `absl::valueless_by_exception()` is false.
+  ~variant() = default;
+
+  // Assignment Operators
+
+  // Copy assignement operator
+  variant& operator=(const variant& other) = default;
+
+  // Move assignment operator
+  variant& operator=(variant&& other) /*noexcept(see above)*/ = default;
+
+  // Converting assignment operator
+  //
+  // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
+  // has been voted passed the design phase in the C++ standard meeting in Mar
+  // 2018. It will be implemented and integrated into `absl::variant`.
+  template <
+      class T,
+      std::size_t I = std::enable_if<
+          !std::is_same<absl::decay_t<T>, variant>::value,
+          variant_internal::IndexOfConstructedType<variant, T>>::type::value,
+      class Tj = absl::variant_alternative_t<I, variant>,
+      typename std::enable_if<std::is_assignable<Tj&, T>::value &&
+                              std::is_constructible<Tj, T>::value>::type* =
+          nullptr>
+  variant& operator=(T&& t) noexcept(
+      std::is_nothrow_assignable<Tj&, T>::value&&
+          std::is_nothrow_constructible<Tj, T>::value) {
+    variant_internal::visit_indices<sizeof...(Tn) + 1>(
+        variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
+            this, absl::forward<T>(t)),
+        index());
+
+    return *this;
+  }
+
+
+  // emplace() Functions
+
+  // Constructs a value of the given alternative type T within the variant.
+  //
+  // Example:
+  //
+  //   absl::variant<std::vector<int>, int, std::string> v;
+  //   v.emplace<int>(99);
+  //   v.emplace<std::string>("abc");
+  template <
+      class T, class... Args,
+      typename std::enable_if<std::is_constructible<
+          absl::variant_alternative_t<
+              variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
+          Args...>::value>::type* = nullptr>
+  T& emplace(Args&&... args) {
+    return variant_internal::VariantCoreAccess::Replace<
+        variant_internal::UnambiguousIndexOf<variant, T>::value>(
+        this, absl::forward<Args>(args)...);
+  }
+
+  // Constructs a value of the given alternative type T within the variant using
+  // an initializer list.
+  //
+  // Example:
+  //
+  //   absl::variant<std::vector<int>, int, std::string> v;
+  //   v.emplace<std::vector<int>>({0, 1, 2});
+  template <
+      class T, class U, class... Args,
+      typename std::enable_if<std::is_constructible<
+          absl::variant_alternative_t<
+              variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
+          std::initializer_list<U>&, Args...>::value>::type* = nullptr>
+  T& emplace(std::initializer_list<U> il, Args&&... args) {
+    return variant_internal::VariantCoreAccess::Replace<
+        variant_internal::UnambiguousIndexOf<variant, T>::value>(
+        this, il, absl::forward<Args>(args)...);
+  }
+
+  // Destroys the current value of the variant (provided that
+  // `absl::valueless_by_exception()` is false, and constructs a new value at
+  // the given index.
+  //
+  // Example:
+  //
+  //   absl::variant<std::vector<int>, int, int> v;
+  //   v.emplace<1>(99);
+  //   v.emplace<2>(98);
+  //   v.emplace<int>(99);  // Won't compile. 'int' isn't a unique type.
+  template <std::size_t I, class... Args,
+            typename std::enable_if<
+                std::is_constructible<absl::variant_alternative_t<I, variant>,
+                                      Args...>::value>::type* = nullptr>
+  absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
+    return variant_internal::VariantCoreAccess::Replace<I>(
+        this, absl::forward<Args>(args)...);
+  }
+
+  // Destroys the current value of the variant (provided that
+  // `absl::valueless_by_exception()` is false, and constructs a new value at
+  // the given index using an initializer list and the provided arguments.
+  //
+  // Example:
+  //
+  //   absl::variant<std::vector<int>, int, int> v;
+  //   v.emplace<0>({0, 1, 2});
+  template <std::size_t I, class U, class... Args,
+            typename std::enable_if<std::is_constructible<
+                absl::variant_alternative_t<I, variant>,
+                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
+  absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
+                                                   Args&&... args) {
+    return variant_internal::VariantCoreAccess::Replace<I>(
+        this, il, absl::forward<Args>(args)...);
+  }
+
+  // variant::valueless_by_exception()
+  //
+  // Returns false if and only if the variant currently holds a valid value.
+  constexpr bool valueless_by_exception() const noexcept {
+    return this->index_ == absl::variant_npos;
+  }
+
+  // variant::index()
+  //
+  // Returns the index value of the variant's currently selected alternative
+  // type.
+  constexpr std::size_t index() const noexcept { return this->index_; }
+
+  // variant::swap()
+  //
+  // Swaps the values of two variant objects.
+  //
+  // TODO(calabrese)
+  //   `variant::swap()` and `swap()` rely on `std::is_(nothrow)_swappable()`
+  //   which is introduced in C++17. So we assume `is_swappable()` is always
+  //   true and `is_nothrow_swappable()` is same as `std::is_trivial()`.
+  void swap(variant& rhs) noexcept(
+      absl::conjunction<std::is_trivial<T0>, std::is_trivial<Tn>...>::value) {
+    return variant_internal::visit_indices<sizeof...(Tn) + 1>(
+        variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
+  }
+};
+
+// We need a valid declaration of variant<> for SFINAE and overload resolution
+// to work properly above, but we don't need a full declaration since this type
+// will never be constructed. This declaration, though incomplete, suffices.
+template <>
+class variant<>;
+
+//------------------------------------------------------------------------------
+// Relational Operators
+//------------------------------------------------------------------------------
+//
+// If neither operand is in the `variant::valueless_by_exception` state:
+//
+//   * If the index of both variants is the same, the relational operator
+//     returns the result of the corresponding relational operator for the
+//     corresponding alternative type.
+//   * If the index of both variants is not the same, the relational operator
+//     returns the result of that operation applied to the value of the left
+//     operand's index and the value of the right operand's index.
+//   * If at least one operand is in the valueless_by_exception state:
+//     - A variant in the valueless_by_exception state is only considered equal
+//       to another variant in the valueless_by_exception state.
+//     - If exactly one operand is in the valueless_by_exception state, the
+//       variant in the valueless_by_exception state is less than the variant
+//       that is not in the valueless_by_exception state.
+//
+// Note: The value 1 is added to each index in the relational comparisons such
+// that the index corresponding to the valueless_by_exception state wraps around
+// to 0 (the lowest value for the index type), and the remaining indices stay in
+// the same relative order.
+
+// Equal-to operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
+    const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() == b.index()) &&
+         variant_internal::visit_indices<sizeof...(Types)>(
+             variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
+}
+
+// Not equal operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
+    const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() != b.index()) ||
+         variant_internal::visit_indices<sizeof...(Types)>(
+             variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
+}
+
+// Less-than operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
+    const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() != b.index())
+             ? (a.index() + 1) < (b.index() + 1)
+             : variant_internal::visit_indices<sizeof...(Types)>(
+                   variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
+}
+
+// Greater-than operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
+    const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() != b.index())
+             ? (a.index() + 1) > (b.index() + 1)
+             : variant_internal::visit_indices<sizeof...(Types)>(
+                   variant_internal::GreaterThanOp<Types...>{&a, &b},
+                   a.index());
+}
+
+// Less-than or equal-to operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
+    const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() != b.index())
+             ? (a.index() + 1) < (b.index() + 1)
+             : variant_internal::visit_indices<sizeof...(Types)>(
+                   variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
+                   a.index());
+}
+
+// Greater-than or equal-to operator
+template <typename... Types>
+constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
+operator>=(const variant<Types...>& a, const variant<Types...>& b) {
+  return (a.index() != b.index())
+             ? (a.index() + 1) > (b.index() + 1)
+             : variant_internal::visit_indices<sizeof...(Types)>(
+                   variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
+                   a.index());
+}
+
+}  // namespace absl
+
+namespace std {
+
+// hash()
+template <>  // NOLINT
+struct hash<absl::monostate> {
+  std::size_t operator()(absl::monostate) const { return 0; }
+};
+
+template <class... T>  // NOLINT
+struct hash<absl::variant<T...>>
+    : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
+                                              absl::remove_const_t<T>...> {};
+
+}  // namespace std
+
+#endif  // ABSL_HAVE_STD_VARIANT
+
+namespace absl {
+namespace variant_internal {
+
+// Helper visitor for converting a variant<Ts...>` into another type (mostly
+// variant) that can be constructed from any type.
+template <typename To>
+struct ConversionVisitor {
+  template <typename T>
+  To operator()(T&& v) const {
+    return To(std::forward<T>(v));
+  }
+};
+
+}  // namespace variant_internal
+
+// ConvertVariantTo()
+//
+// Helper functions to convert an `absl::variant` to a variant of another set of
+// types, provided that the alternative type of the new variant type can be
+// converted from any type in the source variant.
+//
+// Example:
+//
+//   absl::variant<name1, name2, float> InternalReq(const Req&);
+//
+//   // name1 and name2 are convertible to name
+//   absl::variant<name, float> ExternalReq(const Req& req) {
+//     return absl::ConvertVariantTo<absl::variant<name, float>>(
+//              InternalReq(req));
+//   }
+template <typename To, typename Variant>
+To ConvertVariantTo(Variant&& variant) {
+  return absl::visit(variant_internal::ConversionVisitor<To>{},
+                     std::forward<Variant>(variant));
+}
+
+}  // namespace absl
+
+#endif  // ABSL_TYPES_VARIANT_H_