Commit b35973e3 by Abseil Team Committed by Mark Barolak

Export of internal Abseil changes

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

Simplify internal TryAcquireWithSpinning.

No point declaring the `result` variable: we can just return the results
directly.

PiperOrigin-RevId: 307045800

--
421952252bc23be51f47f7d23f3422bad1ed382c by Derek Mauro <dmauro@google.com>:

Add custom sink support for `absl::Format()` through an ADL extension mechanism.

Users can now define
`void AbslFormatFlush(MySink* dest, absl::string_view part)`
to allow `absl::Format()` to append to a custom sink.

PiperOrigin-RevId: 306929052

--
c73d5cdb62cd58ea421ed1aeeab78a0ffcfeeefb by Matt Calabrese <calabrese@google.com>:

Internal-only conformance-testing macro ABSL_INTERNAL_ASSERT_CONFORMANCE_OF for compile-time and runtime checks of a specified type, expected properties of that type, and a logically-ordered series of equivalence classes of that type.

PiperOrigin-RevId: 306885512

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

Internal change

PiperOrigin-RevId: 306766753
GitOrigin-RevId: d857e6e1f9b09a3eb5abd890677a98b23346f07a
Change-Id: Ic23c92ac74f9ffcbb2471ff8c6691f4b7b20354b
parent db5773a7
......@@ -294,6 +294,8 @@ set(ABSL_INTERNAL_DLL_FILES
"types/internal/conformance_aliases.h"
"types/internal/conformance_archetype.h"
"types/internal/conformance_profile.h"
"types/internal/parentheses.h"
"types/internal/transform_args.h"
"types/internal/variant.h"
"types/optional.h"
"types/internal/optional.h"
......
......@@ -651,6 +651,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord",
":str_format",
":strings",
"//absl/base:core_headers",
......@@ -666,8 +667,10 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord",
":str_format",
":str_format_internal",
":strings",
"@com_google_googletest//:gtest_main",
],
)
......@@ -726,6 +729,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord",
":str_format_internal",
"@com_google_googletest//:gtest_main",
],
......
......@@ -409,6 +409,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::str_format
absl::cord
absl::strings
absl::core_headers
gmock_main
......@@ -424,6 +425,8 @@ absl_cc_test(
DEPS
absl::str_format
absl::str_format_internal
absl::cord
absl::strings
gmock_main
)
......@@ -487,6 +490,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::str_format_internal
absl::cord
gmock_main
)
......
......@@ -19,9 +19,27 @@
#include <random>
#include <string>
#include "absl/strings/cord.h"
#include "gtest/gtest.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "gtest/gtest.h"
namespace my_namespace {
class UserDefinedType {
public:
UserDefinedType() = default;
void Append(absl::string_view str) { value_.append(str.data(), str.size()); }
const std::string& Value() const { return value_; }
friend void AbslFormatFlush(UserDefinedType* x, absl::string_view str) {
x->Append(str);
}
private:
std::string value_;
};
} // namespace my_namespace
namespace {
......@@ -63,4 +81,21 @@ TEST(FormatExtensionTest, SinkAppendChars) {
EXPECT_EQ(actual, expected);
}
}
TEST(FormatExtensionTest, CordSink) {
absl::Cord c;
absl::Format(&c, "There were %04d little %s.", 3, "pigs");
EXPECT_EQ(c, "There were 0003 little pigs.");
absl::Format(&c, "And %-3llx bad wolf!", 1);
EXPECT_EQ(c, "There were 0003 little pigs.And 1 bad wolf!");
}
TEST(FormatExtensionTest, CustomSink) {
my_namespace::UserDefinedType sink;
absl::Format(&sink, "There were %04d little %s.", 3, "pigs");
EXPECT_EQ("There were 0003 little pigs.", sink.Value());
absl::Format(&sink, "And %-3llx bad wolf!", 1);
EXPECT_EQ("There were 0003 little pigs.And 1 bad wolf!", sink.Value());
}
} // namespace
......@@ -91,10 +91,11 @@ inline void AbslFormatFlush(BufferRawSink* sink, string_view v) {
sink->Write(v);
}
// This is a SFINAE to get a better compiler error message when the type
// is not supported.
template <typename T>
auto InvokeFlush(T* out, string_view s)
-> decltype(str_format_internal::AbslFormatFlush(out, s)) {
str_format_internal::AbslFormatFlush(out, s);
auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) {
AbslFormatFlush(out, s);
}
} // namespace str_format_internal
......
......@@ -19,6 +19,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/strings/cord.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
......@@ -37,6 +38,12 @@ TEST(InvokeFlush, Stream) {
EXPECT_EQ(str.str(), "ABCDEF");
}
TEST(InvokeFlush, Cord) {
absl::Cord str("ABC");
str_format_internal::InvokeFlush(&str, "DEF");
EXPECT_EQ(str, "ABCDEF");
}
TEST(BufferRawSink, Limits) {
char buf[16];
{
......@@ -70,4 +77,3 @@ TEST(BufferRawSink, Limits) {
} // namespace
ABSL_NAMESPACE_END
} // namespace absl
......@@ -57,8 +57,7 @@
// arbitrary sink types:
//
// * A generic `Format()` function to write outputs to arbitrary sink types,
// which must implement a `RawSinkFormat` interface. (See
// `str_format_sink.h` for more information.)
// which must implement a `FormatRawSink` interface.
//
// * A `FormatUntyped()` function that is similar to `Format()` except it is
// loosely typed. `FormatUntyped()` is not a template and does not perform
......@@ -432,6 +431,16 @@ int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format,
//
// FormatRawSink is a type erased wrapper around arbitrary sink objects
// specifically used as an argument to `Format()`.
//
// All the object has to do define an overload of `AbslFormatFlush()` for the
// sink, usually by adding a ADL-based free function in the same namespace as
// the sink:
//
// void AbslFormatFlush(MySink* dest, absl::string_view part);
//
// where `dest` is the pointer passed to `absl::Format()`. The function should
// append `part` to `dest`.
//
// FormatRawSink does not own the passed sink object. The passed object must
// outlive the FormatRawSink.
class FormatRawSink {
......@@ -455,12 +464,13 @@ class FormatRawSink {
// `absl::FormatRawSink` interface), using a format string and zero or more
// additional arguments.
//
// By default, `std::string` and `std::ostream` are supported as destination
// objects. If a `std::string` is used the formatted string is appended to it.
// By default, `std::string`, `std::ostream`, and `absl::Cord` are supported as
// destination objects. If a `std::string` is used the formatted string is
// appended to it.
//
// `absl::Format()` is a generic version of `absl::StrFormat(), for custom
// sinks. The format string, like format strings for `StrFormat()`, is checked
// at compile-time.
// `absl::Format()` is a generic version of `absl::StrAppendFormat()`, for
// custom sinks. The format string, like format strings for `StrFormat()`, is
// checked at compile-time.
//
// On failure, this function returns `false` and the state of the sink is
// unspecified.
......
......@@ -1439,20 +1439,18 @@ void Mutex::AssertNotHeld() const {
// may spin for a short while if the lock cannot be acquired immediately.
static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) {
int c = mutex_globals.spinloop_iterations;
int result = -1; // result of operation: 0=false, 1=true, -1=unknown
do { // do/while somewhat faster on AMD
intptr_t v = mu->load(std::memory_order_relaxed);
if ((v & (kMuReader|kMuEvent)) != 0) { // a reader or tracing -> give up
result = 0;
if ((v & (kMuReader|kMuEvent)) != 0) {
return false; // a reader or tracing -> give up
} else if (((v & kMuWriter) == 0) && // no holder -> try to acquire
mu->compare_exchange_strong(v, kMuWriter | v,
std::memory_order_acquire,
std::memory_order_relaxed)) {
result = 1;
return true;
}
} while (result == -1 && --c > 0);
return result == 1;
} while (--c > 0);
return false;
}
ABSL_XRAY_LOG_ARGS(1) void Mutex::Lock() {
......
......@@ -216,11 +216,15 @@ cc_library(
"internal/conformance_aliases.h",
"internal/conformance_archetype.h",
"internal/conformance_profile.h",
"internal/conformance_testing.h",
"internal/conformance_testing_helpers.h",
"internal/parentheses.h",
"internal/transform_args.h",
],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/debugging:demangle_internal",
"//absl/algorithm:container",
"//absl/meta:type_traits",
"//absl/strings",
"//absl/utility",
......
......@@ -246,9 +246,14 @@ absl_cc_library(
"internal/conformance_aliases.h"
"internal/conformance_archetype.h"
"internal/conformance_profile.h"
"internal/conformance_testing.h",
"internal/conformance_testing_helpers.h",
"internal/parentheses.h",
"internal/transform_args.h",
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::algorithm
absl::debugging
absl::type_traits
absl::strings
......@@ -282,6 +287,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::conformance_testing
absl::type_traits
gmock_main
)
......
// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// parentheses.h
// -----------------------------------------------------------------------------
//
// This file contains macros that expand to a left parenthesis and a right
// parenthesis. These are in their own file and are generated from macros
// because otherwise clang-format gets confused and clang-format off directives
// do not help.
//
// The parentheses macros are used when wanting to require a rescan before
// expansion of parenthesized text appearing after a function-style macro name.
#ifndef ABSL_TYPES_INTERNAL_PARENTHESES_H_
#define ABSL_TYPES_INTERNAL_PARENTHESES_H_
#define ABSL_INTERNAL_LPAREN (
#define ABSL_INTERNAL_RPAREN )
#endif // ABSL_TYPES_INTERNAL_PARENTHESES_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment