summaryrefslogtreecommitdiff
path: root/absl/types
diff options
context:
space:
mode:
Diffstat (limited to 'absl/types')
-rw-r--r--absl/types/BUILD.bazel21
-rw-r--r--absl/types/CMakeLists.txt10
-rw-r--r--absl/types/any.h8
-rw-r--r--absl/types/any_exception_safety_test.cc8
-rw-r--r--absl/types/bad_any_cast.cc8
-rw-r--r--absl/types/bad_any_cast.h20
-rw-r--r--absl/types/bad_optional_access.cc8
-rw-r--r--absl/types/bad_optional_access.h20
-rw-r--r--absl/types/bad_variant_access.cc8
-rw-r--r--absl/types/bad_variant_access.h20
-rw-r--r--absl/types/internal/variant.h88
-rw-r--r--absl/types/optional.cc4
-rw-r--r--absl/types/optional.h25
-rw-r--r--absl/types/optional_exception_safety_test.cc30
-rw-r--r--absl/types/optional_test.cc33
-rw-r--r--absl/types/span.h55
-rw-r--r--absl/types/span_test.cc3
-rw-r--r--absl/types/variant.h76
-rw-r--r--absl/types/variant_benchmark.cc4
-rw-r--r--absl/types/variant_exception_safety_test.cc108
-rw-r--r--absl/types/variant_test.cc25
21 files changed, 348 insertions, 234 deletions
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index c50ec425..d56fea6e 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -19,6 +19,7 @@ load(
"ABSL_DEFAULT_COPTS",
"ABSL_TEST_COPTS",
"ABSL_EXCEPTIONS_FLAG",
+ "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
)
package(default_visibility = ["//visibility:public"])
@@ -42,7 +43,10 @@ cc_library(
name = "bad_any_cast",
hdrs = ["bad_any_cast.h"],
copts = ABSL_DEFAULT_COPTS,
- deps = [":bad_any_cast_impl"],
+ deps = [
+ ":bad_any_cast_impl",
+ "//absl/base:config",
+ ],
)
cc_library(
@@ -52,6 +56,7 @@ cc_library(
"bad_any_cast.h",
],
copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
visibility = ["//visibility:private"],
deps = [
"//absl/base",
@@ -66,6 +71,7 @@ cc_test(
"any_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":any",
"//absl/base",
@@ -97,6 +103,7 @@ cc_test(
name = "any_exception_safety_test",
srcs = ["any_exception_safety_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":any",
"//absl/base:exception_safety_testing",
@@ -121,6 +128,7 @@ cc_test(
size = "small",
srcs = ["span_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":span",
"//absl/base:config",
@@ -128,6 +136,7 @@ cc_test(
"//absl/base:exception_testing",
"//absl/container:fixed_array",
"//absl/container:inlined_vector",
+ "//absl/hash:hash_testing",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
@@ -145,6 +154,7 @@ cc_test(
"//absl/base:exception_testing",
"//absl/container:fixed_array",
"//absl/container:inlined_vector",
+ "//absl/hash:hash_testing",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
@@ -158,6 +168,7 @@ cc_library(
deps = [
":bad_optional_access",
"//absl/base:config",
+ "//absl/base:core_headers",
"//absl/memory",
"//absl/meta:type_traits",
"//absl/utility",
@@ -169,6 +180,7 @@ cc_library(
srcs = ["bad_optional_access.cc"],
hdrs = ["bad_optional_access.h"],
copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
"//absl/base",
"//absl/base:config",
@@ -180,6 +192,7 @@ cc_library(
srcs = ["bad_variant_access.cc"],
hdrs = ["bad_variant_access.h"],
copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
"//absl/base",
"//absl/base:config",
@@ -193,6 +206,7 @@ cc_test(
"optional_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":optional",
"//absl/base",
@@ -209,6 +223,7 @@ cc_test(
"optional_exception_safety_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":optional",
"//absl/base:exception_safety_testing",
@@ -236,6 +251,7 @@ cc_test(
size = "small",
srcs = ["variant_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":variant",
"//absl/base:config",
@@ -253,6 +269,7 @@ cc_test(
"variant_benchmark.cc",
],
copts = ABSL_TEST_COPTS,
+ tags = ["benchmark"],
deps = [
":variant",
"//absl/utility",
@@ -267,8 +284,10 @@ cc_test(
"variant_exception_safety_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
deps = [
":variant",
+ "//absl/base:config",
"//absl/base:exception_safety_testing",
"//absl/memory",
"@com_google_googletest//:gtest_main",
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 2f2e3a77..e8620766 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -123,7 +123,7 @@ absl_library(
# 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)
+set(ANY_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate absl::any absl::bad_any_cast absl::test_instance_tracker)
absl_test(
TARGET
@@ -152,7 +152,7 @@ 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_internal_exception_safety_testing
)
absl_test(
@@ -169,7 +169,7 @@ absl_test(
# 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)
+set(SPAN_TEST_PUBLIC_LIBRARIES absl::base absl::strings absl_internal_throw_delegate absl::span absl::test_instance_tracker)
absl_test(
TARGET
@@ -197,7 +197,7 @@ absl_test(
# 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)
+set(OPTIONAL_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate absl::optional absl_bad_optional_access)
absl_test(
TARGET
@@ -213,7 +213,7 @@ absl_test(
set(OPTIONAL_EXCEPTION_SAFETY_TEST_SRC "optional_exception_safety_test.cc")
set(OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
absl::optional
- absl_base_internal_exception_safety_testing
+ absl_internal_exception_safety_testing
)
absl_test(
diff --git a/absl/types/any.h b/absl/types/any.h
index 9d297dc8..dc3bfcfe 100644
--- a/absl/types/any.h
+++ b/absl/types/any.h
@@ -61,12 +61,12 @@
#include <any>
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
using std::any;
using std::any_cast;
using std::bad_any_cast;
using std::make_any;
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#else // ABSL_HAVE_STD_ANY
@@ -93,7 +93,7 @@ using std::make_any;
#endif // !defined(__GNUC__) || defined(__GXX_RTTI)
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace any_internal {
@@ -533,7 +533,7 @@ T* any_cast(any* operand) noexcept {
: nullptr;
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#undef ABSL_ANY_DETAIL_HAS_RTTI
diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc
index 36955f6c..f9dd8c48 100644
--- a/absl/types/any_exception_safety_test.cc
+++ b/absl/types/any_exception_safety_test.cc
@@ -62,7 +62,7 @@ testing::AssertionResult AnyInvariants(absl::any* a) {
static_cast<void>(unused);
return AssertionFailure()
<< "A reset `any` should not be able to be any_cast";
- } catch (absl::bad_any_cast) {
+ } catch (const absl::bad_any_cast&) {
} catch (...) {
return AssertionFailure()
<< "Unexpected exception thrown from absl::any_cast";
@@ -107,7 +107,7 @@ TEST(AnyExceptionSafety, Assignment) {
};
auto any_strong_tester = testing::MakeExceptionSafetyTester()
.WithInitialValue(original)
- .WithInvariants(AnyInvariants, any_is_strong);
+ .WithContracts(AnyInvariants, any_is_strong);
Thrower val(2);
absl::any any_val(val);
@@ -129,7 +129,7 @@ TEST(AnyExceptionSafety, Assignment) {
auto strong_empty_any_tester =
testing::MakeExceptionSafetyTester()
.WithInitialValue(absl::any{})
- .WithInvariants(AnyInvariants, empty_any_is_strong);
+ .WithContracts(AnyInvariants, empty_any_is_strong);
EXPECT_TRUE(strong_empty_any_tester.Test(assign_any));
EXPECT_TRUE(strong_empty_any_tester.Test(assign_val));
@@ -142,7 +142,7 @@ TEST(AnyExceptionSafety, Emplace) {
absl::any{absl::in_place_type_t<Thrower>(), 1, testing::nothrow_ctor};
auto one_tester = testing::MakeExceptionSafetyTester()
.WithInitialValue(initial_val)
- .WithInvariants(AnyInvariants, AnyIsEmpty);
+ .WithContracts(AnyInvariants, AnyIsEmpty);
auto emp_thrower = [](absl::any* ap) { ap->emplace<Thrower>(2); };
auto emp_throwervec = [](absl::any* ap) {
diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc
index 537767cd..6244d09e 100644
--- a/absl/types/bad_any_cast.cc
+++ b/absl/types/bad_any_cast.cc
@@ -14,13 +14,15 @@
#include "absl/types/bad_any_cast.h"
+#ifndef ABSL_HAVE_STD_ANY
+
#include <cstdlib>
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
bad_any_cast::~bad_any_cast() = default;
@@ -38,5 +40,7 @@ void ThrowBadAnyCast() {
}
} // namespace any_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+
+#endif // ABSL_HAVE_STD_ANY
diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h
index 3f89e75d..7df9afbb 100644
--- a/absl/types/bad_any_cast.h
+++ b/absl/types/bad_any_cast.h
@@ -23,8 +23,22 @@
#include <typeinfo>
+#include "absl/base/config.h"
+
+#ifdef ABSL_HAVE_STD_ANY
+
+#include <any>
+
+namespace absl {
+inline namespace lts_2018_12_18 {
+using std::bad_any_cast;
+} // inline namespace lts_2018_12_18
+} // namespace absl
+
+#else // ABSL_HAVE_STD_ANY
+
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// -----------------------------------------------------------------------------
// bad_any_cast
@@ -53,7 +67,9 @@ namespace any_internal {
[[noreturn]] void ThrowBadAnyCast();
} // namespace any_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+#endif // ABSL_HAVE_STD_ANY
+
#endif // ABSL_TYPES_BAD_ANY_CAST_H_
diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc
index c5508678..2dc74d3b 100644
--- a/absl/types/bad_optional_access.cc
+++ b/absl/types/bad_optional_access.cc
@@ -14,13 +14,15 @@
#include "absl/types/bad_optional_access.h"
+#ifndef ABSL_HAVE_STD_OPTIONAL
+
#include <cstdlib>
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
bad_optional_access::~bad_optional_access() = default;
@@ -40,5 +42,7 @@ void throw_bad_optional_access() {
}
} // namespace optional_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+
+#endif // ABSL_HAVE_STD_OPTIONAL
diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h
index d468211a..1f56ff64 100644
--- a/absl/types/bad_optional_access.h
+++ b/absl/types/bad_optional_access.h
@@ -23,8 +23,22 @@
#include <stdexcept>
+#include "absl/base/config.h"
+
+#ifdef ABSL_HAVE_STD_OPTIONAL
+
+#include <optional>
+
+namespace absl {
+inline namespace lts_2018_12_18 {
+using std::bad_optional_access;
+} // inline namespace lts_2018_12_18
+} // namespace absl
+
+#else // ABSL_HAVE_STD_OPTIONAL
+
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// -----------------------------------------------------------------------------
// bad_optional_access
@@ -56,7 +70,9 @@ namespace optional_internal {
[[noreturn]] void throw_bad_optional_access();
} // namespace optional_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+#endif // ABSL_HAVE_STD_OPTIONAL
+
#endif // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc
index a796cfaa..a646ff53 100644
--- a/absl/types/bad_variant_access.cc
+++ b/absl/types/bad_variant_access.cc
@@ -14,6 +14,8 @@
#include "absl/types/bad_variant_access.h"
+#ifndef ABSL_HAVE_STD_VARIANT
+
#include <cstdlib>
#include <stdexcept>
@@ -21,7 +23,7 @@
#include "absl/base/internal/raw_logging.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
//////////////////////////
// [variant.bad.access] //
@@ -56,5 +58,7 @@ void Rethrow() {
}
} // namespace variant_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+
+#endif // ABSL_HAVE_STD_VARIANT
diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h
index 2e007315..e0490842 100644
--- a/absl/types/bad_variant_access.h
+++ b/absl/types/bad_variant_access.h
@@ -23,8 +23,22 @@
#include <stdexcept>
+#include "absl/base/config.h"
+
+#ifdef ABSL_HAVE_STD_VARIANT
+
+#include <variant>
+
+namespace absl {
+inline namespace lts_2018_12_18 {
+using std::bad_variant_access;
+} // inline namespace lts_2018_12_18
+} // namespace absl
+
+#else // ABSL_HAVE_STD_VARIANT
+
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// -----------------------------------------------------------------------------
// bad_variant_access
@@ -60,7 +74,9 @@ namespace variant_internal {
[[noreturn]] void Rethrow();
} // namespace variant_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+#endif // ABSL_HAVE_STD_VARIANT
+
#endif // ABSL_TYPES_BAD_VARIANT_ACCESS_H_
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index 3b884647..875f88e0 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -1,4 +1,4 @@
-// Copyright 2017 The Abseil Authors.
+// 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.
@@ -15,6 +15,7 @@
// Implementation details of absl/types/variant.h, pulled into a
// separate file to avoid cluttering the top of the API header with
// implementation details.
+//
#ifndef ABSL_TYPES_variant_internal_H_
#define ABSL_TYPES_variant_internal_H_
@@ -37,8 +38,10 @@
#include "absl/types/bad_variant_access.h"
#include "absl/utility/utility.h"
+#if !defined(ABSL_HAVE_STD_VARIANT)
+
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
template <class... Types>
class variant;
@@ -580,12 +583,9 @@ struct VariantCoreAccess {
self.index_ = other.index();
}
+ // Access a variant alternative, assuming the index is correct.
template <std::size_t I, class Variant>
static VariantAccessResult<I, Variant> Access(Variant&& self) {
- if (ABSL_PREDICT_FALSE(self.index_ != I)) {
- TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
- }
-
// This cast instead of invocation of AccessUnion with an rvalue is a
// workaround for msvc. Without this there is a runtime failure when dealing
// with rvalues.
@@ -594,6 +594,16 @@ struct VariantCoreAccess {
variant_internal::AccessUnion(self.state_, SizeT<I>()));
}
+ // Access a variant alternative, throwing if the index is incorrect.
+ template <std::size_t I, class Variant>
+ static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) {
+ if (ABSL_PREDICT_FALSE(self.index_ != I)) {
+ TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
+ }
+
+ return Access<I>(absl::forward<Variant>(self));
+ }
+
// The implementation of the move-assignment operation for a variant.
template <class VType>
struct MoveAssignVisitor {
@@ -902,6 +912,11 @@ struct PerformVisitation {
template <std::size_t... TupIs, std::size_t... Is>
constexpr ReturnType Run(std::false_type /*has_valueless*/,
index_sequence<TupIs...>, SizeT<Is>...) const {
+ static_assert(
+ std::is_same<ReturnType,
+ absl::result_of_t<Op(VariantAccessResult<
+ Is, QualifiedVariants>...)>>::value,
+ "All visitation overloads must have the same return type.");
return absl::base_internal::Invoke(
absl::forward<Op>(op),
VariantCoreAccess::Access<Is>(
@@ -1056,32 +1071,6 @@ struct OverloadSet<> {
static void Overload(...);
};
-////////////////////////////////
-// Library Fundamentals V2 TS //
-////////////////////////////////
-
-// TODO(calabrese): Consider moving this to absl/meta/type_traits.h
-
-// The following is a rough implementation of parts of the detection idiom.
-// It is used for the comparison operator checks.
-
-template <class Enabler, class To, template <class...> class Op, class... Args>
-struct is_detected_convertible_impl {
- using type = std::false_type;
-};
-
-template <class To, template <class...> class Op, class... Args>
-struct is_detected_convertible_impl<
- absl::enable_if_t<std::is_convertible<Op<Args...>, To>::value>, To, Op,
- Args...> {
- using type = std::true_type;
-};
-
-// NOTE: This differs from library fundamentals by being lazy.
-template <class To, template <class...> class Op, class... Args>
-struct is_detected_convertible
- : is_detected_convertible_impl<void, To, Op, Args...>::type {};
-
template <class T>
using LessThanResult = decltype(std::declval<T>() < std::declval<T>());
@@ -1101,6 +1090,8 @@ using EqualResult = decltype(std::declval<T>() == std::declval<T>());
template <class T>
using NotEqualResult = decltype(std::declval<T>() != std::declval<T>());
+using type_traits_internal::is_detected_convertible;
+
template <class... T>
using RequireAllHaveEqualT = absl::enable_if_t<
absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value,
@@ -1245,23 +1236,29 @@ using VariantCopyBase = absl::conditional_t<
// Base that is dependent on whether or not the move-assign can be trivial.
template <class... T>
using VariantMoveAssignBase = absl::conditional_t<
- absl::disjunction<absl::conjunction<std::is_move_assignable<Union<T...>>,
- std::is_move_constructible<Union<T...>>,
- std::is_destructible<Union<T...>>>,
- absl::negation<absl::conjunction<
- std::is_move_constructible<T>...,
- std::is_move_assignable<T>...>>>::value,
+ absl::disjunction<
+ absl::conjunction<absl::is_move_assignable<Union<T...>>,
+ std::is_move_constructible<Union<T...>>,
+ std::is_destructible<Union<T...>>>,
+ absl::negation<absl::conjunction<std::is_move_constructible<T>...,
+ // Note: We're not qualifying this with
+ // absl:: because it doesn't compile
+ // under MSVC.
+ is_move_assignable<T>...>>>::value,
VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;
// Base that is dependent on whether or not the copy-assign can be trivial.
template <class... T>
using VariantCopyAssignBase = absl::conditional_t<
- absl::disjunction<absl::conjunction<std::is_copy_assignable<Union<T...>>,
- std::is_copy_constructible<Union<T...>>,
- std::is_destructible<Union<T...>>>,
- absl::negation<absl::conjunction<
- std::is_copy_constructible<T>...,
- std::is_copy_assignable<T>...>>>::value,
+ absl::disjunction<
+ absl::conjunction<absl::is_copy_assignable<Union<T...>>,
+ std::is_copy_constructible<Union<T...>>,
+ std::is_destructible<Union<T...>>>,
+ absl::negation<absl::conjunction<std::is_copy_constructible<T>...,
+ // Note: We're not qualifying this with
+ // absl:: because it doesn't compile
+ // under MSVC.
+ is_copy_assignable<T>...>>>::value,
VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;
template <class... T>
@@ -1628,7 +1625,8 @@ struct VariantHashBase<Variant,
};
} // namespace variant_internal
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+#endif // !defined(ABSL_HAVE_STD_VARIANT)
#endif // ABSL_TYPES_variant_internal_H_
diff --git a/absl/types/optional.cc b/absl/types/optional.cc
index 85424ee3..5c77f154 100644
--- a/absl/types/optional.cc
+++ b/absl/types/optional.cc
@@ -16,11 +16,11 @@
#ifndef ABSL_HAVE_STD_OPTIONAL
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
nullopt_t::init_t nullopt_t::init;
extern const nullopt_t nullopt{nullopt_t::init};
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_HAVE_STD_OPTIONAL
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 12f0664a..1ca8dec6 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -43,13 +43,13 @@
#include <optional>
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
using std::bad_optional_access;
using std::optional;
using std::make_optional;
using std::nullopt_t;
using std::nullopt;
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#else // ABSL_HAVE_STD_OPTIONAL
@@ -61,6 +61,7 @@ using std::nullopt;
#include <type_traits>
#include <utility>
+#include "absl/base/attributes.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/types/bad_optional_access.h"
@@ -94,7 +95,7 @@ using std::nullopt;
#endif
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// -----------------------------------------------------------------------------
// absl::optional
@@ -165,7 +166,7 @@ struct empty_struct {};
// This class stores the data in optional<T>.
// It is specialized based on whether T is trivially destructible.
// This is the specialization for non trivially destructible type.
-template <typename T, bool = std::is_trivially_destructible<T>::value>
+template <typename T, bool unused = std::is_trivially_destructible<T>::value>
class optional_data_dtor_base {
struct dummy_type {
static_assert(sizeof(T) % sizeof(empty_struct) == 0, "");
@@ -263,10 +264,10 @@ class optional_data_base : public optional_data_dtor_base<T> {
// have trivial move but nontrivial copy.
// Also, we should be checking is_trivially_copyable here, which is not
// supported now, so we use is_trivially_* traits instead.
-template <typename T, bool = absl::is_trivially_copy_constructible<T>::value&&
- absl::is_trivially_copy_assignable<
- typename std::remove_cv<T>::type>::value&&
- std::is_trivially_destructible<T>::value>
+template <typename T,
+ bool unused = absl::is_trivially_copy_constructible<T>::value&&
+ absl::is_trivially_copy_assignable<typename std::remove_cv<
+ T>::type>::value&& std::is_trivially_destructible<T>::value>
class optional_data;
// Trivially copyable types
@@ -414,10 +415,10 @@ constexpr copy_traits get_ctor_copy_traits() {
template <typename T>
constexpr copy_traits get_assign_copy_traits() {
- return std::is_copy_assignable<T>::value &&
+ return absl::is_copy_assignable<T>::value &&
std::is_copy_constructible<T>::value
? copy_traits::copyable
- : std::is_move_assignable<T>::value &&
+ : absl::is_move_assignable<T>::value &&
std::is_move_constructible<T>::value
? copy_traits::movable
: copy_traits::non_movable;
@@ -703,7 +704,7 @@ class optional : private optional_internal::optional_data<T>,
// optional::reset()
//
// Destroys the inner `T` value of an `absl::optional` if one is present.
- void reset() noexcept { this->destruct(); }
+ ABSL_ATTRIBUTE_REINITIALIZES void reset() noexcept { this->destruct(); }
// optional::emplace()
//
@@ -1125,7 +1126,7 @@ constexpr auto operator>=(const U& v, const optional<T>& x)
return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true;
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
namespace std {
diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc
index e136d0a0..313891f7 100644
--- a/absl/types/optional_exception_safety_test.cc
+++ b/absl/types/optional_exception_safety_test.cc
@@ -18,7 +18,7 @@
#include "absl/base/internal/exception_safety_testing.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
@@ -39,12 +39,12 @@ constexpr int kUpdatedInteger = 10;
template <typename OptionalT>
bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try {
return (static_cast<void>(optional.value()), false);
-} catch (absl::bad_optional_access) {
+} catch (const absl::bad_optional_access&) {
return true;
}
template <typename OptionalT>
-AssertionResult CheckInvariants(OptionalT* optional_ptr) {
+AssertionResult OptionalInvariants(OptionalT* optional_ptr) {
// Check the current state post-throw for validity
auto& optional = *optional_ptr;
@@ -124,8 +124,8 @@ TEST(OptionalExceptionSafety, NothrowConstructors) {
TEST(OptionalExceptionSafety, Emplace) {
// Test the basic guarantee plus test the result of optional::has_value()
// is false in all cases
- auto disengaged_test = MakeExceptionSafetyTester().WithInvariants(
- CheckInvariants<Optional>, CheckDisengaged<Optional>);
+ auto disengaged_test = MakeExceptionSafetyTester().WithContracts(
+ OptionalInvariants<Optional>, CheckDisengaged<Optional>);
auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional());
auto disengaged_test_nonempty =
disengaged_test.WithInitialValue(Optional(kInitialInteger));
@@ -148,11 +148,11 @@ TEST(OptionalExceptionSafety, EverythingThrowsSwap) {
// Test the basic guarantee plus test the result of optional::has_value()
// remains the same
auto test =
- MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
+ MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
auto disengaged_test_empty = test.WithInitialValue(Optional())
- .WithInvariants(CheckDisengaged<Optional>);
+ .WithContracts(CheckDisengaged<Optional>);
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
- .WithInvariants(CheckEngaged<Optional>);
+ .WithContracts(CheckEngaged<Optional>);
auto swap_empty = [](Optional* optional_ptr) {
auto empty = Optional();
@@ -193,11 +193,11 @@ TEST(OptionalExceptionSafety, CopyAssign) {
// Test the basic guarantee plus test the result of optional::has_value()
// remains the same
auto test =
- MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
+ MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
auto disengaged_test_empty = test.WithInitialValue(Optional())
- .WithInvariants(CheckDisengaged<Optional>);
+ .WithContracts(CheckDisengaged<Optional>);
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
- .WithInvariants(CheckEngaged<Optional>);
+ .WithContracts(CheckEngaged<Optional>);
auto copyassign_nonempty = [](Optional* optional_ptr) {
auto nonempty =
@@ -219,11 +219,11 @@ TEST(OptionalExceptionSafety, MoveAssign) {
// Test the basic guarantee plus test the result of optional::has_value()
// remains the same
auto test =
- MakeExceptionSafetyTester().WithInvariants(CheckInvariants<Optional>);
+ MakeExceptionSafetyTester().WithContracts(OptionalInvariants<Optional>);
auto disengaged_test_empty = test.WithInitialValue(Optional())
- .WithInvariants(CheckDisengaged<Optional>);
+ .WithContracts(CheckDisengaged<Optional>);
auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger))
- .WithInvariants(CheckEngaged<Optional>);
+ .WithContracts(CheckEngaged<Optional>);
auto moveassign_empty = [](Optional* optional_ptr) {
auto empty = Optional();
@@ -280,5 +280,5 @@ TEST(OptionalExceptionSafety, NothrowMoveAssign) {
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index 179bfd66..fc4f00a4 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -607,11 +607,12 @@ TEST(optionalTest, CopyAssignment) {
opt2_to_empty = empty;
EXPECT_FALSE(opt2_to_empty);
- EXPECT_FALSE(std::is_copy_assignable<absl::optional<const int>>::value);
- EXPECT_TRUE(std::is_copy_assignable<absl::optional<Copyable>>::value);
- EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableThrow>>::value);
- EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);
- EXPECT_FALSE(std::is_copy_assignable<absl::optional<NonMovable>>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value);
+ EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value);
+ EXPECT_FALSE(
+ absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value);
EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value);
EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value);
@@ -625,9 +626,9 @@ TEST(optionalTest, CopyAssignment) {
};
EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
- EXPECT_FALSE(std::is_copy_assignable<const Trivial>::value);
- EXPECT_FALSE(std::is_copy_assignable<volatile Trivial>::value);
- EXPECT_TRUE(std::is_copy_assignable<NonTrivial>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value);
+ EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value);
EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value);
// std::optional doesn't support volatile nontrivial types.
@@ -695,11 +696,11 @@ TEST(optionalTest, MoveAssignment) {
EXPECT_EQ(1, listener.volatile_move_assign);
}
#endif // ABSL_HAVE_STD_OPTIONAL
- EXPECT_FALSE(std::is_move_assignable<absl::optional<const int>>::value);
- EXPECT_TRUE(std::is_move_assignable<absl::optional<Copyable>>::value);
- EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableThrow>>::value);
- EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableNoThrow>>::value);
- EXPECT_FALSE(std::is_move_assignable<absl::optional<NonMovable>>::value);
+ EXPECT_FALSE(absl::is_move_assignable<absl::optional<const int>>::value);
+ EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value);
+ EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value);
+ EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value);
+ EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value);
EXPECT_FALSE(
std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value);
@@ -1041,9 +1042,9 @@ TEST(optionalTest, Value) {
// test exception throw on value()
absl::optional<int> empty;
#ifdef ABSL_HAVE_EXCEPTIONS
- EXPECT_THROW(empty.value(), absl::bad_optional_access);
+ EXPECT_THROW((void)empty.value(), absl::bad_optional_access);
#else
- EXPECT_DEATH(empty.value(), "Bad optional access");
+ EXPECT_DEATH((void)empty.value(), "Bad optional access");
#endif
// test constexpr value()
@@ -1619,7 +1620,7 @@ TEST(optionalTest, AssignmentConstraints) {
EXPECT_TRUE(
(std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value));
EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value);
- EXPECT_TRUE(std::is_copy_assignable<absl::optional<AnyLike>>::value);
+ EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
}
} // namespace
diff --git a/absl/types/span.h b/absl/types/span.h
index 1b5edf25..99b6765b 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -72,7 +72,7 @@
#include "absl/meta/type_traits.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
template <typename T>
class Span;
@@ -88,7 +88,7 @@ constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references)
return c.data();
}
-// Before C++17, std::string::data returns a const char* in all cases.
+// Before C++17, string::data returns a const char* in all cases.
inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references)
int) noexcept {
return &s[0];
@@ -380,64 +380,70 @@ class Span {
//
// Returns a reference to the i'th element of this span.
constexpr reference at(size_type i) const {
- return ABSL_PREDICT_TRUE(i < size())
- ? ptr_[i]
+ return ABSL_PREDICT_TRUE(i < size()) //
+ ? *(data() + i)
: (base_internal::ThrowStdOutOfRange(
"Span::at failed bounds check"),
- ptr_[i]);
+ *(data() + i));
}
// Span::front()
//
// Returns a reference to the first element of this span.
- reference front() const noexcept { return ABSL_ASSERT(size() > 0), ptr_[0]; }
+ constexpr reference front() const noexcept {
+ return ABSL_ASSERT(size() > 0), *data();
+ }
// Span::back()
//
// Returns a reference to the last element of this span.
- reference back() const noexcept {
- return ABSL_ASSERT(size() > 0), ptr_[size() - 1];
+ constexpr reference back() const noexcept {
+ return ABSL_ASSERT(size() > 0), *(data() + size() - 1);
}
// Span::begin()
//
// Returns an iterator to the first element of this span.
- constexpr iterator begin() const noexcept { return ptr_; }
+ constexpr iterator begin() const noexcept { return data(); }
// Span::cbegin()
//
// Returns a const iterator to the first element of this span.
- constexpr const_iterator cbegin() const noexcept { return ptr_; }
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
// Span::end()
//
// Returns an iterator to the last element of this span.
- iterator end() const noexcept { return ptr_ + len_; }
+ constexpr iterator end() const noexcept { return data() + size(); }
// Span::cend()
//
// Returns a const iterator to the last element of this span.
- const_iterator cend() const noexcept { return end(); }
+ constexpr const_iterator cend() const noexcept { return end(); }
// Span::rbegin()
//
// Returns a reverse iterator starting at the last element of this span.
- reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
+ constexpr reverse_iterator rbegin() const noexcept {
+ return reverse_iterator(end());
+ }
// Span::crbegin()
//
// Returns a reverse const iterator starting at the last element of this span.
- const_reverse_iterator crbegin() const noexcept { return rbegin(); }
+ constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
// Span::rend()
//
// Returns a reverse iterator starting at the first element of this span.
- reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
+ constexpr reverse_iterator rend() const noexcept {
+ return reverse_iterator(begin());
+ }
// Span::crend()
//
// Returns a reverse iterator starting at the first element of this span.
- const_reverse_iterator crend() const noexcept { return rend(); }
+ constexpr const_reverse_iterator crend() const noexcept { return rend(); }
// Span mutations
@@ -445,7 +451,7 @@ class Span {
//
// Removes the first `n` elements from the span.
void remove_prefix(size_type n) noexcept {
- assert(len_ >= n);
+ assert(size() >= n);
ptr_ += n;
len_ -= n;
}
@@ -454,7 +460,7 @@ class Span {
//
// Removes the last `n` elements from the span.
void remove_suffix(size_type n) noexcept {
- assert(len_ >= n);
+ assert(size() >= n);
len_ -= n;
}
@@ -475,11 +481,18 @@ class Span {
// absl::MakeSpan(vec).subspan(4); // {}
// absl::MakeSpan(vec).subspan(5); // throws std::out_of_range
constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
- return (pos <= len_)
- ? Span(ptr_ + pos, span_internal::Min(len_ - pos, len))
+ return (pos <= size())
+ ? Span(data() + pos, span_internal::Min(size() - pos, len))
: (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
}
+ // Support for absl::Hash.
+ template <typename H>
+ friend H AbslHashValue(H h, Span v) {
+ return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
+ v.size());
+ }
+
private:
pointer ptr_;
size_type len_;
@@ -746,6 +759,6 @@ template <int&... ExplicitArgumentBarrier, typename T, size_t N>
constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
return Span<const T>(array, N);
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_TYPES_SPAN_H_
diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc
index 5a4f0014..bd739ff2 100644
--- a/absl/types/span_test.cc
+++ b/absl/types/span_test.cc
@@ -29,6 +29,7 @@
#include "absl/base/internal/exception_testing.h"
#include "absl/container/fixed_array.h"
#include "absl/container/inlined_vector.h"
+#include "absl/hash/hash_testing.h"
#include "absl/strings/str_cat.h"
namespace {
@@ -288,7 +289,7 @@ TEST(IntSpan, Subspan) {
#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), "");
+ EXPECT_DEATH_IF_SUPPORTED(absl::MakeSpan(ramp).subspan(11, 5), "");
#endif
}
diff --git a/absl/types/variant.h b/absl/types/variant.h
index b0898d98..4ae4e00d 100644
--- a/absl/types/variant.h
+++ b/absl/types/variant.h
@@ -50,7 +50,7 @@
#include <variant>
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
using std::bad_variant_access;
using std::get;
using std::get_if;
@@ -63,7 +63,7 @@ using std::variant_npos;
using std::variant_size;
using std::variant_size_v;
using std::visit;
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#else // ABSL_HAVE_STD_VARIANT
@@ -79,13 +79,13 @@ using std::visit;
#include "absl/types/internal/variant.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
// -----------------------------------------------------------------------------
// absl::variant
// -----------------------------------------------------------------------------
//
-// An 'absl::variant` type is a form of type-safe union. An `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.
//
@@ -139,7 +139,7 @@ void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
// variant_size
//
-// Returns the number of alterative types available for a given `absl::variant`
+// Returns the number of alternative 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.
@@ -251,7 +251,7 @@ using variant_alternative_t = typename variant_alternative<I, T>::type;
//
// Example:
//
-// absl::variant<int, std::string> bar = 42;
+// absl::variant<int, std::string> foo = 42;
// if (absl::holds_alternative<int>(foo)) {
// std::cout << "The variant holds an integer";
// }
@@ -293,7 +293,7 @@ constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
// 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<
+ return variant_internal::VariantCoreAccess::CheckedAccess<
variant_internal::IndexOf<T, Types...>::value>(v);
}
@@ -301,14 +301,14 @@ constexpr T& get(variant<Types...>& v) { // NOLINT
// 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<
+ return variant_internal::VariantCoreAccess::CheckedAccess<
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<
+ return variant_internal::VariantCoreAccess::CheckedAccess<
variant_internal::IndexOf<T, Types...>::value>(v);
}
@@ -316,7 +316,7 @@ constexpr const T& get(const variant<Types...>& v) {
// 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<
+ return variant_internal::VariantCoreAccess::CheckedAccess<
variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
}
@@ -324,7 +324,7 @@ constexpr const T&& get(const variant<Types...>&& v) {
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);
+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
}
// Overload for getting a variant's rvalue by index.
@@ -332,14 +332,14 @@ constexpr variant_alternative_t<I, variant<Types...>>& get(
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));
+ return variant_internal::VariantCoreAccess::CheckedAccess<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);
+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
}
// Overload for getting a variant's const rvalue by index.
@@ -347,7 +347,7 @@ constexpr const variant_alternative_t<I, variant<Types...>>& get(
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));
+ return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
}
// get_if()
@@ -365,8 +365,10 @@ constexpr const variant_alternative_t<I, variant<Types...>>&& get(
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;
+ return (v != nullptr && v->index() == I)
+ ? std::addressof(
+ variant_internal::VariantCoreAccess::Access<I>(*v))
+ : nullptr;
}
// Overload for getting a pointer to the const value stored in the given
@@ -374,8 +376,10 @@ get_if(variant<Types...>* v) noexcept {
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;
+ return (v != nullptr && v->index() == I)
+ ? std::addressof(
+ variant_internal::VariantCoreAccess::Access<I>(*v))
+ : nullptr;
}
// Overload for getting a pointer to the value stored in the given variant by
@@ -398,9 +402,9 @@ constexpr absl::add_pointer_t<const T> get_if(
// 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.
+//
+// The functor must return the same type when called with any of the variants'
+// alternatives.
//
// Example:
//
@@ -413,9 +417,10 @@ constexpr absl::add_pointer_t<const T> get_if(
// };
//
// // Declare our variant, and call `absl::visit()` on it.
-// std::variant<int, std::string> foo = std::string("foo");
+// // Note that `GetVariant()` returns void in either case.
+// absl::variant<int, std::string> foo = std::string("foo");
// GetVariant visitor;
-// std::visit(visitor, foo); // Prints `The variant's value is: foo'
+// absl::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) {
@@ -448,14 +453,19 @@ constexpr bool operator!=(monostate, monostate) noexcept { return false; }
//------------------------------------------------------------------------------
template <typename T0, typename... Tn>
class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
- // Intentionally not qualifing `negation` with `absl::` to work around a bug
+ static_assert(absl::conjunction<std::is_object<T0>,
+ std::is_object<Tn>...>::value,
+ "Attempted to instantiate a variant containing a non-object "
+ "type.");
+ // Intentionally not qualifying `negation` with `absl::` to work around a bug
// in MSVC 2015 with inline namespace and variadic template.
- static_assert(absl::conjunction<std::is_object<T0>, std::is_object<Tn>...,
- negation<std::is_array<T0> >,
- negation<std::is_array<Tn> >...,
- std::is_nothrow_destructible<T0>,
+ static_assert(absl::conjunction<negation<std::is_array<T0> >,
+ negation<std::is_array<Tn> >...>::value,
+ "Attempted to instantiate a variant containing an array type.");
+ static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
std::is_nothrow_destructible<Tn>...>::value,
- "Attempted to instantiate a variant with an unsupported type.");
+ "Attempted to instantiate a variant containing a non-nothrow "
+ "destructible type.");
friend struct variant_internal::VariantCoreAccess;
@@ -555,7 +565,7 @@ class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
// Assignment Operators
- // Copy assignement operator
+ // Copy assignment operator
variant& operator=(const variant& other) = default;
// Move assignment operator
@@ -783,7 +793,7 @@ operator>=(const variant<Types...>& a, const variant<Types...>& b) {
a.index());
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
namespace std {
@@ -804,7 +814,7 @@ struct hash<absl::variant<T...>>
#endif // ABSL_HAVE_STD_VARIANT
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace variant_internal {
// Helper visitor for converting a variant<Ts...>` into another type (mostly
@@ -840,7 +850,7 @@ To ConvertVariantTo(Variant&& variant) {
std::forward<Variant>(variant));
}
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
#endif // ABSL_TYPES_VARIANT_H_
diff --git a/absl/types/variant_benchmark.cc b/absl/types/variant_benchmark.cc
index 93acc2b6..854f1448 100644
--- a/absl/types/variant_benchmark.cc
+++ b/absl/types/variant_benchmark.cc
@@ -28,7 +28,7 @@
#include "absl/utility/utility.h"
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
template <std::size_t I>
@@ -218,5 +218,5 @@ BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2)
->DenseRange(0, integral_pow(4, 2) - 1);
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc
index d7bc90d2..ff166051 100644
--- a/absl/types/variant_exception_safety_test.cc
+++ b/absl/types/variant_exception_safety_test.cc
@@ -11,6 +11,7 @@
// 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/variant.h"
#include <iostream>
@@ -20,11 +21,14 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/base/internal/exception_safety_testing.h"
#include "absl/memory/memory.h"
+// See comment in absl/base/config.h
+#if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
using ::testing::MakeExceptionSafetyTester;
@@ -54,13 +58,13 @@ void ToValuelessByException(ThrowingVariant& v) { // NOLINT
try {
v.emplace<Thrower>();
v.emplace<Thrower>(ExceptionOnConversion<Thrower>());
- } catch (ConversionException& /*e*/) {
+ } catch (const ConversionException&) {
// This space intentionally left blank.
}
}
// Check that variant is still in a usable state after an exception is thrown.
-testing::AssertionResult CheckInvariants(ThrowingVariant* v) {
+testing::AssertionResult VariantInvariants(ThrowingVariant* v) {
using testing::AssertionFailure;
using testing::AssertionSuccess;
@@ -101,7 +105,7 @@ testing::AssertionResult CheckInvariants(ThrowingVariant* v) {
auto unused = absl::get<Thrower>(*v);
static_cast<void>(unused);
return AssertionFailure() << "Variant should not contain Thrower";
- } catch (absl::bad_variant_access) {
+ } catch (const absl::bad_variant_access&) {
} catch (...) {
return AssertionFailure() << "Unexpected exception throw from absl::get";
}
@@ -214,8 +218,8 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
.WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
- EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test());
- EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_TRUE(tester.WithContracts(VariantInvariants).Test());
+ EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
}
{
const ThrowingVariant rhs(ExpectedThrowerVec());
@@ -223,8 +227,8 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
MakeExceptionSafetyTester()
.WithInitialValue(WithThrowerVec())
.WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
- EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test());
- EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_TRUE(tester.WithContracts(VariantInvariants).Test());
+ EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
}
// libstdc++ std::variant has bugs on copy assignment regarding exception
// safety.
@@ -252,12 +256,12 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
.WithInitialValue(WithCopyNoThrow())
.WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
EXPECT_TRUE(tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return lhs->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
}
#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
{
@@ -269,7 +273,7 @@ TEST(VariantExceptionSafetyTest, CopyAssign) {
const ThrowingVariant rhs(MoveNothrow{});
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
- .WithInvariants(CheckInvariants, strong_guarantee)
+ .WithContracts(VariantInvariants, strong_guarantee)
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
}
}
@@ -305,11 +309,11 @@ TEST(VariantExceptionSafetyTest, MoveAssign) {
*lhs = std::move(copy);
});
EXPECT_TRUE(tester
- .WithInvariants(
- CheckInvariants,
+ .WithContracts(
+ VariantInvariants,
[&](ThrowingVariant* lhs) { return lhs->index() == j; })
.Test());
- EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
}
{
// - otherwise (index() != j), equivalent to
@@ -319,10 +323,10 @@ TEST(VariantExceptionSafetyTest, MoveAssign) {
ThrowingVariant rhs(CopyNothrow{});
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return lhs->valueless_by_exception();
+ })
.Test([&](ThrowingVariant* lhs) {
auto copy = rhs;
*lhs = std::move(copy);
@@ -348,12 +352,12 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
.WithInitialValue(WithThrower())
.WithOperation([rhs](ThrowingVariant* lhs) { *lhs = rhs; });
EXPECT_TRUE(copy_tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return !lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return !lhs->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(copy_tester.WithContracts(strong_guarantee).Test());
// move assign
auto move_tester = MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
@@ -362,13 +366,13 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
*lhs = std::move(copy);
});
EXPECT_TRUE(move_tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return !lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return !lhs->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(move_tester.WithContracts(strong_guarantee).Test());
}
// Otherwise (*this holds something else), if is_nothrow_constructible_v<Tj,
// T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to
@@ -401,12 +405,12 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
.WithInitialValue(WithCopyNoThrow())
.WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
EXPECT_TRUE(copy_tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return lhs->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(copy_tester.WithContracts(strong_guarantee).Test());
// move
auto move_tester = MakeExceptionSafetyTester()
.WithInitialValue(WithCopyNoThrow())
@@ -414,12 +418,12 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
*lhs = ExpectedThrower(testing::nothrow_ctor);
});
EXPECT_TRUE(move_tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* lhs) {
- return lhs->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* lhs) {
+ return lhs->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(move_tester.WithContracts(strong_guarantee).Test());
}
// Otherwise (if is_nothrow_constructible_v<Tj, T> == false &&
// is_nothrow_move_constructible<Tj> == true),
@@ -433,7 +437,7 @@ TEST(VariantExceptionSafetyTest, ValueAssign) {
MoveNothrow rhs;
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
- .WithInvariants(CheckInvariants, strong_guarantee)
+ .WithContracts(VariantInvariants, strong_guarantee)
.Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
}
#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
@@ -451,12 +455,12 @@ TEST(VariantExceptionSafetyTest, Emplace) {
v->emplace<Thrower>(args);
});
EXPECT_TRUE(tester
- .WithInvariants(CheckInvariants,
- [](ThrowingVariant* v) {
- return v->valueless_by_exception();
- })
+ .WithContracts(VariantInvariants,
+ [](ThrowingVariant* v) {
+ return v->valueless_by_exception();
+ })
.Test());
- EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
+ EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
}
}
@@ -473,7 +477,7 @@ TEST(VariantExceptionSafetyTest, Swap) {
ThrowingVariant rhs = ExpectedThrower();
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithThrower())
- .WithInvariants(CheckInvariants)
+ .WithContracts(VariantInvariants)
.Test([&](ThrowingVariant* lhs) {
auto copy = rhs;
lhs->swap(copy);
@@ -487,7 +491,7 @@ TEST(VariantExceptionSafetyTest, Swap) {
ThrowingVariant rhs = ExpectedThrower();
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithCopyNoThrow())
- .WithInvariants(CheckInvariants)
+ .WithContracts(VariantInvariants)
.Test([&](ThrowingVariant* lhs) {
auto copy = rhs;
lhs->swap(copy);
@@ -497,7 +501,7 @@ TEST(VariantExceptionSafetyTest, Swap) {
ThrowingVariant rhs = ExpectedThrower();
EXPECT_TRUE(MakeExceptionSafetyTester()
.WithInitialValue(WithCopyNoThrow())
- .WithInvariants(CheckInvariants)
+ .WithContracts(VariantInvariants)
.Test([&](ThrowingVariant* lhs) {
auto copy = rhs;
copy.swap(*lhs);
@@ -506,5 +510,7 @@ TEST(VariantExceptionSafetyTest, Swap) {
}
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl
+
+#endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index 295023ae..59223ea7 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -52,7 +52,7 @@
#endif // ABSL_HAVE_EXCEPTIONS
#define ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(...) \
- ABSL_VARIANT_TEST_EXPECT_FAIL((__VA_ARGS__), absl::bad_variant_access, \
+ ABSL_VARIANT_TEST_EXPECT_FAIL((void)(__VA_ARGS__), absl::bad_variant_access, \
"Bad variant access")
struct Hashable {};
@@ -67,7 +67,7 @@ struct hash<Hashable> {
struct NonHashable {};
namespace absl {
-inline namespace lts_2018_06_20 {
+inline namespace lts_2018_12_18 {
namespace {
using ::testing::DoubleEq;
@@ -404,7 +404,7 @@ struct is_trivially_move_constructible
template <class T>
struct is_trivially_move_assignable
- : std::is_move_assignable<SingleUnion<T>>::type {};
+ : absl::is_move_assignable<SingleUnion<T>>::type {};
TEST(VariantTest, NothrowMoveConstructible) {
// Verify that variant is nothrow move constructible iff its template
@@ -560,9 +560,14 @@ TEST(VariantTest, TestDtor) {
}
#ifdef ABSL_HAVE_EXCEPTIONS
-
+// See comment in absl/base/config.h
+#if defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
+TEST(VariantTest, DISABLED_TestDtorValuelessByException)
+#else
// Test destruction when in the valueless_by_exception state.
-TEST(VariantTest, TestDtorValuelessByException) {
+TEST(VariantTest, TestDtorValuelessByException)
+#endif
+{
int counter = 0;
IncrementInDtor counter_adjuster(&counter);
@@ -2440,14 +2445,14 @@ TEST(VariantTest, TestMoveConversionViaConvertVariantTo) {
TEST(VariantTest, TestCopyAndMoveTypeTraits) {
EXPECT_TRUE(std::is_copy_constructible<variant<std::string>>::value);
- EXPECT_TRUE(std::is_copy_assignable<variant<std::string>>::value);
+ EXPECT_TRUE(absl::is_copy_assignable<variant<std::string>>::value);
EXPECT_TRUE(std::is_move_constructible<variant<std::string>>::value);
- EXPECT_TRUE(std::is_move_assignable<variant<std::string>>::value);
+ EXPECT_TRUE(absl::is_move_assignable<variant<std::string>>::value);
EXPECT_TRUE(std::is_move_constructible<variant<std::unique_ptr<int>>>::value);
- EXPECT_TRUE(std::is_move_assignable<variant<std::unique_ptr<int>>>::value);
+ EXPECT_TRUE(absl::is_move_assignable<variant<std::unique_ptr<int>>>::value);
EXPECT_FALSE(
std::is_copy_constructible<variant<std::unique_ptr<int>>>::value);
- EXPECT_FALSE(std::is_copy_assignable<variant<std::unique_ptr<int>>>::value);
+ EXPECT_FALSE(absl::is_copy_assignable<variant<std::unique_ptr<int>>>::value);
EXPECT_FALSE(
absl::is_trivially_copy_constructible<variant<std::string>>::value);
@@ -2610,5 +2615,5 @@ TEST(VariantTest, MoveCtorBug) {
}
} // namespace
-} // inline namespace lts_2018_06_20
+} // inline namespace lts_2018_12_18
} // namespace absl