summaryrefslogtreecommitdiff
path: root/abseil-cpp/absl/types/optional_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'abseil-cpp/absl/types/optional_test.cc')
-rw-r--r--abseil-cpp/absl/types/optional_test.cc115
1 files changed, 57 insertions, 58 deletions
diff --git a/abseil-cpp/absl/types/optional_test.cc b/abseil-cpp/absl/types/optional_test.cc
index 7ef142c..5da297b 100644
--- a/abseil-cpp/absl/types/optional_test.cc
+++ b/abseil-cpp/absl/types/optional_test.cc
@@ -23,10 +23,41 @@
#include "gtest/gtest.h"
#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/log/log.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
+#if defined(__cplusplus) && __cplusplus >= 202002L
+// In C++20, volatile-qualified return types are deprecated.
+#define ABSL_VOLATILE_RETURN_TYPES_DEPRECATED 1
+#endif
+
+// The following types help test an internal compiler error in GCC5 though
+// GCC10. The case OptionalTest.InternalCompilerErrorInGcc5ToGcc10 crashes the
+// compiler without a workaround. This test case should remain at the beginning
+// of the file as the internal compiler error is sensitive to other constructs
+// in this file.
+template <class T, class...>
+using GccIceHelper1 = T;
+template <typename T>
+struct GccIceHelper2 {};
+template <typename T>
+class GccIce {
+ template <typename U,
+ typename SecondTemplateArgHasToExistForSomeReason = void,
+ typename DependentType = void,
+ typename = std::is_assignable<GccIceHelper1<T, DependentType>&, U>>
+ GccIce& operator=(GccIceHelper2<U> const&) {}
+};
+
+TEST(OptionalTest, InternalCompilerErrorInGcc5ToGcc10) {
+ GccIce<int> instantiate_ice_with_same_type_as_optional;
+ static_cast<void>(instantiate_ice_with_same_type_as_optional);
+ absl::optional<int> val1;
+ absl::optional<int> val2;
+ val1 = val2;
+}
+
struct Hashable {};
namespace std {
@@ -66,9 +97,9 @@ struct StructorListener {
// 4522: multiple assignment operators specified
// We wrote multiple of them to test that the correct overloads are selected.
#ifdef _MSC_VER
-#pragma warning( push )
-#pragma warning( disable : 4521)
-#pragma warning( disable : 4522)
+#pragma warning(push)
+#pragma warning(disable : 4521)
+#pragma warning(disable : 4522)
#endif
struct Listenable {
static StructorListener* listener;
@@ -102,20 +133,11 @@ struct Listenable {
~Listenable() { ++listener->destruct; }
};
#ifdef _MSC_VER
-#pragma warning( pop )
+#pragma warning(pop)
#endif
StructorListener* Listenable::listener = nullptr;
-// ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST is defined to 1 when the standard
-// library implementation doesn't marked initializer_list's default constructor
-// constexpr. The C++11 standard doesn't specify constexpr on it, but C++14
-// added it. However, libstdc++ 4.7 marked it constexpr.
-#if defined(_LIBCPP_VERSION) && \
- (_LIBCPP_STD_VER <= 11 || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR))
-#define ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST 1
-#endif
-
struct ConstexprType {
enum CtorTypes {
kCtorDefault,
@@ -125,10 +147,8 @@ struct ConstexprType {
};
constexpr ConstexprType() : x(kCtorDefault) {}
constexpr explicit ConstexprType(int i) : x(kCtorInt) {}
-#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
constexpr ConstexprType(std::initializer_list<int> il)
: x(kCtorInitializerList) {}
-#endif
constexpr ConstexprType(const char*) // NOLINT(runtime/explicit)
: x(kCtorConstChar) {}
int x;
@@ -205,6 +225,7 @@ TEST(optionalTest, CopyConstructor) {
EXPECT_TRUE(opt42_copy);
EXPECT_EQ(42, *opt42_copy);
}
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
{
absl::optional<volatile int> empty, opt42 = 42;
absl::optional<volatile int> empty_copy(empty);
@@ -213,6 +234,7 @@ TEST(optionalTest, CopyConstructor) {
EXPECT_TRUE(opt42_copy);
EXPECT_EQ(42, *opt42_copy);
}
+#endif
// test copyablility
EXPECT_TRUE(std::is_copy_constructible<absl::optional<int>>::value);
EXPECT_TRUE(std::is_copy_constructible<absl::optional<Copyable>>::value);
@@ -224,18 +246,11 @@ TEST(optionalTest, CopyConstructor) {
EXPECT_FALSE(
absl::is_trivially_copy_constructible<absl::optional<Copyable>>::value);
-#if defined(ABSL_USES_STD_OPTIONAL) && defined(__GLIBCXX__)
- // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is
- // trivially copyable, optional<T> is not trivially copyable (due to one of
- // its base class is unconditionally nontrivial).
-#define ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG 1
-#endif
-#ifndef ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
EXPECT_TRUE(
absl::is_trivially_copy_constructible<absl::optional<int>>::value);
EXPECT_TRUE(
absl::is_trivially_copy_constructible<absl::optional<const int>>::value);
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) && !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
// See defect report "Trivial copy/move constructor for class with volatile
// member" at
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2094
@@ -244,8 +259,7 @@ TEST(optionalTest, CopyConstructor) {
// Also a cv-qualified scalar type should be trivially copyable.
EXPECT_TRUE(absl::is_trivially_copy_constructible<
absl::optional<volatile int>>::value);
-#endif // _MSC_VER
-#endif // ABSL_GLIBCXX_OPTIONAL_TRIVIALITY_BUG
+#endif // !defined(_MSC_VER) && !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
// constexpr copy constructor for trivially copyable types
{
@@ -275,17 +289,10 @@ TEST(optionalTest, CopyConstructor) {
EXPECT_TRUE(absl::is_trivially_copy_constructible<
absl::optional<const TrivialCopyable>>::value);
#endif
- // When testing with VS 2017 15.3, there seems to be a bug in MSVC
- // std::optional when T is volatile-qualified. So skipping this test.
- // Bug report:
- // https://connect.microsoft.com/VisualStudio/feedback/details/3142534
-#if defined(ABSL_USES_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911
-#define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1
-#endif
-#ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
EXPECT_FALSE(std::is_copy_constructible<
absl::optional<volatile TrivialCopyable>>::value);
-#endif
+#endif // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
}
}
@@ -305,11 +312,9 @@ TEST(optionalTest, MoveConstructor) {
EXPECT_FALSE(std::is_move_constructible<absl::optional<NonMovable>>::value);
// test noexcept
EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value);
-#ifndef ABSL_USES_STD_OPTIONAL
EXPECT_EQ(
absl::default_allocator_is_nothrow::value,
std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value);
-#endif
EXPECT_TRUE(std::is_nothrow_move_constructible<
absl::optional<MoveableNoThrow>>::value);
}
@@ -336,11 +341,9 @@ TEST(optionalTest, InPlaceConstructor) {
constexpr absl::optional<ConstexprType> opt1{absl::in_place_t(), 1};
static_assert(opt1, "");
static_assert((*opt1).x == ConstexprType::kCtorInt, "");
-#ifndef ABSL_HAVE_NO_CONSTEXPR_INITIALIZER_LIST
constexpr absl::optional<ConstexprType> opt2{absl::in_place_t(), {1, 2}};
static_assert(opt2, "");
static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");
-#endif
EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
absl::in_place_t>::value));
@@ -638,8 +641,7 @@ TEST(optionalTest, CopyAssignment) {
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.
-#ifndef ABSL_USES_STD_OPTIONAL
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
{
StructorListener listener;
Listenable::listener = &listener;
@@ -658,7 +660,7 @@ TEST(optionalTest, CopyAssignment) {
EXPECT_EQ(1, listener.destruct);
EXPECT_EQ(1, listener.volatile_copy_assign);
}
-#endif // ABSL_USES_STD_OPTIONAL
+#endif // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
}
TEST(optionalTest, MoveAssignment) {
@@ -681,8 +683,7 @@ TEST(optionalTest, MoveAssignment) {
EXPECT_EQ(1, listener.destruct);
EXPECT_EQ(1, listener.move_assign);
}
- // std::optional doesn't support volatile nontrivial types.
-#ifndef ABSL_USES_STD_OPTIONAL
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
{
StructorListener listener;
Listenable::listener = &listener;
@@ -702,7 +703,7 @@ TEST(optionalTest, MoveAssignment) {
EXPECT_EQ(1, listener.destruct);
EXPECT_EQ(1, listener.volatile_move_assign);
}
-#endif // ABSL_USES_STD_OPTIONAL
+#endif // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
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);
@@ -974,8 +975,8 @@ TEST(optionalTest, PointerStuff) {
EXPECT_EQ("foo", *opt);
const auto& opt_const = opt;
EXPECT_EQ("foo", *opt_const);
- EXPECT_EQ(opt->size(), 3);
- EXPECT_EQ(opt_const->size(), 3);
+ EXPECT_EQ(opt->size(), 3u);
+ EXPECT_EQ(opt_const->size(), 3u);
constexpr absl::optional<ConstexprType> opt1(1);
static_assert((*opt1).x == ConstexprType::kCtorInt, "");
@@ -986,9 +987,8 @@ TEST(optionalTest, PointerStuff) {
// Skip that test to make the build green again when using the old compiler.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59296 is fixed in 4.9.1.
#if defined(__GNUC__) && !defined(__clang__)
-#define GCC_VERSION (__GNUC__ * 10000 \
- + __GNUC_MINOR__ * 100 \
- + __GNUC_PATCHLEVEL__)
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40901
#define ABSL_SKIP_OVERLOAD_TEST_DUE_TO_GCC_BUG
#endif
@@ -996,7 +996,7 @@ TEST(optionalTest, PointerStuff) {
// MSVC has a bug with "cv-qualifiers in class construction", fixed in 2017. See
// https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#bug-fixes
-// The compiler some incorrectly ingores the cv-qualifier when generating a
+// The compiler some incorrectly ignores the cv-qualifier when generating a
// class object via a constructor call. For example:
//
// class optional {
@@ -1038,6 +1038,7 @@ TEST(optionalTest, Value) {
#endif
EXPECT_EQ("c&&", TypeQuals(OC(absl::in_place, "xvalue_c").value()));
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
// test on volatile type
using OV = absl::optional<volatile int>;
OV lvalue_v(absl::in_place, 42);
@@ -1045,6 +1046,7 @@ TEST(optionalTest, Value) {
EXPECT_EQ(42, OV(42).value());
EXPECT_TRUE((std::is_same<volatile int&, decltype(lvalue_v.value())>::value));
EXPECT_TRUE((std::is_same<volatile int&&, decltype(OV(42).value())>::value));
+#endif // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
// test exception throw on value()
absl::optional<int> empty;
@@ -1087,6 +1089,7 @@ TEST(optionalTest, DerefOperator) {
#endif
EXPECT_EQ("c&&", TypeQuals(*OC(absl::in_place, "xvalue_c")));
+#if !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
// test on volatile type
using OV = absl::optional<volatile int>;
OV lvalue_v(absl::in_place, 42);
@@ -1094,6 +1097,7 @@ TEST(optionalTest, DerefOperator) {
EXPECT_EQ(42, *OV(42));
EXPECT_TRUE((std::is_same<volatile int&, decltype(*lvalue_v)>::value));
EXPECT_TRUE((std::is_same<volatile int&&, decltype(*OV(42))>::value));
+#endif // !defined(ABSL_VOLATILE_RETURN_TYPES_DEPRECATED)
constexpr absl::optional<int> opt1(1);
static_assert(*opt1 == 1, "");
@@ -1196,7 +1200,6 @@ void optionalTest_Comparisons_EXPECT_GREATER(T x, U y) {
EXPECT_TRUE(x >= y);
}
-
template <typename T, typename U, typename V>
void TestComparisons() {
absl::optional<T> ae, a2{2}, a4{4};
@@ -1289,7 +1292,6 @@ TEST(optionalTest, Comparisons) {
EXPECT_TRUE(e1 == e2);
}
-
TEST(optionalTest, SwapRegression) {
StructorListener listener;
Listenable::listener = &listener;
@@ -1505,7 +1507,7 @@ TEST(optionalTest, Hash) {
for (int i = 0; i < 100; ++i) {
hashcodes.insert(hash(i));
}
- EXPECT_GT(hashcodes.size(), 90);
+ EXPECT_GT(hashcodes.size(), 90u);
static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
@@ -1540,8 +1542,7 @@ TEST(optionalTest, Hash) {
struct MoveMeNoThrow {
MoveMeNoThrow() : x(0) {}
[[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) {
- ABSL_RAW_LOG(FATAL, "Should not be called.");
- abort();
+ LOG(FATAL) << "Should not be called.";
}
MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {}
int x;
@@ -1558,12 +1559,10 @@ TEST(optionalTest, NoExcept) {
static_assert(
std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::value,
"");
-#ifndef ABSL_USES_STD_OPTIONAL
static_assert(absl::default_allocator_is_nothrow::value ==
std::is_nothrow_move_constructible<
absl::optional<MoveMeThrow>>::value,
"");
-#endif
std::vector<absl::optional<MoveMeNoThrow>> v;
for (int i = 0; i < 10; ++i) v.emplace_back();
}