Skip to content

Commit 89c531c

Browse files
Abseil Teamrogeeff
Abseil Team
authored andcommitted
Export of internal Abseil changes
-- e1a0989213908927f05002ab7697955ad7dc5632 by Martijn Vels <[email protected]>: Introduce CordRepBtreeReader CordRepBtreeReader provides forward navigation on cord btrees with absolute positional (offset) context, iterating over btree data in absl::string_view chunks. PiperOrigin-RevId: 387585161 -- 206d298e2bccb998731995cb05717b31fa9d90ec by Abseil Team <[email protected]>: Internal change PiperOrigin-RevId: 387577465 -- f07fafe8a400a4f5dfef186d1a3b61fb7f709fe5 by Abseil Team <[email protected]>: This change adds debug-build enforcement that the inputs to absl::c_set_intersection are sorted, which is a prerequisite of std::set_intersection and required for correct operation of the algorithm. PiperOrigin-RevId: 387446657 -- 2ca15c6361bb758be7fb88cae82bf8489b4d3364 by Abseil Team <[email protected]>: Change BadStatusOrAccess::what() to contain status_.ToString() This ensures that on uncaught exception propagation that would cause program termination, the message contains information on the error which caused the failure. Lazy initialization of what_ is a value judgement: if most callers are expected to call status() not what(), lazy initialization is correct. If most callers are expected to call what(), it should be initialized on construction to avoid atomic operation overhead. PiperOrigin-RevId: 387402243 -- 3e855084e104dc972a0c4385395e6d8e8465127f by Gennadiy Rozental <[email protected]>: LSC: Standardize access to GoogleTest flags on GTEST_FLAG_GET/GTEST_FLAG_SET This change is necessary to move Googletest flags out of the testing:: namespace without breaking code. These new macros will continue to be required for code that needs to work both inside Google's monorepo and outside in OSS, but can be used anywhere inside the monorepo. PiperOrigin-RevId: 387396025 -- 1ccf5895a15059ef689af5c4817d7b84f73190be by Gennadiy Rozental <[email protected]>: Import of CCTZ from GitHub. PiperOrigin-RevId: 387388496 GitOrigin-RevId: e1a0989213908927f05002ab7697955ad7dc5632 Change-Id: I3606d9ce29d909a3555e662e9df564202cf5068d
1 parent 4bb7393 commit 89c531c

16 files changed

+763
-62
lines changed

CMake/AbseilDll.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ set(ABSL_INTERNAL_DLL_FILES
209209
"strings/internal/cord_rep_btree.h"
210210
"strings/internal/cord_rep_btree_navigator.cc"
211211
"strings/internal/cord_rep_btree_navigator.h"
212+
"strings/internal/cord_rep_btree_reader.cc"
213+
"strings/internal/cord_rep_btree_reader.h"
212214
"strings/internal/cord_rep_flat.h"
213215
"strings/internal/cord_rep_ring.cc"
214216
"strings/internal/cord_rep_ring.h"

absl/algorithm/container.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output,
12621262
// c_set_intersection()
12631263
//
12641264
// Container-based version of the <algorithm> `std::set_intersection()` function
1265-
// to return an iterator containing the intersection of two containers.
1265+
// to return an iterator containing the intersection of two sorted containers.
12661266
template <typename C1, typename C2, typename OutputIterator,
12671267
typename = typename std::enable_if<
12681268
!container_algorithm_internal::IsUnorderedContainer<C1>::value,
@@ -1272,6 +1272,11 @@ template <typename C1, typename C2, typename OutputIterator,
12721272
void>::type>
12731273
OutputIterator c_set_intersection(const C1& c1, const C2& c2,
12741274
OutputIterator output) {
1275+
// In debug builds, ensure that both containers are sorted with respect to the
1276+
// default comparator. std::set_intersection requires the containers be sorted
1277+
// using operator<.
1278+
assert(absl::c_is_sorted(c1));
1279+
assert(absl::c_is_sorted(c2));
12751280
return std::set_intersection(container_algorithm_internal::c_begin(c1),
12761281
container_algorithm_internal::c_end(c1),
12771282
container_algorithm_internal::c_begin(c2),
@@ -1289,6 +1294,11 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan,
12891294
void>::type>
12901295
OutputIterator c_set_intersection(const C1& c1, const C2& c2,
12911296
OutputIterator output, LessThan&& comp) {
1297+
// In debug builds, ensure that both containers are sorted with respect to the
1298+
// default comparator. std::set_intersection requires the containers be sorted
1299+
// using the same comparator.
1300+
assert(absl::c_is_sorted(c1, comp));
1301+
assert(absl::c_is_sorted(c2, comp));
12921302
return std::set_intersection(container_algorithm_internal::c_begin(c1),
12931303
container_algorithm_internal::c_end(c1),
12941304
container_algorithm_internal::c_begin(c2),

absl/container/btree_test.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ void BtreeTest() {
595595
using V = typename remove_pair_const<typename T::value_type>::type;
596596
const std::vector<V> random_values = GenerateValuesWithSeed<V>(
597597
absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
598-
testing::GTEST_FLAG(random_seed));
598+
GTEST_FLAG_GET(random_seed));
599599

600600
unique_checker<T, C> container;
601601

@@ -619,7 +619,7 @@ void BtreeMultiTest() {
619619
using V = typename remove_pair_const<typename T::value_type>::type;
620620
const std::vector<V> random_values = GenerateValuesWithSeed<V>(
621621
absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
622-
testing::GTEST_FLAG(random_seed));
622+
GTEST_FLAG_GET(random_seed));
623623

624624
multi_checker<T, C> container;
625625

absl/status/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ cc_library(
7878
copts = ABSL_DEFAULT_COPTS,
7979
deps = [
8080
":status",
81+
"//absl/base",
8182
"//absl/base:core_headers",
8283
"//absl/base:raw_logging_internal",
8384
"//absl/meta:type_traits",
@@ -96,6 +97,7 @@ cc_test(
9697
":statusor",
9798
"//absl/base",
9899
"//absl/memory",
100+
"//absl/strings",
99101
"//absl/types:any",
100102
"//absl/utility",
101103
"@com_google_googletest//:gtest_main",

absl/status/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ absl_cc_library(
6464
COPTS
6565
${ABSL_DEFAULT_COPTS}
6666
DEPS
67+
absl::base
6768
absl::status
6869
absl::core_headers
6970
absl::raw_logging_internal

absl/status/statusor.cc

+34-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstdlib>
1717
#include <utility>
1818

19+
#include "absl/base/call_once.h"
1920
#include "absl/base/internal/raw_logging.h"
2021
#include "absl/status/status.h"
2122
#include "absl/strings/str_cat.h"
@@ -26,13 +27,44 @@ ABSL_NAMESPACE_BEGIN
2627
BadStatusOrAccess::BadStatusOrAccess(absl::Status status)
2728
: status_(std::move(status)) {}
2829

29-
BadStatusOrAccess::~BadStatusOrAccess() = default;
30+
BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other)
31+
: status_(other.status_) {}
32+
33+
BadStatusOrAccess& BadStatusOrAccess::operator=(
34+
const BadStatusOrAccess& other) {
35+
// Ensure assignment is correct regardless of whether this->InitWhat() has
36+
// already been called.
37+
other.InitWhat();
38+
status_ = other.status_;
39+
what_ = other.what_;
40+
return *this;
41+
}
42+
43+
BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) {
44+
// Ensure assignment is correct regardless of whether this->InitWhat() has
45+
// already been called.
46+
other.InitWhat();
47+
status_ = std::move(other.status_);
48+
what_ = std::move(other.what_);
49+
return *this;
50+
}
51+
52+
BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other)
53+
: status_(std::move(other.status_)) {}
54+
3055
const char* BadStatusOrAccess::what() const noexcept {
31-
return "Bad StatusOr access";
56+
InitWhat();
57+
return what_.c_str();
3258
}
3359

3460
const absl::Status& BadStatusOrAccess::status() const { return status_; }
3561

62+
void BadStatusOrAccess::InitWhat() const {
63+
absl::call_once(init_what_, [this] {
64+
what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString());
65+
});
66+
}
67+
3668
namespace internal_statusor {
3769

3870
void Helper::HandleInvalidStatusCtorArg(absl::Status* status) {

absl/status/statusor.h

+19-9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <utility>
4545

4646
#include "absl/base/attributes.h"
47+
#include "absl/base/call_once.h"
4748
#include "absl/meta/type_traits.h"
4849
#include "absl/status/internal/statusor_internal.h"
4950
#include "absl/status/status.h"
@@ -72,13 +73,18 @@ ABSL_NAMESPACE_BEGIN
7273
class BadStatusOrAccess : public std::exception {
7374
public:
7475
explicit BadStatusOrAccess(absl::Status status);
75-
~BadStatusOrAccess() override;
76+
~BadStatusOrAccess() override = default;
77+
78+
BadStatusOrAccess(const BadStatusOrAccess& other);
79+
BadStatusOrAccess& operator=(const BadStatusOrAccess& other);
80+
BadStatusOrAccess(BadStatusOrAccess&& other);
81+
BadStatusOrAccess& operator=(BadStatusOrAccess&& other);
7682

7783
// BadStatusOrAccess::what()
7884
//
7985
// Returns the associated explanatory string of the `absl::StatusOr<T>`
80-
// object's error code. This function only returns the string literal "Bad
81-
// StatusOr Access" for cases when evaluating general exceptions.
86+
// object's error code. This function contains information about the failing
87+
// status, but its exact formatting may change and should not be depended on.
8288
//
8389
// The pointer of this string is guaranteed to be valid until any non-const
8490
// function is invoked on the exception object.
@@ -91,7 +97,11 @@ class BadStatusOrAccess : public std::exception {
9197
const absl::Status& status() const;
9298

9399
private:
100+
void InitWhat() const;
101+
94102
absl::Status status_;
103+
mutable absl::once_flag init_what_;
104+
mutable std::string what_;
95105
};
96106

97107
// Returned StatusOr objects may not be ignored.
@@ -437,8 +447,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>,
437447
T, U&&>>>>>::value,
438448
int> = 0>
439449
StatusOr(U&& u) // NOLINT
440-
: StatusOr(absl::in_place, std::forward<U>(u)) {
441-
}
450+
: StatusOr(absl::in_place, std::forward<U>(u)) {}
442451

443452
template <
444453
typename U = T,
@@ -457,8 +466,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>,
457466
absl::negation<std::is_convertible<U&&, T>>>::value,
458467
int> = 0>
459468
explicit StatusOr(U&& u) // NOLINT
460-
: StatusOr(absl::in_place, std::forward<U>(u)) {
461-
}
469+
: StatusOr(absl::in_place, std::forward<U>(u)) {}
462470

463471
// StatusOr<T>::ok()
464472
//
@@ -481,7 +489,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>,
481489
// Returns a reference to the current `absl::Status` contained within the
482490
// `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
483491
// function returns `absl::OkStatus()`.
484-
const Status& status() const &;
492+
const Status& status() const&;
485493
Status status() &&;
486494

487495
// StatusOr<T>::value()
@@ -661,7 +669,9 @@ StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
661669
: Base(absl::in_place, ilist, std::forward<Args>(args)...) {}
662670

663671
template <typename T>
664-
const Status& StatusOr<T>::status() const & { return this->status_; }
672+
const Status& StatusOr<T>::status() const& {
673+
return this->status_;
674+
}
665675
template <typename T>
666676
Status StatusOr<T>::status() && {
667677
return ok() ? OkStatus() : std::move(this->status_);

absl/status/statusor_test.cc

+53-17
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <array>
1818
#include <initializer_list>
1919
#include <memory>
20+
#include <string>
2021
#include <type_traits>
2122
#include <utility>
2223

@@ -25,6 +26,7 @@
2526
#include "absl/base/casts.h"
2627
#include "absl/memory/memory.h"
2728
#include "absl/status/status.h"
29+
#include "absl/strings/string_view.h"
2830
#include "absl/types/any.h"
2931
#include "absl/utility/utility.h"
3032

@@ -34,6 +36,7 @@ using ::testing::AllOf;
3436
using ::testing::AnyWith;
3537
using ::testing::ElementsAre;
3638
using ::testing::Field;
39+
using ::testing::HasSubstr;
3740
using ::testing::Ne;
3841
using ::testing::Not;
3942
using ::testing::Pointee;
@@ -257,9 +260,9 @@ TEST(StatusOr, TestMoveOnlyInitializationFromTemporaryByValueOrDie) {
257260

258261
TEST(StatusOr, TestValueOrDieOverloadForConstTemporary) {
259262
static_assert(
260-
std::is_same<const int&&,
261-
decltype(
262-
std::declval<const absl::StatusOr<int>&&>().value())>(),
263+
std::is_same<
264+
const int&&,
265+
decltype(std::declval<const absl::StatusOr<int>&&>().value())>(),
263266
"value() for const temporaries should return const T&&");
264267
}
265268

@@ -303,20 +306,57 @@ TEST(StatusOr, StatusCtorForwards) {
303306
EXPECT_NE(status.message(), "Some error");
304307
}
305308

309+
TEST(BadStatusOrAccessTest, CopyConstructionWhatOk) {
310+
absl::Status error =
311+
absl::InternalError("some arbitrary message too big for the sso buffer");
312+
absl::BadStatusOrAccess e1{error};
313+
absl::BadStatusOrAccess e2{e1};
314+
EXPECT_THAT(e1.what(), HasSubstr(error.ToString()));
315+
EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
316+
}
317+
318+
TEST(BadStatusOrAccessTest, CopyAssignmentWhatOk) {
319+
absl::Status error =
320+
absl::InternalError("some arbitrary message too big for the sso buffer");
321+
absl::BadStatusOrAccess e1{error};
322+
absl::BadStatusOrAccess e2{absl::InternalError("other")};
323+
e2 = e1;
324+
EXPECT_THAT(e1.what(), HasSubstr(error.ToString()));
325+
EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
326+
}
327+
328+
TEST(BadStatusOrAccessTest, MoveConstructionWhatOk) {
329+
absl::Status error =
330+
absl::InternalError("some arbitrary message too big for the sso buffer");
331+
absl::BadStatusOrAccess e1{error};
332+
absl::BadStatusOrAccess e2{std::move(e1)};
333+
EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
334+
}
335+
336+
TEST(BadStatusOrAccessTest, MoveAssignmentWhatOk) {
337+
absl::Status error =
338+
absl::InternalError("some arbitrary message too big for the sso buffer");
339+
absl::BadStatusOrAccess e1{error};
340+
absl::BadStatusOrAccess e2{absl::InternalError("other")};
341+
e2 = std::move(e1);
342+
EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
343+
}
344+
306345
// Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`,
307346
// which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether
308347
// exceptions are enabled.
309348
#ifdef ABSL_HAVE_EXCEPTIONS
310-
#define EXPECT_DEATH_OR_THROW(statement, status_) \
311-
EXPECT_THROW( \
312-
{ \
313-
try { \
314-
statement; \
315-
} catch (const absl::BadStatusOrAccess& e) { \
316-
EXPECT_EQ(e.status(), status_); \
317-
throw; \
318-
} \
319-
}, \
349+
#define EXPECT_DEATH_OR_THROW(statement, status_) \
350+
EXPECT_THROW( \
351+
{ \
352+
try { \
353+
statement; \
354+
} catch (const absl::BadStatusOrAccess& e) { \
355+
EXPECT_EQ(e.status(), status_); \
356+
EXPECT_THAT(e.what(), HasSubstr(e.status().ToString())); \
357+
throw; \
358+
} \
359+
}, \
320360
absl::BadStatusOrAccess);
321361
#else // ABSL_HAVE_EXCEPTIONS
322362
#define EXPECT_DEATH_OR_THROW(statement, status) \
@@ -412,8 +452,6 @@ TEST(StatusOr, TestStatusCtor) {
412452
EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled);
413453
}
414454

415-
416-
417455
TEST(StatusOr, TestValueCtor) {
418456
const int kI = 4;
419457
const absl::StatusOr<int> thing(kI);
@@ -1300,8 +1338,6 @@ TEST(StatusOr, TestPointerDefaultCtor) {
13001338
EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown);
13011339
}
13021340

1303-
1304-
13051341
TEST(StatusOr, TestPointerStatusCtor) {
13061342
absl::StatusOr<int*> thing(absl::CancelledError());
13071343
EXPECT_FALSE(thing.ok());

absl/strings/BUILD.bazel

+19
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,15 @@ cc_library(
271271
"internal/cord_internal.cc",
272272
"internal/cord_rep_btree.cc",
273273
"internal/cord_rep_btree_navigator.cc",
274+
"internal/cord_rep_btree_reader.cc",
274275
"internal/cord_rep_consume.cc",
275276
"internal/cord_rep_ring.cc",
276277
],
277278
hdrs = [
278279
"internal/cord_internal.h",
279280
"internal/cord_rep_btree.h",
280281
"internal/cord_rep_btree_navigator.h",
282+
"internal/cord_rep_btree_reader.h",
281283
"internal/cord_rep_consume.h",
282284
"internal/cord_rep_flat.h",
283285
"internal/cord_rep_ring.h",
@@ -336,6 +338,23 @@ cc_test(
336338
],
337339
)
338340

341+
cc_test(
342+
name = "cord_rep_btree_reader_test",
343+
size = "medium",
344+
srcs = ["internal/cord_rep_btree_reader_test.cc"],
345+
copts = ABSL_TEST_COPTS,
346+
visibility = ["//visibility:private"],
347+
deps = [
348+
":cord",
349+
":cord_internal",
350+
":cord_rep_test_util",
351+
":strings",
352+
"//absl/base:config",
353+
"//absl/base:raw_logging_internal",
354+
"@com_google_googletest//:gtest_main",
355+
],
356+
)
357+
339358
cc_library(
340359
name = "cordz_update_tracker",
341360
hdrs = ["internal/cordz_update_tracker.h"],

0 commit comments

Comments
 (0)