diff options
author | Randolf J <34705014+jun-sheaf@users.noreply.github.com> | 2022-10-05 22:51:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 22:51:24 +0200 |
commit | beaec233795725fea58fd88b2f9271aa7decabce (patch) | |
tree | 73a75125b0787d3b47f32ae29b079bec864b9102 | |
parent | bf2bf60a3e29f159c8aa513d58cbe65f3f633bb6 (diff) | |
parent | 1fd600dc490db4db0ebf7bcc629d8914e828467e (diff) |
Merge branch 'abseil:master' into patch-1
-rw-r--r-- | absl/base/internal/thread_annotations.h | 9 | ||||
-rw-r--r-- | absl/container/BUILD.bazel | 3 | ||||
-rw-r--r-- | absl/container/CMakeLists.txt | 3 | ||||
-rw-r--r-- | absl/container/internal/common_policy_traits.h | 15 | ||||
-rw-r--r-- | absl/container/internal/common_policy_traits_test.cc | 9 | ||||
-rw-r--r-- | absl/container/internal/container_memory.h | 13 | ||||
-rw-r--r-- | absl/container/internal/raw_hash_set_test.cc | 27 | ||||
-rw-r--r-- | absl/hash/CMakeLists.txt | 5 | ||||
-rw-r--r-- | absl/log/internal/log_sink_set.cc | 1 | ||||
-rw-r--r-- | absl/log/log_entry.h | 6 | ||||
-rw-r--r-- | absl/strings/BUILD.bazel | 5 | ||||
-rw-r--r-- | absl/strings/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/strings/charconv.cc | 106 | ||||
-rw-r--r-- | absl/strings/cord_test.cc | 1 | ||||
-rw-r--r-- | absl/strings/str_cat.h | 5 | ||||
-rw-r--r-- | absl/strings/str_cat_test.cc | 18 | ||||
-rw-r--r-- | absl/strings/str_format.h | 5 | ||||
-rw-r--r-- | absl/strings/str_format_test.cc | 17 | ||||
-rw-r--r-- | absl/types/internal/variant.h | 62 |
19 files changed, 183 insertions, 129 deletions
diff --git a/absl/base/internal/thread_annotations.h b/absl/base/internal/thread_annotations.h index 4dab6a9c..8c5c67e0 100644 --- a/absl/base/internal/thread_annotations.h +++ b/absl/base/internal/thread_annotations.h @@ -38,6 +38,13 @@ #ifndef ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_ #define ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_ +// ABSL_LEGACY_THREAD_ANNOTATIONS is a *temporary* compatibility macro that can +// be defined on the compile command-line to restore the legacy spellings of the +// thread annotations macros/functions. The macros in this file are available +// under ABSL_ prefixed spellings in absl/base/thread_annotations.h. This macro +// and the legacy spellings will be removed in the future. +#ifdef ABSL_LEGACY_THREAD_ANNOTATIONS + #if defined(__clang__) #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) #else @@ -268,4 +275,6 @@ inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS { } // namespace thread_safety_analysis +#endif // defined(ABSL_LEGACY_THREAD_ANNOTATIONS) + #endif // ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_ diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 71afe9d2..15162f28 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -637,6 +637,8 @@ cc_test( ], deps = [ ":container_memory", + ":flat_hash_map", + ":flat_hash_set", ":hash_function_defaults", ":hash_policy_testing", ":hashtable_debug", @@ -646,6 +648,7 @@ cc_test( "//absl/base:core_headers", "//absl/base:prefetch", "//absl/base:raw_logging_internal", + "//absl/log", "//absl/strings", "@com_google_googletest//:gtest_main", ], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index a3fdb969..6c2931b6 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -722,12 +722,15 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::container_memory + absl::flat_hash_map + absl::flat_hash_set absl::hash_function_defaults absl::hash_policy_testing absl::hashtable_debug absl::raw_hash_set absl::base absl::config + absl::log absl::core_headers absl::prefetch absl::raw_logging_internal diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h index cc2e89ba..c99e68f4 100644 --- a/absl/container/internal/common_policy_traits.h +++ b/absl/container/internal/common_policy_traits.h @@ -16,6 +16,7 @@ #define ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_ #include <cstddef> +#include <cstring> #include <memory> #include <new> #include <type_traits> @@ -32,7 +33,8 @@ template <class Policy, class = void> struct common_policy_traits { // The actual object stored in the container. using slot_type = typename Policy::slot_type; - + using reference = decltype(Policy::element(std::declval<slot_type*>())); + using value_type = typename std::remove_reference<reference>::type; // PRECONDITION: `slot` is UNINITIALIZED // POSTCONDITION: `slot` is INITIALIZED @@ -89,6 +91,17 @@ struct common_policy_traits { template <class Alloc> static void transfer_impl(Alloc* alloc, slot_type* new_slot, slot_type* old_slot, char) { +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + if (absl::is_trivially_relocatable<value_type>()) { + // TODO(b/247130232): remove cast after fixing class-memaccess warning. + std::memcpy(static_cast<void*>( + std::launder(const_cast<std::remove_const_t<value_type>*>( + &element(new_slot)))), + &element(old_slot), sizeof(value_type)); + return; + } +#endif + construct(alloc, new_slot, std::move(element(old_slot))); destroy(alloc, old_slot); } diff --git a/absl/container/internal/common_policy_traits_test.cc b/absl/container/internal/common_policy_traits_test.cc index 768d870e..5eaa4aae 100644 --- a/absl/container/internal/common_policy_traits_test.cc +++ b/absl/container/internal/common_policy_traits_test.cc @@ -27,7 +27,7 @@ namespace container_internal { namespace { using ::testing::MockFunction; -using ::testing::Return; +using ::testing::AnyNumber; using ::testing::ReturnRef; using Slot = int; @@ -101,9 +101,10 @@ TEST_F(Test, element) { TEST_F(Test, without_transfer) { int b = 42; - EXPECT_CALL(element, Call(&b)).WillOnce(::testing::ReturnRef(b)); - EXPECT_CALL(construct, Call(&alloc, &a, b)); - EXPECT_CALL(destroy, Call(&alloc, &b)); + EXPECT_CALL(element, Call(&a)).Times(AnyNumber()).WillOnce(ReturnRef(a)); + EXPECT_CALL(element, Call(&b)).WillOnce(ReturnRef(b)); + EXPECT_CALL(construct, Call(&alloc, &a, b)).Times(AnyNumber()); + EXPECT_CALL(destroy, Call(&alloc, &b)).Times(AnyNumber()); common_policy_traits<PolicyWithoutOptionalOps>::transfer(&alloc, &a, &b); } diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 00e9f6d7..c29c533b 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -17,6 +17,7 @@ #include <cassert> #include <cstddef> +#include <cstring> #include <memory> #include <new> #include <tuple> @@ -340,7 +341,8 @@ template <class K, class V> struct map_slot_policy { using slot_type = map_slot_type<K, V>; using value_type = std::pair<const K, V>; - using mutable_value_type = std::pair<K, V>; + using mutable_value_type = + std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>; private: static void emplace(slot_type* slot) { @@ -424,6 +426,15 @@ struct map_slot_policy { static void transfer(Allocator* alloc, slot_type* new_slot, slot_type* old_slot) { emplace(new_slot); +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + if (absl::is_trivially_relocatable<value_type>()) { + // TODO(b/247130232): remove cast after fixing class-memaccess warning. + std::memcpy(static_cast<void*>(std::launder(&new_slot->value)), + &old_slot->value, sizeof(value_type)); + return; + } +#endif + if (kMutableKeys::value) { absl::allocator_traits<Allocator>::construct( *alloc, &new_slot->mutable_value, std::move(old_slot->mutable_value)); diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index f77ffbc1..eec9da43 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -14,17 +14,25 @@ #include "absl/container/internal/raw_hash_set.h" +#include <algorithm> #include <atomic> #include <cmath> #include <cstdint> #include <deque> #include <functional> +#include <iterator> +#include <list> +#include <map> #include <memory> #include <numeric> +#include <ostream> #include <random> #include <string> +#include <type_traits> #include <unordered_map> #include <unordered_set> +#include <utility> +#include <vector> #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -33,10 +41,13 @@ #include "absl/base/internal/cycleclock.h" #include "absl/base/internal/prefetch.h" #include "absl/base/internal/raw_logging.h" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" #include "absl/container/internal/hash_policy_testing.h" #include "absl/container/internal/hashtable_debug.h" +#include "absl/log/log.h" #include "absl/strings/string_view.h" namespace absl { @@ -339,7 +350,7 @@ class StringPolicy { struct ctor {}; template <class... Ts> - slot_type(ctor, Ts&&... ts) : pair(std::forward<Ts>(ts)...) {} + explicit slot_type(ctor, Ts&&... ts) : pair(std::forward<Ts>(ts)...) {} std::pair<std::string, std::string> pair; }; @@ -411,7 +422,7 @@ struct CustomAlloc : std::allocator<T> { CustomAlloc() {} template <typename U> - CustomAlloc(const CustomAlloc<U>& other) {} + explicit CustomAlloc(const CustomAlloc<U>& /*other*/) {} template<class U> struct rebind { using other = CustomAlloc<U>; @@ -1275,6 +1286,7 @@ TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) { for (size_t size : sizes) { auto& stat = stats[size]; VerifyStats(size, expected, stat); + LOG(INFO) << size << " " << stat; } } @@ -1370,6 +1382,7 @@ TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) { for (size_t size : sizes) { auto& stat = stats[size]; VerifyStats(size, expected, stat); + LOG(INFO) << size << " " << stat; } } @@ -1504,7 +1517,7 @@ TEST(Table, RehashZeroForcesRehash) { TEST(Table, ConstructFromInitList) { using P = std::pair<std::string, std::string>; struct Q { - operator P() const { return {}; } + operator P() const { return {}; } // NOLINT }; StringTable t = {P(), Q(), {}, {{}, {}}}; } @@ -2027,7 +2040,7 @@ TEST(Table, UnstablePointers) { TEST(TableDeathTest, EraseOfEndAsserts) { // Use an assert with side-effects to figure out if they are actually enabled. bool assert_enabled = false; - assert([&]() { + assert([&]() { // NOLINT assert_enabled = true; return true; }()); @@ -2047,7 +2060,7 @@ TEST(RawHashSamplerTest, Sample) { auto& sampler = GlobalHashtablezSampler(); size_t start_size = 0; - std::unordered_set<const HashtablezInfo*> preexisting_info; + absl::flat_hash_set<const HashtablezInfo*> preexisting_info; start_size += sampler.Iterate([&](const HashtablezInfo& info) { preexisting_info.insert(&info); ++start_size; @@ -2074,8 +2087,8 @@ TEST(RawHashSamplerTest, Sample) { } } size_t end_size = 0; - std::unordered_map<size_t, int> observed_checksums; - std::unordered_map<ssize_t, int> reservations; + absl::flat_hash_map<size_t, int> observed_checksums; + absl::flat_hash_map<ssize_t, int> reservations; end_size += sampler.Iterate([&](const HashtablezInfo& info) { if (preexisting_info.count(&info) == 0) { observed_checksums[info.hashes_bitwise_xor.load( diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index 46365790..15691254 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt @@ -82,6 +82,10 @@ absl_cc_test( ) # Internal-only target, do not depend on directly. +# +# Note: Even though external code should not depend on this target +# directly, it must be marked PUBLIC since it is a dependency of +# hash_testing. absl_cc_library( NAME spy_hash_state @@ -94,6 +98,7 @@ absl_cc_library( absl::strings absl::str_format TESTONLY + PUBLIC ) # Internal-only target, do not depend on directly. diff --git a/absl/log/internal/log_sink_set.cc b/absl/log/internal/log_sink_set.cc index 4fe301c6..f9d030aa 100644 --- a/absl/log/internal/log_sink_set.cc +++ b/absl/log/internal/log_sink_set.cc @@ -69,6 +69,7 @@ bool& ThreadIsLoggingStatus() { } return true; }(); + (void)unused; // Fixes -wunused-variable warning bool* thread_is_logging_ptr = reinterpret_cast<bool*>(pthread_getspecific(thread_is_logging_key)); diff --git a/absl/log/log_entry.h b/absl/log/log_entry.h index d90961fe..30114c33 100644 --- a/absl/log/log_entry.h +++ b/absl/log/log_entry.h @@ -58,8 +58,10 @@ class LogEntry final { static constexpr int kNoVerbosityLevel = -1; static constexpr int kNoVerboseLevel = -1; // TO BE removed - LogEntry(const LogEntry&) = default; - LogEntry& operator=(const LogEntry&) = default; + // Pass `LogEntry` by reference, and do not store it as its state does not + // outlive the call to `LogSink::Send()`. + LogEntry(const LogEntry&) = delete; + LogEntry& operator=(const LogEntry&) = delete; // Source file and line where the log message occurred. Taken from `__FILE__` // and `__LINE__` unless overridden by `LOG(...).AtLocation(...)`. diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index ba7ae835..5b12c010 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -747,13 +747,13 @@ cc_test( ":cordz_test_helpers", ":str_format", ":strings", - "//absl/base", "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", "//absl/base:raw_logging_internal", "//absl/container:fixed_array", "//absl/hash", + "//absl/log", "//absl/random", "@com_google_googletest//:gtest_main", ], @@ -963,8 +963,8 @@ cc_test( copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ + ":str_format", ":strings", - "//absl/base:core_headers", "@com_google_googletest//:gtest_main", ], ) @@ -1164,7 +1164,6 @@ cc_test( ":cord", ":str_format", ":strings", - "//absl/base:core_headers", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index bb073301..01f86184 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -281,6 +281,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings + absl::str_format absl::core_headers GTest::gmock_main ) @@ -903,6 +904,7 @@ absl_cc_library( absl::cord_internal absl::strings TESTONLY + PUBLIC ) # Internal-only target, do not depend on directly. diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index a961d16c..501297c8 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -229,6 +229,8 @@ struct FloatTraits<float> { // // 2**63 <= Power10Mantissa(n) < 2**64. // +// See the "Table of powers of 10" comment below for a "1e60" example. +// // Lookups into the power-of-10 table must first check the Power10Overflow() and // Power10Underflow() functions, to avoid out-of-bounds table access. // @@ -236,7 +238,6 @@ struct FloatTraits<float> { // indexes range from kPower10TableMinInclusive to kPower10TableMaxExclusive. extern const uint64_t kPower10MantissaHighTable[]; // High 64 of 128 bits. extern const uint64_t kPower10MantissaLowTable[]; // Low 64 of 128 bits. -extern const int16_t kPower10ExponentTable[]; // The smallest (inclusive) allowed value for use with the Power10Mantissa() // and Power10Exponent() functions below. (If a smaller exponent is needed in @@ -253,7 +254,11 @@ uint64_t Power10Mantissa(int n) { } int Power10Exponent(int n) { - return kPower10ExponentTable[n - kPower10TableMinInclusive]; + // The 217706 etc magic numbers encode the results as a formula instead of a + // table. Their equivalence (over the kPower10TableMinInclusive .. + // kPower10TableMaxExclusive range) is confirmed by + // https://github.com/google/wuffs/blob/315b2e52625ebd7b02d8fac13e3cd85ea374fb80/script/print-mpb-powers-of-10.go + return (217706 * n >> 16) - 63; } // Returns true if n is large enough that 10**n always results in an IEEE @@ -698,9 +703,7 @@ bool EiselLemire(const strings_internal::ParsedFloat& input, bool negative, // (+) Normalization. int clz = countl_zero(man); man <<= static_cast<unsigned int>(clz); - // The 217706 etc magic numbers encode the kPower10ExponentTable as a formula - // instead of a table. Their equivalence is confirmed by - // https://github.com/google/wuffs/blob/315b2e52625ebd7b02d8fac13e3cd85ea374fb80/script/print-mpb-powers-of-10.go + // The 217706 etc magic numbers are from the Power10Exponent function. uint64_t ret_exp2 = static_cast<uint64_t>((217706 * exp10 >> 16) + 64 + FloatTraits<FloatType>::kExponentBias - clz); @@ -935,13 +938,33 @@ namespace { // kPower10MantissaHighTable[i - kPower10TableMinInclusive] stores the 64-bit // mantissa. The high bit is always on. // -// kPower10ExponentTable[i - kPower10TableMinInclusive] stores the power-of-two -// exponent. +// kPower10MantissaLowTable extends that 64-bit mantissa to 128 bits. // -// For a given number i, this gives the unique mantissa and exponent such that -// (mantissa * 2**exponent) <= 10**i < ((mantissa + 1) * 2**exponent). +// Power10Exponent(i) calculates the power-of-two exponent. // -// kPower10MantissaLowTable extends that 64-bit mantissa to 128 bits. +// For a number i, this gives the unique mantissaHigh and exponent such that +// (mantissaHigh * 2**exponent) <= 10**i < ((mantissaHigh + 1) * 2**exponent). +// +// For example, Python can confirm that the exact hexadecimal value of 1e60 is: +// >>> a = 1000000000000000000000000000000000000000000000000000000000000 +// >>> hex(a) +// '0x9f4f2726179a224501d762422c946590d91000000000000000' +// Adding underscores at every 8th hex digit shows 50 hex digits: +// '0x9f4f2726_179a2245_01d76242_2c946590_d9100000_00000000_00'. +// In this case, the high bit of the first hex digit, 9, is coincidentally set, +// so we do not have to do further shifting to deduce the 128-bit mantissa: +// - kPower10MantissaHighTable[60 - kP10TMI] = 0x9f4f2726179a2245U +// - kPower10MantissaLowTable[ 60 - kP10TMI] = 0x01d762422c946590U +// where kP10TMI is kPower10TableMinInclusive. The low 18 of those 50 hex +// digits are truncated. +// +// 50 hex digits (with the high bit set) is 200 bits and mantissaHigh holds 64 +// bits, so Power10Exponent(60) = 200 - 64 = 136. Again, Python can confirm: +// >>> b = 0x9f4f2726179a2245 +// >>> ((b+0)<<136) <= a +// True +// >>> ((b+1)<<136) <= a +// False // // The tables were generated by // https://github.com/google/wuffs/blob/315b2e52625ebd7b02d8fac13e3cd85ea374fb80/script/print-mpb-powers-of-10.go @@ -1388,69 +1411,6 @@ const uint64_t kPower10MantissaLowTable[] = { 0xe0133fe4adf8e952U, 0x58180fddd97723a6U, 0x570f09eaa7ea7648U, }; -const int16_t kPower10ExponentTable[] = { - -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, - -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, - -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, - -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, - -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, - -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, - -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, - -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, - -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, - -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, - -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, - -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, - -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, - -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, - -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, - -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, - -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, - -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, - -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, - -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, - -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, - -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, - -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, - -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, - -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, - -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, - -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, - -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, - -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, - -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, - -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, - -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, - -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, - 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, - 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, - 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, - 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, - 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, - 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, - 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, - 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, - 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, - 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, - 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, - 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, - 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, - 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, - 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, - 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, - 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, - 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, - 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, - 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, - 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, - 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, - 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, - 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, - 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, - 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, - 956, 960, -}; - } // namespace ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index d28ba113..1fc4be6e 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -28,7 +28,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/casts.h" #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/raw_logging.h" diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 05728ab5..6ee88f14 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -85,6 +85,11 @@ class StringifySink { bool PutPaddedString(string_view v, int width, int precision, bool left); + // Support `absl::Format(&sink, format, args...)`. + friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) { + sink->Append(v); + } + template <typename T> friend string_view ExtractStringification(StringifySink& sink, const T& v); diff --git a/absl/strings/str_cat_test.cc b/absl/strings/str_cat_test.cc index 868b9bce..1b3b7ece 100644 --- a/absl/strings/str_cat_test.cc +++ b/absl/strings/str_cat_test.cc @@ -21,6 +21,7 @@ #include <vector> #include "gtest/gtest.h" +#include "absl/strings/str_format.h" #include "absl/strings/substitute.h" #ifdef __ANDROID__ @@ -632,4 +633,21 @@ TEST(StrCat, AbslStringifyExample) { EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z"); } +struct PointStringifyUsingFormat { + template <typename FormatSink> + friend void AbslStringify(FormatSink& sink, + const PointStringifyUsingFormat& p) { + absl::Format(&sink, "(%g, %g)", p.x, p.y); + } + + double x = 10.0; + double y = 20.0; +}; + +TEST(StrCat, AbslStringifyExampleUsingFormat) { + PointStringifyUsingFormat p; + EXPECT_EQ(absl::StrCat(p), "(10, 20)"); + EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z"); +} + } // namespace diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index e6537ea0..ffbcb9af 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -789,6 +789,11 @@ class FormatSink { return sink_->PutPaddedString(v, width, precision, left); } + // Support `absl::Format(&sink, format, args...)`. + friend void AbslFormatFlush(FormatSink* sink, absl::string_view v) { + sink->Append(v); + } + private: friend str_format_internal::FormatSinkImpl; explicit FormatSink(str_format_internal::FormatSinkImpl* s) : sink_(s) {} diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 0c4f10c8..62ed262d 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -1118,6 +1118,23 @@ TEST_F(FormatExtensionTest, AbslStringifyExample) { PointStringify p; EXPECT_EQ(absl::StrFormat("a %v z", p), "a (10, 20) z"); } + +struct PointStringifyUsingFormat { + template <typename FormatSink> + friend void AbslStringify(FormatSink& sink, + const PointStringifyUsingFormat& p) { + absl::Format(&sink, "(%g, %g)", p.x, p.y); + } + + double x = 10.0; + double y = 20.0; +}; + +TEST_F(FormatExtensionTest, AbslStringifyExampleUsingFormat) { + PointStringifyUsingFormat p; + EXPECT_EQ(absl::StrFormat("a %v z", p), "a (10, 20) z"); +} + } // namespace // Some codegen thunks that we can use to easily dump the generated assembly for diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 9adea563..c82ded44 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -449,7 +449,7 @@ struct FlattenIndices; template <std::size_t HeadSize, std::size_t... TailSize> struct FlattenIndices<HeadSize, TailSize...> { - template<class... SizeType> + template <class... SizeType> static constexpr std::size_t Run(std::size_t head, SizeType... tail) { return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...); } @@ -498,8 +498,8 @@ struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> { }; template <class Op, class... SizeType> - static VisitIndicesResultT<Op, decltype(EndIndices)...> Run( - Op&& op, SizeType... i) { + static VisitIndicesResultT<Op, decltype(EndIndices)...> Run(Op&& op, + SizeType... i) { return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run( FlattenedOp<Op>{absl::forward<Op>(op)}, FlattenIndices<(EndIndices + std::size_t{1})...>::Run( @@ -683,13 +683,13 @@ struct VariantCoreAccess { variant_internal::IndexOfConstructedType<Left, QualifiedNew>; void operator()(SizeT<NewIndex::value> /*old_i*/ - ) const { + ) const { Access<NewIndex::value>(*left) = absl::forward<QualifiedNew>(other); } template <std::size_t OldIndex> void operator()(SizeT<OldIndex> /*old_i*/ - ) const { + ) const { using New = typename absl::variant_alternative<NewIndex::value, Left>::type; if (std::is_nothrow_constructible<New, QualifiedNew>::value || @@ -868,18 +868,6 @@ struct IsNeitherSelfNorInPlace<Self, in_place_type_t<T>> : std::false_type {}; template <class Self, std::size_t I> struct IsNeitherSelfNorInPlace<Self, in_place_index_t<I>> : std::false_type {}; -template <class Variant, class T, class = void> -struct ConversionIsPossibleImpl : std::false_type {}; - -template <class Variant, class T> -struct ConversionIsPossibleImpl< - Variant, T, - void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {}))>> - : std::true_type {}; - -template <class Variant, class T> -struct ConversionIsPossible : ConversionIsPossibleImpl<Variant, T>::type {}; - template <class Variant, class T> struct IndexOfConstructedType< Variant, T, @@ -1151,16 +1139,16 @@ struct VariantHelper<variant<Ts...>> { // Type metafunction which returns the element type selected if // OverloadSet::Overload() is well-formed when called with argument type U. template <typename U> - using BestMatch = decltype( - variant_internal::OverloadSet<Ts...>::Overload(std::declval<U>())); + using BestMatch = decltype(variant_internal::OverloadSet<Ts...>::Overload( + std::declval<U>())); // Type metafunction which returns true if OverloadSet::Overload() is // well-formed when called with argument type U. // CanAccept can't be just an alias because there is a MSVC bug on parameter // pack expansion involving decltype. template <typename U> - struct CanAccept : - std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {}; + struct CanAccept + : std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {}; // Type metafunction which returns true if Other is an instantiation of // variant, and variants's converting constructor from Other will be @@ -1183,8 +1171,8 @@ struct TrivialMoveOnly { // A union's defaulted copy/move constructor is deleted if any variant member's // copy/move constructor is nontrivial. template <typename T> -struct IsTriviallyMoveConstructible: - std::is_move_constructible<Union<T, TrivialMoveOnly>> {}; +struct IsTriviallyMoveConstructible + : std::is_move_constructible<Union<T, TrivialMoveOnly>> {}; // To guarantee triviality of all special-member functions that can be trivial, // we use a chain of conditional bases for each one. @@ -1419,14 +1407,14 @@ class VariantMoveAssignBaseNontrivial : protected VariantCopyBase<T...> { VariantMoveAssignBaseNontrivial& operator=( VariantMoveAssignBaseNontrivial const&) = default; - VariantMoveAssignBaseNontrivial& - operator=(VariantMoveAssignBaseNontrivial&& other) noexcept( - absl::conjunction<std::is_nothrow_move_constructible<T>..., - std::is_nothrow_move_assignable<T>...>::value) { - VisitIndices<sizeof...(T)>::Run( - VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_); - return *this; - } + VariantMoveAssignBaseNontrivial& + operator=(VariantMoveAssignBaseNontrivial&& other) noexcept( + absl::conjunction<std::is_nothrow_move_constructible<T>..., + std::is_nothrow_move_assignable<T>...>::value) { + VisitIndices<sizeof...(T)>::Run( + VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_); + return *this; + } protected: using Base::index_; @@ -1450,12 +1438,12 @@ class VariantCopyAssignBaseNontrivial : protected VariantMoveAssignBase<T...> { VariantCopyAssignBaseNontrivial& operator=( VariantCopyAssignBaseNontrivial&&) = default; - VariantCopyAssignBaseNontrivial& operator=( - const VariantCopyAssignBaseNontrivial& other) { - VisitIndices<sizeof...(T)>::Run( - VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_); - return *this; - } + VariantCopyAssignBaseNontrivial& operator=( + const VariantCopyAssignBaseNontrivial& other) { + VisitIndices<sizeof...(T)>::Run( + VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_); + return *this; + } protected: using Base::index_; |