Export of internal Abseil changes

--
fb671efb2a70f452f17a884b17cf18817b977a8f by Abseil Team <absl-team@google.com>:

Remove extra semicolon in ABSL_INTERNAL_ASSERT_IS_FULL macro

To fix compilation when empty statement warning is treated as error.

PiperOrigin-RevId: 438342663
Change-Id: I3067fbeffa2691888f37554e88f229f24fb55ecc

--
a58c9396f1d88d11347aed36ef2e1b633071363c by Martijn Vels <mvels@google.com>:

Fix kMaxHeight bounds to kMaxDepth for CordrepBtreeNavigator

Added unit test (confirmed failure mode with old code) and extra assertion in the implementation.

PiperOrigin-RevId: 438327463
Change-Id: I32242c86b0c879b8a42cb9a92075e537d588e09f

--
f348e85dbfc9187ef59085fa2b999374f1670338 by Jorge Gorbe Moya <jgorbe@google.com>:

Make the flags enum in `RefcountAndFlags` a named enum to workaround an lldb
issue (https://github.com/llvm/llvm-project/issues/54602).

PiperOrigin-RevId: 438146097
Change-Id: Ibc2ee26489d99de515a779a903b6458dd0befef7

--
a960a3e9fb2a2e3418f806178e73d8566b78bc85 by Gennadiy Rozental <rogeeff@google.com>:

Introduce support for std::optional<T>/absl::optional<T> flag types.

PiperOrigin-RevId: 438129500
Change-Id: I3d925c0a7f9ce9f857277fac3b0bf664ccd3a95c
GitOrigin-RevId: fb671efb2a70f452f17a884b17cf18817b977a8f
pull/1157/head
Abseil Team 3 years ago committed by rogeeff
parent 3204cc0625
commit cfccbd2eb5
  1. 6
      absl/container/internal/raw_hash_set.h
  2. 1
      absl/flags/BUILD.bazel
  3. 1
      absl/flags/CMakeLists.txt
  4. 174
      absl/flags/flag_test.cc
  5. 57
      absl/flags/marshalling.h
  6. 162
      absl/flags/marshalling_test.cc
  7. 2
      absl/strings/internal/cord_internal.h
  8. 6
      absl/strings/internal/cord_rep_btree_navigator.h
  9. 21
      absl/strings/internal/cord_rep_btree_navigator_test.cc

@ -713,7 +713,7 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
}
#define ABSL_INTERNAL_ASSERT_IS_FULL(ctrl, msg) \
ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && msg);
ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && msg)
inline void AssertIsValid(ctrl_t* ctrl) {
ABSL_HARDENING_ASSERT(
@ -1514,7 +1514,7 @@ class raw_hash_set {
// a better match if non-const iterator is passed as an argument.
void erase(iterator it) {
ABSL_INTERNAL_ASSERT_IS_FULL(it.ctrl_,
"erase() called on invalid iterator.")
"erase() called on invalid iterator.");
PolicyTraits::destroy(&alloc_ref(), it.slot_);
erase_meta_only(it);
}
@ -1549,7 +1549,7 @@ class raw_hash_set {
node_type extract(const_iterator position) {
ABSL_INTERNAL_ASSERT_IS_FULL(position.inner_.ctrl_,
"extract() called on invalid iterator.")
"extract() called on invalid iterator.");
auto node =
CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
erase_meta_only(position);

@ -100,6 +100,7 @@ cc_library(
"//absl/base:log_severity",
"//absl/strings",
"//absl/strings:str_format",
"//absl/types:optional",
],
)

@ -87,6 +87,7 @@ absl_cc_library(
absl::config
absl::core_headers
absl::log_severity
absl::optional
absl::strings
absl::str_format
)

@ -990,3 +990,177 @@ TEST_F(FlagTest, MacroWithinAbslFlag) {
absl::SetFlag(&FLAGS_prefix_test_macro_named_flag, 1);
EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 1);
}
// --------------------------------------------------------------------
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
#define ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
#endif
#ifndef ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
ABSL_FLAG(absl::optional<bool>, optional_bool, absl::nullopt, "help");
#endif
ABSL_FLAG(absl::optional<int>, optional_int, {}, "help");
ABSL_FLAG(absl::optional<double>, optional_double, 9.3, "help");
ABSL_FLAG(absl::optional<std::string>, optional_string, absl::nullopt, "help");
ABSL_FLAG(absl::optional<absl::Duration>, optional_duration, absl::nullopt,
"help");
ABSL_FLAG(absl::optional<absl::optional<int>>, optional_optional_int,
absl::nullopt, "help");
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
ABSL_FLAG(std::optional<int64_t>, std_optional_int64, std::nullopt, "help");
#endif
namespace {
#ifndef ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
TEST_F(FlagTest, TestOptionalBool) {
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt);
absl::SetFlag(&FLAGS_optional_bool, false);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), false);
absl::SetFlag(&FLAGS_optional_bool, true);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), true);
absl::SetFlag(&FLAGS_optional_bool, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt);
}
// --------------------------------------------------------------------
#endif
TEST_F(FlagTest, TestOptionalInt) {
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt);
absl::SetFlag(&FLAGS_optional_int, 0);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 0);
absl::SetFlag(&FLAGS_optional_int, 10);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 10);
absl::SetFlag(&FLAGS_optional_int, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt);
}
// --------------------------------------------------------------------
TEST_F(FlagTest, TestOptionalDouble) {
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 9.3);
absl::SetFlag(&FLAGS_optional_double, 0.0);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), 0.0);
absl::SetFlag(&FLAGS_optional_double, 1.234);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 1.234);
absl::SetFlag(&FLAGS_optional_double, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_double).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), absl::nullopt);
}
// --------------------------------------------------------------------
TEST_F(FlagTest, TestOptionalString) {
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt);
// Setting optional string to "" leads to undefined behavior.
absl::SetFlag(&FLAGS_optional_string, " ");
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), " ");
absl::SetFlag(&FLAGS_optional_string, "QWERTY");
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), "QWERTY");
absl::SetFlag(&FLAGS_optional_string, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt);
}
// --------------------------------------------------------------------
TEST_F(FlagTest, TestOptionalDuration) {
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt);
absl::SetFlag(&FLAGS_optional_duration, absl::ZeroDuration());
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Seconds(0));
absl::SetFlag(&FLAGS_optional_duration, absl::Hours(3));
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Hours(3));
absl::SetFlag(&FLAGS_optional_duration, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt);
}
// --------------------------------------------------------------------
TEST_F(FlagTest, TestOptionalOptional) {
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt);
absl::optional<int> nullint{absl::nullopt};
absl::SetFlag(&FLAGS_optional_optional_int, nullint);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
EXPECT_NE(absl::GetFlag(FLAGS_optional_optional_int), nullint);
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int),
absl::optional<absl::optional<int>>{nullint});
absl::SetFlag(&FLAGS_optional_optional_int, 0);
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0);
absl::SetFlag(&FLAGS_optional_optional_int, absl::optional<int>{0});
EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0);
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::optional<int>{0});
absl::SetFlag(&FLAGS_optional_optional_int, absl::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt);
}
// --------------------------------------------------------------------
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
TEST_F(FlagTest, TestStdOptional) {
EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt);
absl::SetFlag(&FLAGS_std_optional_int64, 0);
EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0);
absl::SetFlag(&FLAGS_std_optional_int64, 0xFFFFFFFFFF16);
EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0xFFFFFFFFFF16);
absl::SetFlag(&FLAGS_std_optional_int64, std::nullopt);
EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt);
}
// --------------------------------------------------------------------
#endif
} // namespace

@ -162,14 +162,27 @@
#ifndef ABSL_FLAGS_MARSHALLING_H_
#define ABSL_FLAGS_MARSHALLING_H_
#include "absl/base/config.h"
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
#include <optional>
#endif
#include <string>
#include <vector>
#include "absl/base/config.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
// Forward declaration to be used inside composable flag parse/unparse
// implementations
template <typename T>
inline bool ParseFlag(absl::string_view input, T* dst, std::string* error);
template <typename T>
inline std::string UnparseFlag(const T& v);
namespace flags_internal {
// Overloads of `AbslParseFlag()` and `AbslUnparseFlag()` for fundamental types.
@ -188,6 +201,36 @@ bool AbslParseFlag(absl::string_view, double*, std::string*);
bool AbslParseFlag(absl::string_view, std::string*, std::string*);
bool AbslParseFlag(absl::string_view, std::vector<std::string>*, std::string*);
template <typename T>
bool AbslParseFlag(absl::string_view text, absl::optional<T>* f,
std::string* err) {
if (text.empty()) {
*f = absl::nullopt;
return true;
}
T value;
if (!absl::ParseFlag(text, &value, err)) return false;
*f = std::move(value);
return true;
}
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
template <typename T>
bool AbslParseFlag(absl::string_view text, std::optional<T>* f,
std::string* err) {
if (text.empty()) {
*f = std::nullopt;
return true;
}
T value;
if (!absl::ParseFlag(text, &value, err)) return false;
*f = std::move(value);
return true;
}
#endif
template <typename T>
bool InvokeParseFlag(absl::string_view input, T* dst, std::string* err) {
// Comment on next line provides a good compiler error message if T
@ -201,6 +244,18 @@ bool InvokeParseFlag(absl::string_view input, T* dst, std::string* err) {
std::string AbslUnparseFlag(absl::string_view v);
std::string AbslUnparseFlag(const std::vector<std::string>&);
template <typename T>
std::string AbslUnparseFlag(const absl::optional<T>& f) {
return f.has_value() ? absl::UnparseFlag(*f) : "";
}
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
template <typename T>
std::string AbslUnparseFlag(const std::optional<T>& f) {
return f.has_value() ? absl::UnparseFlag(*f) : "";
}
#endif
template <typename T>
std::string Unparse(const T& v) {
// Comment on next line provides a good compiler error message if T does not

@ -659,6 +659,88 @@ TEST(MarshallingTest, TestVectorOfStringParsing) {
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalBoolParsing) {
std::string err;
absl::optional<bool> value;
EXPECT_TRUE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(value.has_value());
EXPECT_TRUE(absl::ParseFlag("true", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_TRUE(*value);
EXPECT_TRUE(absl::ParseFlag("false", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_FALSE(*value);
EXPECT_FALSE(absl::ParseFlag("nullopt", &value, &err));
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalIntParsing) {
std::string err;
absl::optional<int> value;
EXPECT_TRUE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(value.has_value());
EXPECT_TRUE(absl::ParseFlag("10", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, 10);
EXPECT_TRUE(absl::ParseFlag("0x1F", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, 31);
EXPECT_FALSE(absl::ParseFlag("nullopt", &value, &err));
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalDoubleParsing) {
std::string err;
absl::optional<double> value;
EXPECT_TRUE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(value.has_value());
EXPECT_TRUE(absl::ParseFlag("1.11", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, 1.11);
EXPECT_TRUE(absl::ParseFlag("-0.12", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, -0.12);
EXPECT_FALSE(absl::ParseFlag("nullopt", &value, &err));
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalStringParsing) {
std::string err;
absl::optional<std::string> value;
EXPECT_TRUE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(value.has_value());
EXPECT_TRUE(absl::ParseFlag(" ", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, " ");
EXPECT_TRUE(absl::ParseFlag("aqswde", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, "aqswde");
EXPECT_TRUE(absl::ParseFlag("nullopt", &value, &err));
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, "nullopt");
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestBoolUnparsing) {
EXPECT_EQ(absl::UnparseFlag(true), "true");
EXPECT_EQ(absl::UnparseFlag(false), "false");
@ -808,6 +890,86 @@ TEST(MarshallingTest, TestStringUnparsing) {
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalBoolUnparsing) {
absl::optional<bool> value;
EXPECT_EQ(absl::UnparseFlag(value), "");
value = true;
EXPECT_EQ(absl::UnparseFlag(value), "true");
value = false;
EXPECT_EQ(absl::UnparseFlag(value), "false");
value = absl::nullopt;
EXPECT_EQ(absl::UnparseFlag(value), "");
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalIntUnparsing) {
absl::optional<int> value;
EXPECT_EQ(absl::UnparseFlag(value), "");
value = 0;
EXPECT_EQ(absl::UnparseFlag(value), "0");
value = -12;
EXPECT_EQ(absl::UnparseFlag(value), "-12");
value = absl::nullopt;
EXPECT_EQ(absl::UnparseFlag(value), "");
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalDoubleUnparsing) {
absl::optional<double> value;
EXPECT_EQ(absl::UnparseFlag(value), "");
value = 1.;
EXPECT_EQ(absl::UnparseFlag(value), "1");
value = -1.23;
EXPECT_EQ(absl::UnparseFlag(value), "-1.23");
value = absl::nullopt;
EXPECT_EQ(absl::UnparseFlag(value), "");
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestOptionalStringUnparsing) {
absl::optional<std::string> value;
EXPECT_EQ(absl::UnparseFlag(value), "");
value = "asdfg";
EXPECT_EQ(absl::UnparseFlag(value), "asdfg");
value = " ";
EXPECT_EQ(absl::UnparseFlag(value), " ");
value = ""; // This is UB to set optional string flag to ""
EXPECT_EQ(absl::UnparseFlag(value), "");
value = absl::nullopt;
EXPECT_EQ(absl::UnparseFlag(value), "");
}
// --------------------------------------------------------------------
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
TEST(MarshallingTest, TestStdOptionalUnparsing) {
std::optional<std::string> strvalue;
EXPECT_EQ(absl::UnparseFlag(strvalue), "");
strvalue = "asdfg";
EXPECT_EQ(absl::UnparseFlag(strvalue), "asdfg");
strvalue = std::nullopt;
EXPECT_EQ(absl::UnparseFlag(strvalue), "");
std::optional<int> intvalue(10);
EXPECT_EQ(absl::UnparseFlag(intvalue), "10");
intvalue = std::nullopt;
EXPECT_EQ(absl::UnparseFlag(intvalue), "");
}
// --------------------------------------------------------------------
#endif
template <typename T>
void TestRoundtrip(T v) {
T new_v;

@ -156,7 +156,7 @@ class RefcountAndFlags {
// used for the StringConstant constructor to avoid collecting immutable
// constant cords.
// kReservedFlag is reserved for future use.
enum {
enum Flags {
kNumFlags = 2,
kImmortalFlag = 0x1,

@ -143,8 +143,8 @@ class CordRepBtreeNavigator {
// `index_` and `node_` contain the navigation state as the 'path' to the
// current data edge which is at `node_[0]->Edge(index_[0])`. The contents
// of these are undefined until the instance is initialized (`height_ >= 0`).
uint8_t index_[CordRepBtree::kMaxHeight];
CordRepBtree* node_[CordRepBtree::kMaxHeight];
uint8_t index_[CordRepBtree::kMaxDepth];
CordRepBtree* node_[CordRepBtree::kMaxDepth];
};
// Returns true if this instance is not empty.
@ -173,6 +173,7 @@ template <CordRepBtree::EdgeType edge_type>
inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) {
assert(tree != nullptr);
assert(tree->size() > 0);
assert(tree->height() <= CordRepBtree::kMaxHeight);
int height = height_ = tree->height();
size_t index = tree->index(edge_type);
node_[height] = tree;
@ -206,6 +207,7 @@ inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek(
inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset(
CordRepBtree* tree, size_t offset) {
assert(tree != nullptr);
assert(tree->height() <= CordRepBtree::kMaxHeight);
if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0};
height_ = tree->height();
node_[height_] = tree;

@ -319,6 +319,27 @@ TEST_P(CordRepBtreeNavigatorTest, ReadBeyondLengthOfTree) {
ASSERT_THAT(result.tree, Eq(nullptr));
}
TEST(CordRepBtreeNavigatorTest, NavigateMaximumTreeDepth) {
CordRepFlat* flat1 = MakeFlat("Hello world");
CordRepFlat* flat2 = MakeFlat("World Hello");
CordRepBtree* node = CordRepBtree::Create(flat1);
node = CordRepBtree::Append(node, flat2);
while (node->height() < CordRepBtree::kMaxHeight) {
node = CordRepBtree::New(node);
}
CordRepBtreeNavigator nav;
CordRep* edge = nav.InitFirst(node);
EXPECT_THAT(edge, Eq(flat1));
EXPECT_THAT(nav.Next(), Eq(flat2));
EXPECT_THAT(nav.Next(), Eq(nullptr));
EXPECT_THAT(nav.Previous(), Eq(flat1));
EXPECT_THAT(nav.Previous(), Eq(nullptr));
CordRep::Unref(node);
}
} // namespace
} // namespace cord_internal
ABSL_NAMESPACE_END

Loading…
Cancel
Save